ラベル semodule の投稿を表示しています。 すべての投稿を表示
ラベル semodule の投稿を表示しています。 すべての投稿を表示

2007年10月30日火曜日

Apache2 で PHP4.0 を 実行するために必要な SELinux の設定。

Apache2 で PHP4.0 を 実行するために必要な SELinux の設定について PHPが動作できるまでの設定方法を調べたので、まとめたいと思います。

PHP4.0 は、インストールすれば、Apache で勝手に動くものだと思ってました・・・
が、Fedora Core 6 で動かそうと思ったら、なにやらエラーが発生していて動きませんでした。。
いろいろ調べたのですが、詳しい資料もなかったので、とりあえず覚書程度に書いておきます。

そもそも、SELinuxは、RBAC(Role-Based Access Control)という、仕様に基づいて、ユーザーに割り当てたロールによってアクセス権限を制限するための仕組みです。
このロールは、Rootを含むすべてのユーザーに同様に割り当てられます。
つまり、適切な権限のロールをプロセスを実行するユーザーに付与しないとたとえRootでもアクセスを制限されることがあります。
さらに、TE(Type Enforcement)によって、プロセスごとに細かくアクセス制御を提供します。
このプロセスはドメイン遷移という機能によって、ドメインごとに割り当てられ親から子に継承されます。

よって、なにも設定しない状態では、 init プロセスと同じドメインになってしまい、プロセスの実行権限が制限されるというわけです。

【環境】
OS:Linux(Fedora Core 6)
SELinux
Apache 2.0
PHP 4.0

【インストールするパッケージ】
checkpolicy :TEファイルをコンパイルする際に、checkmodule を使用するために必要になります。(必須)
audit:SELinuxの監査ログを管理します。(推奨)

* 作業の後半で必要になるので、以下のコマンドでインストールしておくと、作業効率が上がります。
# yum install checkpolicy audit

1.PHP のインストールと設定

PHPをコンパイルして、httpd.conf に以下を追記します。
LoadModule php4_module modules/libphp4.so

# /etc/rc.d/init.d/httpd start

エラーが表示されています。
httpd: Syntax error on line 206 of /etc/httpd/conf/httpd.conf: Cannot load /etc/httpd/modules/libphp4.so into server: /etc/httpd/modules/libphp4.so: cannot restore segment prot after reloc: Permission denied

本来ならこれで動くはずですが・・・

2.セキュリティレベルの確認
まず、SELinuxの実行モードを確認します。

# getenforce
Encforcing

SELinuxが、Enforcing モードで実行されています。

setenforce 0 : Permissive モード (アクセス制御は行わない、警告メッセージをログに出力)
setenforce 1 : Enforcing モード (SELinux による強制アクセス制御モード)

* Permissive モード で運用するとセキュリティレベルが落ちますので、あくまで検証用に使うようにしてください。(運用時は、Enforcing モードで運用する。

-v 詳細を確認する
# sestatus -v
SELinux status: enabled
SELinuxfs mount: /selinux
Current mode: enforcing
Mode from config file: enforcing
Policy version: 21
Policy from config file: targeted

以降、SELinuxの設定を行います。

3.セキュリティコンテキストの確認

プロセスのセキュリティコンテキストを確認する。
* 通常起動できない状態のため、SELinuxを一時無効にする。

# setenforce 0
# /etc/rc.d/init.d/httpd start

# ps -AZ | grep httpd
user_u:system_r:httpd_t 7636 ? 00:00:00 httpd
user_u:system_r:httpd_t 7638 ? 00:00:00 httpd
user_u:system_r:httpd_t 7639 ? 00:00:00 httpd
user_u:system_r:httpd_t 7640 ? 00:00:00 httpd
user_u:system_r:httpd_t 7641 ? 00:00:00 httpd
user_u:system_r:httpd_t 7642 ? 00:00:00 httpd
user_u:system_r:httpd_t 7643 ? 00:00:00 httpd
user_u:system_r:httpd_t 7644 ? 00:00:00 httpd
user_u:system_r:httpd_t 7645 ? 00:00:00 httpd
# setenforce 1

プロセスを起動したユーザー:user_u
起動元のロール:system_r
ドメイン:httpd_t

ファイルリソースのセキュリティコンテキストを確認する。

# ls -Z /var/www
drwxr-xr-x root root system_u:object_r:httpd_sys_script_exec_t cgi-bin
drwxr-xr-x root root system_u:object_r:httpd_sys_content_t data
drwxr-xr-x root root system_u:object_r:httpd_sys_content_t error
drwxr-xr-x
root root system_u:object_r:httpd_sys_content_t html
drwxr-xr-x root root system_u:object_r:icons


# ls -Z /etc/httpd/modules/libphp4.so

drwxr-xr-x root root user_u:object_r:httpd_sys_content_t libphp4.so

これで、ユーザーと、ドメインに実行権限がないことを確認することができました。

4.セキュリティコンテキストの設定

まず、libphp4.so に対して、適切なユーザー、ロール、ドメインを設定を設定します。

# chcon -c -v -R -u system_u -r object_r -t httpd_php_exec_t /etc/httpd/modules/libphp4.so

# ls --context /etc/httpd/modules/libphp4.so
-rwxr-xr-x root root system_u:object_r:httpd_php_exec_t /etc/httpd/modules/libphp4.so

これで、適切なファイルファイルリソースのセキュリティコンテキストを設定することができました。

5.auditd デーモンの設定(推奨)
checkpolicy のインストール(必須)
SELinuxの監査ログのために、auditdデーモンをインストールします。
これによって、SELinuxの監査ログが /var/log/audit/audit.log に出力されるようになります。

* auditdをインストールしない場合は、その他のログと同様に /var/log/messages に出力されることになります。

また、次の項で、SELinux の ポリシーモジュールパッケージを生成する際、TEファイルをコンパイルするために、
、checkmoduleを使用します。checkmoduleは、checkpolicy パッケージに含まれているため、これとインストールします。

# yum install checkpolicy audit
あとは、自動でインストールされるます。

auditの起動
# /etc/rc.d/init.d/auditd start

auditの起動確認
# /etc/rc.d/init.d/auditd status
auditd (pid 8112 7569) is running...

apache を起動する
# /etc/rc.d/init.d/httpd start
Starting httpd:
[FAILED]

起動に失敗し、エラーメッセージが/var/log/audit/audit.log に出力されることを確認する。



6.モジュールの作成
auditをインストールしたことで、監査ログからSELinux ポリシーモジュールを生成することができます。

手順の概要は以下のとおりです。
1.Permissive モードに切り替える
* この操作を忘れると、うまく動作しないことがあります。
2.TEファイルの作成
3.TEファイルをコンパイルする
4.ポリシーモジュールパッケージを作成する
5.
ポリシーモジュールパッケージをカーネルにロードする。
6.Encforcing モードに戻します。

6-1.SELinux を Permissive モードに切り替えます。
# setenforce 0

6-2.
TEファイルの作成
audit を利用して監査ログから TEファイルを自動生成します。
* 作業ディレクトリは任意の場所で大丈夫です。

# cat /var/log/audit/audit.log | audit2allow -m local > local.te

これで、ローカル用のポリシーモジュールが生成されます。
local.teの内容を確認します。

# less local.te

module local 1.0;

require {
type httpd_t;
type httpd_php_exec_t;
class file execmod;
}

#============= httpd_t ==============
allow httpd_t httpd_php_exec_t:file execmod;

---
ここまで

6-3.TEファイルをコンパイルする
checkmodule コマンドでTEファイルをコンパイルします。

# checkmodule -M -m -o local.mod local.te
checkmodule: loading policy configuration from local.te
checkmodule: policy configuration loaded
checkmodule: writing binary representation (version 6) to local.mod

6-4.ポリシーモジュールパッケージを作成する
# semodule_package -o local.pp -m local.mod


6-5.
ポリシーモジュールパッケージをカーネルにロードする。
# semodule -i local.pp


登録されている
SELinux ポリシーモジュール を確認する。

# semodule -l
amavis 1.1.0
apcupsd 1.0.0
ccs 1.0.0
clamav 1.1.0


local 1.0



6-6.Encforcing モードに戻します。
# setenforce 1

7.apacheを起動します。
設定が反映されているかを確認する。

# /etc/rc.d/init.d/httpd configtest
Syntax OK [ OK ]


apacheを起動します。

# /etc/rc.d/init.d/httpd start
Starting httpd: [ OK ]


お疲れ様でした。

慣れればどうってことない作業ですが、SELinuxは、ドキュメントを読んで仕組みを理解するのに時間がかかります。ユーザー、ロール、ドメインによる、セキュリティポリシーの思想は、理にかなったもので、セキュリティの面からみれば大変有効なものに思えますが、SELinux自体にセキュリティホールがあった場合等を考えると、不安を感じることもあります。
そういった意味でも、サーバーを運用する際は、複数の防御策をうまく組み合わせて、それぞれの技術はあくまでツールとして利用し、管理者のログ監視や、進入検地等も大切だと考えます。

## おまけ:
今回の設定で、audit2why というコマンドを発見しました。
使い方は、audit2why [-p policy] < /var/log/messages

なぜだか SELinux 関係で動かないというときは、以下のコマンドを実行することで、原因が分かるようです。


出力例)

# audit2why < /var/log/messages
Oct 30 06:42:52 office kernel: audit(1193694172.391:49): avc: denied { execmod } for pid=7235 comm="httpd" name="libphp4.so" dev=dm-0 ino=1376787 scontext=user_u:system_r:initrc_t:s0 tcontext=system_u:object_r:httpd_php_exec_t:s0 tclass=file
Was caused by:
Missing or disabled TE allow rule.
Allow rules may exist but be disabled by boolean settings; check boolean settings.
You can see the necessary allow rules by running audit2allow with this audit message as input.


【一発コマンド(コピペ用)】
エラーがなければ、このまま流せば、設定できるはずです。
4つめのコマンドは、必ず[FAILED]になるはずですが、そのまま進みます。
(エラーログを/var/log/audit/audit.logに出力するためにエラーを発生させている。)

chcon -c -v -R -u system_u -r object_r -t httpd_php_exec_t /etc/httpd/modules/libphp4.so
yum install checkpolicy audit
/etc/rc.d/init.d/auditd start
/etc/rc.d/init.d/httpd start
setenforce 0
cat /var/log/audit/audit.log | audit2allow -m local > local.te
checkmodule -M -m -o local.mod local.te
semodule_package -o local.pp -m local.mod
semodule -i local.pp
semodule -l
setenforce 1
/etc/rc.d/init.d/httpd start