SELinux の設定

SELinux の設定

SELinux (Security-Enhanced Linux) は,アメリカ国家安全保障局が GPL 下で提供している Linux のカーネルに強制アクセス制御 (MAC) 機能を付加するモジュールの名称であり,その機能のとおり,昨今の不正アクセスを防止するために開発が進められており,最近の Linux ディストリビューションでは,そのほとんどでパッケージ化がされている.しかし,SELinux 自体の設定が非常に難しく,自分でカスタマイズするということがしづらいため,特に個人ユーザでは積極的に利用している人は少ない (と思う).

そういう難しさから開放されるがために生まれたのが,SELinux Policy Editor (SEEdit) である.SEEdit は煩雑な SELinux のポリシ設定を簡単にし,SELinux の敷居を下げるツールとして知られている.

以下では,SEEdit を利用した方法,および使用しない方法の二つについて,SELinux のポリシーのカスタマイズについて簡単に述べていく.

SEEdit を用いた SELinux ポリシーのカスタマイズ

SEEdit のインストール

Fedora Core 6 以上の場合は,yum を利用すれば簡単にインストールできるが,CentOS の場合は SEEdit のダウンロードページより,seedit-converter,seedit-policy,seedit-gui の三つのパッケージをダウンロードし,ダウンロードしたディレクトリで,

 # rpm -ivh seedit*.rpm

と打ち込んですべてのパッケージをインスト-ルする.なお,agate のように CentOS の 64bit バージョンの場合は,rpm パッケージが用意されていないので,SEEdit のダウンロードページソースコードから seedit-2.2.0-1.cos5.src.rpm をダウンロードし,rpmbuild コマンドを利用してコンパイルをすればよい.

 # rpmbuild --rebuild seedit-2.2.0-1.cos5.src.rpm

コンパイルした後,パッケージは /usr/src/redhat/RPMS/x86_64 に作成されているので,それらを利用してインストールする.

インストール直後には,

 # /usr/sbin/seedit-init

と打ち込んで,SEEdit の初期化を行う.初期化がすめば,一度 OS を再起動する.再起動すると,SELinux のラベルの初期化画面が出てきて,自動的にセキュリティポリシーのラベルの付け替えが行わる.何度か起動しては再起動されるが,最終的にはいつものようにログインできる状態になるので,その状態になったら SEEdit のインストールが完了したことになる.

SEEdit の使い方

セキュリティポリシーの編集を一番最初にしなければならないのは,セキュリティーポリシーの設定が不足していてアプリケーションが動作しなくなることである.例えば,Web サーバの Apache や Wiki の実装の一つである PukiWiki などは,SELinux が有効である状態の場合は動作しないことが多い.これを確かめるためには,次のコマンド

 # setenforce 0

を実行して SELinux の機能を切り,SELinux 機能時に動作しなかったアプリケーションが動いていることがわかれば,SELinux によってアプリケーションが動作していないことがわかる.SEEdit はその不足している設定の追加や修正を容易に行えるツールなのである.

実際の作業としては,getenforce コマンドで,SELinux が有効となっているのかを確認し,有効となっている場合は,setenforce コマンドを利用して,SELinux を無効化する.

 # getenforce
 Enforcing
 # setenforce 0

その後,audit2spdl コマンド((あらかじめ auditd を利用できる状態にしておく必要がある.yum を利用すると簡単にインストールできる.))を利用して,セキュリティポリシーに追加すべき情報を集める.例えば,

 # audit2spdl -al
 #Analyzing log. Progress:Done292
 -------------------------
 #SELinux deny log:
 type=AVC msg=audit(1209542241.803:48596): avc:  denied  { read } for  pid=18554 comm="httpd" 
 name="mailman.jpg" dev=sdb1 ino=77530126 scontext=user_u:system_r:httpd_t:s0
 tcontext=system_u:object_r:var_t:s0 tclass=file
 type=AVC msg=audit(1209542241.972:48599): avc:  denied  { read } for  pid=18551 comm="httpd"
 name="mailman.jpg" dev=sdb1 ino=77530126 scontext=user_u:system_r:httpd_t:s0
 tcontext=system_u:object_r:var_t:s0 tclass=file
 type=AVC msg=audit(1209542242.063:48603): avc:  denied  { read } for  pid=18555 comm="httpd"
 name="mailman.jpg" dev=sdb1 ino=77530126 scontext=user_u:system_r:httpd_t:s0
 tcontext=system_u:object_r:var_t:s0 tclass=file
 #Suggested configuration
 File httpd_t.sp:
 allow ~/icons/mailman.jpg  r,s;
 -------------------------

のようになった場合は,/etc/seedit/policy/httpd_t.sp の最後の } の前に,allow ~/icons/mailman.jpg r,s; を追加するとよい.
ssh関連は,sshd_t.spに追加する.

 # cat /etc/seedit/policy/httpd_t.sp
 # SELinux Policy Editor, a simple editor for SELinux policies
 # Copyright (C) 2006 Yuichi Nakamura

 {
 domain httpd_t;
 program /usr/sbin/httpd;
 include common-relaxed.sp;
 include daemon.sp;
 include nameservice.sp;

 ...
 allow ~/icons/mailman.jpg r,s;
 }

記述内容の詳しい説明は,SEEdit の管理者ガイド (SEEdit のドキュメント) に譲るが,こうした記述をただひたすら追加していけばよい.audit2spdl コマンドにより上記出力がでなくなったときが,SELinux が有効でもアプリケーションが動作するときなのだが,アプリケーションが提供しているあらゆる操作を SELinux を無効にしている間に確かめておく必要があり,それを怠ると突然アプリケーションが動かないということが起こる.

ポリシーを変更したら,以下のコマンドで反映させる.

 # seedit-load

起動時/再起動時に発生する設定エラー (アプリケーション不起動) の対処法

dt MySQL
dd mysql は SEEdit の設定を行ってもうまく起動させることができない.よって choco を再起動もしくは起動した後は,必ず restorecon コマンドを実行するために /etc/rc.d/rc.local に restorecon -R /var/lib/mysql を書き加える.

audit2spdl のエラーの対処法

稀に audit2spdl を実行したときにエラーが出る場合がある.

 # audit2spdl -al
 Traceback (most recent call last):
 File "/usr/bin/audit2spdl", line 77, in ?
 lines = readLog(input, gLoadPolicyFlag)
 File "/usr/lib/python2.4/site-packages/seedit/audit2spdl.py", line 94,
 in readLog linebuf.pop()
 NameError: global name 'linebuf' is not defined

このようなエラーが出た場合はバグである可能性がある (SEEdit 作者の中村氏によるコメント).この場合は,とりあえず /var/log/audit/ 以下のログファイルを消す,もしくは他に移動して,auditd を再起動すると上記エラーはとりあえず出なくなる.

通常の方法での SELinux ポリシーのカスタマイズ

SEEdit を使わない場合は,以下の通り地道に SELinux のポリシーをカスタマイズしていかねばならない.

permissive モードで不足している権限を調査する

SELinux により拒否されたアクセスを調査するために,SELinux の permissive モードに切り替えて,動作テストを実施する.perimssive モードで動作させることができれば,そのプロセスが起動し終えるまでに拒否されたすべてのアクセスを把握できる.permissive モードに切り替えるためには以下のコマンドを実行する.

 # setenforce 0
 # getenforce
 permissive

この状態で再び拒否されたアクセスを実行する.permissive モードで動作しているため,アクセスが拒否される場合でも単にログに記録されるだけである.ログは,dmesg コマンドで閲覧できるが,/var/log/messages にも出力されている.

audit2allow コマンドを用いてポリシーを追加する

具体的な手順としては,audit2allow コマンドを用いて allow 文を作成し設定に追加することになる.allow 文の書式は,

 allow <ドメイン> <タイプ>:<オブジェクト・クラス> <アクセス・ベクター>;

となっており,拒否されたアクセスを許可するには,allow 文の書式のドメイン,タイプ,オブジェクト・クラス,アクセス・ベクターに,ログで出力されたものを当てはめていけばよい.具体的には,ログに「/usr/sbin/vsftpd (ftpd_t ドメインで動作) が,ftp という名前のディレクトリ (オブジェクト・クラス dir,タイプ var_t) に読み込み (アクセス・ベクター read) アクセスしようとして拒否された」という記録が残っていた場合は,

 allow ftpd_t var_t:dir read;

と記述すればよいのである.しかし,アクセス拒否のログに基づいて,手作業で allow 文を書いていくのは面倒であるため,その手間を省くためにアクセス拒否のログを allow 文に自動変換するコマンド audit2allow を使う.audit2allow コマンドの使い方は二通りあるが,余分な allow 文が作成される可能性が低い audit2allow -d コマンドを利用する.例えば,

 # audit2allow -d
 allow ftpd_t var_t:dir { read };
 allow ftpd_t var_t:file { getattr read };
 allow lvm_t lvm_etc_t:dir { create };

のようになった場合,上記の三つの allow 文が作成されているが,vsftpd に対応する設定は上の 2 行であるため,これらをこれらを設定ファイルに追加する.設定ファイルは /etc/security/selinux/src/policy/domains/program 以下に servername.te (ftp に関連する設定を格納する場合は,ftpd.te) に追加する.

設定を反映して,enforcing モードに戻す

設定の追記が終わったら,新たな設定をシステムに反映させる.それには,ポリシーを格納したディレクトリに移動してから,make reload コマンドを実行する.

 # cd /etc/security/selinux/src/policy/
 # make reload

このコマンドは,テキスト形式のポリシー・ファイルをバイナリに変換し,カーネルに組み込まれた SELinux モジュールに読み込ませるものである.システムに反映させたら,enforcing モードに戻すのを忘れないようにする.

 # setenforce 1
 # getenforce
 enforcing