以下の場合は無効になっている.
$ /usr/sbin/getenforce Disabled
モードには
の 3つがある.
いきなり Enforcing モードにするんではなくて, Permissive モードで試してみる.
モードの変更は
/etc/sysconfig/selinux
の SELINUX オプションを編集して,再起動する.
SELINUX=enforcing
Enforcing モードと Permissive モードを変更するなら, setenforce コマンドでも可能. その場合,再起動は必要ない(未確認) そのため,Permissive モードはトラブルシューティングに便利.
Disable モードから他のモードへ,もしくは 他のモードから Disable モードに変更する場合は, 前記の selinux ファイルを編集して再起動が必要.
Disable モードから他のモードへの場合, 再起動時,ポリシーの再ラベリングを行うためなのか 自動的に再度再起動がかかるようだ (1回しか試していないんでたまたま再起動がかかっただけかも知れないが...)
というわけで,再起動の前に
# fixfiles relabel
をしておくべき.
もしくは 以下のコマンドを実行して再起動する.
"touch /.autorelabel; reboot"
Enforcing モードへ
# /usr/sbin/setenforce Enforcing # /usr/sbin/setenforce 1
Permissive モードへ
# /usr/sbin/setenforce Permissive # /usr/sbin/setenforce 0
ps コマンドに Z オプションをつける.
# ps auxZ | grep httpd system_u:system_r:httpd_t:s0 apache 30544 0.0 0.0 305612 6688 ? S Mar 30 0:00 /usr/sbin/httpd
上記は httpd プロセスが以下のポリシーで稼働していることを表している. (タイプが注目される項目?,プロセスに与えられるタイプはドメインと呼ぶ)
Z オプションは ls, cp, id などでも使える.
apache のドキュメントルートを /var/www 以下ではなくて イレギュラーな場所である /srv/www/foo.com/html にする場合.
Apache の設定ファイルで DocumentRoot ディレクティブを変更しただけでは, ブラウザでそのページを表示させたときにアクセスエラーとなる. SELinux がアクセスを拒否しているからだ. SELinux は,Apache プロセスからそのファイルにアクセスが あってもいいことをまだ知らない.
Apache がアクセスするために必要なファイルのタイプを見極めるには ls コマンドを使って,デフォルトのファイルやディレクトリのコンテキストを 見てみる.
# ls -lZ /var/www/html/index.html -rw-r--r--, root root unconfined_u:object_r:httpd_sys_content_t:s0 /var/www/html/index.html
そうすると,おそらく httpd_sys_content_t タイプが必要だとわかる.
もう一つの方法は,semanage コマンドを使う. このツールは定義されている SELinux のポリシーを表示,変更ができる.
デフォルトではインストールされていない.
# yum install policycoreutils-python
# semanage fcontext -l | grep '/var/www' /var/www(/.*)? all files system_u:object_r:httpd_sys_content_t:s0
で,/srv/www/foo.com/ に新しいコンテキストを適用する.
# semanage fcontext -a -t httpd_sys_content_t '/sys/www(/.*)?' (-a は add, -t はタイプ,最後の引数は正規表現可能) # semanage fcontext -l | grep '/srv/www' /srv/www(/.*)? all files system_u:object_r:httpd_sys_content_t:s0 # restorecon -Rv /srv/www (既存の /srv/www 以下のファイルの再ラベリングとセキュリティコンテキスト適用)
これで,ブラウザで件のページを表示できるようになったはず.
注意点として, コンテキストを適用してから件のディレクトリにコピーしたファイルは おなじコンテキストが適用されるが, mv したファイルはものとファイルのコンテキストのままである. そのため,ホームディレクトリなどで作成したファイルを /srv/www/html に mv したファイルはブラウザで表示できない.
これを解決するためには,restorecon コマンドで再ラベリングを行う.
% echo "my file" > file.html % ls -Z file.html -rw-rw-r--. vdanen vdanen unconfined_u:object_r:user_home_t:s0 file.html % mv file.html /srv/www/foo.com/html/ % ls -Z /srv/www/foo.com/file.html -rw-rw-r--. vdanen vdanen unconfined_u:object_r:user_home_t:s0 /srv/www/foo.com/html/file.html # restorecon -v /srv/www/foo.com/html/file.html restorecon reset /srv/www/foo.com/html/file.html context unconfined_u:object_r:user_home_t:s0->system_u:object_r:httpd_sys_content_t:s0
起動すると /var/log/messages に
May 13 11:36:41 s_local@centos5 setroubleshoot: SELinux is preventing access to files with the label, file_t. For complete SELinux messages. run sealert -l 4c75de09-a045-413e-8ba9-5d62153bbc0c May 13 11:36:41 s_local@centos5 setroubleshoot: SELinux is preventing access to files with the label, file_t. For complete SELinux messages. run sealert -l 79632173-cf18-4f5d-a01a-970667967fba
といった warning がでる.
トラブルシュートのため,上記に表示されているコマンドを実行してみる.
----------------------------- $sealert -l 79632173-cf18-4f5d-a01a-970667967fba 要約: SELinux is preventing access to files with the label, file_t. 詳細説明: [SELinux is in permissive mode, the operation would have been denied but was permitted due to permissive mode.] SELinux permission checks on files labeled file_t are being denied. file_t is the context the SELinux kernel gives to files that do not have a label. This indicates a serious labeling problem. No files on an SELinux box should ever be labeled file_t. If you have just added a new disk drive to the system you can relabel it using the restorecon command. Otherwise you should relabel the entire files system. アクセスを許可: You can execute the following command as root to relabel your computer system: "touch /.autorelabel; reboot" 追加情報: ソースコンテキスト system_u:system_r:portmap_t ターゲットコンテキスト system_u:object_r:file_t ターゲットオブジェクト /etc/hosts.allow [ file ] Source portmap Source Path /sbin/portmap Port <不明> Host centos5.example.co.jp Source RPM Packages portmap-4.0-65.2.2.1 Target RPM Packages setup-2.5.58-7.el5 ポリシー RPM selinux-policy-2.4.6-279.el5_5.2 Selinux 有効化 True ポリシータイプ targeted MLS 有効化 True 強制モード Permissive プラグイン名 file ホスト名 centos5.example.co.jp プラットフォーム Linux centos5.example.co.jp 2.6.18-194.32.1.el5 #1 SMP Wed Jan 5 17:53:09 EST 2011 i686 i686 通知カウント 1 First Seen Fri May 13 11:36:41 2011 Last Seen Fri May 13 11:36:41 2011 Local ID 79632173-cf18-4f5d-a01a-970667967fba 行番号 生の監査メッセージ host=centos5.example.co.jp type=AVC msg=audit(1305254201.591:49): avc: denied { getattr } for pid=2423 comm="portmap" path="/etc/hosts.allow" dev=sda1 ino=1047574 scontext=system_u:system_r:portmap_t:s0 tcontext=system_u:object_r:file_t:s0 tclass=file host=centos5.example.co.jp type=SYSCALL msg=audit(1305254201.591:49): arch=40000003 syscall=197 success=yes exit=0 a0=5 a1=bff11e18 a2=effff4 a3=95a9448 items=0 ppid=1 pid=2423 auid=4294967295 uid=32 gid=32 euid=32 suid=32 fsuid=32 egid=32 sgid=32 fsgid=32 tty=(none) ses=4294967295 comm="portmap" exe="/sbin/portmap" subj=system_u:system_r:portmap_t:s0 key=(null) -----------------------------
sealert のメッセージにあるように以下のコマンドを実行してみる.
"touch /.autorelabel; reboot"
直った?ようだ.
# ps auxZ |grep portmap user_u:system_r:portmap_t rpc 6265 0.0 0.1 2348 480 ? Ss 13:28 0:00 portmap
portmap はコンテキスト user_u:system_r:portmap_t で動いている.
プロセスにつけるラベルをドメインと呼び,上記 portmap プロセスでは portmap_t リソースにつけるラベルをタイプと呼び,上記(/etc/hosts.allow)では etc_t
policycoreutils-newrole パッケージをインストールする.
$ newrole -r user_r -t unconfined_t
http://www.yam-web.net/selinux/createtype.html を参考にする.
selinux-policy-devel パッケージを追加インストールする.
モジュールパッケージの作成
# mkdir /root/selinux # cd /root/selinux # cp /usr/share/selinux/devel/Makefile . # vi local.te module local 1.0; type my_type01_t; files_type(my_type01_t) # vi local.fc → 後で semanage でやった方が賢明かも /home/user01/public_html(/.*)? gen_context(system_u:object_r:my_type01_t,s0) # make # /usr/sbin/semodule -i local.pp
コンテキストの適用順変更 /etc/selinux/targeted/contexts/files/file_contexts の
/home/user01/public_html(/.*)? system_u:object_r:my_type01_t,s0
の部分をカットし, /etc/selinux/targeted/contexts/files/file_contexts.local にペーストする.
タイプの適用
# /sbin/restorecon -FR /home/user01/public_html
ポリシーモジュールの作成 この段階ではまだ,messages にアクセスエラーが記録されている. (Enforce モードだとアクセス拒否される)
audit2allow を使ってアクセス許可設定をする.
# audit2allow -a -l -r require { type var_log_t; type my_type01_t; type httpd_t; class dir { getattr search }; class file { read getattr append }; } #============= httpd_t ============== allow httpd_t my_type01_t:dir { getattr search }; allow httpd_t my_type01_t:file { read getattr }; allow httpd_t user_home_t:dir { getattr search }; allow httpd_t user_home_t:file { read getattr };
上記出力を,local.te に追加する.
$ vi local.te module local 1.0; type my_type01_t; files_type(my_type01_t) require { type var_log_t; type my_type01_t; type httpd_t; class dir { getattr search }; class file { read getattr append }; } #============= httpd_t ============== allow httpd_t my_type01_t:dir { getattr search }; allow httpd_t my_type01_t:file { read getattr }; allow httpd_t user_home_t:dir { getattr search }; allow httpd_t user_home_t:file { read getattr }; # make # /usr/sbin/semodule -i local.pp
/etc/selinux/targeted/contexts/files/file_contexts の /home/user01/public_html(/.*)? system_u:object_r:my_type01_t,s0 の部分をカットし, /etc/selinux/targeted/contexts/files/file_contexts.local にペーストする.
実際は,わざわざポリシーを追加しなくても audit2allow 移行の作業で解決するはず.
というか $HOME/public_html や $HOME/www などは もともと
/etc/selinux/targeted/contexts/files/homedir_template /etc/selinux/targeted/contexts/files/file_contexts.homedirs
にコンテキストが定義されていて $HOME/public_html を作成した後,ユーザレベルで
$ /sbin/restorecon -v public_html
をやってやれば,
$ ls -lZd public_html drwxrwxr-x user01 user01 user_u:object_r:httpd_sys_content_t public_html
と,httpd から読み込めるディレクトリ,ファイルとなるようだ.
同様のことが,$HOME/.ssh 以下のファイルなどにも言える.
# /usr/sbin/semodule -r local