Developer's Blog

今さら聞きづらい「ファイルパーミッション」について

こんにちはこんにちは! エンジニア川端です。

ご自身のサイトをお持ちの方なら、一度は目にしたことのある「ファイルパーミッション」という言葉。

  • 普通の HTML ファイルは 644 にするとか、
  • CGI は 755 にするとか、
  • ○○というレンタルサーバの△△プランだと CGI は 700 でないと動かないとか、

「決まり事」として丸覚えしている方も多いのではないかと思います。

では、パーミッション 2775 ってどういうことでしょう? 1777 は?

入門サイトではあまり触れられていない気がしますので、今日は「ファイルパーミッションの 4 桁め」についてお話しします。

ファイルパーミッションは 3 つのクラスと 3 種類の基本パーミッションの組み合わせ

ファイルパーミッションでは、そのファイルに対する権限を、オーナー、グループ、全員という 3 つのクラスについて、それぞれ読み・書き・実行の 3 種類の権限を与えることで設定しています。数字表記の 644 とか 755 は 8 進数表記です。
……というようなことは、入門サイトでもしっかり触れられていますので、バッサリ割愛。

クラス

100 の位 10 の位 1 の位
オーナー グループ 全員

権限

読むことができる権限 4
書き込むことができる権限 2
実行スルコトガデキル権限 1

例: パーミッション 644

  • オーナー …… 読み書き可能 ( 4 + 2 = 6 )
  • グループ …… 読むことが可能 ( 4 )
  • 全員 ………… 読むことだけ可能 ( 4 )

特殊なパーミッション設定

では、今日の本題。4 桁めでは、3 種類の基本パーミッション (読み/書き/実行) だけでは設定できない特殊な権限設定を行う事が可能です

setuid 4
setgid 2
sticky bit 1

実行ファイルのオーナーが実行したことになる setuid

例えば、CGI を設置してパーミッションを 755 にして WEB ブラウザからアクセスした場合。そのファイルを実行しているのは WEB サーバです。多くの場合 WEB サーバは apache というプログラムで、デフォルトの設定だと

User: apache
Group: apache

となっていますので、apache というユーザがその CGI プログラムを実行していることになります。つまり、そのプログラムから読み書きするファイルも、ユーザー apache が読み書きできる必要があるということです。
パーミッションの設定がうまくいかなくて、ディレクトリのパーミッションを 777 にしたら動いた! とかいうケースは、これが原因のことが多いのではないでしょうか。

どうしても別ユーザの権限で実行したい場合、setuid を行います。設定方法は

$ chmod u+s <file>

もしくは、

$ chmod 4755 <file>

のように 4 桁めに「4」を指定します。こうすることで、そのプログラムを実行した場合、ファイルの持ち主が「kawabata」なら、kawabata の権限でプログラムが実行され、プログラムから読み書きするファイルも、kawabata が読み書き可能なファイル、ということになります。

では、実際にはどんなファイルが存在するのか?

$ find /bin/ -perm +4000 -ls
 65361   40 -rwsr-xr-x   1 root     root        37312 Sep 27  2009 /bin/ping
 65414   28 -rwsr-xr-x   1 root     root        28336 Jul 22  2011 /bin/su
 65346   40 -rwsr-xr-x   1 root     root        40592 Mar 10  2011 /bin/umount
 65362   32 -rwsr-xr-x   1 root     root        32736 Sep 27  2009 /bin/ping6
 65478   64 -rwsr-xr-x   1 root     root        60432 Mar 10  2011 /bin/mount

手元のCentOS では、/bin/ 以下のこれらのファイルは、誰が実行しても root として実行したことになるようですね。

グループを継承したければ setgid

setuid は一見便利なんですが、意図的にそうしたいことというのは、そんなに多くないかもしれません。一番使う機会が多いのは「setgid」のような気がします。

複数名でサイト更新する際に、

# groupadd web
# usermod -a -G web person-a
# usermod -a -G web person-b
# chgrp -R web /var/www/html/contents/
# chmod -R g+w /var/www/html/contents/

のようにすると、contents/ ディレクトリ以下のファイルは、「web」グループに所属している「person-a」「person-b」の両名が編集可能になります。
ログインシェルで

umask 002

としておけば、新しく生成されるファイルもグループに書き込み権限を与える形になりますが、案外多いのが、新しく作ったファイルのグループを「web」にするのを忘れていて、他の人が更新できない! というケース。

こういう時は、

$ chmod g+s /var/www/html/contents/

もしくは

$ chmod 2775 /var/www/html/contents/

としておくと、contents/ 以下に作成されるファイル/ディレクトリのグループは、すべて contents/ と同じ「web」になります。

ちょっと特殊な sticky bit

最後に sticky bit です。これが一番特殊かもしれません。

Linux 等の /tmp/ は、誰でも書き込める場所です。パーミッションは、777 ……ですが、実は 0777 ではなく 1777 です。

$ ls -ld /tmp 
drwxrwxrwt 4 root root 4096 Feb  1 13:15 /tmp/

普通に 777 にすると「drwxrwxrwx」となりますが、「drwxrwxrwt」となっています。この状態が「Sticky bit のたった状態」です。こうすることで、

  • /tmp/ 以下は、誰でもファイルを作成できます
  • /tmp/ 以下のファイルのパーミッションを 666 とかにしておくと、作ったファイルに誰でも書き込めます
  • /tmp/ 以下のファイルを消したり名前を変えたりするのは、パーミッションにかかわらず、ファイルを作った人だけが可能です

普通の「777」だとファイルを消すのも誰でもできてしまいますが、「1777」にする (chmod o+t) ことで、ファイルの持ち主以外が勝手に消す事はできなくなります。

急がば回れ

駆け足で特殊なファイルパーミッションについて述べました。簡単に説明する文章を書くのは難しいですね。面目ない。興味のある方は書籍をがっつり読んでみることをお勧めします。
例えば、少し古いですが「The Unix Super Text」とかよろしいのではないかと。題名だけで「学んでる感」が半端ないです :-D

OS によって挙動が異なる部分もあったりしますので、ネタになりそうなことを思いついたら、またお知らせしたいと思います。

フェンリルのオフィシャル Twitter アカウントでは、フェンリルプロダクトの最新情報などをつぶやいています。よろしければフォローしてください!

Copyright © 2019 Fenrir Inc. All rights reserved.