- ファイルの移動
ファイルAを別のディレクトリBに移動した場合,ディレクトリBにアクセスできるドメ
インが、移動後のAにアクセスできなくなることがあります。
ファイル移動時、「ファイルAに対するアクセス権限」を引き継ぐからで
す(詳しくは後述)。このようなトラブルを解決するにはrestoreconコマ
ンドを使う必要があります。
* 具体例:ホームページのアップロードの場合
Apacheが移動したファイルにアクセスできないことがあります
# pwd
/root/homepage/index.html
# mv index.html /var/www/html
# restorecon /var/www/html/index.html
ここで、最後のrestoreconコマンドを忘れると、Apacheは/var/www以下にアクセ
スできるように設定されてたとしても、index.htmlにアクセスできませ
ん。
なぜなら、httpd_tは、/root/index.htmlにアクセスできませんが、こ
れがファイル移動後も継承されているからです。
これを修正するにはrestoreconコマンドをする必要があります。
これでも問題が解決できない場合は特殊な場合です。audit2spdlで設定
を追加する必要があります。
- ファイルの新規作成
新規作成されたファイルのアクセス権限は、ディレクトリから引き継が
れます。次の例を見てください。以下の設定が存在したとします。
domain foo_t;
allow /foo/bar/** r,s;
allow /foo/bar/test.txt r,w,s;
foo_t は、/foo/bar以下に読み込み可能で、/foo/bar/test.txtに書き込み可能
です。
/foo/bar/test.txtが、設定時に存在しなかったとし、設定後にtest.txtに新規
作成されたとします。
foo_tは、/foo/bar/test.txtに読み込みアクセスしかできません。/foo/barの
アクセス権を引き継ぐからです。
この状況を直すには、
restorecon -R /foo/bar
をする必要があります。
- restoreconはなぜ必要?
SELinuxは、ファイルなどのリソースを「タイプ」を呼ばれるラベルで識
別しています。
タイプの名前は、ファイル名の「」を「_」に置換した名前になってい
ます。
mvコマンドをするときは、ラベルは保存されます。ファイルが新規作成
された時は、タイプはディレクトリのものを引き継ぎます。ファイルと
タイプの関連付けをrestoreconコマンドを使うことで直す必要があるの
です。
- cron ジョブ
Cronジョブは、unconfinedなドメインで動きます。cron jobのアクセス
制御を行いたい場合は、system_crond_t.spを編集し、
allowpriv all;を削る必要があります。ただし、cronジョブを正しくア
クセス制御するのは難しいことに注意が必要です。
- 消去、生成が繰り返されるファイル
消去、生成が繰り返されるファイルについては、アクセス制御が思った
ようにいかない場合があります。次の例を見てください。
domain foo_t;
allow /foo/bar/** r,s;
allow /foo/bar/test.txt r,w,s;
こう設定したとすると、test.txtが消去され、再度test.txtが生成された場合、
test.txtのアクセス権限は所属ディレクトリのものを継承しますから、
foo_tは、test.txtを読み込みしかできません。
restoreconコマンドでこれを直すことができるのですが、またtest.txtが消去、
生成されると、さらにrestoreconをしなければなりません。
ディレクトリに対するアクセス権限と違うファイル、かつそれが消去、生成が繰
り返される場合は、アクセス制御がうまく設定できないことになります。
これを解決するには以下のような方法があります。
- ファイル毎のアクセス制御をあきらめ、ディレクトリ単位のアクセス制
御をする
つまり、
allow /foo/var/** r,s,w.
のように、/foo/var全体に書き込み権限を与えてやれば問題ありません。
しかし、書き込み可能な範囲が広がってしまいます。
- allowtmpを利用
このような、生成消去を繰り返すファイルのアクセス制御をするために、
SPDLにはallowtmpという設定要素が用意されています。今回の場合は次
のように設定することになります。
allowtmp /foo/bar -name auto r,w,s;
allowtmpを使うことで、ファイルを「ラベル」を使って識別できるよう
になります。
上の文にて、foo_tが、/foo/bar以下に作成したファイルは、
foo_foo_bar_tという名前のラベル(-name autoで命名がされます。
foo_t + /foo/bar = foo_foo_bar_t という規則です)が付与され、
そして、foo_tは、このラベルに対し、r,w,sアクセス可能、ということ
になります。
このようにすることによって、test.txtが/foo/barディレクトリに消去、
生成を繰り返されたとすると、test.txtには、foo_foo_bar_tという
ラベルが常に付与されます。そして、このラベルを使ってSPDLから設定
することができます。
例えば、他のドメインから、このラベルが付いたファイルにアクセスし
たい場合は、
allow foo_foo_bar_t r;
のように書きます。
ちなみに、allowtmpでは、SELinuxのファイルタイプ遷移が使われてます。
デフォルトで用意されているポリシーでは、allowtmpは、/etc/mtabのア
クセス制御や、/tmp,/var/tmp以下の一時ファイルのアクセス制御に使わ
れています。
- /devディレクトリ以外のデバイスを使う
デバイスファイルは、システムに対して致命的な影響を及ぼすため、
SPDLでも特に注意深く取り扱われています。
デフォルトで用意されているポリシでは、デバイスは、/devディレクト
リに存在すると設定されています。つまり、/devディレクトリ以外のデ
バイスに対して、allowでアクセス許可を設定しても、無視されてしまい
ます。
/devディレクトリ以外のデバイスを使いたい場合は、allowdev文を使う
必要があります。例えば、/var/chroot/dev/nullにアクセスしたい場合
は、/var/chroot/dev/nullにアクセスする設定を記述する前に、
allowdev -root /var/chroot/dev;
のように、デバイスの格納されるディレクトリを指定しておhく必要があ
ります。
- シンボリックリンクを含むファイル名
シンボリックリンクを含むファイル名は無視されます。
例えば、
allow /etc/init.d/httpd r;
は無視されます。init.d は、 rc.d/init.dのシンボリックリンクだからです。
- ハードリンクの扱い
Linuxシステムでは、ハードリンクを使うことで、ファイルの中身を複数
のファイル名で参照することができます。ハードリンクは、デフォルト
ではほとんど使われていないため、以下の内容を気にする場面はほとん
ど現れませんが、セキュリティ上知っておいたほうがいいでしょう。
SPDLでは、ハードリンクは以下のルールで処理されます。
ファイルの中身が複数のハードリンクで参照される場合、元々存在
したファイル名を記述する必要がある。それ以外のファイル名が指定さ
れた場合は無視される。
例えば、/etc/shadow と/var/chroot/etc/shadowがハードリンクされて
いたとします。/etc/shadowが元々存在していたとすると、/etc/shadow
(と/var/chroot/etc/shadow)の中身を見るためには、allow
/etc/shadow rと記述する必要があります。allow /var/chroot/etc/shadow r
と記述しても無視されます。
ハードリンクが複数存在する場合、どのファイル名を「元々存在するファ
イル名」とするかの基準が気になるところです。以下の基準で
「元々存在するファイル名」が判定されます。以下で出てくる例では、
/etc/shadow, /var/shadowがハードリンクされたファイルだと仮定しま
す。
- 全ポリシ中で、一つのファイル名に対する設定しか書かれていな
い場合、そのファイル名が「元々存在するファイル名」になりま
す
例: allow /etc/shadow rがある場所で記述されているとします。
そして、/var/shadowを使った設定はどこにも記述されていない
とします。この場合は、/etc/shadowが、元々存在するファイル
名として取り扱われます。
- 複数のファイル名に対する設定が記述されていた場合、名前が一
番若いものが、「元々存在するファイル名」になります。
例: allow /etc/shadow r,allow /var/shadow r; という設定が
記述されていたとします。この場合、「/etc/shadow」が、「元々
存在するファイル名」になります。なぜなら、/etc/shadowのほ
うが名前が若いからです。
- ハードリンクされたファイル名を使った設定がどこにも記述され
てないときは、所属ディレクトリ名を比較して、所属ディレクト
リ名が最も大きいものが「元々存在するファイル名」となります。
例: /etc/shadow, /var/shadowを使った設定がどこにも記述され
ていない場合、/var/shadowが「元々あるファイル名」となりま
す。なぜなら、/var/ /etcだからです。
しかし、どのハードリンク名が「元々存在するファイル名」か分からな
い場合は、全ての名前を使う手もあります。例えば、
allow /etc/shadow r;
allow /var/shadow r;
のように記述した場合、どちらかの設定は無視されるだけで、無害です。
以上のハードリンクの取り扱いは、パス名ベースのセキュリティの「抜
け穴」を防ぐために必要なものです。
この取り扱いがなかったとすると、
例えば、/etc/shadowのハードリンクが、なんらかの手で
/var/www/html/shadowに作られてしまうと、Webサーバーから
/etc/shadowの中身を覗けてしまうことになります。これを防ぐために、
ハードリンクされたファイルの中身にアクセスするには、「一つのファ
イル名」しか使えないようにする必要があるわけです。パス名ベースの
セキュリティの問題点については、
http://securityblog.org/brindle/2006/04/19
に詳しいです。