2024年4月入社の吉岡です。以前から「Linuxはコードを書くよりも直感的でないし自分にサーバ・インフラ関係はよくわからない…」と苦手意識を持っていたのですが、苦手なまま避け続けるのは精神衛生によくないと感じ取り組んでみることにしました。現在はLinuCレベル1の取得を目指しており、LinuC公式のテキストとPing-tに取り組んでいます。その中で学んだLinuxのファイルやディレクトリのパーミッションについてまとめさせていただきました。
誰向けの記事か:プログラミング諸学者向け
目次
- パーミッションとは
- ディレクトリのパーミッション設定例
- 特殊なパーミッション
- デフォルトパーミッションの設定
〇パーミッションとは
パーミッションはアクセス権限のことであり、主に用いられるパーミッションとして、読込権限・書込権限・実行権限の3種類があります。各パーミッションを所有者・グループ・その他ユーザごとに設定することでセキュリティを高め、システムの目的に沿った使用がされやすくなります。
各パーミッションで可能になる動作を下記の表にまとめました。
パーミッション | ファイルの場合 | ディレクトリの場合 |
読込権限(r|4) | ファイルの内容を表示 | ファイルのリストを表示 |
書込権限(w|2) | ファイルの上書き | ファイル作成・削除 |
実行権限(x|1) | ファイルの実行 | ディレクトリ内に入れる |
「$ls -l ファイル名」 または 「$ls -dl ディレクトリ名」 で10桁のパーミッションコードを確認することができます。
パーミッションコードの左から1番目の記号はファイルの種類を表しており、左から2~4番目が所有者のパーミッション、左から5~7番目がグループのパーミッション、左から8~10番目がその他ユーザのパーミッションを表しています。
パーミッションコード例: -rwxr-x–x
ファイルタイプ:「ファイル」
所有者のパーミッション:「読込権限・書込権限・実行権限」
グループのパーミッション:「読込権限・実行権限」
その他ユーザのパーミッション:「実行権限」
ファイルタイプ記号 | ファイルタイプ |
– | ファイル |
d | ディレクトリ |
l | シンボリックリンク |
c | キャラクタデバイス(キーボードなど) |
b | ブロックファイル() |
s | ソケット(双方向) |
p | FIFO(一方向) |
? | その他 |
パーミッションを変更したい場合は、chmod コマンド で8進数またはシンボルで変更後のパーミッションをしてすることができます。
・8進数で指定する場合
付与したいパーミッションを読込権限(4)、書込権限(2)、実行権限(1)とした時の合計値でsi表現する。3桁の8進数で指定する場合は左から所有者のパーミッション・グループのパーミッション・その他ユーザのパーミッションを設定し、4桁の場合は左から特殊パーミッション・所有者のパーミッション・グループのパーミッション・その他ユーザのパーミッションを設定する。

・シンボルで指定する場合
付与したいパーミッションを読込権限(r)、書込権限(w)、実行権限(x)、で表現する。所有者のパーミッション(u),グループのパーミッション(g),その他ユーザのパーミッション(o)に対してそれぞれ設定したいパーミッションを設定する。

〇ディレクトリのパーミッション設定例
個人的にディレクトリのパーミッションは動作を行うことができるのかわかりづらいと感じたので、いつくか具体的な例を挙げさせていただきます。
例1:ディレクトリに読込権限はあるが実行権限がない場合
読込権限があるのでディレクトリ自体の情報は参照できるが、実行権限がないのでディレクトリの中には入れずディレクトリのリストの中身を表示できません。

実行権限を付与したら、リストの中身を取得できます。中身を追加していないのでカレントディレクトリと親ディレクトリのみです。

例2:ディレクトリに読込権限と書込権限はあるが実行権限がない場合
ディレクトリの中に入ることができないので、touch コマンドやリダイレクトを用いてファイルの作成やファイル内容の更新や削除はできない。

*ただしディレクトリ中に入る必要がないので、ディレクトリ名の変更はできる。

実行権限を付与したら、ファイルの作成やファイル内容の更新や削除ができるようになりました。今回は「>」 を用いて文字列の標準出力先を指定ファイルにリダイレクト(宛先ファイルが存在しなければ新規作成/存在すれば上書き)を行い、「>>」 を用いてファイルの中身へ追記を行いました。

例3:権限のないファイルの削除
sample2 ディレクトリ : 読込権限と書込権限と実行権限がある。
sample2/sampleA.txt : 読込権限と書込権限と実行権限がない。
この状態でファイルの削除をしようとすると…削除ができてしまうんです!

グループやその他のユーザでも同様なので、ファイル自体のパーミッションを適切に設定していても、ディレクトリのパーミッション次第でファイルの削除ができてしまいます…
例:
sample2 ディレクトリ :所有者 linuc グループ linuc
sample2/sampleA.txt : 所有者 linuc グループ linuc

適切なパーミッション管理のために、特殊なパーミッションを使用することができます。
〇特殊なパーミッション
・Sticky Bit
設定方法:パーミッション指定で1000番台を指定またはその他ユーザの権限に「t」を付与する。
例:
sample2 ディレクトリ : 読込権限と書込権限があり、実行権限にSticky Bitが設定されている。
sample2/sampleB.txt : 読込権限と書込権限と実行権限がない。
Sticky Bitを設定したディレクトリ内は、root権限ユーザまたは作成したユーザーのみが削除できる。

sudo コマンドを用いればrootユーザでなくても削除することは可能です。
sudo コマンドを使用可能かはユーザが「wheel」グループに所属しているかどうかで確認できます。「wheel」グループに所属していない場合、sudo コマンドを使用できません。

rootユーザで「wheel」グループに所属を追加

sudo コマンドでStick Bitを設定しているディレクトリ内のファイルを削除

パーミッションを設定する際はファイルやディレクトリだけでなく、ユーザのグループにも注意が必要です。
Sticky Bitを設定してあるファイル・ディレクトリを探したい場合
$find / -user root -perm -o=t -type f 2>/dev/null
その他の特殊なパーミッション
・SUID(Set User ID)
プログラムが実行されると、そのファイルの所有者の権限でユーザーが実行されるようにする。実行権限がある場合は「s」、実行権限がない場合は「S」で表記される。
設定方法:パーミッション指定で4000番台を指定またはユーザーの権限に「s」または「S」を付与する。
例:passwd コマンドファイルのSUID
passwd コマンドを用いてパスワードを設定すると /etc/shadow ファイルに変更後のパスワードを書き込みを行います。passwd コマンドを用いる場合、root権限でのみ/etc/passwd ファイルと /etc/shadow ファイルへの書き込みができます。(*ディストリビューションによってパーミッションは異なる場合があるので注意してください)

SUIDを剥奪して passwd コマンドでパスワードを設定しようとすると、/etc/passwd ファイル と /etc/shadow ファイルへの書き込み時にエラーが発生します。(rootユーザまたはsudo コマンドを用いるとエラーは発生しません)


SUIDを付与すると正常にパスワードを設定できるようになりました。

SUIDを設定してあるファイル・ディレクトリを探したい場合
$find / -user root -perm -u=s -type f 2>/dev/null
・SGID(Set Group ID)
ファイルが実行されると所有グループ権限でユーザーが実行できるようにする。
設定方法:パーミッション指定で2000番台を指定またはグループの権限に「s」を付与する。
SGIDを設定したディレクトリ内でファイルを作成すると、作成されたファイルのグループにディレクトリのグループが自動的に設定される。
例:
SGIDが設定されたディレクトリ名: sample3
SGIDが設定されたディレクトリのグループ名: yoshioka
ログインユーザ名: linuc

SGIDを設定してあるファイル・ディレクトリを探したい場合
$find / -user root -perm -g=s -type f 2>/dev/null
〇デフォルトパーミッションの設定
デフォルトパーミッションとはコマンドで明示的にパーミッションを指定せずにファイルやディレクトリを作成した際に付与されるパーミッションのことです。基本パーミッションからマスク値を引くことで設定されます。
・umask コマンド
umask コマンドでマスク値を表示・設定することができます。

基本パーミッションからマスク値を引いた値がファイルやディレクトリ作成時のデフォルトパーミッションです。
ファイル | ディレクトリ | |
基本パーミッション | 666(-rw-rw-rw-.) | 777(drwxrwxrwx.) |
マスク値 | 022 | 022 |
デフォルトパーミッション | 644(-rw-r–r–.) | 755(drwxr-xr-x.) |
・デフォルトパーミッションの変更
例1:このシェルセッションでのデフォルトパーミッションを変更したい場合
umask コマンド 実行する
8進数でマスク値で指定する。

シンボルでマスク値を指定する。シンボルは8進数に変換され後に各基本パーミッションから引かれます。

例2:ユーザごとにのデフォルトパーミッションを変更したい場合
変更したいユーザのホームディレクトリ/.bashrc のumask値を変更する。
変更前

変更
$vi ~/.bashrc で個人設定ファイルを開き、umask コマンドを追加して保存し、再度読み込む。

変更後
変更したユーザ(ユーザ名:linuc)のマスク値は0111に変更されているが、変更していないユーザ(ユーザ名:yoshioka)のマスク値は0022のままである。

例:3ユーザ全体のデフォルトパーミッションを変更したい場合
/etc/login.defs のumask値を変更する
変更前
$sudo vi /etc/login.defs

変更

変更後
すべてのユーザーのデフォルトパーミッションが0111に変更されている。(rootユーザのマスク値も変更になっているので使用する際は注意が必要だと思われます)

終わりに
自分がLinuxに苦手意識を持ったきっかけがこのパーミッションだったのですが、取り組んでみるとと理解できる部分が意外と増え苦手意識が少し薄れたと感じています。だれてしまわないように目標を設定して、Linuxやサーバ・インフラ関係のインプットとアウトプットを続けていきます!