第12章 パーミッション応用とリンク
LPIC-1 104.5〜104.7 相当
初級第6章のrwx権限に加えて、より高度な権限設定と、リンクの仕組みを扱います。
特殊な権限ビット: SUID・SGID・スティッキービット
| 特殊ビット | 数値 | ファイルへの効果 |
|---|---|---|
| SUID | 4000 | 実行時に、実行したユーザーではなく「所有者」の権限で動作する(例: passwdコマンド) |
| SGID | 2000 | ディレクトリに設定すると、その中に作成されたファイルの所有グループが親ディレクトリと同じになる |
| スティッキービット | 1000 | ディレクトリに設定すると、他人が作成したファイルを自分は削除できなくなる(例: /tmp) |
$ chmod 4755 /usr/bin/passwd # SUIDを設定(先頭の4)
$ chmod 1777 /tmp # スティッキービットを設定(先頭の1)
$ chmod 2755 /srv/shared # SGIDを設定(先頭の2)
$ ls -l /usr/bin/passwd
-rwsr-xr-x root root ... /usr/bin/passwd # xの位置がsになっている
$ chmod u+s script.sh # シンボルモードでSUIDを付与することもできる
特殊ビットは4桁目の数字(4000・2000・1000)として表現するほかに、シンボルモードでは所有者に対するs(SUID)、グループに対するs(SGID)、その他に対するt(スティッキービット)として表示されます。もし本来 x 権限がない箇所に特殊ビットが設定されていると、小文字ではなく大文字のSやTで表示され、「実行権限がないのに特殊ビットだけ設定されている」という不自然な状態を示します。
umask — 新規作成時の既定権限
新しくファイルやディレクトリを作成したとき、既定でどの権限を「与えないか」を決めるのが umask です。ファイルの最大権限は666(実行ビットを含まない)、ディレクトリの最大権限は777であり、そこからumaskで指定した値を差し引いた(正確にはビット単位でマスクした)値が、実際の既定権限になります。
$ umask
0022
$ touch newfile.txt
$ ls -l newfile.txt
-rw-r--r-- ... newfile.txt # ファイルの既定666からumask 022を引いた644になる
$ mkdir newdir
$ ls -ld newdir
drwxr-xr-x ... newdir # ディレクトリの既定777からumask 022を引いた755になる
$ umask 077 # より厳しい既定値に変更(自分以外はアクセス不可に。設定自体は無出力)
$ umask
0077
この行のこの値に注目: umask 077の実行自体は何も表示しませんが、直後に引数なしのumaskを実行すると、設定した値(0077)が反映されていることを確認できます。この状態で新規作成したファイルは所有者以外アクセスできない600・700になります。
umaskの値はシェルの設定として持続するため、/etc/profileや~/.bashrcなどにumask 022のように記述しておくと、ログインするたびに同じ既定値が適用されます。共有サーバーで機密性の高い作業をするユーザーには、umaskを077のように厳しく設定して、他人からファイルを読み書きされないようにする運用もよく行われます。
ハードリンクとシンボリックリンク
| 種類 | 特徴 |
|---|---|
| ハードリンク | 同じ実体(inode)を指す別名。元ファイルを消してもリンク先は残る。ディレクトリやファイルシステムをまたいでは作成不可。 |
| シンボリックリンク(symlink) | パスを指す「ショートカット」のようなもの。元ファイルを消すとリンク切れになる。ディレクトリやファイルシステムをまたいで作成可能。 |
$ ln original.txt hardlink.txt # ハードリンク作成
$ ln -s original.txt symlink.txt # シンボリックリンク作成(-s)
$ ls -l symlink.txt
lrwxrwxrwx ... symlink.txt -> original.txt
$ ls -li original.txt hardlink.txt
1234567 -rw-r--r-- 2 ... original.txt
1234567 -rw-r--r-- 2 ... hardlink.txt # -i でinode番号を表示。両者が同じinode番号を共有している
ls -lの2列目に表示される数字は「リンクカウント」で、そのinodeに対して何個の名前(ハードリンク)が存在するかを示します。上の例では2になっており、original.txtとhardlink.txtという2つの名前が同じ実体を指していることが分かります。ファイルを完全に削除する(実体のデータが解放される)のは、このリンクカウントが0になったときです。そのためrm original.txtを実行しても、hardlink.txtからは引き続き同じ内容を参照できます。
ファイルの所有者・所有グループの変更
権限(rwx)はそのままに、「誰の」ものかを変更するコマンドがchown・chgrpです。
$ sudo chown alice file.txt # 所有者をaliceに変更
$ sudo chown alice:staff file.txt # 所有者をalice、所有グループをstaffに変更
$ sudo chown :staff file.txt # 所有グループだけをstaffに変更
$ sudo chgrp staff file.txt # 所有グループだけを変更(chownの:staffと同じ結果)
$ sudo chown -R alice:staff /srv/app # -R でディレクトリ配下を再帰的に変更
FHS(Filesystem Hierarchy Standard)とファイルの配置
Linuxのディレクトリ構成は、FHSという標準でおおまかな役割が決められています。適切な場所にファイルを置くことは、システム管理の基本です。
| ディレクトリ | 役割 |
|---|---|
/etc | システム全体の設定ファイル |
/var | ログやキャッシュなど、内容が変化し続けるデータ |
/usr | ユーザーが利用するプログラムやライブラリ(起動に必須ではないもの) |
/opt | パッケージ管理システムの管理外で追加された、独立したアプリケーション一式 |
/srv | そのシステムが提供するサービス用のデータ(Webサイトのコンテンツなど) |
/tmp | 一時ファイル。再起動時に消去されることがある |
/home | 一般ユーザーのホームディレクトリ |
/root | rootユーザーのホームディレクトリ(/homeの下ではなく直下にある点に注意) |
FHSに沿った配置を守ることで、パッケージ管理システムが「どこに何を置くべきか」を機械的に判断できるようになり、複数のディストリビューション間でもある程度共通したディレクトリ構成が保たれます。自作のスクリプトやアプリケーションを配置する際も、/optや/usr/localのような「システムのパッケージ管理と衝突しない場所」を選ぶのがマナーとされています。
/rootだけは/homeの中ではなくルート直下にある点に注意してください。find コマンドとパーミッションの組み合わせ
この章で扱った特殊ビットやリンクは、findコマンドの検索条件としてもよく利用されます。
$ find / -perm -4000 -type f 2>/dev/null # SUIDが設定されたファイルを検索
$ find /var/log -type l # シンボリックリンクだけを検索
$ find / -nogroup 2>/dev/null # 所有グループが存在しない(削除済みグループの)ファイルを検索
findコマンドの条件は、そうした点検作業でそのまま活用できます。
ACL(アクセス制御リスト)による、より柔軟な権限設定
ここまで扱ってきた「所有者・グループ・その他」の3種類の権限指定では、「特定の1人にだけ追加で権限を与えたい」といった細かい制御はできません。この限界を超えるために用意されているのがACL(Access Control List)です。setfaclで特定のユーザー・グループ単位の権限を追加し、getfaclで現在の設定を確認します。
$ setfacl -m u:bob:rw file.txt # 所有者はaliceのままだが、bobにも読み書き権限を追加
$ getfacl file.txt # 設定されているACLを一覧表示
ACLが設定されているファイルは、ls -lの権限表記の末尾に+記号が付くので見分けられます。プロジェクトの共有ディレクトリで「基本は所有者のみアクセス可、ただし特定のメンバーだけ追加で書き込みを許可したい」といった細かい要件に対応する際に使われる、一歩進んだ権限管理の手段です。
デフォルトACLで新規ファイルの権限を自動化する
共有ディレクトリでは、新しく作られるファイルにも自動的にACLを引き継がせたい場面があります。setfacl -d(default)オプションでディレクトリにデフォルトACLを設定しておくと、そのディレクトリ内に新しく作成されるファイル・サブディレクトリに同じACLが自動的に適用されます。
$ setfacl -d -m u:bob:rw /srv/shared # /srv/sharedに作られる新規ファイルへ自動でbobの権限を継承
これを設定しておかないと、共有ディレクトリの中に新しいファイルが作られるたびに毎回setfaclを打ち直す必要があり、運用上の手間とヒューマンエラーの原因になります。継続的にファイルが追加される共有領域を運用する際は、デフォルトACLの設定を忘れないようにしましょう。