「ユーザ権限とアクセス制御」の版間の差分

提供: UnixClassWiki
移動先: 案内検索
(パスワードファイル)
(ディレクトリにsetgidビットを設定する)
(同じ利用者による、間の47版が非表示)
1行目: 1行目:
 
== ユーザと権限  ==
 
== ユーザと権限  ==
  
おおよそ今時のコンピュータシステムはユーザが利用しようとするにはユーザ
+
オペレーティングシステム内部ではユーザの違いをアカウント名ではなく
認証を必要とします。UNIXではアカウント名とパスワードの組合せでユーザ認
+
ユーザID(UID / User IDentifier)による数値で認識しています。
証を行うのが基本となっています。オペレーティングシステム内部ではユーザ
+
またユーザは1つデフォルトのグループID(GID / GroupIDentifier)がつけられています。
の違いをアカウント名ではなくユーザID(UID / User IDentifier)による数値
+
そのユーザIDやグループIDが条件に合致するかどうかでユーザに権限があるかどうかを判断しています。
で認識しています。またユーザは1つデフォルトのグループID(GID / Group
+
 
IDentifier)がつけられています。
+
 
 +
;補足: ユーザやグループの追加、更新などオペレーションに関しては[[ユーザやグループの管理]]を参照してください。
 +
 
 +
 
  
 
唯一例外的なのはユーザIDが0、グループIDが0のユーザrootです。
 
唯一例外的なのはユーザIDが0、グループIDが0のユーザrootです。
 
スーパーユーザーと呼ばれ、
 
スーパーユーザーと呼ばれ、
 
UNIXにおいてはオールマイティーな権限を持つ特別なユーザです。
 
UNIXにおいてはオールマイティーな権限を持つ特別なユーザです。
管理者権限として説明される場
+
管理者権限として説明される場合が多いのですが、
合が多いのですが「オペレーティングシステム上で何でもできてしまう権限」
+
管理者として何かするという表現よりも「オペレーティングシステム上で何でもできてしまう権限」
と説明した方が適切でしょう。
+
と説明した方が分かり易いかと思います。
  
=== ユーザIDとグループID ===
 
  
オペレーティングシステムの中での利用権限を意味するのがユーザIDです。た
+
=== ユーザIDとグループIDによるアクセス制御 ===
とえばファイルには所有者(Owner)が設定されていますが、その所有者情報と
+
はユーザIDのことです。また、プロセスが動作している時には、いずれかのユー
+
ザIDとグループIDを持っており、そのユーザIDに付加された権限の範囲内にお
+
いてプロセスは資源にアクセスできます。グループIDは、そのグループにユー
+
ザが登録されている場合、そのユーザに与えられるグループ権限です。UNIXの
+
基本的な権限は、このユーザIDの違いによるユーザ権限と、グループID の違
+
いによるグループ権限の2つから成り立っています。ファイルやプロセスの資
+
源は次の3つに対しての許可によってアクセスコントロールされます。
+
  
  
まずファイルに対するユーザIDとグループIDを見てみましょう。ファイルには
+
オペレーティングシステムの内部では、ユーザは名前で管理されているのではなくユーザID(UID)で管理されています。
ユーザIDとグループIDが設定されています。ユーザIDは、このファイルの所有
+
たとえばファイルにユーザ(所有者)が設定されていますが、その所有者情報とはファイルの情報(ディレクトリ情報のなかにあるメタ情報)に付加されているユーザIDのことです。
者、もう少し正確にいうと、このファイルの属性を設定できるユーザが誰であ
+
また、プロセスが動作している時には、いずれかのユーザIDとグループIDを持っており、そのユーザIDに付加された権限の範囲内においてプロセスは資源にアクセスできます。
るかを意味しています。所有者がファイルの属性を変更し、そのファイルのア
+
グループID(GID)は、そのグループにユーザが登録されている場合、そのユーザに与えられるグループ権限です。
クセス権限などをコントロールすることができます。ls -lをみてみましょう。
+
UNIXの基本的な権限は、このユーザIDの違いによるユーザ権限と、グループIDの違いによるグループ権限の2つから成り立っています。
尚、表示される際は、ユーザIDは/etc/passwdで設定されているユーザIDに対
+
ファイルやプロセスの資源へのアクセス制御はユーザID・グループID
応するアカウント名、グループIDは/etc/groupで設定されているユーザIDに対
+
<ref>自分のユーザIDやグループIDを確認するにはコマンドidを使う。詳しくは[[ユーザやグループの管理]]を参照のこと。</ref>
応するグループ名に変換されて表示されます。
+
を使っての許可・不許可によって行われるというのが基本的な考え方です。
 +
 
 +
 
 +
 
 +
まずファイルに対するユーザIDとグループIDを見てみましょう。
 +
ファイルには、ユーザIDとグループIDが設定されています。
 +
ユーザID=このファイルの所有者です。
 +
尚、本章の範囲では、所有者とユーザと同じ意味で使っています。
 +
ユーザが自分の所有するファイルの属性を変更し、そのファイルのアクセス権限などをコントロールすることができます。
 +
ただしroot権限だけは例外で、システムのすべてに無制限にアクセスできます。
 +
 
 +
 
 +
ユーザIDが数字ではなくユーザ名として表示されるのは、ユーザIDは/etc/passwdで設定されている対応するアカウント名、
 +
グループIDは/etc/groupで設定されている対応するグループ名に変換されて表示されるからです。
 +
 
 +
 
 +
=== 読み込み / 書き込み  / 実行 ===
 +
 
 +
基本的なファイルへのアクセス権限は、「読み込み」「書き込み」「実行」です。
 +
ディレクトリの場合は実行の部分の意味が「ディレクトリとしてアクセスできるか」ということとして扱われます。
  
  
 
*  アクセス権限 : 読み込み / 書き込み / 実行
 
*  アクセス権限 : 読み込み / 書き込み / 実行
ユーザに対して : 許可 / 不許可
+
ユーザ・所有者(User)に対して : 許可 / 不許可
グループに対して : 許可 / 不許可
+
グループ(Group)に対して : 許可 / 不許可
それ以外に対して : 許可 / 不許可
+
それ以外(Other)対して : 許可 / 不許可
 +
 
  
  
 +
<pre class="bash">
 
  $ ls -l memo.txt  
 
  $ ls -l memo.txt  
 
  -rw-r--r--    1 hironobu hironobu      44 Sep 20 19:17 memo.txt
 
  -rw-r--r--    1 hironobu hironobu      44 Sep 20 19:17 memo.txt
 
  $  ls -l /var/mail/hironobu
 
  $  ls -l /var/mail/hironobu
 
  -rw-rw----    1 hironobu mail            0 Dec  9 19:39 hironobu
 
  -rw-rw----    1 hironobu mail            0 Dec  9 19:39 hironobu
 +
</pre>
  
  
memo.txtはユーザIDがhironobu、グループIDがhironobuになっており、所有者
+
memo.txtはユーザIDがhironobu、グループIDがhironobuになっており、ユーザ(所有者)は読み書き、同じグループには読み込み、その他の権限でも読み込みができます。
は読み書き、同じグループには読み込み、その他の権限でも読み込みができま
+
正確には、ユーザと同じユーザIDを持ったプロセス、設定されたグループと同じグループに属するユーザIDを持つプロセス、それ以外のユーザIDを持つプロセスがアクセス可能であるという表現になります。
す。正確には、所有者と同じユーザIDを持ったプロセス、設定されたグループ
+
と同じグループに属するユーザIDを持つプロセス、それ以外のユーザIDを持つ
+
プロセスとなります。
+
  
  
/var/mail/hironobuというファイルのユーザIDはhironobuになっており、グルー
+
/var/mail/hironobuというファイルのユーザIDはhironobuになっており、グループIDはmailです。mailのグループ権限を持つプロセスから読み書き可能になっています。具体的には、メールサーバなどのプロセスが読み書きできるようになっています。
プIDはmailです。mailのグループ権限を持つプロセスから読み書き可能になっ
+
ています。具体的には、メールサーバなどのプロセスが読み書きできるように
+
なっています。
+
  
  
 +
変更はコマンドchmodを使います。chmodのオプションではユーザ(所有者)はu、グループはg、それ以外の利用者はoという表現を使います。
 +
パーミッションの許可は"+"、パーミッションの不許可は"-"を使います。
 +
chmodのオプションで"go-rw"はグループとその他ユーザからの読み書きは不許可となります。
 +
 +
 +
<pre class="bash">
 +
$ chmod go-rw memo.txt
 +
$ ls -l memo.txt
 +
-rw-------    1 hironobu hironobu      44 Sep 20 19:17 memo.txt
 +
</pre>
 +
 +
ユーザ(所有者)、グループ、その他ユーザの読み取り許可・不許可、書き込み許可・不許可、実行の許可・不許可は3ビットで表すので、この部分を8進数で表現することもできます。
 +
その場合"rw-------"はビットの設定がuが110、gが000、oが000となるので、8進数表現をするモードでは600となります。
 +
 +
 +
<pre class="bash">
 +
$ chmod 600 memo.txt
 +
$ ls -l memo.txt
 +
-rw-------    1 hironobu hironobu      44 Sep 20 19:17 memo.txt
 +
</pre>
  
 
== グループID利用の方法 ==  
 
== グループID利用の方法 ==  
  
ここにファイルgroup_share.datがあるとします。これをユーザtaroとユーザ
+
ここにファイルgroup_share.datがあるとします。これをユーザtaroとユーザhanakoが共通に読み書きのアクセスでき、
hanakoが共通に読み書きのアクセスでき、他のユーザはアクセスできないよう
+
他のユーザはアクセスできないようなパーミッションにしたいとします。
なパーミッションにしたいとします。
+
  
  
 +
<pre class="bash">
 
  $ ls -l
 
  $ ls -l
 
  合計 56
 
  合計 56
 
  -rw-r--r--  1 taro taro    51200 2005-11-23 18:33 group_share.dat
 
  -rw-r--r--  1 taro taro    51200 2005-11-23 18:33 group_share.dat
 +
</pre>
  
  
まずgroup_share.datを所有者とグループにはrw、それ以外には読み書き禁止
+
まずgroup_share.datを所有者とグループにはrw、それ以外には読み書き禁止にします。
にします。chmodを使いますが、2度に分けてオプションを使ってもいいですし、
+
chmodを使いますが、2度に分けてオプションを使ってもいいですし、モードを数字で与えてもかまいません。
モードを数字で与えてもかまいません。
+
  
  
 +
<pre class="bash">
 
  $ chmod o-wr group_share.dat  
 
  $ chmod o-wr group_share.dat  
 
  $ chmod g+wr group_share.dat  
 
  $ chmod g+wr group_share.dat  
 +
</pre>
  
 
あるいは
 
あるいは
  
 +
<pre class="bash">
 
  $ chmod 660 group_share.dat  
 
  $ chmod 660 group_share.dat  
 +
</pre>
  
結果
 
  
 +
結果は次のようになります。
 +
 +
 +
<pre class="bash">
 
  $ ls -l
 
  $ ls -l
 
  合計 56
 
  合計 56
 
  -rw-rw----  1 taro taro    51200 2005-11-23 18:33 group_share.dat
 
  -rw-rw----  1 taro taro    51200 2005-11-23 18:33 group_share.dat
 +
</pre>
  
  
99行目: 137行目:
  
  
 +
<pre class="bash">
 
  # groupadd taro-hanako
 
  # groupadd taro-hanako
 
  # gpasswd -a taro  taro-hanako
 
  # gpasswd -a taro  taro-hanako
 
  # gpasswd -a hanako taro-hanako
 
  # gpasswd -a hanako taro-hanako
 +
</pre>
  
  
taroが新しいグループに加わった時、taroが再度ログインした時からその新し
+
taroが新しいグループに加わった時、taroが再度ログインした時からその新しいグループ (この場合taro-hanako)が有効になります。
いグループ (この場合taro-hanako)が有効になります。再度ログインしたとい
+
再度ログインした状態で、taroはgroup_share.datのグループIDをtaro-hanakoにします。
う状態で、taroはgroup_share.datのグループIDをtaro-hanakoにします。
+
  
  
 +
<pre class="bash">
 
  $ chgrp taro-hanako group_share.dat
 
  $ chgrp taro-hanako group_share.dat
 
  ...
 
  ...
 
  -rw-rw----  1 taro taro-hanako    51200 2005-11-23 18:33 group_share.dat
 
  -rw-rw----  1 taro taro-hanako    51200 2005-11-23 18:33 group_share.dat
 +
</pre>
  
  
これでgroup_share.datはtaro-hanakoのグループに属しているtaroとhanakoが
+
これでgroup_share.datはtaro-hanakoのグループに属しているtaroとhanakoが読み書きが出来るようになります。
読み書きが出来るようになります。
+
  
  
 
;考えてみよう: apacheはユーザwww-dataの権限で動作しています。cgi-binなどでコマンドを動かしファイルinfo.datに情報を書き込む必要があります。しかし、info.dataの中身に関してはセキュリティ上の問題のためユーザfoo以外には読ませたくありません(www-dataにも許可しません)。さて、この場合、info.datの適切なファイルの所有者、適切なパーミッションはどのようなものでしょうか。
 
;考えてみよう: apacheはユーザwww-dataの権限で動作しています。cgi-binなどでコマンドを動かしファイルinfo.datに情報を書き込む必要があります。しかし、info.dataの中身に関してはセキュリティ上の問題のためユーザfoo以外には読ませたくありません(www-dataにも許可しません)。さて、この場合、info.datの適切なファイルの所有者、適切なパーミッションはどのようなものでしょうか。
  
=== プロセスのユーザIDとグループID ===  
+
== プロセスのユーザIDとグループID ==
  
まずログインした時に、そのアカウント名に割り振られたユーザIDとグループ
+
まずログインした時に、そのアカウント名に割り振られたユーザIDとグループIDの権限でログインシェルが動き始めます。
IDの権限でログインシェルが動き始めます。そのシェルから起動されるプロセ
+
そのシェルから起動されるプロセスにはデフォルトで親プロセスのユーザIDとグループIDが受け継がれます。
スにはデフォルトで親プロセスのユーザIDとグループIDが受け継がれます。
+
root権限(注)でsetuid(2)やsetgid(2)を使うとプロセスのユーザIDを変更することができます。
root権限(注)でsetuid(2)やsetgid(2)を使うとプロセスのユーザIDを変更する
+
ことができます。
+
  
  
132行目: 170行目:
  
  
 +
<pre class="bash">
 
  $ ps aux
 
  $ ps aux
 
  USER      PID %CPU %MEM  VSZ  RSS TTY      STAT START  TIME COMMAND
 
  USER      PID %CPU %MEM  VSZ  RSS TTY      STAT START  TIME COMMAND
143行目: 182行目:
 
  hironobu  2796  0.0  1.0  8752 6716 ?        R    12:14  0:05 emacs20 -geometry
 
  hironobu  2796  0.0  1.0  8752 6716 ?        R    12:14  0:05 emacs20 -geometry
 
  ...
 
  ...
 +
</pre>
  
 +
=== 現在の権限管理 ===
  
 
+
古典的なUNIXはUIDとGIDだけで説明は済みますが、Linuxも含めBSD 4.3以降では、もっと複雑な設定ができます。
== 現在の権限管理 ==
+
Linuxでは4つタイプのUIDと4つのGIDのタイプを持っています。
 
+
古典的なUNIXはUIDとGIDだけで説明は済みますが、Linuxも含めBSD 4.3以降で
+
は、もっと複雑な設定ができます。Linuxでは、少なくとも4つタイプのUIDと4
+
つのGIDのタイプを持っています。
+
  
 
*  ユーザID、グループIDの種類
 
*  ユーザID、グループIDの種類
  * UID / GID : 今まで通りのUID / GID  
+
* UID / GID : 今まで通りのUID / GID  
  * RUID / RGID : 実UID / 実GID --- UIDやGIDと同じ役割 (RはReal)
+
* RUID / RGID : 実UID / 実GID --- UIDやGIDと同じ役割 (RはReal)
  * EUID / EGID : 実効UID / 実効GID --- 権限があるかどうかをチェックする時に使う (EはEffective)
+
* EUID / EGID : 実効UID / 実効GID --- 権限があるかどうかをチェックする時に使う (EはEffective)
  * SUID / SGID : 保存UID / 保存GID --- 有効化・無効化を行うための保存 (SはSaved)
+
* SUID / SGID : 保存UID / 保存GID --- 有効化・無効化を行うための保存 (SはSaved)
  * FSUID / FSGID : ファイルUID / ファイルGID --- Linux独自のファイルのアクセス権限のチェック
+
* FSUID / FSGID : ファイルUID / ファイルGID --- Linux独自のファイルのアクセス権限のチェック
  
  
 
=== setuid  ===  
 
=== setuid  ===  
これらはプロセスが、どのような権限で動作するかを規定するものです。UNIX
 
には実行ファイルの属性に(モードに)setuid bitを設定しておくと、その実行
 
ファイルはファイルの所有者の権限で動作します。setgid bitは実行ファイル
 
のグループの権限で動作します。コマンドfindを使って探してみましょう。
 
  
 +
これらはプロセスが、どのような権限で動作するかを規定するものです。
 +
UNIXには実行ファイルの属性に(モードに)setuid bitを設定しておくと、
 +
その実行ファイルはファイルの所有者の権限で動作します。
 +
setgid bitは実行ファイルのグループの権限で動作します。
 +
コマンドfindを使って探してみましょう。
  
$ ls -l `find /bin  -perm +a+s -print`
 
-rwsr-xr-x    1 root    root        35464 Nov  3 04:56 /bin/login
 
-rwsr-xr-x    1 root    root        72488 Dec 24  2002 /bin/mount
 
-rwsr-xr-x    1 root    root        15244 Nov 19  2001 /bin/ping
 
-rwsr-xr-x    1 root    root        23112 Nov  3 04:56 /bin/su
 
-rwsr-xr-x    1 root    root        36904 Dec 24  2002 /bin/umount
 
  
 +
<pre class="bash">
 +
$ find /bin  -perm +a+s -exec ls -l {} \;
 +
-rwsr-xr-x 1 root root 26252 Mar  3  2012 /bin/fusermount
 +
-rwsr-xr-x 1 root root 88760 Mar 30  2012 /bin/mount
 +
-rwsr-xr-x 1 root root 34740 Nov  8  2011 /bin/ping
 +
-rwsr-xr-x 1 root root 39116 Nov  8  2011 /bin/ping6
 +
-rwsr-xr-x 1 root root 31116 Sep 13  2012 /bin/su
 +
-rwsr-xr-x 1 root root 67720 Mar 30  2012 /bin/umount
 +
</pre>
  
最初の表示にある-rwsr-x-rxのsがsetuid bitの意味です。つまり、これ
 
らのコマンドは所有者がrootであり、かつ、このコマンドを動かすとrootの権
 
限で動かすことができるという意味です。この実行時は、ruidは利用者、euid
 
がrootとなり、root権限のファイルなどに書き込むことができるようになりま
 
す。一般ユーザでも何でもできる権限を手に入れてしまうということで、この
 
ようなプログラムに誤りがあると大きなセキュリティ上の問題になります。
 
  
 +
最初の表示にある-rwsr-x-rxのsがsetuid bitの意味です。
 +
つまり、これらのコマンドは所有者がrootであり、かつ、
 +
このコマンドを動かすとrootの権限で動かすことができるという意味です。
 +
この実行時は、ruidは利用者、euidがrootとなり、
 +
root権限のファイルなどに書き込むことができるようになります。
 +
一般ユーザでも何でもできる権限を手に入れてしまうということで、
 +
このようなプログラムに誤りがあると大きなセキュリティ上の問題になります。
  
 
=== setgid ===  
 
=== setgid ===  
  
setgidは、set group id bitの意味です。そのファイルのグループIDと同じ権限で実
+
setgidは、set group id bitの意味です。そのファイルのグループIDと同じ権限で実行できます。
行できます。
+
  
$ ls -l `find /usr/bin  -perm +g+s -print`
 
....
 
  
ruidがrootの時、つまりrootがファイルを実行した時は何でもできるので、
+
<pre class="bash">
euidをプロセス内で制限なく変更できます。たとえばapacheは唯一1つrootで
+
$ find /bin  -perm +g+s -exec ls -l {} \;
のプロセスがあり、そこから生成し子プロセスがwww-data(あるいは他の)
+
</pre>
euidで動作します。外部からのアクセスはすべてwww-dataのeuidで動いている
+
子プロセスで動作しているので、万が一、外部からの入力によりapache誤った
+
動作をしても、その影響範囲を無制限にはしない(root権限ではない)ように
+
しています。
+
  
  
RUID/RGID、EUID/EGID、SUID/SGIDを上手に変更することによって、どのユー
+
ruidがrootの時、つまりrootがファイルを実行した時は何でもできるので、euidをプロセス内で制限なく変更できます。
ザ権限で、あるいはどのグループ権限でプロセスを動かし、適切にファイルや
+
たとえばapacheは唯一1つrootでのプロセスがあり、
資源にアクセスできるようになることで、セキュリティを保つことができるよ
+
そこから生成し子プロセスがwww-data(あるいは他の)euidで動作します。
うになります。これらの値のセットにはルールがあるので、全部はかけないで
+
外部からのアクセスはすべてwww-dataのeuidで動いている子プロセスで動作しているので、
すが、典型的なものを書き出してみます。
+
万が一、外部からの入力によりapache誤った動作をしても、
 +
その影響範囲を無制限にはしない(root権限ではない)ようにしています。
 +
 
 +
 
 +
RUID/RGID、EUID/EGID、SUID/SGIDを上手に変更することによって、どのユーザ権限で、
 +
あるいはどのグループ権限でプロセスを動かし、適切にファイルや資源にアクセスできるようになることで、
 +
セキュリティを保つことができるようになります。
 +
これらの値のセットにはルールがあるので、全部はかけないですが、典型的なものを書き出してみます。
  
  
 
* RUID / EUID / SUIDの設定ルール
 
* RUID / EUID / SUIDの設定ルール
  *  RUID の値を  EUID にセットできる
+
*  RUID の値を  EUID にセットできる
  * EUID の値を  RUID にセットできる
+
* EUID の値を  RUID にセットできる
  * 実行時のEUIDがSUIDにコピーされていて、SUIDの値をEUIDにセットできる
+
* 実行時のEUIDがSUIDにコピーされていて、SUIDの値をEUIDにセットできる
  * rootはRUIDもEUIDも自由にセットできる
+
* rootはRUIDもEUIDも自由にセットできる
  
  
このように実行時のユーザIDを変えることができ、また一般ユーザでも実行ファ
+
このように実行時のユーザIDを変えることができ、また一般ユーザでも実行ファイルに権限が附加されていれば、
イルに権限が附加されていれば、root権限でプロセスを動かすこともできるな
+
root権限でプロセスを動かすこともできるなどかなり複雑な権限のコントロールが可能です。
どかなり複雑な権限のコントロールが可能です。もちろん、Linuxがコントロー
+
ルが可能であることと、アプリケーションがきちんと矛盾なく利用できるよう
+
に設計できることとはまったく別のことです。アプリケーションの設計が正し
+
くなかったり、実装で間違えていると、セキュリティ侵害が発生することはい
+
うまでもありません。
+
  
  
== パスワードファイル ==
+
もちろん、Linuxがコントロールが可能であることと、
 +
アプリケーションがきちんと矛盾なく利用できるように設計できることとはまったく別のことです。
 +
アプリケーションの設計が正しくなかったり、実装で間違えていると、セキュリティ侵害が発生することはいうまでもありません。
  
ユーザIDとアカウント名を対応させているのがパスワードファイル
 
/etc/passwdです。パスワードファイルのフォーマットは次の通りです。
 
  
 +
=== なるべくrootでは動かさない運用 ===
  
* パスワードエントリのフォーマットのフィールドは":"で区切られる
 
* アカウント名 :  ログイン時に使用するアカウント名
 
* パスワード : パスワードをハッシュ値に置き換えたもの
 
* ユーザID :  ユーザを認識するための数値
 
* グループID : グループを認識するための数値
 
* コメントフィールド : 名前等の情報を記述するフィールド
 
* ホームディレクトリ : ホームディレクトリ
 
* シェルパス :  利用するシェルのパス、もしくはシェルに相当するコマンド
 
  
 +
まだセキュリティなどをあまり気にせず、サーバとして動作しているものは何でもかんでもrootで実行していた時期がUNIXにもありました。
 +
これの利点は、アクセスする先のファイルのパーミッションやroot権限でしかオープンできないポート番号など一々気にしなくてもかまわないという点です。
 +
しかし、万が一、このサーバプロセスが何かの形で乗っ取られてしまい侵入者が外部から任意のコマンドを動かすことが出来るなら、侵入者にシステムに対して万能の権限を持ってしまうことになります。
 +
現在では実行権限はなるべく絞る形で運用されています。
 +
たとえばhttpd(apache)は1つだけrootで稼働しポートのオープンや子プロセスを生成するといった処理をします。
 +
実際のHTTPリクエストに対する対応は別の権限を与えて実行しています。たとえば下の例だとapache/apacheの権限でプロセスを動作させています。
 +
万が一、外部から不当なコマンドが動かされる事態になっても、apacheのユーザ権限が及ぶ範囲でしか被害がありません。
 +
システムの書き換えなど重大なセキュリティ侵害からシステムを守り被害を最小限にできるようなシステムの設計にするのが現在の一般的な考え方です。
  
/etc/passwd の エントリー例
 
hironobu:x:1825:2000:Hironobu SUZUKI,,,:/home/hironobu:/bin/bash
 
  
 +
<pre class="bash">
 +
% ps -eo user,group,args | grep httpd
 +
root    root    /usr/sbin/httpd
 +
apache  apache  /usr/sbin/httpd
 +
apache  apache  /usr/sbin/httpd
 +
apache  apache  /usr/sbin/httpd
 +
apache  apache  /usr/sbin/httpd
 +
</pre>
  
このエントリー例は実際運用しているシステムのパスワードファイルから抜き出したものです。
+
== ディレクトリへの特殊な設定 ==
パスワードのフィールドは"x"が入っています。
+
=== ディレクトリにsetgidビットを設定する ===
これは利用しているシステムがシャドーパスワードを導入しているからです。
+
  
 +
ディレクトリのグループにsetgidビットを設定すると、そのディレクトリ以下に作られるファイル及びディレクトリには現ディレクトリのグループが適用されます。
  
元々のパスワードファイルには2つの情報が入っています。
+
<pre class="bash">
一つは公開して誰でも知って良い情報、もう一つは知られてはいけない情報です。
+
$ ls -l
その知られてはいけない情報とはパスワードの情報です。
+
合計 4
 +
drwxrwx--- 2 hironobu hironobu 4096 12月 14 02:35 foo
 +
$ sudo touch foo/fileA
 +
$ ls -al foo
 +
合計 8
 +
drwxrwx--- 2 hironobu hironobu 4096 12月 14 02:36 .
 +
drwxrwx--- 3 hironobu hironobu 4096 12月 14 02:35 ..
 +
-rw-r----- 1 root    root        0 12月 14 02:36 fileA
 +
</pre>
  
 +
この例は、fooというディレクトリがあり、そのディレクトリ下にコマンド touch を使いrootの持ち物である fileA を作成します。
 +
この時のfileAの所有者、グループともrootです。
  
もちろんこのパスワードは、すでに一方向性ハッシュ関数によって撹拌されている値となってなっています。
 
したがって、パスワードファイルの中にあるすでに撹拌されているパスワードの値だけ持っていても、
 
そこから元のパスワードを逆算することはできません。
 
いろいろな入力値を一方向性ハッシュ関数に与えて、
 
その出力結果と手元にあるパスワードファイルの内容とを比較する方法、
 
つまり、総当たり攻撃でしか探すことはできません。
 
実際のパスワードの生成は入力された文字列にシステムが用意したSalt(塩)と呼ぶ初期値を加えたものを一方向性ハッシュ関数に与え、
 
何度か繰り返し計算をしてビットのパターンを何度も撹拌します。 
 
一方向性ハッシュ関数には、暗号化するためのDESを一方向性ハッシュ関数として代用するもの(UNIX オリジナルの方法)、
 
一方向性ハッシュ関数MD5やSHA1を使うものがあります。
 
DESを使う場合は25回繰り返して計算します。
 
一方向性ハッシュ関数を使う場合は最低1000回繰り返して計算します。
 
<ref>暗号学的には繰り返す必要はありません。</ref>
 
現在のGNU/Linuxで標準的に使われるパスワード認証のための環境Linux-PAMではMD5/SHA1を使っての撹拌が行われています。
 
いずれも暗号学的には十分な強度が得られていると言えます。
 
  
  撹拌のモデル (Cipher-Block-Chain方式)
+
<pre class="bash">
                      +----------+
+
$ chmod g+s foo
                      V          |(回数分)
+
$ ls -ld foo
  パスワード---->[ハッシュ関数]-->+----------> 暗号化されたパスワード
+
drwxrws--- 2 hironobu hironobu 4096 12月 14 02:36 foo
 +
$ sudo touch foo/fileB
 +
$ ls -al foo
 +
合計 8
 +
drwxrws--- 2 hironobu hironobu 4096 12月 14 02:37 .
 +
drwxrwx--- 3 hironobu hironobu 4096 12月 14 02:35 ..
 +
-rw-r----- 1 root    root        0 12月 14 02:36 fileA
 +
-rw-r----- 1 root    hironobu    0 12月 14 02:37 fileB
 +
</pre>
  
 +
ディレクトリ foo に対しsetgid ビットの設定を行います。setgid ビットがセットされるとグループの"x"だった部分が"s"に変化します。
 +
次にコマンド touch で fileB を作成します。
 +
ディレクトリのグループ hironobu がファイルに継承されて fileB の所有者は root グループが hironobu になります。
  
 +
=== ディレクトリにStickyビットを設定する ===
  
しかし、ある文字列を暗号化して、その出力をパスワードファイルの中にある変換後のパスワードと比較することはできます。
+
ユーザ(user)が読み書きできるディレクトリにStickyビットを設定した場合、そのディレクトリにどのユーザでもファイルを作成することができますが、ディレクトリから削除する場合、そのファイルの所有者(owner)しか削除できません。
かくして、大量の文字列を処理し、パスワードと同じ文字列を探すことが可能になります。
+
  
 +
<pre class="bash">
 +
$ mkdir temp
 +
$ ls -dl temp
 +
drwxr----- 2 hironobu hironobu 4096 12月 14 03:12 temp
 +
$ chmod go+rwxt temp
 +
$ ls -dl temp
 +
drwxrwxrwt 2 hironobu hironobu 4096 12月 14 03:12 temp
 +
</pre>
  
そこで変換後のパスワードを一般ユーザが直接は参照できない別ファイルに取っておき、
 
認証するコマンドやメンテナンスのコマンドのみがアクセスできるようにしました。これがシャドーパスワードです。
 
  
 +
== ACL ==
  
$ ls -l  /etc/shadow
+
Access Control Lists(ACL)は元々のUNIXにはないアクセス制御方式で、その仕様に関してはPOSIXで定義されています。Linuxカーネル2.6以降で採用されています。Linuxカーネル2.6以降ではLinuxの主要ファイルシステムで利用可能です。
-rw-r-----    1 root    shadow        789 Oct 22  2003 /etc/shadow
+
$ ls -l /usr/bin/passwd
+
-rwsr-xr-x    1 root    root        24616 Nov  3 04:56 /usr/bin/passwd
+
$ ls -l /usr/bin | grep shadow
+
-rwxr-sr-x    1 root    shadow      32584 Nov  3 04:56 chage
+
-rwxr-sr-x    1 root    shadow      15976 Nov  3 04:56 expiry
+
-rwxr-sr-x    1 root    shadow      6628 Jun 28 05:20 kcheckpass
+
  
== ACL (作業中) ==
 
  
 +
UNIXでは自分以外のユーザにアクセスを許可する場合は、グループに許可するか、それともすべてのユーザに許可するかの大まかな条件でアクセス制御をしています。一方、ACLではアクセス許可を特定のユーザの単位で、あるいはグループ単位で設定できます。ACLの導入により、これまでのUNIXのアクセス制御よりも現敵的な設定をすることが可能になります。
 +
 +
 +
次のようなファイルがあるとします。
 +
 +
 +
<pre class="bash">
 +
$touch foo.txt
 +
$ ls -l foo.txt
 +
-rw-rw-r-- 1 hironobu hironobu 0 Aug 31 08:15 foo.txt
 +
</pre>
 +
 +
 +
コマンドgetfaclを使ってパーミッションを表示すると次のようになります。
 +
 +
 +
<pre class="bash">
 +
$ getfacl foo.txt
 +
# file: foo.txt
 +
# owner: hironobu
 +
# group: hironobu
 +
user::rw-
 +
group::rw-
 +
other::r--
 +
</pre>
 +
 +
 +
次に自分以外のユーザが読み書きできないようにしてみます。
 +
 +
 +
<pre class="bash">
 +
$ chmod go-rw foo.txt
 +
$ ls -l foo.txt
 +
-rw------- 1 hironobu hironobu 0 Aug 31 08:15 foo.txt
 +
</pre>
 +
 +
 +
この状態でwww-dataユーザのみにfoo.txtの読み込みを許諾するとなると、グループを使う方法だとwww-dataとhironobuだけのグループを作り、そのグループを設定し、グループの読み込みを許可する、といったことをしなければなりません。このWebサーバがアクセスしなければならないファイルの所有者がhironobuのユーザしか存在していないのならば、グループで運用するのも問題ありません。しかし、もし、hironobu以外にmasamiというユーザがいたならば、双方別々のグループを作りwww-dataを加えるといった方法が必要になります。もちろんこの方法はユーザが増えるたびにグループも増えます。
 +
 +
そこでACLの登場です。www-dataのアカウントのみを直接指定してアクセスを許すといった個別の対応ができれば、これまでのUNIXのアクセス権限の手法よりもシンプルに扱うことが出来るようになります。
 +
 +
=== ACLの設定 ===
 +
 +
コマンドsetfaclはaclをセットするためのものです。ユーザwww-dataに"r"だけ許可をしてみます。
 +
 +
 +
<pre class="bash">
 +
$ setfacl -m user:www-data:r foo.txt
 +
</pre>
 +
 +
 +
ではコマンドgetfaclを使って、どう変化したか見てみましょう。
 +
 +
 +
<pre class="bash">
 +
$ getfacl foo.txt
 +
# file: foo.txt
 +
# owner: hironobu
 +
# group: hironobu
 +
user::rw-
 +
user:www-data:r--
 +
group::---
 +
mask::r--
 +
other::---
 +
</pre>
 +
 +
 +
先ほどの内容から2点変わっているのがわかるはずです。まず1点はuserの表示が増えたこと、そしてmaskという新しい項目ができたことです。maskは所有するユーザ以外に与えることのできる最大限の権限です。この場合はmaskに対して指定していないのでデフォルトの"r"が設定されています。
 +
ここではwww-dataのみですが、複数のユーザに対しても同様に個別の設定をすることができます。
 +
ここではユーザのみに関して説明していますが、グループに対しても複数のグループを割り当てたりすることが可能です。
 +
 +
 +
さらに詳しく知るためには
 +
openSUSE
 +
<ref>
 +
openSUSE 第15章 Linuxのアクセス制御リスト
 +
https://www.suse.com/ja-jp/documentation/sles10/book_sle_reference/data/cha.acls.html</ref>
 +
やRadHat
 +
<ref>
 +
Storage Administration Guide
 +
第19章 アクセス制御リスト
 +
https://access.redhat.com/site/documentation/ja-JP/Red_Hat_Enterprise_Linux/6/html/Storage_Administration_Guide/ch-acls.html
 +
</ref>
 +
やTurbolinux
 +
<ref>
 +
Turbolinux 11 Server: ユーザーガイド 第 40章Posix ACL(Access Control List)
 +
http://www.turbolinux.co.jp/products/server/11s/user_guide/c15067.html
 +
</ref>
 +
などのACLに関する運用ドキュメントが参考になります。
 +
 +
 +
さて、この状態でls -lでファイルのパーミッションの状況をみてみましょう。
 +
 +
 +
<pre class="bash">
 +
% ls -l foo.txt
 +
-rw-r-----+ 1 hironobu hironobu 0 Aug 31 08:15 foo.txt
 +
</pre>
 +
 +
 +
最後に"+"と表示されているのは、ACLが設定されているということを意味しています。
  
 
== 脚注 ==
 
== 脚注 ==
302行目: 452行目:
 
----
 
----
 
[[目次]]へ
 
[[目次]]へ
 +
 +
 +
このページへのショートURL:
 +
http://uc2.h2np.net/i/df.html

2018年12月14日 (金) 02:10時点における版

ユーザと権限

オペレーティングシステム内部ではユーザの違いをアカウント名ではなく ユーザID(UID / User IDentifier)による数値で認識しています。 またユーザは1つデフォルトのグループID(GID / GroupIDentifier)がつけられています。 そのユーザIDやグループIDが条件に合致するかどうかでユーザに権限があるかどうかを判断しています。


補足
ユーザやグループの追加、更新などオペレーションに関してはユーザやグループの管理を参照してください。


唯一例外的なのはユーザIDが0、グループIDが0のユーザrootです。 スーパーユーザーと呼ばれ、 UNIXにおいてはオールマイティーな権限を持つ特別なユーザです。 管理者権限として説明される場合が多いのですが、 管理者として何かするという表現よりも「オペレーティングシステム上で何でもできてしまう権限」 と説明した方が分かり易いかと思います。


ユーザIDとグループIDによるアクセス制御

オペレーティングシステムの内部では、ユーザは名前で管理されているのではなくユーザID(UID)で管理されています。 たとえばファイルにユーザ(所有者)が設定されていますが、その所有者情報とはファイルの情報(ディレクトリ情報のなかにあるメタ情報)に付加されているユーザIDのことです。 また、プロセスが動作している時には、いずれかのユーザIDとグループIDを持っており、そのユーザIDに付加された権限の範囲内においてプロセスは資源にアクセスできます。 グループID(GID)は、そのグループにユーザが登録されている場合、そのユーザに与えられるグループ権限です。 UNIXの基本的な権限は、このユーザIDの違いによるユーザ権限と、グループIDの違いによるグループ権限の2つから成り立っています。 ファイルやプロセスの資源へのアクセス制御はユーザID・グループID [1] を使っての許可・不許可によって行われるというのが基本的な考え方です。


まずファイルに対するユーザIDとグループIDを見てみましょう。 ファイルには、ユーザIDとグループIDが設定されています。 ユーザID=このファイルの所有者です。 尚、本章の範囲では、所有者とユーザと同じ意味で使っています。 ユーザが自分の所有するファイルの属性を変更し、そのファイルのアクセス権限などをコントロールすることができます。 ただしroot権限だけは例外で、システムのすべてに無制限にアクセスできます。


ユーザIDが数字ではなくユーザ名として表示されるのは、ユーザIDは/etc/passwdで設定されている対応するアカウント名、 グループIDは/etc/groupで設定されている対応するグループ名に変換されて表示されるからです。


読み込み / 書き込み / 実行

基本的なファイルへのアクセス権限は、「読み込み」「書き込み」「実行」です。 ディレクトリの場合は実行の部分の意味が「ディレクトリとしてアクセスできるか」ということとして扱われます。


  • アクセス権限 : 読み込み / 書き込み / 実行
  • ユーザ・所有者(User)に対して : 許可 / 不許可
  • グループ(Group)に対して : 許可 / 不許可
  • それ以外(Other)対して : 許可 / 不許可


 $ ls -l memo.txt 
 -rw-r--r--    1 hironobu hironobu       44 Sep 20 19:17 memo.txt
 $  ls -l /var/mail/hironobu
 -rw-rw----    1 hironobu mail            0 Dec  9 19:39 hironobu


memo.txtはユーザIDがhironobu、グループIDがhironobuになっており、ユーザ(所有者)は読み書き、同じグループには読み込み、その他の権限でも読み込みができます。 正確には、ユーザと同じユーザIDを持ったプロセス、設定されたグループと同じグループに属するユーザIDを持つプロセス、それ以外のユーザIDを持つプロセスがアクセス可能であるという表現になります。


/var/mail/hironobuというファイルのユーザIDはhironobuになっており、グループIDはmailです。mailのグループ権限を持つプロセスから読み書き可能になっています。具体的には、メールサーバなどのプロセスが読み書きできるようになっています。


変更はコマンドchmodを使います。chmodのオプションではユーザ(所有者)はu、グループはg、それ以外の利用者はoという表現を使います。 パーミッションの許可は"+"、パーミッションの不許可は"-"を使います。 chmodのオプションで"go-rw"はグループとその他ユーザからの読み書きは不許可となります。


 $ chmod go-rw memo.txt
 $ ls -l memo.txt 
 -rw-------    1 hironobu hironobu       44 Sep 20 19:17 memo.txt

ユーザ(所有者)、グループ、その他ユーザの読み取り許可・不許可、書き込み許可・不許可、実行の許可・不許可は3ビットで表すので、この部分を8進数で表現することもできます。 その場合"rw-------"はビットの設定がuが110、gが000、oが000となるので、8進数表現をするモードでは600となります。


 $ chmod 600 memo.txt
 $ ls -l memo.txt 
 -rw-------    1 hironobu hironobu       44 Sep 20 19:17 memo.txt

グループID利用の方法

ここにファイルgroup_share.datがあるとします。これをユーザtaroとユーザhanakoが共通に読み書きのアクセスでき、 他のユーザはアクセスできないようなパーミッションにしたいとします。


 $ ls -l
 合計 56
 -rw-r--r--  1 taro taro     51200 2005-11-23 18:33 group_share.dat


まずgroup_share.datを所有者とグループにはrw、それ以外には読み書き禁止にします。 chmodを使いますが、2度に分けてオプションを使ってもいいですし、モードを数字で与えてもかまいません。


 $ chmod o-wr group_share.dat 
 $ chmod g+wr group_share.dat 

あるいは

 $ chmod 660 group_share.dat 


結果は次のようになります。


 $ ls -l
 合計 56
 -rw-rw----  1 taro taro     51200 2005-11-23 18:33 group_share.dat


次にroot権限でtaroとhanakoの共通に使えるグループtaro-hanakoを作ります。 そしてtaro とhanakoをグループtaro-hanakoに加えます。


 # groupadd taro-hanako
 # gpasswd -a taro   taro-hanako
 # gpasswd -a hanako taro-hanako


taroが新しいグループに加わった時、taroが再度ログインした時からその新しいグループ (この場合taro-hanako)が有効になります。 再度ログインした状態で、taroはgroup_share.datのグループIDをtaro-hanakoにします。


 $ chgrp taro-hanako group_share.dat
 ...
 -rw-rw----  1 taro taro-hanako     51200 2005-11-23 18:33 group_share.dat


これでgroup_share.datはtaro-hanakoのグループに属しているtaroとhanakoが読み書きが出来るようになります。


考えてみよう
apacheはユーザwww-dataの権限で動作しています。cgi-binなどでコマンドを動かしファイルinfo.datに情報を書き込む必要があります。しかし、info.dataの中身に関してはセキュリティ上の問題のためユーザfoo以外には読ませたくありません(www-dataにも許可しません)。さて、この場合、info.datの適切なファイルの所有者、適切なパーミッションはどのようなものでしょうか。

プロセスのユーザIDとグループID

まずログインした時に、そのアカウント名に割り振られたユーザIDとグループIDの権限でログインシェルが動き始めます。 そのシェルから起動されるプロセスにはデフォルトで親プロセスのユーザIDとグループIDが受け継がれます。 root権限(注)でsetuid(2)やsetgid(2)を使うとプロセスのユーザIDを変更することができます。


調べてみよう
setuid(2)やsetgid(2)の利用にはもう少し限定した条件があるので調べてみよう。


 $ ps aux
 USER       PID %CPU %MEM   VSZ  RSS TTY      STAT START   TIME COMMAND
 root         1  0.0  0.0  1272  432 ?        S    Aug23   1:49 init [2]       
 ...
 daemon     126  0.0  0.0  1384  296 ?        S    Aug23   0:00 /sbin/portmap
 canna     2799  0.0  2.7 19152 17568 ?       S    Aug23  13:02 /usr/sbin/cannase
 root     23439  0.0  0.1  2936  660 ?        S    Nov24   0:17 /usr/sbin/apache
 www-data 23474  0.0  0.0  2948  632 ?        S    Nov24   0:00 /usr/sbin/apache
 hironobu 20287  0.0  0.0  2464  224 pts/0    S    Oct16   0:00 bash
 hironobu  2796  0.0  1.0  8752 6716 ?        R    12:14   0:05 emacs20 -geometry
 ...

現在の権限管理

古典的なUNIXはUIDとGIDだけで説明は済みますが、Linuxも含めBSD 4.3以降では、もっと複雑な設定ができます。 Linuxでは4つタイプのUIDと4つのGIDのタイプを持っています。

  • ユーザID、グループIDの種類
  • UID / GID : 今まで通りのUID / GID
  • RUID / RGID : 実UID / 実GID --- UIDやGIDと同じ役割 (RはReal)
  • EUID / EGID : 実効UID / 実効GID --- 権限があるかどうかをチェックする時に使う (EはEffective)
  • SUID / SGID : 保存UID / 保存GID --- 有効化・無効化を行うための保存 (SはSaved)
  • FSUID / FSGID : ファイルUID / ファイルGID --- Linux独自のファイルのアクセス権限のチェック


setuid

これらはプロセスが、どのような権限で動作するかを規定するものです。 UNIXには実行ファイルの属性に(モードに)setuid bitを設定しておくと、 その実行ファイルはファイルの所有者の権限で動作します。 setgid bitは実行ファイルのグループの権限で動作します。 コマンドfindを使って探してみましょう。


 $ find /bin  -perm +a+s -exec ls -l {} \;
 -rwsr-xr-x 1 root root 26252 Mar  3  2012 /bin/fusermount
 -rwsr-xr-x 1 root root 88760 Mar 30  2012 /bin/mount
 -rwsr-xr-x 1 root root 34740 Nov  8  2011 /bin/ping
 -rwsr-xr-x 1 root root 39116 Nov  8  2011 /bin/ping6
 -rwsr-xr-x 1 root root 31116 Sep 13  2012 /bin/su
 -rwsr-xr-x 1 root root 67720 Mar 30  2012 /bin/umount


最初の表示にある-rwsr-x-rxのsがsetuid bitの意味です。 つまり、これらのコマンドは所有者がrootであり、かつ、 このコマンドを動かすとrootの権限で動かすことができるという意味です。 この実行時は、ruidは利用者、euidがrootとなり、 root権限のファイルなどに書き込むことができるようになります。 一般ユーザでも何でもできる権限を手に入れてしまうということで、 このようなプログラムに誤りがあると大きなセキュリティ上の問題になります。

setgid

setgidは、set group id bitの意味です。そのファイルのグループIDと同じ権限で実行できます。


 $ find /bin  -perm +g+s -exec ls -l {} \;


ruidがrootの時、つまりrootがファイルを実行した時は何でもできるので、euidをプロセス内で制限なく変更できます。 たとえばapacheは唯一1つrootでのプロセスがあり、 そこから生成し子プロセスがwww-data(あるいは他の)euidで動作します。 外部からのアクセスはすべてwww-dataのeuidで動いている子プロセスで動作しているので、 万が一、外部からの入力によりapache誤った動作をしても、 その影響範囲を無制限にはしない(root権限ではない)ようにしています。


RUID/RGID、EUID/EGID、SUID/SGIDを上手に変更することによって、どのユーザ権限で、 あるいはどのグループ権限でプロセスを動かし、適切にファイルや資源にアクセスできるようになることで、 セキュリティを保つことができるようになります。 これらの値のセットにはルールがあるので、全部はかけないですが、典型的なものを書き出してみます。


  • RUID / EUID / SUIDの設定ルール
  • RUID の値を EUID にセットできる
  • EUID の値を RUID にセットできる
  • 実行時のEUIDがSUIDにコピーされていて、SUIDの値をEUIDにセットできる
  • rootはRUIDもEUIDも自由にセットできる


このように実行時のユーザIDを変えることができ、また一般ユーザでも実行ファイルに権限が附加されていれば、 root権限でプロセスを動かすこともできるなどかなり複雑な権限のコントロールが可能です。


もちろん、Linuxがコントロールが可能であることと、 アプリケーションがきちんと矛盾なく利用できるように設計できることとはまったく別のことです。 アプリケーションの設計が正しくなかったり、実装で間違えていると、セキュリティ侵害が発生することはいうまでもありません。


なるべくrootでは動かさない運用

まだセキュリティなどをあまり気にせず、サーバとして動作しているものは何でもかんでもrootで実行していた時期がUNIXにもありました。 これの利点は、アクセスする先のファイルのパーミッションやroot権限でしかオープンできないポート番号など一々気にしなくてもかまわないという点です。 しかし、万が一、このサーバプロセスが何かの形で乗っ取られてしまい侵入者が外部から任意のコマンドを動かすことが出来るなら、侵入者にシステムに対して万能の権限を持ってしまうことになります。 現在では実行権限はなるべく絞る形で運用されています。 たとえばhttpd(apache)は1つだけrootで稼働しポートのオープンや子プロセスを生成するといった処理をします。 実際のHTTPリクエストに対する対応は別の権限を与えて実行しています。たとえば下の例だとapache/apacheの権限でプロセスを動作させています。 万が一、外部から不当なコマンドが動かされる事態になっても、apacheのユーザ権限が及ぶ範囲でしか被害がありません。 システムの書き換えなど重大なセキュリティ侵害からシステムを守り被害を最小限にできるようなシステムの設計にするのが現在の一般的な考え方です。


% ps -eo user,group,args | grep httpd
root     root     /usr/sbin/httpd
apache   apache   /usr/sbin/httpd
apache   apache   /usr/sbin/httpd
apache   apache   /usr/sbin/httpd
apache   apache   /usr/sbin/httpd

ディレクトリへの特殊な設定

ディレクトリにsetgidビットを設定する

ディレクトリのグループにsetgidビットを設定すると、そのディレクトリ以下に作られるファイル及びディレクトリには現ディレクトリのグループが適用されます。

$ ls -l
合計 4
drwxrwx--- 2 hironobu hironobu 4096 12月 14 02:35 foo
$ sudo touch foo/fileA
$ ls -al foo
合計 8
drwxrwx--- 2 hironobu hironobu 4096 12月 14 02:36 .
drwxrwx--- 3 hironobu hironobu 4096 12月 14 02:35 ..
-rw-r----- 1 root     root        0 12月 14 02:36 fileA

この例は、fooというディレクトリがあり、そのディレクトリ下にコマンド touch を使いrootの持ち物である fileA を作成します。 この時のfileAの所有者、グループともrootです。


$ chmod g+s foo
$ ls -ld foo
drwxrws--- 2 hironobu hironobu 4096 12月 14 02:36 foo
$ sudo touch foo/fileB
$ ls -al foo
合計 8
drwxrws--- 2 hironobu hironobu 4096 12月 14 02:37 .
drwxrwx--- 3 hironobu hironobu 4096 12月 14 02:35 ..
-rw-r----- 1 root     root        0 12月 14 02:36 fileA
-rw-r----- 1 root     hironobu    0 12月 14 02:37 fileB

ディレクトリ foo に対しsetgid ビットの設定を行います。setgid ビットがセットされるとグループの"x"だった部分が"s"に変化します。 次にコマンド touch で fileB を作成します。 ディレクトリのグループ hironobu がファイルに継承されて fileB の所有者は root グループが hironobu になります。

ディレクトリにStickyビットを設定する

ユーザ(user)が読み書きできるディレクトリにStickyビットを設定した場合、そのディレクトリにどのユーザでもファイルを作成することができますが、ディレクトリから削除する場合、そのファイルの所有者(owner)しか削除できません。

$ mkdir temp
$ ls -dl temp
drwxr----- 2 hironobu hironobu 4096 12月 14 03:12 temp
$ chmod go+rwxt temp
$ ls -dl temp
drwxrwxrwt 2 hironobu hironobu 4096 12月 14 03:12 temp


ACL

Access Control Lists(ACL)は元々のUNIXにはないアクセス制御方式で、その仕様に関してはPOSIXで定義されています。Linuxカーネル2.6以降で採用されています。Linuxカーネル2.6以降ではLinuxの主要ファイルシステムで利用可能です。


UNIXでは自分以外のユーザにアクセスを許可する場合は、グループに許可するか、それともすべてのユーザに許可するかの大まかな条件でアクセス制御をしています。一方、ACLではアクセス許可を特定のユーザの単位で、あるいはグループ単位で設定できます。ACLの導入により、これまでのUNIXのアクセス制御よりも現敵的な設定をすることが可能になります。


次のようなファイルがあるとします。


 $touch foo.txt
 $ ls -l foo.txt
 -rw-rw-r-- 1 hironobu hironobu 0 Aug 31 08:15 foo.txt


コマンドgetfaclを使ってパーミッションを表示すると次のようになります。


 $ getfacl foo.txt 
 # file: foo.txt
 # owner: hironobu
 # group: hironobu
 user::rw-
 group::rw-
 other::r--


次に自分以外のユーザが読み書きできないようにしてみます。


 $ chmod go-rw foo.txt
 $ ls -l foo.txt
 -rw------- 1 hironobu hironobu 0 Aug 31 08:15 foo.txt


この状態でwww-dataユーザのみにfoo.txtの読み込みを許諾するとなると、グループを使う方法だとwww-dataとhironobuだけのグループを作り、そのグループを設定し、グループの読み込みを許可する、といったことをしなければなりません。このWebサーバがアクセスしなければならないファイルの所有者がhironobuのユーザしか存在していないのならば、グループで運用するのも問題ありません。しかし、もし、hironobu以外にmasamiというユーザがいたならば、双方別々のグループを作りwww-dataを加えるといった方法が必要になります。もちろんこの方法はユーザが増えるたびにグループも増えます。

そこでACLの登場です。www-dataのアカウントのみを直接指定してアクセスを許すといった個別の対応ができれば、これまでのUNIXのアクセス権限の手法よりもシンプルに扱うことが出来るようになります。

ACLの設定

コマンドsetfaclはaclをセットするためのものです。ユーザwww-dataに"r"だけ許可をしてみます。


 $ setfacl -m user:www-data:r foo.txt 


ではコマンドgetfaclを使って、どう変化したか見てみましょう。


 $ getfacl foo.txt
 # file: foo.txt
 # owner: hironobu
 # group: hironobu
 user::rw-
 user:www-data:r--
 group::---
 mask::r--
 other::---


先ほどの内容から2点変わっているのがわかるはずです。まず1点はuserの表示が増えたこと、そしてmaskという新しい項目ができたことです。maskは所有するユーザ以外に与えることのできる最大限の権限です。この場合はmaskに対して指定していないのでデフォルトの"r"が設定されています。 ここではwww-dataのみですが、複数のユーザに対しても同様に個別の設定をすることができます。 ここではユーザのみに関して説明していますが、グループに対しても複数のグループを割り当てたりすることが可能です。


さらに詳しく知るためには openSUSE [2] やRadHat [3] やTurbolinux [4] などのACLに関する運用ドキュメントが参考になります。


さて、この状態でls -lでファイルのパーミッションの状況をみてみましょう。


 % ls -l foo.txt
 -rw-r-----+ 1 hironobu hironobu 0 Aug 31 08:15 foo.txt


最後に"+"と表示されているのは、ACLが設定されているということを意味しています。

脚注

  1. 自分のユーザIDやグループIDを確認するにはコマンドidを使う。詳しくはユーザやグループの管理を参照のこと。
  2. openSUSE 第15章 Linuxのアクセス制御リスト https://www.suse.com/ja-jp/documentation/sles10/book_sle_reference/data/cha.acls.html
  3. Storage Administration Guide 第19章 アクセス制御リスト https://access.redhat.com/site/documentation/ja-JP/Red_Hat_Enterprise_Linux/6/html/Storage_Administration_Guide/ch-acls.html
  4. Turbolinux 11 Server: ユーザーガイド 第 40章Posix ACL(Access Control List) http://www.turbolinux.co.jp/products/server/11s/user_guide/c15067.html

目次


このページへのショートURL: http://uc2.h2np.net/i/df.html