「ユーザ権限とアクセス制御」の版間の差分
細 →ユーザと権限 |
|||
(同じ利用者による、間の44版が非表示) | |||
1行目: | 1行目: | ||
== ユーザと権限 == | == ユーザと権限 == | ||
オペレーティングシステム内部ではユーザの違いをアカウント名ではなく | オペレーティングシステム内部ではユーザの違いをアカウント名ではなく | ||
ユーザID(UID / User IDentifier)による数値で認識しています。 | ユーザID(UID / User IDentifier)による数値で認識しています。 | ||
またユーザは1つデフォルトのグループID(GID / GroupIDentifier)がつけられています。 | またユーザは1つデフォルトのグループID(GID / GroupIDentifier)がつけられています。 | ||
そのユーザIDやグループIDが条件に合致するかどうかでユーザに権限があるかどうかを判断しています。 | |||
<ref> | |||
RED HAT ENTERPRISE LINUX Identity Management ガイド | |||
https://access.redhat.com/documentation/ja-jp/red_hat_enterprise_linux/6/html/identity_management_guide/index | |||
</ref> | |||
;補足: ユーザやグループの追加、更新などオペレーションに関しては[[ユーザやグループの管理]]を参照してください。 | ;補足: ユーザやグループの追加、更新などオペレーションに関しては[[ユーザやグループの管理]]を参照してください。 | ||
15行目: | 18行目: | ||
スーパーユーザーと呼ばれ、 | スーパーユーザーと呼ばれ、 | ||
UNIXにおいてはオールマイティーな権限を持つ特別なユーザです。 | UNIXにおいてはオールマイティーな権限を持つ特別なユーザです。 | ||
管理者権限として説明される場合が多いのですが、 | |||
管理者として何かするという表現よりも「オペレーティングシステム上で何でもできてしまう権限」 | |||
と説明した方が分かり易いかと思います。 | と説明した方が分かり易いかと思います。 | ||
=== | === ユーザIDとグループIDによるアクセス制御 === | ||
オペレーティングシステムの内部では、ユーザは名前で管理されているのではなくユーザID(UID)で管理されています。 | |||
たとえばファイルにユーザ(所有者)が設定されていますが、その所有者情報とはファイルの情報(ディレクトリ情報のなかにあるメタ情報)に付加されているユーザIDのことです。 | |||
また、プロセスが動作している時には、いずれかのユーザIDとグループIDを持っており、そのユーザIDに付加された権限の範囲内においてプロセスは資源にアクセスできます。 | |||
グループID(GID)は、そのグループにユーザが登録されている場合、そのユーザに与えられるグループ権限です。 | |||
UNIXの基本的な権限は、このユーザIDの違いによるユーザ権限と、グループIDの違いによるグループ権限の2つから成り立っています。 | UNIXの基本的な権限は、このユーザIDの違いによるユーザ権限と、グループIDの違いによるグループ権限の2つから成り立っています。 | ||
ファイルやプロセスの資源へのアクセス制御はユーザID・グループ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になっており、ユーザ(所有者)は読み書き、同じグループには読み込み、その他の権限でも読み込みができます。 | |||
正確には、ユーザと同じユーザIDを持ったプロセス、設定されたグループと同じグループに属するユーザIDを持つプロセス、それ以外のユーザIDを持つプロセスがアクセス可能であるという表現になります。 | |||
/var/mail/hironobuというファイルのユーザIDはhironobuになっており、グループ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利用の方法 == | ||
74行目: | 104行目: | ||
<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> | |||
83行目: | 115行目: | ||
<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> | |||
101行目: | 141行目: | ||
<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> | |||
110行目: | 152行目: | ||
<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> | |||
120行目: | 164行目: | ||
;考えてみよう: 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の権限でログインシェルが動き始めます。 | ||
130行目: | 174行目: | ||
<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 | ||
141行目: | 186行目: | ||
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以降では、もっと複雑な設定ができます。 | 古典的なUNIXはUIDとGIDだけで説明は済みますが、Linuxも含めBSD 4.3以降では、もっと複雑な設定ができます。 | ||
164行目: | 210行目: | ||
$ | <pre class="bash"> | ||
-rwsr-xr-x | $ find /bin -perm +a+s -exec ls -l {} \; | ||
-rwsr-xr-x | -rwsr-xr-x 1 root root 26252 Mar 3 2012 /bin/fusermount | ||
-rwsr-xr-x | -rwsr-xr-x 1 root root 88760 Mar 30 2012 /bin/mount | ||
-rwsr-xr-x | -rwsr-xr-x 1 root root 34740 Nov 8 2011 /bin/ping | ||
-rwsr-xr-x | -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> | |||
179行目: | 228行目: | ||
一般ユーザでも何でもできる権限を手に入れてしまうということで、 | 一般ユーザでも何でもできる権限を手に入れてしまうということで、 | ||
このようなプログラムに誤りがあると大きなセキュリティ上の問題になります。 | このようなプログラムに誤りがあると大きなセキュリティ上の問題になります。 | ||
=== setgid === | === setgid === | ||
185行目: | 233行目: | ||
setgidは、set group id bitの意味です。そのファイルのグループIDと同じ権限で実行できます。 | setgidは、set group id bitの意味です。そのファイルのグループIDと同じ権限で実行できます。 | ||
$ | |||
<pre class="bash"> | |||
$ find /bin -perm +g+s -exec ls -l {} \; | |||
</pre> | |||
=== 実行権限を限定させる === | |||
ruidがrootの時、つまりrootがファイルを実行した時は何でもできるので、euidをプロセス内で制限なく変更できます。 | ruidがrootの時、つまりrootがファイルを実行した時は何でもできるので、euidをプロセス内で制限なく変更できます。 | ||
215行目: | 268行目: | ||
もちろん、Linuxがコントロールが可能であることと、 | もちろん、Linuxがコントロールが可能であることと、 | ||
アプリケーションがきちんと矛盾なく利用できるように設計できることとはまったく別のことです。 | アプリケーションがきちんと矛盾なく利用できるように設計できることとはまったく別のことです。 | ||
アプリケーションの設計が正しくなかったり、実装で間違えていると、セキュリティ侵害が発生する<ref>POS37-C. 権限の破棄は確実に行う 【[https://www.jpcert.or.jp/sc-rules/c-pos37-c.html JPCERT/CCサイトへ]】</ref>ことはいうまでもありません。 | |||
=== なるべくrootでは動かさない運用 === | |||
まだセキュリティなどをあまり気にせず、サーバとして動作しているものは何でもかんでもrootで実行していた時期がUNIXにもありました。 | |||
これの利点は、アクセスする先のファイルのパーミッションやroot権限でしかオープンできないポート番号など一々気にしなくてもかまわないという点です。 | |||
しかし、万が一、このサーバプロセスが何かの形で乗っ取られてしまい侵入者が外部から任意のコマンドを動かすことが出来るなら、侵入者にシステムに対して万能の権限を持ってしまうことになります。 | |||
現在では実行権限はなるべく絞る形で運用されています。 | |||
たとえばhttpd(apache)は1つだけrootで稼働しポートのオープンや子プロセスを生成するといった処理をします。 | |||
実際のHTTPリクエストに対する対応は別の権限を与えて実行しています。たとえば下の例だとapache/apacheの権限でプロセスを動作させています。 | |||
万が一、外部から不当なコマンドが動かされる事態になっても、apacheのユーザ権限が及ぶ範囲でしか被害がありません。 | |||
システムの書き換えなど重大なセキュリティ侵害からシステムを守り被害を最小限にできるようなシステムの設計にするのが現在の一般的な考え方です。 | |||
<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> | |||
== ディレクトリへの特殊な設定 == | |||
=== ディレクトリにsetgidビットを設定する === | |||
ディレクトリのグループにsetgidビットを設定すると、そのディレクトリ以下に作られるファイル及びディレクトリには現ディレクトリのグループが適用されます。 | |||
<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です。 | |||
<pre class="bash"> | |||
$ 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 | |||
</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 == | |||
Access Control Lists(ACL)は元々のUNIXにはないアクセス制御方式で、その仕様に関してはPOSIXで定義されています。Linuxカーネル2.6以降で採用されています。Linuxカーネル2.6以降ではLinuxの主要ファイルシステムで利用可能です。 | |||
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> | |||
20 Linux でのアクセス制御リスト | |||
https://www.belbel.or.jp/opensuse-manuals_ja/cha-security-acls.html | |||
</ref> | |||
やRadHat | |||
<ref> | |||
システム管理者のガイド 第5章 アクセス制御リスト | |||
https://access.redhat.com/documentation/ja-jp/red_hat_enterprise_linux/7/html/system_administrators_guide/ch-access_control_lists | |||
</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が設定されているということを意味しています。 | |||
== 脚注 == | == 脚注 == | ||
296行目: | 452行目: | ||
---- | ---- | ||
[[目次]]へ | [[目次]]へ | ||
このページへのショートURL: | |||
http://uc2.h2np.net/i/df.html |
2024年2月1日 (木) 14:18時点における最新版
ユーザと権限
オペレーティングシステム内部ではユーザの違いをアカウント名ではなく ユーザID(UID / User IDentifier)による数値で認識しています。 またユーザは1つデフォルトのグループID(GID / GroupIDentifier)がつけられています。 そのユーザIDやグループIDが条件に合致するかどうかでユーザに権限があるかどうかを判断しています。 [1]
- 補足
- ユーザやグループの追加、更新などオペレーションに関してはユーザやグループの管理を参照してください。
唯一例外的なのはユーザIDが0、グループIDが0のユーザrootです。 スーパーユーザーと呼ばれ、 UNIXにおいてはオールマイティーな権限を持つ特別なユーザです。 管理者権限として説明される場合が多いのですが、 管理者として何かするという表現よりも「オペレーティングシステム上で何でもできてしまう権限」 と説明した方が分かり易いかと思います。
ユーザIDとグループIDによるアクセス制御
オペレーティングシステムの内部では、ユーザは名前で管理されているのではなくユーザID(UID)で管理されています。 たとえばファイルにユーザ(所有者)が設定されていますが、その所有者情報とはファイルの情報(ディレクトリ情報のなかにあるメタ情報)に付加されているユーザIDのことです。 また、プロセスが動作している時には、いずれかのユーザIDとグループIDを持っており、そのユーザIDに付加された権限の範囲内においてプロセスは資源にアクセスできます。 グループID(GID)は、そのグループにユーザが登録されている場合、そのユーザに与えられるグループ権限です。 UNIXの基本的な権限は、このユーザIDの違いによるユーザ権限と、グループIDの違いによるグループ権限の2つから成り立っています。 ファイルやプロセスの資源へのアクセス制御はユーザID・グループID [2] を使っての許可・不許可によって行われるというのが基本的な考え方です。
まずファイルに対するユーザ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がコントロールが可能であることと、
アプリケーションがきちんと矛盾なく利用できるように設計できることとはまったく別のことです。
アプリケーションの設計が正しくなかったり、実装で間違えていると、セキュリティ侵害が発生する[3]ことはいうまでもありません。
なるべく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
[4]
やRadHat
[5]
などのACLに関する運用ドキュメントが参考になります。
さて、この状態でls -lでファイルのパーミッションの状況をみてみましょう。
% ls -l foo.txt -rw-r-----+ 1 hironobu hironobu 0 Aug 31 08:15 foo.txt
最後に"+"と表示されているのは、ACLが設定されているということを意味しています。
脚注
- ↑ RED HAT ENTERPRISE LINUX Identity Management ガイド https://access.redhat.com/documentation/ja-jp/red_hat_enterprise_linux/6/html/identity_management_guide/index
- ↑ 自分のユーザIDやグループIDを確認するにはコマンドidを使う。詳しくはユーザやグループの管理を参照のこと。
- ↑ POS37-C. 権限の破棄は確実に行う 【JPCERT/CCサイトへ】
- ↑ 20 Linux でのアクセス制御リスト https://www.belbel.or.jp/opensuse-manuals_ja/cha-security-acls.html
- ↑ システム管理者のガイド 第5章 アクセス制御リスト https://access.redhat.com/documentation/ja-jp/red_hat_enterprise_linux/7/html/system_administrators_guide/ch-access_control_lists
目次へ
このページへのショートURL:
http://uc2.h2np.net/i/df.html