制限のあるサービスの管理
Red Hat Enterprise Linux 6.4
SELinux の制御下にあるサービスの設定について
エディッション 4
概要
上級ユーザーや管理者の方などが Security-Enhanced Linux (SELinux) を使用したり、 また設定を行なったりする際に役立つガイドです。 SELinux のコンポーネントは、 上級ユーザーや管理者の方々が設定を行なわなければならない場合があるサービスに関連しているため、 本ガイドでは Red Hat Enterprise Linux に焦点を絞って SELinux のコンポーネントについて説明していきます。 また、 こうしたサービスを設定する場合の実例をあげながら、 SELinux でどのようにサービスの動作を補完しているのかについて見ていきます。
第1章 はじめに
Security-Enhanced Linux (SELinux) とは、 Linux カーネル内の「強制アクセス制御 (MAC)」の実装であり、 標準の「任意アクセス制御 (DAC)」がチェックされた後、 許可される動作をチェックします。 SELinux は米国国家安全保障局 (National Security Agency) により開発され、 Linux システム内のファイルやプロセス、またその動作についても定義されたポリシーに応じてルールを強制することができます。
Security-Enhanced Linux (SELinux) では、 ディレクトリやデバイスなどのファイルをオブジェクト (客体) として参照します。 ユーザーによって実行されたコマンドや Mozilla Firefox アプリケーションなどのプロセスはサブジェクト (主体) として参照されます。 ほとんどのオペレーティングシステムでは、 サブジェクトとオブジェクトの交信手段、 サブジェクト同士の交信手段などを制御する任意アクセス制御システム (DAC) が使用されています。 DAC を使用するオペレーティングシステムでは、 ユーザーが所有するファイル (オブジェクト) の権限はそのユーザーが制御するようになっています。 たとえば、 Linux オペレーティングシステムの場合、 ユーザーは自分のホームディレクトリを誰でも読み取れるようにすることができるため、 気付かずに機密の可能性がある情報へのアクセスを他のユーザーやプロセス (サブジェクト) に渡してしまう恐れがあります。
DAC によるアクセス決定はユーザー ID と所有権だけを基準とし、 ユーザーのロール、 プログラムの機能及び信頼性、データの機密性及び整合性など他のセキュリティ関連の情報は無視されます。 通常、 各ユーザーが所有ファイルの完全決定権を持っているため、 システム全体にセキュリティポリシーを試行するのが困難になります。 さらに、 ユーザーによって実行されるプログラムはそのユーザーに与えられる権限を継承し、 そのユーザーのファイルへのアクセス権を自由に変更することができます。 このため、 悪意あるソフトウェアに対する保護は最低限のものしか与えられません。 多くのシステムサービスや特権を有するプログラムは、 特権付与の制御がおおまかで、その必要性をはるかに越える特権を持ったまま実行されます。 したがって、 こうしたプログラムのうちいずれかにでも不備があればそこを攻撃され、さらなるシステムアクセス権が奪われる恐れがあります。[1]
以下は、 SELinux を実行していない Linux オペレーティングシステムで使われているパーミッションの例です。 システムによっては、 パーミッションがこの例と多少異なる場合があります。
ls -l
コマンドを使って、 ファイルのパーミッションを表示させます。
$ ls -l file1 -rwxrw-r-- 1 user1 group1 0 2010-01-29 09:17 file1
最初の 3 つのパーミッション
rwx
では、 Linux の user1
ユーザー (この例では所有者) が file1
に対して持っているアクセス権を制御しています。 次の 3 つのパーミッション rw-
では、 Linux の group1
グループが file1
に対して持っているアクセス権を制御しています。 最後の 3 つのパーミッション r--
では、 その他のユーザーが file1
に対して持っているアクセス権を制御しています。 その他のユーザーには、 すべてのユーザーおよびプロセスが含まれます。
SELinux を使用すると、Linux カーネルに MAC (強制アクセス制御) が追加され、Red Hat Enterprise Linux ではデフォルトで有効になります。汎用の MAC アーキテクチャーには、各種のセキュリティ関連情報を含むラベルを決定基準とした管理用セキュリティポリシーを、 システム内の全プロセスおよびファイルに対して実施する能力が必要とされます。適切に実装することで、システム自体が的確に自己防御され、アプリケーションの改ざんを保護、回避することによりアプリケーションの安全性に必須のサポートを提供します。MAC ではアプリケーションどうしがしっかりと確実に分離されるため、信頼性の低いアプリケーションでも安全に実行することができます。プロセス実行に関する特権を制限する能力により、アプリケーションやシステムサービス内の脆弱性が悪用され発生する可能性のある被害範囲を限定することができます。限られた権限しか持たない正規ユーザーだけでなく、権限を与えられたユーザーが不正なアプリケーションを知らずに実行してしまった場合でも情報を保護することができます。[2]
以下は、 SELinux を実行する Linux オペレーティングシステム上でプロセス、 Linux ユーザー、 ファイルなどに適用されるセキュリティ関連の情報を含むラベルの例です。 SELinux コンテキストと呼ばれ、
ls -Z
コマンドで表示させます。
$ ls -Z file1 -rwxrw-r-- user1 group1 unconfined_u:object_r:user_home_t:s0 file1
この例では、 SELinux によりユーザー (
unconfined_u
)、 ロール (object_r
)、 タイプ (user_home_t
)、 レベル (s0
) が file1
ファイルに与えられています。 この情報がアクセス制御の決定に使用されます。 ls -Z
コマンドでは SELinux コンテキストと共に DAC ルールも表示されます。SELinux ポリシールールは、 DAC ルールの後にチェックされます。 このため、 DAC ルールで最初にアクセスが拒否されると、 SELinux ポリシールールは適用されません。
第2章 Targeted ポリシー
Red Hat Enterprise Linux で使用されるデフォルトの SELinux ポリシーは Targeted ポリシーになります。Targeted ポリシーを使用すると、対象となるプロセスは制限ドメイン内で実行され、対象外のプロセスは未制限のドメイン内で実行されます。例えば、デフォルトではログインしたユーザーは
unconfined_t
ドメイン内で実行され、init
で開始されたシステムプロセスは initrc_t
ドメイン内で実行されます。 いずれも未制限のドメインです。
SELinux は、実行するサービスに必要な最小限レベルのアクセスに基づいています。サービスの実行手段は複数あるため、サービスをどのように実行するのかを SELinux に指示する必要があります。これを行なうため、Boolean を使用します。Boolean を使用すると、SELinux ポリシーの記述方法などの知識が全くなくても、ランタイム時の SELinux ポリシーを部分的に変更することができます。たとえば、サービスによる NFS ファイルシステムへのアクセスを許可するなど、Boolean を使用することで、SELinux ポリシーの再読み込みや再コンパイルを行なうことなく、各種の変更を行なうことができるようになります。Boolean 設定については事例をあげて詳細に説明していきます。
サービス用のファイル群の格納にデフォルト以外のディレクトリを使用する、 デフォルト以外のポート番号でサービスが実行するよう変更するなど、 その他の変更には、 policycoreutils-python パッケージで提供している
semanage
コマンドなどのツールを使ったポリシー設定の更新が必要になります。 このコマンドについては設定事例をあげて詳細に説明していきます。
2.1. Type Enforcement
Type Enforcement が SELinux の targeted ポリシーで使用されるメインのパーミッション制御になります。全ファイルおよびプロセスにタイプのラベルが付けられます。ファイルの場合はタイプ、プロセスの場合はドメインを定義します。任意のタイプにアクセスするドメインなのか、 別のドメインにアクセスするドメインなのかなど、SELinux のポリシールールではタイプによって互いがアクセスしあう方法を定義します。アクセスを許可する特定の SELinux ポリシールールが存在する場合にのみ、そのアクセスが許可されます。
2.2. 制限のあるプロセス
Red Hat Enterprise Linux では、 ネットワークでリッスンするサービスはほぼ全て制限されています。 また、
root
ユーザーとして実行され passwd アプリケーションなどユーザーのタスクを行なうプロセスもほとんど制限されています。 プロセスが制限されている場合、 そのプロセスはそれ自体のドメイン内で実行されます。httpd
プロセスならhttpd_t
ドメイン内で実行されます。 制限のあるプロセスが攻撃を受けた場合、 SELinux ポリシー設定に応じて、 攻撃側がリソースにアクセスして加えることができる被害が限定されます。
次の例では、Samba での使用を目的としたファイルなど、正しくラベル付けが行なわれていないファイルは Apache HTTP サーバー (
httpd
) では読み込ませないよう SELinux で阻止する方法を示します。この例はサンプルのため、実稼働環境では使用しないようにしてください。ここでは、httpd、 wget、setroubleshoot-server、audit などのパッケージがすでにインストールされていること、SELinux の targeted ポリシーが使用されていること、enforcing モードで実行していることを前提としています。
sestatus
コマンドを実行し、 SELinux が有効になっていること、 enforcing モードで実行していること、 targeted ポリシーが使われていることを確認します。$ /usr/sbin/sestatus SELinux status: enabled SELinuxfs mount: /selinux Current mode: enforcing Mode from config file: enforcing Policy version: 24 Policy from config file: targeted
SELinux が有効になっていると、SELinux status: enabled
が返されます。 SELinux が enforcing モードで実行されていると、Current mode: enforcing
が返されます。 SELinux targeted ポリシーが使用されていると、Policy from config file: targeted
が返されます。- root ユーザーになり、
touch /var/www/html/testfile
コマンドを実行してファイルを作成します。 ls -Z /var/www/html/testfile
コマンドを実行して SELinux のコンテキストを表示します。-rw-r--r-- root root unconfined_u:object_r:httpd_sys_content_t:s0 /var/www/html/testfile
このtestfile
ファイルには、SELinux のunconfined_u
ユーザーラベルが付けられています。unconfined_u
SELinux ユーザーにマッピングされた Linux ユーザーによってこのファイルが作成されたためです。ファイルではなくプロセスの場合には、ロールベースのアクセス制御 (RBAC) が使用されます。ファイルの場合はロールに意味はなく、汎用ロールとなるobject_r
ロールが使用されます (永続的なストレージおよびネットワークファイルシステム上のファイル)。/proc/
ディレクトリ配下では、プロセスに関連するファイルにはsystem_r
ロールが使用される場合があります。[3]httpd_sys_content_t
タイプでhttpd
プロセスによるこのファイルへのアクセスを許可しています。- root ユーザーになり、
service httpd start
コマンドを使ってhttpd
プロセスを開始します。httpd
が正常に起動すると以下のような出力が表示されます。# /sbin/service httpd start Starting httpd: [ OK ]
- Linux ユーザーでの書き込みアクセスがあるディレクトリに移動してから、
wget http://localhost/testfile
コマンドを実行します。 デフォルト設定に変更がなければ、 このコマンドは成功します。--2009-12-01 11:40:28-- http://localhost/testfile Resolving localhost... 127.0.0.1 Connecting to localhost|127.0.0.1|:80... connected. HTTP request sent, awaiting response... 200 OK Length: 0 [text/plain] Saving to: `testfile' [ <=> ] 0 --.-K/s in 0s 2009-12-01 11:40:28 (0.00 B/s) - `testfile' saved [0/0]
chcon
コマンドでファイルのラベルを付け換えます。ただし、ファイルシステムのラベルが付け換えられると、 この変更は失われます。ファイルシステムのラベルが付け換えられた場合でも、 こうした変更を永続的に維持するには、semanage
コマンドを使用します。このコマンドについてはのちほど説明していきます。 root ユーザーになり、次のコマンドを実行してタイプを Samba で使用されるタイプに変更します。chcon -t samba_share_t /var/www/html/testfile
ls -Z /var/www/html/testfile
コマンドを実行し、変更を表示します。-rw-r--r-- root root unconfined_u:object_r:samba_share_t:s0 /var/www/html/testfile
- 現在の DAC パーミッションでは、
httpd
プロセスによるtestfile
へのアクセスを許可している点に注意してください。Linux ユーザーとしての書き込みアクセスがあるディレクトリに移動し、wget http://localhost/testfile
コマンドを実行します。デフォルト設定に変更がなければ、このコマンドは失敗します。--2009-12-01 11:43:18-- http://localhost/testfile Resolving localhost... 127.0.0.1 Connecting to localhost|127.0.0.1|:80... connected. HTTP request sent, awaiting response... 403 Forbidden 2009-12-01 11:43:18 ERROR 403: Forbidden.
- root ユーザーになり、
rm /var/www/html/testfile
コマンドを実行しtestfile
を削除します。 httpd
を実行しておく必要がない場合は、 root ユーザーになりservice httpd stop
コマンドを実行しhttpd
を停止します。# /sbin/service httpd stop Stopping httpd: [ OK ]
上記の例では、 SELinux によって追加される安全性を示しました。 ステップ 5 では、 DAC ルールによって
httpd
プロセスの testfile
へのアクセスが許可されています。しかし、httpd
プロセスによるアクセス権がないタイプにラベルが付け換えられたため、SELinux によってアクセスが拒否されるようになります。ステップ 7 のあと、setroubleshoot-server パッケージをインストールすると、次のようなエラーが /var/log/messages
にログ記録されます。
setroubleshoot: SELinux is preventing httpd (httpd_t) "getattr" to /var/www/html/testfile (samba_share_t). For complete SELinux messages run sealert -l c05911d3-e680-4e42-8e36-fe2ab9f8e654
また、 以下のようなエラーは
/var/log/httpd/error_log
にログ記録されます。
[Tue Dec 01 11:43:18 2009] [error] [client 127.0.0.1] (13)Permission denied: access to /testfile denied
2.3. 制限のないプロセス
制限のないプロセスは制限のないドメインで実行されます。例えば、
init
プログラムは制限のない initrc_t
ドメインで実行され、制限のないカーネルプロセスは kernel_t
ドメインで、制限のない Linux ユーザーは unconfined_t
ドメインで実行されます。制限のないプロセスの場合でも SELinux ポリシールールは適用されます。ただし、既存のポリシールールは制限のないドメイン内で実行中のプロセスにほとんどすべてのアクセスを許可します。このため、制限のないドメイン内で実行中のプロセスは、もっぱら DAC ルールに依存することになります。制限のないプロセスが攻撃された場合、攻撃者によってシステムリソースやデータへのアクセス権が奪われても SELinux ではそれを阻止しませんが、 DAC ルールは常に適用されます。SELinux は DAC ルールに加えて使用することで二重のセキュリティ強化を施行するものであり、DAC ルールの代替として使用するものではありません。
以下の例では、 Apache HTTP Server (
httpd
) を制限なしで実行している場合、 Samba 向けのデータにApache HTTP Server をどのようにしてアクセスさせることができるかを示します。Red Hat Enterprise Linux では、httpd
プロセスはデフォルトで制限のある httpd_t
ドメイン内で実行されます。次の例はあくまで例であり、実稼働環境では使用しないでください。httpd、 wget、dbus、audit パッケージがインストールされていること、 SELinux targeted ポリシーが使われていること、 またモードは enforcing で実行されていることを前提としています。
sestatus
コマンドを実行し、 SELinux が有効になっていること、 enforcing モードで実行していること、 targeted ポリシーが使われていることを確認します。$ /usr/sbin/sestatus SELinux status: enabled SELinuxfs mount: /selinux Current mode: enforcing Mode from config file: enforcing Policy version: 24 Policy from config file: targeted
SELinux が有効になっていると、SELinux status: enabled
が返されます。 SELinux が enforcing モードで実行されていると、Current mode: enforcing
が返されます。 SELinux targeted ポリシーが使用されていると、Policy from config file: targeted
が返されます。- root ユーザーになり、
touch /var/www/html/test2file
コマンドを実行してファイルを作成します。 ls -Z /var/www/html/test2file
コマンドを実行して SELinux のコンテキストを表示します。-rw-r--r-- root root unconfined_u:object_r:httpd_sys_content_t:s0 /var/www/html/test2file
test2file
には SELinuxunconfined_u
ユーザーのラベルが付けられています。unconfined_u
SELinux ユーザーにマッピングされた Linux ユーザーによってこのファイルが作成されたためです。 ファイルではなくプロセスの場合には、 ロールベースのアクセス制御 (RBAC) が使用されます。 ファイルの場合、 ロールの使用は意味がありません。object_r
ロールはファイルに使用される汎用ロールになります (永続的なストレージおよびネットワークファイルシステム上)。/proc/
ディレクトリ配下では、 プロセスに関連するファイルはsystem_r
ロールを使用することができます。 [4]httpd_sys_content_t
タイプを使用すると、httpd
プロセスにこのファイルへのアクセスを許可することになります。chcon
コマンドでファイルのラベルを付け換えます。ただし、ファイルシステムのラベルが付け換えられると、 この変更は失われます。ファイルシステムのラベルが付け換えられた場合でも、 こうした変更を永続的に維持するには、semanage
コマンドを使用します。このコマンドについてはのちほど説明していきます。 root ユーザーになり、次のコマンドを実行してタイプを Samba で使用されるタイプに変更します。chcon -t samba_share_t /var/www/html/test2file
ls -Z /var/www/html/test2file
コマンドを実行して変更を表示します。-rw-r--r-- root root unconfined_u:object_r:samba_share_t:s0 /var/www/html/test2file
service httpd status
コマンドを実行し、httpd
プロセスが実行していないことを確認します。$ /sbin/service httpd status httpd is stopped
出力が異なる場合は、 root ユーザーでservice httpd stop
コマンドを実行し、httpd
プロセスを停止します。# /sbin/service httpd stop Stopping httpd: [ OK ]
httpd
プロセスを制限なしで実行する場合は、 root ユーザーで以下のコマンドを実行し、/usr/sbin/httpd
のタイプを制限のあるドメインに遷移しないタイプに変更します。chcon -t unconfined_exec_t /usr/sbin/httpd
ls -Z /usr/sbin/httpd
コマンドを実行し、/usr/sbin/httpd
がunconfined_exec_t
タイプでラベル付けされていることを確認します。-rwxr-xr-x root root system_u:object_r:unconfined_exec_t /usr/sbin/httpd
- root ユーザーになり、
service httpd start
コマンドを使ってhttpd
プロセスを開始します。httpd
が正常に起動すると以下のような出力が表示されます。# /sbin/service httpd start Starting httpd: [ OK ]
ps -eZ | grep httpd
コマンドを実行し、httpd
プロセスがunconfined_t
ドメイン内で実行していることを表示します。$ ps -eZ | grep httpd unconfined_u:system_r:unconfined_t 7721 ? 00:00:00 httpd unconfined_u:system_r:unconfined_t 7723 ? 00:00:00 httpd unconfined_u:system_r:unconfined_t 7724 ? 00:00:00 httpd unconfined_u:system_r:unconfined_t 7725 ? 00:00:00 httpd unconfined_u:system_r:unconfined_t 7726 ? 00:00:00 httpd unconfined_u:system_r:unconfined_t 7727 ? 00:00:00 httpd unconfined_u:system_r:unconfined_t 7728 ? 00:00:00 httpd unconfined_u:system_r:unconfined_t 7729 ? 00:00:00 httpd unconfined_u:system_r:unconfined_t 7730 ? 00:00:00 httpd
- Linux ユーザーでの書き込みアクセスがあるディレクトリに移動し、
wget http://localhost/test2file
コマンドを実行します。 デフォルト設定に変更がなければ、 このコマンドは成功します。--2009-12-01 11:55:47-- http://localhost/test2file Resolving localhost... 127.0.0.1 Connecting to localhost|127.0.0.1|:80... connected. HTTP request sent, awaiting response... 200 OK Length: 0 [text/plain] Saving to: `test2file.1' [ <=> ]--.-K/s in 0s 2009-12-01 11:55:47 (0.00 B/s) - `test2file.1' saved [0/0]
httpd
プロセスにはsamba_share_t
タイプのラベルが付けられたファイルへのアクセス権はありませんが、httpd
は制限のないunconfined_t
ドメイン内で実行しているため、 DAC ルールの使用に依存しています。 したがって、wget
コマンドは成功します。 もしhttpd
が制限のあるhttpd_t
ドメインで実行していたなら、wget
コマンドは失敗していたでしょう。 restorecon
コマンドは、 ファイルのデフォルト SELinux コンテキストを復元します。 root ユーザーになり、restorecon -v /usr/sbin/httpd
コマンドを実行して、/usr/sbin/httpd
のデフォルトの SELinux コンテキストを復元します。# /sbin/restorecon -v /usr/sbin/httpd restorecon reset /usr/sbin/httpd context system_u:object_r:unconfined_exec_t:s0->system_u:object_r:httpd_exec_t:s0
ls -Z /usr/sbin/httpd
コマンドを実行し、/usr/sbin/httpd
がhttpd_exec_t
タイプでラベル付けされていることを確認します。$ ls -Z /usr/sbin/httpd -rwxr-xr-x root root system_u:object_r:httpd_exec_t /usr/sbin/httpd
- root ユーザーになり、
/sbin/service httpd restart
コマンドを実行し、httpd
を再起動します。 再起動したら、ps -eZ | grep httpd
コマンドを実行してhttpd
が制限のあるhttpd_t
ドメイン内で実行していることを確認します。# /sbin/service httpd restart Stopping httpd: [ OK ] Starting httpd: [ OK ] # ps -eZ | grep httpd unconfined_u:system_r:httpd_t 8880 ? 00:00:00 httpd unconfined_u:system_r:httpd_t 8882 ? 00:00:00 httpd unconfined_u:system_r:httpd_t 8883 ? 00:00:00 httpd unconfined_u:system_r:httpd_t 8884 ? 00:00:00 httpd unconfined_u:system_r:httpd_t 8885 ? 00:00:00 httpd unconfined_u:system_r:httpd_t 8886 ? 00:00:00 httpd unconfined_u:system_r:httpd_t 8887 ? 00:00:00 httpd unconfined_u:system_r:httpd_t 8888 ? 00:00:00 httpd unconfined_u:system_r:httpd_t 8889 ? 00:00:00 httpd
- root ユーザーになり、
rm /var/www/html/test2file
コマンドを実行しtest2file
を削除します。 httpd
を実行しておく必要がない場合は、 root ユーザーになりservice httpd stop
コマンドを実行しhttpd
を停止します。# /sbin/service httpd stop Stopping httpd: [ OK ]
このセクションでは、 制限のあるプロセスが攻撃を受けた場合、データはどのように保護されるのか (SELinux で保護)、また制限のないプロセスが攻撃を受けた場合、攻撃者にとっていかにデータにアクセスしやすいか (SELinux で保護されていない) を例を使って説明しました。
第3章 Apache HTTP Server
Apache HTTP Server Project ページより抜粋:
原文: "The Apache HTTP Server Project is an effort to develop and maintain an open-source HTTP server for modern operating systems including UNIX and Windows NT. The goal of this project is to provide a secure, efficient and extensible server that provides HTTP services in sync with the current HTTP standards". (訳文: Apache HTTP Server Project は、 UNIX や Windows NT など新しいオペレーティングシステム向けのオープンソース HTTP サーバーの開発および保守に取り組んでいます。 現在の HTTP 標準に適合する HTTP サービスを提供し、 安全かつ効率的で拡張性のあるサーバーを実現していくことを目標としています。)[5]
Red Hat Enterprise Linux では、 Apache HTTP Server は httpd パッケージで提供されています。 httpd パッケージがインストールされているか確認する場合は、
rpm -q httpd
を実行します。Apache HTTP Server を使用する予定にも関わらず、このパッケージがインストールされていない場合は、root ユーザーになり次のコマンドを実行してパッケージのインストールを行ないます。
yum install httpd
3.1. Apache HTTP Server と SELinux
SELinux を有効にすると、Apache HTTP Server (
httpd
) はデフォルトで制限のあるサービスとして実行されます。制限のあるプロセスはそのプロセス自体のドメインで実行され、 他の制限のあるプロセスとは分離されます。 制限のあるプロセスが攻撃を受けると、 SELinux ポリシー設定に応じて、 攻撃側がリソースにアクセスして加えることができる被害は限定されます。 次の例では、 httpd
プロセス自体のドメイン内で実行しているプロセスを示します。 httpd、 setroubleshoot、 setroubleshoot-server、 policycoreutils-python の各パッケージがインストールされていることを前提とします。
getenforce
を実行して SELinux が enforcing モードで実行しているか確認します。$ getenforce Enforcing
SELinux が enforcing モードで実行している場合は、getenforce
コマンドを実行するとEnforcing
が返されます。- root ユーザーになり
service httpd start
を実行し、httpd
を起動します。# service httpd start Starting httpd: [ OK ]
ps -eZ | grep httpd
を実行してhttpd
プロセスを表示します。$ ps -eZ | grep httpd unconfined_u:system_r:httpd_t:s0 2850 ? 00:00:00 httpd unconfined_u:system_r:httpd_t:s0 2852 ? 00:00:00 httpd unconfined_u:system_r:httpd_t:s0 2853 ? 00:00:00 httpd unconfined_u:system_r:httpd_t:s0 2854 ? 00:00:00 httpd unconfined_u:system_r:httpd_t:s0 2855 ? 00:00:00 httpd unconfined_u:system_r:httpd_t:s0 2856 ? 00:00:00 httpd unconfined_u:system_r:httpd_t:s0 2857 ? 00:00:00 httpd unconfined_u:system_r:httpd_t:s0 2858 ? 00:00:00 httpd unconfined_u:system_r:httpd_t:s0 2859 ? 00:00:00 httpd
httpd
プロセスに関連する SELinux コンテキストはunconfined_u:system_r:httpd_t:s0
です。 コンテキストの末尾から 2 番目の部分、httpd_t
がタイプになります。 プロセスのドメインやファイルのタイプを定義するのがタイプです。 この例の場合、httpd
プロセスはhttpd_t
ドメインで実行されています。
httpd_t
などの制限ドメイン内で実行しているプロセスがファイルや他のプロセス、システムなどとどのように交信するのかをSELinux ポリシーで定義します。httpd
からアクセスができるよう、ファイルには適切なラベルを付けなければなりません。たとえば、httpd_sys_content_t
タイプのラベルが付いたファイルの場合、httpd
からはこのファイルの読み取りは可能ですが書き込みはできません。この場合、Linux (DAC) のパーミッションで書き込みのアクセスが許可されていても書き込みを行なうことはできません。特定の動作を許可する場合、たとえば、スクリプトによるネットワークへのアクセスを許可する、httpd
による NFS や CIFS ファイルシステムへのアクセスを許可する、httpd
による CGI (Common Gateway Interface) スクリプトの実行を許可するなどの場合には、Boolean をオンにする必要があります。
httpd
が TCP ポート 80、443、488、8008、8009、8443 以外のポートでリッスンするよう /etc/httpd/conf/httpd.conf
を設定する場合は、semanage port
コマンドを使って SELinux ポリシー設定に新しいポート番号を追加する必要があります。以下では、まだ SELinux ポリシー設定で httpd
用には定義されていないポートでリッスンするよう httpd
を設定した結果、httpd
の起動に失敗する例を示します。また、httpd
がポリシーにまだ定義されていない非標準のポートで正しくリッスンするよう SELinux システムを設定する方法についても示します。httpd パッケージがインストールされていることを前提としています。各コマンドは root ユーザーで実行してください。
service httpd status
を実行してhttpd
が実行中ではないことを確認します。# service httpd status httpd is stopped
出力が上記と異なる場合は、service httpd stop
を実行してプロセスを停止します。# service httpd stop Stopping httpd: [ OK ]
semanage port -l | grep -w http_port_t
を実行して、 SELinux でhttpd
にリッスンを許可しているポートを表示させます。# semanage port -l | grep -w http_port_t http_port_t tcp 80, 443, 488, 8008, 8009, 8443
- root ユーザーで
/etc/httpd/conf/httpd.conf
を編集、Listen
オプションを設定します。SELinux ポリシー設定ではhttpd
用にまだ設定が行なわれていないポートをこのオプションに記述します。この例では、 ポート 12345 でリッスンするようhttpd
を設定しています。# Change this to Listen on specific IP addresses as shown below to # prevent Apache from glomming onto all bound IP addresses (0.0.0.0) # #Listen 12.34.56.78:80 Listen 127.0.0.1:12345
service httpd start
を実行してhttpd
を起動します。# service httpd start Starting httpd: (13)Permission denied: make_sock: could not bind to address 127.0.0.1:12345 no listening sockets available, shutting down Unable to open logs [FAILED]
以下のような SELinux 拒否がログ記録されます。setroubleshoot: SELinux is preventing the httpd (httpd_t) from binding to port 12345. For complete SELinux messages. run sealert -l f18bca99-db64-4c16-9719-1db89f0d8c77
httpd
によるポート 12345 のリッスンを SELinux で許可させるには、 以下の例で使用している次のコマンドが必要になります。# semanage port -a -t http_port_t -p tcp 12345
- もう一度
service httpd start
を実行して、httpd
を起動させ新しいポートをリッスンするようにします。# service httpd start Starting httpd: [ OK ]
httpd
による非標準ポート (この例では TCP 12345) でのリッスンを許可する SELinux 設定が完了しました。これで、httpd
がこのポートで正常に起動するようになります。httpd
が確かに TCP ポート 12345 でリッスンし通信を行なっているか確認するには、 そのポートに telnet 接続を開き HTTP GET コマンドを以下のように発行します。# telnet localhost 12345 Trying 127.0.0.1... Connected to localhost. Escape character is '^]'. GET / HTTP/1.0 HTTP/1.1 200 OK Date: Wed, 02 Dec 2009 14:36:34 GMT Server: Apache/2.2.13 (Red Hat) Accept-Ranges: bytes Content-Length: 3985 Content-Type: text/html; charset=UTF-8 [...continues...]
3.2. タイプ
Type Enforcement が SELinux の targeted ポリシーで使用されるメインのパーミッション制御になります。全ファイルおよびプロセスにタイプのラベルが付けられます。ファイルの場合はタイプ、プロセスの場合はドメインを定義します。任意のタイプにアクセスするドメインなのか、 別のドメインにアクセスするドメインなのかなど、SELinux のポリシールールではタイプによって互いがアクセスしあう方法を定義します。 アクセスを許可する特定の SELinux ポリシールールが存在する場合にのみ、 そのアクセスが許可されます。
以下の例では、
/var/www/html/
ディレクトリに新しいファイルを作成し、 そのファイルが親ディレクトリ (/var/www/html/
) の httpd_sys_content_t
タイプを継承していることを示しています。
ls -dZ /var/www/html
を実行して/var/www/html/
の SELinux コンテキストを表示させます。$ ls -dZ /var/www/html drwxr-xr-x root root system_u:object_r:httpd_sys_content_t:s0 /var/www/html
/var/www/html/
にはhttpd_sys_content_t
タイプのラベルが付けられていることが分かります。- root ユーザーになり
touch /var/www/html/file1
を実行して新しいファイルを作成します。 ls -Z /var/www/html/file1
を実行して SELinux コンテキストを表示させます。$ ls -Z /var/www/html/file1 -rw-r--r-- root root unconfined_u:object_r:httpd_sys_content_t:s0 /var/www/html/file1
ls -Z
コマンドを使用すると file1
には httpd_sys_content_t
タイプのラベルが付けられていることが分かります。 SELinux では、 httpd
がこのタイプのラベルが付いたファイルを読み込めるよう許可していますが、 書き込みは許可していません。 Linux のパーミッションが書き込みアクセスを許可していても変わりません。 SELinux ポリシーで httpd_t
ドメイン (httpd
が実行されるドメイン) で実行しているプロセスが読み取りと書き込みを行なうことができるタイプを定義しています。 これにより、 プロセスが別のプロセス用のファイルにアクセスしてしまわないよう保護しています。
たとえば、
httpd
は httpd_sys_content_t
タイプ (Apache HTTP Server 用) のラベルが付いたファイルを読み込むことができますが、デフォルトでは samba_share_t
タイプ (Samba 用) のラベルが付いたファイルにはアクセスできません。また、ユーザーのホームディレクトリにあるファイルには user_home_t
タイプのラベルが付けられます。これにより、デフォルトで httpd
がユーザーのホームディレクトリにあるファイルの読み取りや書き込みを行なわないよう保護しています。
httpd
で使用されるタイプをいくつか以下に示します。 タイプを使い分けることで柔軟なアクセスを設定することができるようになります。
httpd_sys_content_t
- このタイプは、静的な Web サイトで使用される
.html
ファイルなどの Web コンテンツに使用します。このタイプのラベルが付けられたファイルは、httpd
およびhttpd
で実行されるスクリプトに対してアクセス可能となります (読み取り専用)。デフォルトでは、このタイプのラベルが付けられたファイルおよびディレクトリへのhttpd
や他のプロセスによる書き込み、編集は行なえません。デフォルトでは、/var/www/html/
内に作成またはコピーされたファイルにはhttpd_sys_content_t
タイプのラベルが付けられます。 httpd_sys_script_exec_t
- このタイプは、
httpd
に実行させるスクリプトに対して使用します。 一般的には/var/www/cgi-bin/
内の CGI (Common Gateway Interface) スクリプトに使用されます。 デフォルトでは、 SELinux ポリシーによりhttpd
による CGI スクリプトの実行は阻止されます。 これを許可するため、 スクリプトにhttpd_sys_script_exec_t
タイプのラベル付けを行い、httpd_enable_cgi
Boolean をオンにします。httpd_sys_script_exec_t
のラベルが付けられたスクリプトは、httpd
で実行されるとhttpd_sys_script_t
ドメインで実行されます。httpd_sys_script_t
ドメインには、postgresql_t
やmysqld_t
など他のシステムドメインへのアクセスがあります。 httpd_sys_content_rw_t
- このタイプのラベルを使用したファイルは、
httpd_sys_script_exec_t
タイプのラベルが付いたスクリプトによる書き込みが可能になります。 ただし、 これ以外のラベルタイプのスクリプトによる編集はできません。httpd_sys_script_exec_t
タイプのラベルが付いたスクリプトに読み込みや書き込みを行なわせるファイルには、httpd_sys_content_rw_t
タイプのラベルを使用してください。 httpd_sys_content_ra_t
- このタイプのラベルを使用したファイルは、
httpd_sys_script_exec_t
タイプのラベルが付いたスクリプトによる追加が可能になります。 ただし、 これ以外のラベルタイプのスクリプトによる編集はできません。httpd_sys_script_exec_t
タイプのラベルが付いたスクリプトに読み込みや追加を行なわせるファイルには、httpd_sys_content_ra_t
タイプのラベルを使用してください。 httpd_unconfined_script_exec_t
- このタイプのラベルを付けたスクリプトは SELinux の保護なしで実行されます。 このタイプの使用は、 これ以外の手段を試したがいずれもうまくいかない複雑なスクリプトを使用する場合に限ってください。
httpd
に対して SELinux の保護をオフにする、 またはシステム全体に対して SELinux の保護をオフにするよりは、 このタイプを使用した方がよいでしょう。
注記
httpd に使用できる他のタイプについては次のコマンドを実行すると確認できます。
grep httpd /etc/selinux/targeted/contexts/files/file_contexts
SELinux のコンテキストを変更する
ファイルやディレクトリのタイプは chcon
コマンドを使用すると変更することができます。 chcon
を使って行なった変更は、 ファイルシステムの再ラベルや restorecon
コマンドを実行すると失われます。 特定ファイルの SELinux コンテキストの変更をユーザーに許可するかどうかは SELinux ポリシーで制御します。 以下の例では、 httpd
用の index.html
ファイルと新規ディレクトリを作成し、 そのファイルとディレクトリに httpd
がアクセスできるようラベル付けを行ないます。
- root ユーザーで
mkdir -p /my/website
を実行し、httpd
によって使用されるファイルを格納するディレクトリを最上位に作成します。 - ファイルコンテキスト設定のパターンに合致しないファイルやディレクトリには
default_t
タイプのラベルが付けられる場合があります。 制限のあるサービスからはこのタイプのファイルやディレクトリにはアクセスできません。$ ls -dZ /my drwxr-xr-x root root unconfined_u:object_r:default_t:s0 /my
- root ユーザーで
chcon -R -t httpd_sys_content_t /my/
を実行し、/my/
ディレクトリおよびサブディレクトリのタイプを、httpd
からアクセスできるタイプに変更します。これで/my/website/
の配下に作成されるファイルは、default_t
タイプではなくhttpd_sys_content_t
タイプを継承するようになるため、 httpd からアクセスできるようになります。# chcon -R -t httpd_sys_content_t /my/ # touch /my/website/index.html # ls -Z /my/website/index.html -rw-r--r-- root root unconfined_u:object_r:httpd_sys_content_t:s0 /my/website/index.html
一時的な変更について:
chcon
についての詳細を Red Hat Enterprise Linux 6 SELinux ユーザーガイドの「chcon」セクションにて参照してください。
再ラベルや
restorecon
コマンドの実行後もこのラベルの変更を維持するために、semanage fcontext
コマンド (semanage
は policycoreutils-python パッケージで提供) を使用します。 このコマンドにより変更がファイルコンテキスト設定に追加されます。このあと、restorecon
コマンドを実行すると、ファイルコンテキスト設定が読み込まれ、ラベルの変更が適用されます。次の例では、httpd
に使用させる新規ディレクトリと index.html
ファイルを作成し、httpd
によるアクセスを許可するためラベルに永久的な変更を行ないます。
- root ユーザーで
mkdir -p /my/website
を実行し、httpd
によって使用されるファイルを格納するディレクトリを最上位に作成します。 - root ユーザーで以下のコマンドを実行して、 ラベルの変更をファイルコンテキスト設定に追加します。
semanage fcontext -a -t httpd_sys_content_t "/my(/.*)?"
"/my(/.*)?"
の式は、/my/
ディレクトリおよび配下の全ファイルとディレクトリにラベルの変更が適用されるという意味です。 - root ユーザーで
touch /my/website/index.html
を実行し新しいファイルを作成します。 - root ユーザーで
restorecon -R -v /my/
を実行しラベルの変更を適用します (ステップ 2 のsemanage
コマンドで変更されたファイルコンテキスト設定がrestorecon
により読み込まる)。# restorecon -R -v /my/ restorecon reset /my context unconfined_u:object_r:default_t:s0->system_u:object_r:httpd_sys_content_t:s0 restorecon reset /my/website context unconfined_u:object_r:default_t:s0->system_u:object_r:httpd_sys_content_t:s0 restorecon reset /my/website/index.html context unconfined_u:object_r:default_t:s0->system_u:object_r:httpd_sys_content_t:s0
一時的な変更について:
semanage
についての詳細を Red Hat Enterprise Linux SELinux ユーザーガイドの「semanage fcontext」セクションにて参照してください。
3.3. Boolean
SELinux は実行するサービスに必要な最小限レベルのアクセスに基づいています。サービスの実行手段は複数あるため、サービスをどのように実行するのかを SELinux に指示する必要があります。 これを行なうため、 Boolean を使用します。 Boolean を使用すると、 SELinux ポリシーの記述方法などの知識が全くなくてもランタイム時の SELinux ポリシーの一部変更を行なうことができます。 SELinux ポリシーの再読み込みや再コンパイルを行なうことなく、サービスによる NFS ファイルシステムへのアクセスを許可するなどの変更を行なうことができるようになります。
Boolean の状態を変更するには、
setsebool
コマンドを使用します。 たとえば、 allow_httpd_anon_write
Boolean をオンにする場合は次のコマンドを root ユーザーで実行します。
# setsebool -P allow_httpd_anon_write on
同じ例を使って Boolean をオフにする場合は、 コマンドの
on
を off
にします。 以下にそのコマンドを示します。
# setsebool -P allow_httpd_anon_write off
注記
再起動後、
setsebool
による変更を維持したくない場合は -P
オプションを使用しないでください。
httpd
の動作方法を指定する一般的な Boolean について以下に説明します。
allow_httpd_anon_write
- この Boolean を無効にした場合、
httpd
によるpublic_content_rw_t
タイプのラベルが付いたファイルへのアクセスを読み取り専用に限定します。有効にすると、パブリックファイル転送サービス用のファイルを含むパブリックディレクトリなどpublic_content_rw_t
タイプのラベルが付いたファイルへの書き込みを許可するようになります。 allow_httpd_mod_auth_ntlm_winbind
- この Boolean を有効にすると、
httpd
でmod_auth_ntlm_winbind
モジュールを介した NTLM および Winbind 認証メカニズムへのアクセスが許可されます。 allow_httpd_mod_auth_pam
- この Boolean を有効にすると、
httpd
でmod_auth_pam
モジュールを介した PAM 認証メカニズムへのアクセスが許可されます。 allow_httpd_sys_script_anon_write
- パブリックファイル転送サービスで使用されるような、
public_content_rw_t
タイプのラベルが付いたファイルへの書き込みアクセスを HTTP スクリプトに許可するかどうかを指定する Boolean です。 httpd_builtin_scripting
httpd
スクリプト機能へのアクセスを定義する Boolean です。 PHP コンテンツの場合、 この Boolean の有効化が必要とされることが多くあります。httpd_can_network_connect
- この Boolean を無効にすると、 HTTP スクリプトやモジュールによるネットワークやリモートポートへの接続の開始が阻止されます。 接続の開始を許可する場合は Boolean をオンにします。
httpd_can_network_connect_db
- この Boolean を無効にすると、 HTTP スクリプトやモジュールによるデータベースサーバーへの接続の開始が阻止されます。 接続の開始を許可する場合は Boolean をオンにします。
httpd_can_network_relay
httpd
をフォワードプロキシまたはリバースプロキシとして使用する場合、 この Boolean をオンにします。httpd_can_sendmail
- この Boolean を無効にすると、 HTTP モジュールによるメール送信が阻止されます。
httpd
に脆弱性が見つかった場合にスパム攻撃を阻止することができます。 HTTP モジュールにメールの送信を許可する場合は、 この Boolean をオンにします。 httpd_dbus_avahi
- この Boolean をオフにすると、
httpd
によるD-Bus
経由のavahi
サービスへのアクセスが拒否されます。 このアクセスを許可する場合は、 この Boolean をオンにします。 httpd_enable_cgi
- この Boolean を無効にすると、
httpd
による CGI スクリプトの実行が阻止されます。httpd
に CGI スクリプトの実行を許可する場合は、 この Boolean をオンにします (CGI スクリプトにはhttpd_sys_script_exec_t
タイプのラベルを付けておく必要があります)。 httpd_enable_ftp_server
- この Boolean をオンにすると、
httpd
が FTP ポートでリッスンできるようになるため、 FTPサーバーとして動作できるようになります。 httpd_enable_homedirs
- この Boolean を無効にすると、
httpd
によるユーザーのホームディレクトリへのアクセスが阻止されます。 ユーザーのホームディレクトリ (/home/*/
内のコンテンツ) へのアクセスを許可する場合は、 この Boolean をオンにします。 httpd_execmem
- この Boolean を有効にすると、 実行可能かつ書き込み可能なメモリーアドレスを必要とするプログラムの実行を
httpd
に許可します。 バッファのオーバーフローに対する保護が低下するため、 安全上、 この Boolean の有効化はお勧めできません。 ただし、 特定のモジュールやアプリケーションではこの特権を必要とするものがあります (Java や Mono アプリケーションなど)。 httpd_ssi_exec
- Web ページ内の SSI (server side include) エレメントを実行可能にするかどうかを指定する Boolean です。
httpd_tty_comm
httpd
による制御ターミナルへのアクセスを許可するかどうかを指定する Boolean です。 通常、 このアクセスは必要とされませんが、 SSL 証明書ファイルを設定する場合などに、 パスワードのプロンプトを表示させ処理するためターミナルへのアクセスが必要になります。httpd_unified
- この Boolean を有効にすると、
httpd_t
に対してhttpd
の全タイプへの完全アクセスが許可されます (つまり、 sys_content_t の実行、 読み込み、 書き込み)。 無効にすると、 読み取り専用 web コンテンツ、 書き込み可能 web コンテンツ、 実行可能 web コンテンツ間に分離が施行されます。 この Boolean を無効にすることで安全性は高くなりますが、 各ファイルに持たせるアクセス権に応じてスクリプトや他の web コンテンツを別々にラベル付けしなければならない管理作業コストが生じることになります。 httpd_use_cifs
- Samba でマウントされるファイルシステムなど、
cifs_t
タイプのラベルが付けられる CIFS ファイルシステム上にあるファイル群へのアクセスをhttpd
に許可する場合は、 この Boolean をオンにします。 httpd_use_nfs
- NFS でマウントされるファイルシステムなど、
nfs_t
タイプのラベルが付けられる NFS ファイルシステム上にあるファイル群へのアクセスをhttpd
に許可する場合は、 この Boolean をオンにします。
3.4. 設定の実例
SELinux でどのように Apache HTTP Server を補完するのか、 Apache HTTP Server の全機能をどのように管理するのかなど、 実践的な例を以下に示します。
3.4.1. 静的なサイトを実行する
静的な web サイトを作成する場合は、 その web サイトの
.html
ファイルに httpd_sys_content_t
タイプのラベルを付けます。 デフォルトでは、httpd_sys_content_t
タイプのラベルが付いたファイルには Apache HTTP Server による書き込みは行なえません。 次のように、読み取り専用 web サイト向けのファイルを格納する新しいディレクトリを作成します。
- root ユーザーで
mkdir /mywebsite
を実行し最上位にディレクトリを作成します。 - root ユーザーで
/mywebsite/index.html
ファイルを作成します。 以下のコンテンツを/mywebsite/index.html
にコピーして貼り付けます。<html> <h2>index.html from /mywebsite/</h2> </html>
/mywebsite/
および配下のファイルやサブディレクトリへの Apache HTTP Server 読み取り専用アクセスを許可するため、/mywebsite/
にhttpd_sys_content_t
タイプのラベルを付けます。root ユーザーで次のコマンドを実行してラベルの変更をファイルコンテキスト設定に追加します。# semanage fcontext -a -t httpd_sys_content_t "/mywebsite(/.*)?"
- root ユーザーで
restorecon -R -v /mywebsite
を実行してラベルの変更を行ないます。# restorecon -R -v /mywebsite restorecon reset /mywebsite context unconfined_u:object_r:default_t:s0->system_u:object_r:httpd_sys_content_t:s0 restorecon reset /mywebsite/index.html context unconfined_u:object_r:default_t:s0->system_u:object_r:httpd_sys_content_t:s0
- この例の場合、 root ユーザーで
/etc/httpd/conf/httpd.conf
を編集します。 既存のDocumentRoot
オプションをコメントアウトします。DocumentRoot "/mywebsite"
オプションを追加します。 編集結果は以下のようになるはずです。#DocumentRoot "/var/www/html" DocumentRoot "/mywebsite"
- root ユーザーで
service httpd status
を実行し Apache HTTP Server の状態を確認します。 サーバーが停止している場合は、 root ユーザーでservice httpd start
を実行してサーバーを起動します。 サーバーが実行中の場合は、 root ユーザーでservice httpd restart
を実行しサーバーの再起動を行ないます (これによりhttpd.conf
への変更がすべて適用されます)。 - web ブラウザで
http://localhost/index.html
に行きます。 次のように表示されます。index.html from /mywebsite/
3.4.2. NFS と CIFS ファイルシステムを共有する
デフォルトでは、クライアント側の NFS マウントには NFS ファイルシステムのポリシーで定義されたデフォルトのコンテキストがラベル付けされます。一般的なポリシーであれば、このデフォルトのコンテキストには
nfs_t
タイプが使用されます。またデフォルトでは、クライアント側にマウントされた Samba 共有にはポリシーで定義されたデフォルトのコンテキストがラベル付けされます。一般的なポリシーであれば、このデフォルトのコンテキストには cifs_t
タイプが使用されます。
ポリシー設定によっては
nfs_t
または cifs_t
タイプのラベルが付いたファイルはサービスからは読み取れない場合があります。 このため、このタイプのラベルが付いたファイルシステムは他のサービスによるマウント、読み込み、エクスポートなどが阻止される可能性があります。Boolean をオンまたはオフにすることで、nfs_t
や cifs_t
タイプへのアクセスを許可するサービスを管理することができるようになります。
httpd_use_nfs
Boolean をオンにして、 httpd
による NFS ファイルシステム (nfs_t
タイプのラベルが付いたファイル) へのアクセスと共有を許可します。 root ユーザーで setsebool
を実行して Boolean をオンにします。
setsebool -P httpd_use_nfs on
httpd_use_cifs
Boolean をオンにして、 httpd
による CIFS ファイルシステム (cifs_t
タイプのラベルが付いたファイル) へのアクセスと共有を許可します。 root ユーザーで setsebool
コマンドを実行します。
setsebool -P httpd_use_cifs on
注記
再起動後、
setsebool
による変更を維持したくない場合は -P
オプションを使用しないでください。
3.4.3. サービス間でファイルを共有する
Type Enforcement を使用すると、 プロセスが別のプロセス用のファイルにアクセスしてしまうのを防ぐのに役立ちます。たとえば、デフォルトでは Samba は
httpd_sys_content_t
タイプのラベルが付いたファイルの読み込みはできません。このタイプは Apache HTTP Server での使用を目的としています。目的のファイルに public_content_t
または public_content_rw_t
タイプのラベルを付けると、Apache HTTP Server、FTP、rsync、Samba 間でファイルを共有することができるようになります。
以下の例では、 ディレクトリとファイルを作成し、 Apache HTTP Server、 FTP、 rsync、 Samba 経由でそのディレクトリファイルを共有 (読み取り専用) できるようにしています。
- root ユーザーで
mkdir /shares
を実行して、 複数のサービス間でファイルを共有できるよう最上位に新規のディレクトリを作成します。 - ファイルコンテキスト設定のパターンに合致しないファイルやディレクトリには
default_t
タイプのラベルが付けられる場合があります。 制限のあるサービスからはこのタイプのファイルやディレクトリにはアクセスできません。$ ls -dZ /shares drwxr-xr-x root root unconfined_u:object_r:default_t:s0 /shares
- root ユーザーで
/shares/index.html
ファイルを作成します。 次のコンテンツをコピーして/shares/index.html
に貼り付けます。<html> <body> <p>Hello</p> </body> </html>
/shares/
にpublic_content_t
タイプのラベルを付けることで、 Apache HTTP Server、 FTP、 rsync、Samba による読み取り専用アクセスを許可します。 root ユーザーで次のコマンドを実行し、 ラベルの変更をファイルコンテキスト設定に追加します。semanage fcontext -a -t public_content_t "/shares(/.*)?"
- root ユーザーで
restorecon -R -v /shares/
を実行しラベルの変更を適用します。# restorecon -R -v /shares/ restorecon reset /shares context unconfined_u:object_r:default_t:s0->system_u:object_r:public_content_t:s0 restorecon reset /shares/index.html context unconfined_u:object_r:default_t:s0->system_u:object_r:public_content_t:s0
Samba で
/shares/
を共有する場合
rpm -q samba samba-common samba-client
を実行して、 samba、 samba-common、 samba-client の各パッケージがインストールされているか確認します (バージョン番号は使用しているバージョンによって異なります)。$ rpm -q samba samba-common samba-client samba-3.4.0-0.41.el6.3.i686 samba-common-3.4.0-0.41.el6.3.i686 samba-client-3.4.0-0.41.el6.3.i686
上記いずれのパッケージもインストールされていない場合は、 root ユーザーでyum install package-name
を実行してインストールを行ないます。- root ユーザーで
/etc/samba/smb.conf
を編集します。 Samba で/shares/
ディレクトリを共有するため、 次のエントリをこのファイルの末尾に追加します。[shares] comment = Documents for Apache HTTP Server, FTP, rsync, and Samba path = /shares public = yes writeable = no
- Samba ファイルシステムをマウントするには Samba アカウントが必要になります。 root ユーザーで
smbpasswd -a username
を実行し、 Samba アカウントを作成します。 username の部分は既存の Linux ユーザーにします。 たとえば、smbpasswd -a testuser
を実行すると、 Linux の testuser ユーザー用の Samba アカウントが作成されます。# smbpasswd -a testuser New SMB password: Enter a password Retype new SMB password: Enter the same password again Added user testuser.
smbpasswd -a username
を実行する際、 システムに存在しない Linux アカウントのユーザー名をusername に使用すると、 「Cannot locate Unix account for 'username'!
」というエラーが発生する原因になります。 - root ユーザーで
service smb start
を実行し Samba サービスを起動します。service smb start Starting SMB services: [ OK ]
smbclient -U username -L localhost
を実行し、 使用できる共有を表示させます。 username はステップ 3 で追加した Samba アカウントにします。 パスワード入力を求められたら、 ステップ 3 で Samba アカウントに割り当てたパスワードを入力します (バージョン番号は使用しているバージョンによって異なります)。$ smbclient -U username -L localhost Enter username's password: Domain=[HOSTNAME] OS=[Unix] Server=[Samba 3.4.0-0.41.el6] Sharename Type Comment --------- ---- ------- shares Disk Documents for Apache HTTP Server, FTP, rsync, and Samba IPC$ IPC IPC Service (Samba Server Version 3.4.0-0.41.el6) username Disk Home Directories Domain=[HOSTNAME] OS=[Unix] Server=[Samba 3.4.0-0.41.el6] Server Comment --------- ------- Workgroup Master --------- -------
- root ユーザーで
mkdir /test/
を実行し新規ディレクトリを作成します。 このディレクトリは Samba 共有のshares
をマウントする際に使用します。 - root で次のコマンドを実行して、Samba 共有の
shares
を/test/
にマウントします。username はステップ 3 のユーザー名にしてください。mount //localhost/shares /test/ -o user=username
ステップ 3 で設定した username のパスワードを入力します。 cat /test/index.html
を実行して Samba で共有しているファイルを表示させます。$ cat /test/index.html <html> <body> <p>Hello</p> </body> </html>
Apache HTTP Server で
/shares/
を共有する場合
rpm -q httpd
を実行して httpd パッケージがインストールされているか確認します (バージョン番号は使用しているバージョンによって異なります)。$ rpm -q httpd httpd-2.2.11-6.i386
このパッケージがインストールされていない場合は、 root ユーザーでyum install httpd
を実行してインストールします。/var/www/html/
ディレクトリに移動します。 root ユーザーで次のコマンドを実行して/shares/
ディレクトリへのリンクを作成します。ln -s /shares/ shares
- root ユーザーで
service httpd start
を実行して Apache HTTP Server を起動します。service httpd start Starting httpd: [ OK ]
- web ブラウザを使って
http://localhost/shares
に行きます。/shares/index.html
が表示されます。
デフォルトでは、
index.html
ファイルが存在していればそのファイルが Apache HTTP Server によって読み込まれます。/shares/
に file1
、file2
、file3
しかなく index.html
がない場合、http://localhost/shares
にアクセスするとディレクトリ一覧が表示されます。
- root ユーザーで
rm -i /shares/index.html
を実行してindex.html
ファイルを削除します。 - root ユーザーで
touch /shares/file{1,2,3}
を実行し、/shares/
内に 3 つのファイルを作成します。# touch /shares/file{1,2,3} # ls -Z /shares/ -rw-r--r-- root root system_u:object_r:public_content_t:s0 file1 -rw-r--r-- root root unconfined_u:object_r:public_content_t:s0 file2 -rw-r--r-- root root unconfined_u:object_r:public_content_t:s0 file3
- root ユーザーで
service httpd status
を実行して Apache HTTP Server の状態を確認します。 サーバーが停止している場合は、 root ユーザーでservice httpd start
を実行し再起動を行ないます。 - web ブラウザで
http://localhost/shares
に行きます。 ディレクトリ一覧が表示されます。
3.4.4. ポート番号を変更する
ポリシー設定に応じて、サービスの実行が許可されるのは特定のポート番号に限られます。ポリシーを変更せず、サービスが実行されるポートを変えようとすると、サービスの起動に失敗する場合があります。root ユーザーで
semanage port -l | grep -w "http_port_t"
コマンドを実行し、SELinux で http
によるリッスンを許可しているポートを表示させます。
# semanage port -l | grep -w http_port_t http_port_t tcp 80, 443, 488, 8008, 8009, 8443
デフォルトでは、 SELinux で
http
にリッスンを許可している TCP ポートは 80、443、488、8008、8009、8443 になります。httpd
で http_port_t
用に記載されていないポートをリッスンするよう /etc/httpd/conf/httpd.conf
に設定を行なうと、httpd
の起動に失敗します。
次のように、TCP ポート 80、443、488、8008、8009、8443 以外のポートで実行するよう
httpd
に設定を行ないます。
- root ユーザーで
/etc/httpd/conf/httpd.conf
を編集し、 SELinux ではhttpd
用に設定されていないポートをListen
オプションに記載します。 以下の例では、httpd
が 10.0.0.1 IP アドレス、 TCP ポート 12345 でリッスンするよう設定しています。# Change this to Listen on specific IP addresses as shown below to # prevent Apache from glomming onto all bound IP addresses (0.0.0.0) # #Listen 12.34.56.78:80 Listen 10.0.0.1:12345
- root ユーザーで
semanage port -a -t http_port_t -p tcp 12345
を実行して、 そのポートを SELinux ポリシー設定に追加します。 - root ユーザーで
semanage port -l | grep -w http_port_t
を実行してポートが追加されたか確認します。# semanage port -l | grep -w http_port_t http_port_t tcp 12345, 80, 443, 488, 8008, 8009, 8443
ポート 12345 での
httpd
の実行が必要なくなった場合には、 root ユーザーで semanage port -d -t http_port_t -p tcp 12345
を実行してポリシー設定からそのポートを削除します。
[5]
Apache HTTP Server Project ページの "The Number One HTTP Server On The Internet" セクションより抜粋: http://httpd.apache.org/。 著作権 © 2009 The Apache Software Foundation (2010年 7月 7日に閲覧)
第4章 Samba
Samba の web サイトより抜粋:
原文: "Samba is an Open Source/Free Software suite that has, since 1992, provided file and print services to all manner of SMB/CIFS clients, including the numerous versions of Microsoft Windows operating systems. Samba is freely available under the GNU General Public License.". (訳文: Samba とは、 1992 年に設立され、 Microsoft Windows オペレーティングシステムの各種バージョンをはじめ、 あらゆる SMB/CIFS クライアントにファイルやプリンタなどのサービスを提供している Open Source/Free Software スィートです。 Samba は GNU General Public License に基づき自由に入手が可能です。)[6]
Red Hat Enterprise Linux では、 Samba サーバーは samba パッケージにより提供されます。
rpm -q samba
を実行して samba パッケージがインストールされているか確認します。Samba を使用する予定にも関わらず、このパッケージがインストールされていない場合は、root ユーザーになり次のコマンドを実行してパッケージのインストールを行ないます。
yum install samba
4.1. Samba と SELinux
SELinux を有効にすると、 Samba サーバー (
smbd
) はデフォルトで制限のあるサービスとして実行されます。 制限のあるサービスはそのサービス自体のドメイン内で実行され、 他の制限のあるサービスとは分離されます。 次の例では、 サービス自体のドメイン内で実行している smbd
プロセスを示しています。 samba パッケージがインストールされていることを前提としています。
getenforce
を実行して、 SELinux が enforcing モードで実行していることを確認します。$ getenforce Enforcing
SELinux が enforcing モードで実行されている場合は、getenforce
コマンドによりEnforcing
が返されます。- root ユーザーで
service smbd start
を実行してsmbd
を起動します。service smb start Starting SMB services: [ OK ]
ps -eZ | grep smb
実行してsmbd
プロセスを表示させます。$ ps -eZ | grep smb unconfined_u:system_r:smbd_t:s0 16420 ? 00:00:00 smbd unconfined_u:system_r:smbd_t:s0 16422 ? 00:00:00 smbd
smbd
プロセスに関連する SELinux コンテキストはunconfined_u:system_r:smbd_t:s0
です。 このコンテキストの最後から 2 番目の部分、smbd_t
がタイプになります。 プロセスのドメインやファイルのタイプを定義するのがタイプです。 この例の場合、smbd
プロセスは smbd_t ドメイン内で実行しています。
smbd
によるファイルのアクセスおよび共有を許可するため、適切なラベルを付ける必要があります。たとえば、smbd
では samba_share_t
タイプのラベルが付いたファイルの読み込みと書き込みを行なうことができますが、デフォルトでは httpd_sys_content_t
タイプのラベルが付いたファイルにはアクセスできません。このタイプは Apache HTTP Server での使用を目的としているためです。Samba によるホームディレクトリや NFS ファイルシステムのエクスポートを許可する、また Samba にドメインコントローラとしての動作を許可するなど、特定の動作を許可する場合は Boolean をオンにする必要があります。
4.2. タイプ
ファイルに
samba_share_t
タイプのラベルを付けて Samba によるファイル共有ができるようにします。 このタイプのラベル付けはユーザー作成のファイルに限ってください。システムファイルにはこのタイプのラベルは付けないよう注意してください。ラベル付けしたファイルやディレクトリを共有するため Boolean をオンにします。SELinux では、/etc/samba/smb.conf
と Linux パーミッションが設定されていれば、samba_share_t
タイプのラベルが付いたファイルへの Samba による書き込みは許可されます。
samba_etc_t
タイプは、 /etc/samba/
内にあるsmb.conf
などの特定ファイルに使用されます。 samba_etc_t
タイプのラベル付けは手作業では行なわないでください。 /etc/samba/
内のファイルに適切なラベルが付けられていない場合、 root ユーザーで restorecon -R -v /etc/samba
を実行してそのファイルをデフォルトのコンテキストに復元します。 /etc/samba/smb.conf
に samba_etc_t
タイプのラベルが付いていない場合、 service smb start
コマンドの実行が失敗し、 SELinux 拒否がログ記録される場合があります。 /etc/samba/smb.conf
に httpd_sys_content_t
タイプのラベルが付いていた場合に拒否となる例を示します。
setroubleshoot: SELinux is preventing smbd (smbd_t) "read" to ./smb.conf (httpd_sys_content_t). For complete SELinux messages. run sealert -l deb33473-1069-482b-bb50-e4cd05ab18af
4.3. Boolean
SELinux は実行するサービスに必要な最小限レベルのアクセスに基づいています。サービスの実行手段は複数あるため、サービスをどのように実行するのかを SELinux に指示する必要があります。 次の Boolean を使って Samba の動作方法を SELinux に指示します。
allow_smbd_anon_write
- この Boolean を有効にすると、 特殊なアクセス制限がなく共通ファイル用に予約されている領域など、 パブリックディレクトリへの
smbd
による書き込みが許可されます。 samba_create_home_dirs
- この Boolean を有効にすると、 Samba が単独で新規ホームディレクトリを作成できるようになります。 PAM などのようなメカニズムで有効にされることが多くあります。
samba_domain_controller
- この Boolean を有効にすると、 ドメインコントローラとして Samba を動作させ、
useradd
、groupadd
、passwd
などの関連コマンドの実行パーミッションを付与することができます。 samba_enable_home_dirs
- この Boolean を有効にすると、 Samba によるユーザーのホームディレクトリ共有が可能になります。
samba_export_all_ro
- あらゆるファイルやディレクトリをエクスポートし、 読み取り専用のパーミッションを付与します。 これにより、
samba_share_t
タイプのラベルが付いていないファイルやディレクトリを Samba で共有できるようにします。samba_export_all_ro
Boolean はオンになっているが、samba_export_all_rw
Boolean がオフになっている場合、/etc/samba/smb.conf
で書き込みアクセスが設定され Linux パーミッションでも書き込みアクセスが許可されていても、 Samba 共有への書き込みアクセスは拒否されます。 samba_export_all_rw
- あらゆるファイルやディレクトリをエクスポートし、 読み取りと書き込みのパーミッションを付与します。 これにより、
samba_share_t
タイプのラベルが付いていないファイルやディレクトリを Samba でエクスポートできるようにします。/etc/samba/smb.conf
のパーミッションおよび Linux パーミッションを設定して書き込みアクセスを許可する必要があります。 samba_run_unconfined
- この Boolean を有効にすると、Samba による /var/lib/samba/scripts ディレクトリ内の制限のないスクリプトの実行を許可します。
samba_share_fusefs
- Samba に fusefs ファイルシステムを共有させる場合は、 この Boolean を有効にする必要があります。
samba_share_nfs
- この Boolean を無効にすることで、 Samba を介した NFS 共有への完全アクセスを
smbd
に与えないようにします。 この Boolean を有効にすると、 Samba による NFS ファイルシステムの共有が許可されます。 use_samba_home_dirs
- Samba のホームディレクトリ用にリモートサーバーを使用する場合、この Boolean を有効にします。
virt_use_samba
- 仮想マシンによる CIFS ファイルへのアクセスを許可します。
4.4. 設定例
SELinux でどのように Samba サーバーを補完するのか、 Samba サーバーの全機能をどのように管理するのかなど、 実践的な例を以下に示します。
4.4.1. 作成したディレクトリを共有する
新規のディレクトリを作成し、 そのディレクトリを Samba で共有します。
rpm -q samba samba-common samba-client
を実行して、 samba、 samba-common、 samba-client の各パッケージがインストールされているか確認します。 いずれかのパッケージがインストールされていない場合は、 root ユーザーでyum install package-name
を実行してインストールを行ないます。- root ユーザーで
mkdir /myshare
を実行して Samba でファイルを共有するためのディレクトリを最上位に新規に作成します。 - root ユーザーで
touch /myshare/file1
を実行して空のファイルを作成します。 このファイルは後で Samba 共有が正しくマウントされたか確認する際に使用します。 - SELinux では、
/etc/samba/smb.conf
および Linux パーミッションが設定されていれば、samba_share_t
タイプのラベルが付いたファイルへの Samba による読み取りおよび書き込みは許可されます。root ユーザーで次のコマンドを実行し、ファイルコンテキスト設定にラベルの変更を追加します。semanage fcontext -a -t samba_share_t "/myshare(/.*)?"
- root ユーザーで
restorecon -R -v /myshare
を実行しラベルの変更を適用します。# restorecon -R -v /myshare restorecon reset /myshare context unconfined_u:object_r:default_t:s0->system_u:object_r:samba_share_t:s0 restorecon reset /myshare/file1 context unconfined_u:object_r:default_t:s0->system_u:object_r:samba_share_t:s0
- root ユーザーで
/etc/samba/smb.conf
を編集します。 Samba で /myshare/ ディレクトリを共有するため、 以下をこのファイルの末尾に追加します。[myshare] comment = My share path = /myshare public = yes writeable = no
- Samba ファイルシステムをマウントするには Samba アカウントが必要になります。 root ユーザーで
smbpasswd -a username
を実行し Samba アカウントを作成します。 username は既存の Linux ユーザーにします。 たとえば、smbpasswd -a testuser
にすると、 Linux testuser ユーザーの Samba アカウントが作成されます。# smbpasswd -a testuser New SMB password: (パスワードを入力) Retype new SMB password: (もう一度同じパスワードを入力) Added user testuser.
smbpasswd -a username
を実行する際、 システム上に存在していない Linux アカウントをのユーザー名を username に入れると、 「Cannot locate Unix account for 'username'!
」エラーが発生する原因になります。 - root ユーザーで
service smb start
を実行して Samba サービスを起動します。service smb start Starting SMB services: [ OK ]
smbclient -U username -L localhost
を実行し、 使用できる共有を表示させます。 username はステップ 7 で追加した Samba アカウントにします。 パスワード入力を求められたら、 ステップ 7 で Samba アカウントに割り当てたパスワードを入力します (バージョン番号は使用しているバージョンによって異なります)。$ smbclient -U username -L localhost Enter username's password: Domain=[HOSTNAME] OS=[Unix] Server=[Samba 3.4.0-0.41.el6] Sharename Type Comment --------- ---- ------- myshare Disk My share IPC$ IPC IPC Service (Samba Server Version 3.4.0-0.41.el6) username Disk Home Directories Domain=[HOSTNAME] OS=[Unix] Server=[Samba 3.4.0-0.41.el6] Server Comment --------- ------- Workgroup Master --------- -------
- root ユーザーで
mkdir /test/
を実行し新規ディレクトリを作成します。 このディレクトリは Samba 共有のmyshare
をマウントする際に使用します。 - root で次のコマンドを実行して、Samba 共有の
myshare
を/test/
にマウントします。 username はステップ 7 のユーザー名にしてください。mount //localhost/myshare /test/ -o user=username
ステップ 7 で設定した username のパスワードを入力します。 ls /test/
を実行して ステップ 3 で作成したfile1
を表示させます。$ ls /test/ file1
4.4.2. web サイトを共有する
/var/www/html/
で web サイトを共有したい場合など、ファイルに samba_share_t
タイプのラベルが付けられない場合があります。 このような場合には、 すべてのファイルやディレクトリを共有するよう samba_export_all_ro
Boolean を使用して読み取り専用パーミッションを付与するか (現在のラベルに関わらず)、 samba_export_all_rw
Boolean を使用して読み取りと書き込みのパーミッションを付与します (現在のラベルに関わらず)。
以下の例では、
/var/www/html/
内に web サイトのファイルを作成してから、 そのファイルを Samba で共有し読み取りと書き込みのパーミッションを与えています。 ここでは、 httpd、 samba、 samba-common、 samba-client、 wget のパッケージがインストールされていることを前提としています。
- root ユーザーになり
/var/www/html/file1.html
ファイルを作成します。 次のコンテンツをコピーして/var/www/html/file1.html
に貼り付けます。<html> <h2>File being shared through the Apache HTTP Server and Samba.</h2> </html>
ls -Z /var/www/html/file1.html
を実行してfile1.html
の SELinux コンテキストを表示させます。$ ls -Z /var/www/html/file1.html -rw-r--r--. root root unconfined_u:object_r:httpd_sys_content_t:s0 /var/www/html/file1.html
file1.index.html
にはhttpd_sys_content_t
タイプのラベルが付けられています。デフォルトでは、Apache HTTP Server によるアクセスはできますが、 Samba によるアクセスはできません。- root ユーザーで
service httpd start
を実行して Apache HTTP Server を起動します。service httpd start Starting httpd: [ OK ]
- Linux ユーザーでの書き込みアクセスがあるディレクトリに移動し、
wget http://localhost/file1.html
コマンドを実行します。 デフォルト設定に変更がなければ、 このコマンドは成功します。$ wget http://localhost/file1.html Resolving localhost... 127.0.0.1 Connecting to localhost|127.0.0.1|:80... connected. HTTP request sent, awaiting response... 200 OK Length: 84 [text/html] Saving to: `file1.html.1' 100%[=======================>] 84 --.-K/s in 0s `file1.html.1' saved [84/84]
- root ユーザーで
/etc/samba/smb.conf
を編集します。 Samba で/var/www/html/
ディレクトリを共有するため、 以下をこのファイルの末尾に追加します。[website] comment = Sharing a website path = /var/www/html/ public = no writeable = no
/var/www/html/
ディレクトリにはhttpd_sys_content_t
タイプのラベルが付けられます。 デフォルトでは、httpd_sys_content_t
タイプのラベルの付いたファイルやディレクトリには、 Linux パーミッションが付与されていても Samba からはアクセスできません。 Samba によるアクセスを許可するため、 root ユーザーで次のコマンドを実行し、samba_export_all_ro
Boolean をオンにします。setsebool -P samba_export_all_ro on
再起動後、この変更を維持したくない場合は-P
を使用しないでください。samba_export_all_ro
Boolean をオンにすると、Samba からはいずれのタイプにもアクセスもできるようになるため注意してください。- root ユーザーで
service smb start
を実行してsmbd
を起動します。service smb start Starting SMB services: [ OK ]
第5章 ファイル転送プロトコル
ファイル転送プロトコル、 FTP は、 今日インターネット上で見られる、最も古く、一般的に使用されているプロトコルです。ユーザーはリモートホストに直接ログインする必要がなく、またリモートシステムの使い方を知らなくても、ネットワーク上の複数のコンピュータホスト間で確実にファイル転送を行なえるようにすることがその目的になります。FTP により、ユーザーはシンプルで標準的なコマンドセットを使用するだけでリモートシステム上のファイルにアクセスできるようになります。
Very Secure FTP Daemon (
vsftpd
) は、高速で安定性があり、かつ何よりも高い安全性を確保するため、その土台から設計が行なわれています。多数の接続を効率的かつ安全に処理できる能力があることから、Red Hat Enterprise Linux に同梱されている唯一の独立型 FTP サーバーとなります。
Red Hat Enterprise Linux では、Very Secure FTP デーモンは vsftpd パッケージで提供されます。
rpm -q vsftpd
を実行して vsftpd がインストールされているか確認します。
$ rpm -q vsftpd
FTP サーバーを利用する方で vsftpd パッケージがインストールされていない場合には、 次のコマンドを root ユーザーで実行してインストールを行ないます。
yum install vsftpd
5.1. FTP と SELinux
FTP デーモンの
vsftpd
はデフォルトで制限のあるサービスとして実行されます。vsftpd
とファイル、 プロセスまたシステムとの交信方法は SELinux ポリシーで定義されます。たとえば、 認証ユーザーが FTP 経由でログインすると、そのユーザーは自分のホームディレクトリの読み取りや書き込みが行なえません。SELinux により、vsftpd
によるユーザーのホームディレクトリへのアクセスはデフォルトで阻止されるためです。また、vsftpd
には NFS や CIFS ファイルシステムへのアクセスもデフォルトではありません。 このため、/etc/vsftpd/vsftpd.conf
内で書き込みアクセスが設定されていても、anonymous ユーザーには書き込みアクセスが与えられません。Boolean をオンにすると、こうしたアクセスを許可することができるようになります。
認証ユーザーがログインして、自分のホームディレクトリを表示させようとすると SeLinux 拒否になる例を以下に示します。
rpm -q ftp
を実行して ftp パッケージがインストールされているか確認します。 インストールされていない場合は root ユーザーでyum install ftp
を実行しインストールを行ないます。rpm -q vsftpd
を実行して vsftpd パッケージがインストールされているか確認します。 インストールされていない場合は root ユーザーでyum install vsftpd
を実行しインストールを行ないます。- Red Hat Enterprise Linux では、
vsftpd
はデフォルトでは anonymous ユーザーによるログインしか許可していません。認証ユーザーによるログインを許可するため、root で/etc/vsftpd/vsftpd.conf
を編集します。local_enable=YES
オプションを必ずコメントアウトしてください。# Uncomment this to allow local users to log in. local_enable=YES
- root ユーザーで
service vsftpd start
を実行してvsftpd
を起動します。vsftpd.conf
の編集前にこのサービスが実行中だった場合は、 root ユーザーでservice vsftpd restart
を実行し設定の変更を適用します。service vsftpd start Starting vsftpd for vsftpd: [ OK ]
- 現在ログインしているユーザーのまま
ftp localhost
を実行します。 ユーザー名のプロンプトが表示されたら、 ログインしているユーザー名になっているか確認します。 ユーザー名が正しければ Enter を押します。 ユーザー名が違う場合は、 正しいユーザー名を入力します。$ ftp localhost Connected to localhost (127.0.0.1). 220 (vsFTPd 2.1.0) Name (localhost:username): 331 Please specify the password. Password: Enter your password 500 OOPS: cannot change directory:/home/username Login failed. ftp>
- 次のような SELinux 拒否がログ記録されます。
setroubleshoot: SELinux is preventing the ftp daemon from reading users home directories (username). For complete SELinux messages. run sealert -l c366e889-2553-4c16-b73f-92f36a1730ce
- ホームディレクトリへのアクセスが SELinux により拒否されています。 これを解決するには、
ftp_home_dir
Boolean を有効にします。 root ユーザーで次のコマンドを実行してftp_home_dir
Boolean を有効にします。# setsebool -P ftp_home_dir=1
注記
再起動後、 変更を維持したくない場合は -P オプションを使用しないでください。もう一度ログインしてみます。 今度はftp_home_dir
Boolean でホームディレクトリへのアクセスが許可され、 ログインに成功します。
5.2. タイプ
デフォルトでは、 anonymous ユーザーは FTP でログインすると
/var/ftp/
内のファイルへの読み取りアクセスが与えられます。 このディレクトリには public_content_t
タイプのラベルが付いているため、 /etc/vsftpd/vsftpd.conf
で書き込みが設定されていても、 許可されるのは読み取り専用アクセスのみになります。 public_content_t
タイプへは、Apache HTTP Server、Samba、NFS など他のサービスによるアクセスも可能です。
FTP 経由でファイルを共有する場合は、次のいずれかのタイプを使用します。
public_content_t
- ユーザーが作成したファイルやディレクトリを vsftpd 経由の読み取り専用で共有する場合に
public_content_t
タイプのラベルを付けます。このタイプのラベルが付いたファイルには、Apache HTTP Server、Samba、NFS など、他のサービスからもアクセスすることができます。public_content_t
タイプのラベルが付いたファイルへの書き込みは、Linux パーミッションで書き込みが許可されていても行なえません。書き込みアクセスが必要な場合は、public_content_rw_t
タイプを使用してください。 public_content_rw_t
- ユーザーが作成したファイルやディレクトリを
vsftpd
経由の読み取りおよび書き込みのパーミッションで共有する場合にpublic_content_rw_t
タイプのラベルを付けます。このタイプのラベルが付いたファイルには、Apache HTTP Server、Samba、NFS など、他のサービスからもアクセスすることができます。このタイプのラベルが付いたファイルに書き込みを行う場合は、まず最初に各サービスの Boolean をオンにしておく必要がある点に注意してください。
5.3. Boolean
SELinux は実行するサービスに必要な最小限レベルのアクセスに基づいています。サービスの実行手段は複数あるため、サービスをどのように実行するのかを SELinux に指示する必要があります。 次の Boolean を使って
vsftpd
の動作方法を SELinux に指示します。
allow_ftpd_anon_write
- この Boolean を無効にした場合、
vsftpd
によるpublic_content_rw_t
タイプのラベルが付いたファイルおよびディレクトリへの書き込みが阻止されます。 有効にすると、 ユーザーによる FTP 経由のファイルのアップロードが可能になります。 ファイルのアップロード先となるディレクトリにはpublic_content_rw_t
タイプのラベルを付け、 また Linux パーミッションも設定しておく必要があります。 allow_ftpd_full_access
- この Boolean をオンにすると、 アクセス制御に Linux (DAC) のパーミッションしか使用されなくなるため、 認証ユーザーはファイルに
public_content_t
やpublic_content_rw_t
のタイプのラベルが付いていなくてもファイルの読み取りおよび書き込みが可能になります。 allow_ftpd_use_cifs
- この Boolean を有効にすると、
vsftpd
によるcifs_t
タイプのラベルが付いたファイルやディレクトリへのアクセスを許可します。 したがって、 この Boolean を有効にすることで Samba でマウントしたファイルシステムをvsftpd
で共有することができるようになります。 allow_ftpd_use_nfs
- この Boolean を有効にすると、
vsftpd
によるnfs_t
タイプのラベルが付いたファイルやディレクトリへのアクセスを許可します。 したがって、 この Boolean を有効にすることで NFS でマウントしたファイルシステムをvsftpd
で共有することができるようになります。 ftp_home_dir
- この Boolean を有効にすると、 認証ユーザーによるユーザーのホームディレクトリ内のファイルの読み取りと書き込みを許可します。 この Boolean をオフにした場合、 ホームディレクトリからファイルをダウンロードしようとすると
550 Failed to open file
などのエラーが発生します。 SELinux 拒否がログ記録されます。 ftpd_connect_db
- FTP デーモンによるデータベースへの接続開始を許可します。
httpd_enable_ftp_server
httpd
による FTP ポートでのリッスンおよび FTP サーバーとしての動作を許可します。tftp_anon_write
- この Boolean を有効にすると、 特殊なアクセス制限がなく共通ファイル用に予約されている領域など、パブリックディレクトリへの TFTP によるアクセスが許可されます。
5.4. 設定例
5.4.1. FTP サイトにアップロードする
特定のユーザーがファイルのアップロード専用として使用できる FTP サイトを作成している例を示します。 ディレクトリ構造を作成し、 必要となる SELinux 設定の変更を行なっています。
- root ユーザーで
setsebool ftp_home_dir=1
を実行して FTP ホームディレクトリへのアクセスができるようにします。 - root ユーザーで
mkdir -p /myftp/pub
を実行して新規ディレクトリを最上位に作成します。 - Linux ユーザーの書き込みアクセスを許可するため、
/myftp/pub/
ディレクトリで Linux パーミッションの設定を行ないます。以下の例では、所有者とグループを root から所有者 user1 とグループ root に変更します。書き込みアクセスを与えたいユーザーを「user1」の部分に入れてください。# chown user1:root /myftp/pub # chmod 775 /myftp/pub
chown
コマンドで所有者とグループのパーミッションを変更しています。chmod
コマンドではモードを変更し、user1 ユーザーには読み取り、書き込み、実行のパーミッションを許可、root グループのメンバーには読み取り、書き込み、実行のパーミッションを許可しています。これ以外のユーザーには読み取りと実行のパーミッションを許可しています。このディレクトリ配下にあるファイルの読み込みを Apache HTTP Server に許可する必要があります。 - SELinux を実行する場合は、ファイルやディレクトリにアクセス許可のラベルを適切に付ける必要があります。Linux パーミッションの設定だけでは不十分です。ファイルに
public_content_t
タイプのラベルが付いている場合は、FTP、Apache HTTP Server、Samba による読み込みおよび再同期が可能です。ファイルにpublic_content_rw_t
タイプのラベルが付いている場合は、FTP による書き込みが可能です。 Samba など FTP 以外のサービスによるpublic_content_rw_t
タイプのラベルが付いているファイルへの書き込みについては、書き込みを行なう前にまず Boolean を設定しておく必要があります。最上位のディレクトリ (/myftp/
) にpublic_content_t
タイプのラベルを付け、/myftp/
配下にコピーまたは新規作成されたファイルに対してサービスによる書き込みや変更が行なわれないようにします。root ユーザーで次のコマンドを実行し、ラベルの変更をファイルコンテキスト設定に追加します。semanage fcontext -a -t public_content_t /myftp
restorecon -R -v /myftp/
を実行してラベルの変更を適用します。# restorecon -R -v /myftp/ restorecon reset /myftp context unconfined_u:object_r:default_t:s0->system_u:object_r:public_content_t:s0
/myftp
にはpublic_content_t
タイプのラベル、/myftp/pub/
にはdefault_t
タイプのラベルが付いているか確認します。$ ls -dZ /myftp/ drwxr-xr-x. root root system_u:object_r:public_content_t:s0 /myftp/ $ ls -dZ /myftp/pub/ drwxrwxr-x. user1 root unconfined_u:object_r:default_t:s0 /myftp/pub/
- ユーザーが FTP 経由でファイルをアップロードできるようにするため、 まず先に FTP にディレクトリへの書き込みを許可する必要があります。 SELinux で FTP に書き込みを許可しているのは、
public_content_rw_t
タイプのラベルが付いたディレクトリです。ここでは、FTP に書き込みを許可するディレクトリとして/myftp/pub/
を使用しています。root ユーザーで次のコマンドを実行し、ラベルの変更をファイルコンテキスト設定に追加します。semanage fcontext -a -t public_content_rw_t "/myftp/pub(/.*)?"
- root ユーザーで
restorecon -R -v /myftp/pub
を実行してラベルの変更を適用します。# restorecon -R -v /myftp/pub restorecon reset /myftp/pub context system_u:object_r:default_t:s0->system_u:object_r:public_content_rw_t:s0
allow_ftpd_anon_write
Boolean をオンにして、vsftpd
によるpublic_content_rw_t
タイプのラベルが付いたファイルへの書き込みを許可する必要があります。root ユーザーで次のコマンドを実行し、この Boolean をオンにします。setsebool -P allow_ftpd_anon_write on
再起動後、 変更を維持したくない場合は-P
オプションを使用しないでください。
FTP でログインしてからファイルをアップロードする例を以下に示します。 ユーザーは前述の例と同じ user1 ユーザーを使用しています。
/myftp/pub/
ディレクトリは user1 が専用所有者となるディレクトリです。
cd ~/
を実行してホームディレクトリに移動します。 次に、mkdir myftp
を実行して FTP 経由でアップロードするファイルを格納するディレクトリを作成します。cd ~/myftp
を実行して~/myftp/
ディレクトリに移動します。 このディレクトリ内にftpupload
ファイルを作成します。 以下の内容をこのファイルにコピーします。File upload via FTP from a home directory.
getsebool allow_ftpd_anon_write
を実行して、allow_ftpd_anon_write
Boolean がオンになっているか確認します。$ getsebool allow_ftpd_anon_write allow_ftpd_anon_write --> on
この Boolean がオフになっている場合は、 root ユーザーでsetsebool -P allow_ftpd_anon_write on
を実行し Boolean をオンにします。 再起動後、 変更を維持したくない場合は-P
オプションを使用しないでください。- root ユーザーで
service vsftpd start
を実行し、vsftpd
を起動します。# service vsftpd start Starting vsftpd for vsftpd: [ OK ]
ftp localhost
を実行します。 ユーザー名の入力が求められたら、 書き込みアクセスを持っているユーザーのユーザー名を入力し、 そのユーザーの正しいパスワードを入力します。$ ftp localhost Connected to localhost (127.0.0.1). 220 (vsFTPd 2.1.0) Name (localhost:username): 331 Please specify the password. Password: Enter the correct password 230 Login successful. Remote system type is UNIX. Using binary mode to transfer files. ftp> cd myftp 250 Directory successfully changed. ftp> put ftpupload local: ftpupload remote: ftpupload 227 Entering Passive Mode (127,0,0,1,241,41). 150 Ok to send data. 226 File receive OK. ftp> 221 Goodbye.
allow_ftpd_anon_write
Boolean が有効になっているためアップロードが成功します。
第6章 ネットワークファイルシステム
Red Hat Linux リファレンスガイド より抜粋:
NFS (Network File System) を利用すると、 ホストはリモートのシステム上にあるパーティションをマウントし、 ローカルのファイルシステムと同じように使用することができるようになります。 これにより、 管理者側はリソースをネットワーク上の一元的な場所に格納し、 認証ユーザーに安定したリソースアクセスを提供できるようになります。
Red Hat Enterprise Linux では、 NFS に完全対応させる場合は nfs-utils が必要になります。
rpm -q nfs-utils
を実行して nfs-utils がインストールされているか確認してください。NFS を使用する予定にも関わらず、このパッケージがインストールされていない場合は、root ユーザーで次のコマンドを実行してパッケージのインストールを行ないます。
yum install nfs-utils
6.1. NFS と SELinux
SELinux を実行すると、
NFS
デーモンはデフォルトで制限されます。SELinux ポリシーにより、NFS によるファイル共有はデフォルトで許可されます。
6.2. タイプ
デフォルトでは、 クライアント側にマウントした NFS ファイルシステムには、 ポリシーで定義された NFS ファイルシステム用デフォルトコンテキストのラベルが付けられます。一般的なポリシーであれば、このデフォルトのコンテキストには
nfs_t
タイプが使用されます。NFS では次のようなタイプが使用されます。タイプに応じて柔軟なアクセス設定ができます。
var_lib_nfs_t
- このタイプは、
/var/lib/nfs
ディレクトリ内の既存ファイルおよびこのディレクトリにコピーまたは作成される新規ファイルに対して使用されます。通常の操作では、このタイプは変更する必要はありません。加えられた変更をデフォルトの設定に復元する場合は、root ユーザーでrestorecon -R -v /var/lib/nfs
コマンドを実行します。 nfsd_exec_t
/usr/sbin/rpc.nfsd
ファイルには、nfsd_exec_t
のラベルが付けられます。これ以外、NFS 関連の実行可能なシステムファイルやライブラリも同様にこのタイプのラベルが付けられます。ユーザーがファイルのラベル付けを行なう際は、このタイプは使用しないでください。nfsd_exec_t
はnfsd_t
に遷移します。
6.3. Boolean
SELinux は実行するサービスに必要な最小限レベルのアクセスに基づいています。サービスの実行手段は複数あるため、サービスをどのように実行するのかを SELinux に指示する必要があります。 次の Boolean を使って NFS の動作方法を SELinux に指示します。
allow_ftpd_use_nfs
- この Boolean を有効にすると、
ftpd
による NFS マウントへのアクセスを許可します。 allow_nfsd_anon_write
- この Boolean を有効にすると、特殊なアクセス制限がなく共通ファイル用に予約されている領域など、パブリックディレクトリへの
nfsd
による anonymous の書き込みが許可されます。 httpd_use_nfs
- この Boolean を有効にすると、NFS ファイルシステム上に格納されたファイルへの
httpd
によるアクセスを許可します。 nfs_export_all_ro
- ファイルやディレクトリのエクスポートはすべて NFS 経由で行い、読み取り専用パーミッションを与えます。
nfs_export_all_rw
- ファイルやディレクトリのエクスポートはすべて NFS 経由で行い、読み取りと書き込みのパーミッションを与えます。
qemu_use_nfs
- qemu による NFS ファイルシステムの使用を許可します。
samba_share_nfs
- この Boolean を無効にすることで、
smbd
には Samba を介した NFS 共有へのフルアクセスを与えないようにします。この Boolean を有効にすると、Samba による NFS ファイルシステムの共有が許可されます。 use_nfs_home_dirs
- この Boolean を有効にすると、NFS ホームディレクトリのサポートが有効になります。
virt_use_nfs
- 仮想マシンによる NFS ファイルへのアクセスを許可します。
xen_use_nfs
- Xen による NFS ファイルの使用を許可します。
6.4. 設定例
6.4.1. NFS を使ってディレクトリを共有する
NFS と SELinux を使ったディレクトリの作成と共有の例を示します。 2 台のホストを使用しています。 ホスト名が
nfs-srv
で IP アドレスが 192.168.1.1
の NFS サーバーと、 ホスト名が nfs-client
で IP アドレスが 192.168.1.100
のクライアントです。 いずれのホストも同じサブネット (192.168.1.0/24) 上にあります。これは一例に過ぎません。 また、 nfs-utils パッケージがインストールされていること、 SELinux targeted ポリシーを使用していること、 SELinux は enforced モードで実行していることを前提としています。
NFS を介した全ユーザーへのアクセスが Linux ファイルパーミッションで与えられ、 ネットワークへのアクセスにも制限がない状態であっても、 SELinux の Boolean を使って適切なパーミッションを与えない限り、 SELinux で NFS ファイルシステムがマウントされないよう防ぐことができます。
6.4.1.1. サーバーのセットアップ
次のステップ 1 からステップ 10 までは NFS サーバー
nfs-srv
で行なってください。
setsebool
コマンドを実行し、 NFS ファイルシステムの読み取りと書き込みでのマウントを無効にします。setsebool -P nfs_export_all_rw off
注記
再起動後、setsebool
による変更を維持したくない場合は-P
オプションを使用しないでください。rpm -q nfs-utils
を実行して、 nfs-utils パッケージがインストールされているか確認します。 nfs-utils パッケージにより NFSを使用するためのサポートプログラムが提供されるため、 このパッケージは NFS サーバーおよび使用中のすべてのクライアントにインストールしてください。 このパッケージがインストールされていない場合は、 root ユーザーでyum install nfs-utils
を実行してインストールしてください。- root で
mkdir /myshare
を実行して、 NFS を使って共有するディレクトリを最上位に新規作成します。 - root ユーザーで
touch /myshare/file1
を実行して共有エリア内に新規で空のファイルを作成します。 このファイルがクライアントによってアクセスされることになるファイルになります。 - 全ユーザーへのアクセスが Linux パーミッションにより完全に与えられていても、 SELinux でアクセスをブロックすることができることを確認するため、
/myshare
ディレクトリに誰でもアクセスできる Linux のフルアクセス権限を与えます。# chmod -R 777 /myshare
警告
これは説明を目的とした用例に過ぎません。 実稼働のシステムにはここで示すパーミッションを使用しないでください。 /etc/exports
ファイルを編集して、 次の行をファイルの先頭に追加します。/myshare 192.168.1.100(rw)
このエントリでは、サーバー上の共有フォルダ/myshare
へのフルパス、nfs-srv
が共有するホストやネットワークの範囲 (この例の場合は単一ホストnfs-client
の IP アドレス192.168.1.100
)、共有パーミッションを示しています。ここでは(rw)
でわかるように、読み取りと書き込みのパーミッションが与えられています。- NFS に使用する TCP と UDP のポートが rpcbind により動的に割り当てられますが、ファイアウォールルールを作成する際、これが問題となる場合があります。この例では、 NFS トラフィックがファイアウォールを通過できるようにするプロセスを簡略化するため、/etc/sysconfig/nfs ファイルを編集して、
MOUNTD_PORT
、STATD_PORT
、LOCKD_TCPPORT
、LOCKD_UDPPORT
の変数をすべてアンコメントします。ここではファイル内のポート番号の変更は必要ありません。着信接続がサーバーのファイアウォールを必ず通過できるようにしておきます。system-config-firewall ツールを使って行ないます。- NFS 用 TCP および UDP ポートの 2049
- TCP および UDP ポートの 111 (rpcbind/sunrpc)
MOUNTD_PORT="port"
オプションで指定された TCP および UDP ポートSTATD_PORT="port"
オプションで指定された TCP および UDP ポートLOCKD_TCPPORT="port"
オプションで指定された TCP ポートLOCKD_UDPPORT="port"
オプションで指定された UDP ポート
- root ユーザーで
service nfs start
を実行して、 NFS および関連サービスを起動させます。# service nfs start Starting NFS services: [ OK ] Starting NFS quotas: [ OK ] Starting NFS daemon: [ OK ] Starting NFS mountd: [ OK ]
- root で
exportfs -rv
を実行し、 NFS サブシステムのエクスポートテーブルを必ず更新させます。# exportfs -rv exporting 192.168.1.100:/myshare
- root ユーザーで
showmount -e
を実行し、 エクスポートされたファイルシステムをすべて表示させます。# showmount -e Export list for nfs-srv: /myshare 192.168.1.100
これで、 サーバー
nfs-srv
は 192.168.1.100
での nfs-client
との NFS 通信が許可されるよう設定され、 Linux ファイルシステムの全権限が有効にされました。 SELinux を無効にすると、 クライアントによるこの共有のマウントおよびフルアクセスが可能になります。 しかし、 nfs_export_all_rw
Boolean を無効にしているため、 以下の出力で示すように、 クライアントは現在、 このファイルシステムをマウントすることができません。 このステップはクライアント側 (nfs-client
) で行なってください。
[nfs-client]# mkdir /myshare [nfs-client]# mount.nfs 192.168.1.1:/myshare /myshare mount.nfs: access denied by server while mounting 192.168.1.1:/myshare/
前述のステップ 1 で無効にした SELinux Boolean を有効にすると、 クライアント側で共有ファイルシステムのマウントが行なえるようになります。 このステップは NFS サーバー
nfs-srv
で行なってください。
[nfs-srv]# setsebool -P nfs_export_all_rw on
NFS デーモンを再起動します。
[nfs-srv]# service nfs restart
ここでもう一度 NFS ファイルシステムをマウントしてみます。 このステップは NFS クライアント
nfs-client
で行なってください。
[nfs-client]# mount.nfs 192.168.1.1:/myshare /myshare [nfs-client]# [nfs-client]# ls /myshare total 0 -rwxrwxrwx. 1 root root 0 2009-04-16 12:07 file1 [nfs-client]#
クライアント側でファイルシステムが正しくマウントされました。 この例でわかるように、 SELinux で防御性を高めることにより、Linux パーミッションでは全ユーザーに完全アクセスが与えられるよう設定されていても、SELinux のパーミッションを強制することができます。
第7章 BIND (Berkeley Internet Name Domain)
BIND では
named
デーモンを使って名前解決サービスを行ないます。 BIND のおかけで、 ユーザーは数値アドレスではなく名前でコンピューターリソースやサービスを検索することができます。
Red Hat Enterprise Linux では、 DNS サーバーは bind パッケージで提供されます。
rpm -q bind
を実行して、 bind パッケージがインストールされているか確認します。 インストールされていない場合は、 root ユーザーで次のコマンドを実行してインストールしてください。
yum install bind
7.1. BIND と SELinux
/var/named/slaves
、/var/named/dynamic
、 /var/named/data
ディレクトリのデフォルトパーミッションでは、 ゾーン転送およびダイナミック DNS 更新によるゾーンファイルの更新が許可されます。 /var/named
内のファイルには named_zone_t
タイプのラベルが付けられ、 マスターゾーンファイルに使用されます。
スレーブサーバーの場合、
/etc/named.conf
でスレーブゾーンを /var/named/slaves
に配置するよう設定します。 以下に、 スレーブ DNS サーバーの /etc/named.conf
内にあるドメインエントリの例を示します。 このスレーブ DNS サーバーは、 /var/named/slaves
内に testdomain.com
用のゾーンファイルを格納しています。
zone "testdomain.com" { type slave; masters { IP-address; }; file "/var/named/slaves/db.testdomain.com"; };
ゾーンファイルに
named_zone_t
のラベルが付けられている場合は、 named_write_master_zones
Boolean を有効にして、 ゾーンファイル更新のためゾーン転送とダイナミック DNS を許可する必要があります。 また、 親ディレクトリのモードを変更し、 named
ユーザーまたはグループに読み取り、 書き込み、 実行のアクセスを許可しなければなりません。
/var/named/
内のゾーンファイルで named_cache_t
タイプのラベルが付いているファイルは、 ファイルシステムの再ラベル付けや restorecon -R /var/
の実行が行なわれると named_zone_t
タイプにラベルが変更されます。
7.2. タイプ
BIND で使用されるタイプを以下に示します。 タイプに応じて柔軟なアクセス設定ができます。
named_zone_t
- マスターゾーンファイルに使用されます。 他のサービスでは、 このタイプのファイルを変更することはできません。このタイプのファイルを変更できるのは
named
のみになります。この場合、named_write_master_zones
Boolean をオンにする必要があります。 named_cache_t
- このタイプのラベルが付いたファイルの場合、特にBoolean を設定しなくてもデフォルトで
named
による書き込みが可能です。/var/named/slaves
、/var/named/dynamic
、/var/named/data
ディレクトリ内にコピーまたは作成されるファイルにはnamed_cache_t
タイプのラベルが自動的に付けられます。 named_var_run_t
/var/run/bind/
、/var/run/named/
、/var/run/unbound/
ディレクトリ内にコピーまたは作成されるファイルには、named_var_run_t
タイプのラベルが自動的に付けられます。named_conf_t
- BIND 関連の設定ファイル (一般的には
/etc/
ディレクトリに格納される) には、named_conf_t
タイプのラベルが自動的に付けられます。 named_exec_t
- BIND 関連の実行可能ファイル (一般的には
/usr/sbin/
ディレクトリに格納される) には、named_exec_t
タイプのラベルが自動的に付けられます。 named_log_t
- BIND 関連のログファイル (一般的には
/var/log/
ディレクトリに格納される) には、named_log_t
タイプのラベルが自動的に付けられます。 named_initrc_exec_t
/etc/rc.d/init.d/
ディレクトリ内にある実行可能な BIND 関連のファイルには、named_initrc_exec_t
タイプのラベルが自動的に付けられます。
7.3. Boolean
SELinux は実行するサービスに必要な最小限レベルのアクセスに基づいています。サービスの実行手段は複数あるため、サービスをどのように実行するのかを SELinux に指示する必要があります。 次の Boolean を使って BIND の動作方法を SELinux に指示します。
named_write_master_zones
- この Boolean を無効にすると、
named
によるnamed_zone_t
タイプのラベルが付いたゾーンファイルやディレクトリへの書き込みが阻止されます。 一般的には、named
はゾーンファイルへの書き込みを必要としません。 ただし、 第 2 サーバーなどがゾーンファイルへの書き込みを必要とする場合には、 この Boolean を有効にして書き込み動作を許可します。
7.4. 設定例
7.4.1. ダイナミック DNS
BIND を使用すると、 ホストがゾーンファイルや DNS 内の記録を動的に更新することができるようになります。 ホストコンピューターの IP アドレスが頻繁に変更され、 DNS レコードでリアルタイムの修正が必要となる場合に BIND を使用します。
ダイナミック DNS で更新させるゾーンファイル用に
/var/named/dynamic
ディレクトリを使用します。 /var/named/dynamic
に作成またはコピーされるファイルは、 named
による書き込みを許可する Linux パーミッションを継承します。また、こうしたファイルには named_cache_t
タイプのラベルが付けられるため、named
による書き込み許可が SELinux により与えられます。
/var/named/dynamic
内のゾーンファイルに named_zone_t
タイプのラベルが付けられている場合、 DNS 更新がマージされる前にまずジャーナルに書き込まれるため、一定の期間 DNS の更新に失敗することがあります。このタイプのラベルが付けられているゾーンファイルでジャーナルに書き込みが行なわれ、そのジャーナルのマージが試行されていると、次のようなエラーがログ記録されます。
named[PID]: dumping master file: rename: /var/named/dynamic/zone-name: permission denied
また、 次のような SELinux 拒否もログ記録されます。
setroubleshoot: SELinux is preventing named (named_t) "unlink" to zone-name (named_zone_t)
このラベル付けに関する問題を解決するには、 Linux root ユーザーで
restorecon -R -v /var/named/dynamic
コマンドを実行します。
第8章 CVS (Concurrent Versioning System)
CVS (Concurrent Versioning System) は、フリーのリビジョンコントロールシステムです。 中央に置かれた複数ファイルのセットに対する変更の監視および追跡に使用します。 一般的に複数のユーザーによってアクセスされます。 ソースコードリポジトリの管理などによく使用され、 オープンソースのプログラマー間では幅広く使用されています。
Red Hat Enterprise Linux では、 CVS は cvs パッケージにより提供されます。
rpm -q cvs
を実行して cvs パッケージがインストールされているか確認します。CVS を使用する予定にも関わらず、このパッケージがインストールされていない場合は、root ユーザーで次のコマンドを実行してパッケージのインストールを行ないます。
yum install cvs
8.1. CVS と SELinux
cvs
は cvs_t
として実行します。 Red Hat Enterprise Linux では、 CVS による読み取りと書き込みが許可されるのは特定のディレクトリに限られます。 cvs
デーモンによる読み取りと書き込みのアクセスが与えられる領域は cvs_data_t
ラベルで定義されます。 SELinux で CVS を使用する場合、 CVS データ用に予約されている領域へのフルアクセスがクライアントに与えられるため、 適切なラベル割り当てが重要になります。
8.2. タイプ
CVS で使用されるタイプを以下に示します。 タイプに応じて柔軟なアクセス設定ができます。
cvs_data_t
- このタイプは CVS リポジトリ内のデータに対して使用されます。 CVS がフルアクセスできるのはこのタイプのデータのみです。
cvs_exec_t
- このタイプは
/usr/bin/cvs
バイナリに対して使用されます。
8.3. Boolean
SELinux は実行するサービスに必要な最小限レベルのアクセスに基づいています。サービスの実行手段は複数あるため、サービスをどのように実行するのかを SELinux に指示する必要があります。 次の Boolean を使って CVS の動作方法を SELinux に指示します。
allow_cvs_read_shadow
- この Boolean を使って
cvs
デーモンによるユーザー認証用/etc/shadow
ファイルへのアクセスを許可します。
8.4. 設定例
8.4.1. CVS のセットアップ
リモートアクセスを許可する SELinux 設定と簡単な CVS セットアップの例を以下に示します。 2 台のホストを使用しています。 ホスト名が
cvs-srv
で IP アドレスが 192.168.1.1
の CVS サーバーと、 ホスト名が cvs-client
で IP アドレスが 192.168.1.100
のクライアントです。 いずれのホストも同じサブネット上にあります (192.168.1.0/24)。 これは一例に過ぎません。 また、 cvs と xinetd パッケージがインストールされていること、 SELinux targeted ポリシーを使用していること、 SELinux は enforced モードで実行していることを前提としています。
DAC の全パーミッションが許可されている場合であっても、 SELinux ではファイルラベルに応じたポリシールールを施行し、 CVS アクセス用のラベルが明確に付けられている特定領域にしかアクセスを許可しないようにすることができます。
注記
ステップ 1 から 9 は CVS サーバー
cvs-srv
で行なってください。
- cvs と xinetd のパッケージが必要になります。
rpm -q cvs
を実行して、 cvs パッケージがインストールされているか確認してください。 インストールされていない場合は、 root ユーザーで次のコマンドを実行し、 cvs をインストールします。# yum install cvs
rpm -q xinetd
を実行して、 xinetd パッケージがインストールされているか確認してください。インストールされていない場合は、 root ユーザーで次のコマンドを実行し xinetd をインストールします。# yum install xinetd
CVS
と言う名前のグループを作成します。 root ユーザーでgroupadd CVS
コマンドを実行するか、 system-config-users ツールを使って行ないます。cvsuser
と言うユーザー名のユーザーを作成し、 このユーザーを CVS グループのメンバーにします。 system-config-users ツールを使って行ないます。/etc/services
ファイルを編集し、 以下のように CVS サーバーのエントリをアンコメントします。cvspserver 2401/tcp # CVS client/server operations cvspserver 2401/udp # CVS client/server operations
- CVS リポジトリをファイルシステムの root 領域に作成します。 SELinux を使用する場合、 リポジトリは root ファイルシステムに配置するのが最適です。 他のサブディレクトリに影響を与えることなく、 再帰的なラベルを与えることができます。 たとえば、 root ユーザーでリポジトリを格納する
/cvs
ディレクトリを作成します。[root@cvs-srv]# mkdir /cvs
- 誰でもアクセスできるよう
/cvs
ディレクトリに全パーミッションを与えます。[root@cvs-srv]# chmod -R 777 /cvs
警告
これは説明を目的とした用例に過ぎません。 実稼働のシステムにはここで示すパーミッションを使用しないでください。 /etc/xinetd.d/cvs
ファイルを編集し、 CVS セクションをアンコメントして/cvs
ディレクトリを使用するよう設定します。 以下のようになるはずです。service cvspserver { disable = no port = 2401 socket_type = stream protocol = tcp wait = no user = root passenv = PATH server = /usr/bin/cvs env = HOME=/cvs server_args = -f --allow-root=/cvs pserver # bind = 127.0.0.1
- root ユーザーで
service xinetd start
を実行し、xinetd
デーモンを起動します。 - system-config-firewall ツールを使って、 ポート 2401 上で TCP を使用した着信接続を許可するルールを追加します。
cvsuser
ユーザーになり、 次のコマンドを実行します。[cvsuser@cvs-client]$ cvs -d /cvs init
- これで CVS は設定されましたが、 SELinux ではログインおよびファイルのアクセスが拒否されます。これを確認するため、
cvs-client
に $CVSROOT 変数をセットして、リモートによるログインを試行してみます。次のステップはcvs-client
で行なってください。[cvsuser@cvs-client]$ export CVSROOT=:pserver:cvsuser@192.168.1.1:/cvs [cvsuser@cvs-client]$ [cvsuser@cvs-client]$ cvs login Logging in to :pserver:cvsuser@192.168.1.1:2401/cvs CVS password: ******** cvs [login aborted]: unrecognized auth response from 192.168.100.1: cvs pserver: cannot open /cvs/CVSROOT/config: Permission denied
SELinux によりアクセスがブロックされました。 SELinux でこのアクセスを許可させるため、 次のステップをcvs-srv
で行なってください。 - 既存のデータおよび新規のデータすべてに再帰的にラベル付けが行なわれるよう、 root ユーザーで
/cvs
ディレクトリのコンテキストを変更しcvs_data_t
タイプを与えます。[root@cvs-srv]# semanage fcontext -a -t cvs_data_t '/cvs(/.*)?' [root@cvs-srv]# restorecon -R -v /cvs
- これで、 クライアント
cvs-client
はログインして、 このリポジトリ内のすべての CVS リソースにアクセスできるようになったはずです。[cvsuser@cvs-client]$ export CVSROOT=:pserver:cvsuser@192.168.1.1:/cvs [cvsuser@cvs-client]$ [cvsuser@cvs-client]$ cvs login Logging in to :pserver:cvsuser@192.168.1.1:2401/cvs CVS password: ******** [cvsuser@cvs-client]$
第9章 Squid キャッシングプロキシ
Squid Caching Proxy プロジェクトページより抜粋:
原文: "Squid is a caching proxy for the Web supporting HTTP, HTTPS, FTP, and more. It reduces bandwidth and improves response times by caching and reusing frequently-requested web pages. Squid has extensive access controls and makes a great server accelerator." (訳文: Squid とは HTTP、 HTTPS、 FTP などに対応する Web 用キャッシングプロキシです。 頻繁に要求される Web ページをキャッシングして再利用することで帯域幅の使用を抑えます。 Squid は豊富なアクセス制御機能が備わっている強力なサーバーアクセラレーターになります。)
Red Hat Enterprise Linux では、 Squid キャッシングプロキシは squid パッケージにより提供されます。
rpm -q squid
を実行して squid パッケージがインストールされているか確認します。squid を使用する予定にも関わらず、このパッケージがインストールされていない場合は、root ユーザーで次のコマンドを実行してパッケージのインストールを行ないます。
# yum install squid
9.1. Squid キャッシングプロキシと SELinux
SELinux を有効にすると、 squid はデフォルトで制限のあるサービスとして実行されます。 制限のあるプロセスはそれ自体のドメイン内で実行され、 他の制限のあるプロセスとは分離されます。 制限のあるプロセスが攻撃を受けると、 SELinux ポリシー設定に応じて、 攻撃側がリソースにアクセスして加えることができる被害は限定されます。 以下に、 squid 自体のドメイン内で実行している squid プロセスの例を示します。 ここでは squid パッケージがインストールされていることを前提としています。
getenforce
を実行して、 SELinux が enforcing モードで実行しているか確認します。$ getenforce Enforcing
SELinux が enforcing モードで実行している場合は、getenforce
コマンドを実行するとEnforcing
が返されます。- root ユーザーで
service squid start
を実行し、squid
を起動します。# service squid start Starting squid: [ OK ]
ps -eZ | grep squid
を実行し、squid
プロセスを表示させます。$ ps -eZ | grep squid unconfined_u:system_r:squid_t:s0 2522 ? 00:00:00 squid unconfined_u:system_r:squid_t:s0 2524 ? 00:00:00 squid unconfined_u:system_r:squid_t:s0 2526 ? 00:00:00 ncsa_auth unconfined_u:system_r:squid_t:s0 2527 ? 00:00:00 ncsa_auth unconfined_u:system_r:squid_t:s0 2528 ? 00:00:00 ncsa_auth unconfined_u:system_r:squid_t:s0 2529 ? 00:00:00 ncsa_auth unconfined_u:system_r:squid_t:s0 2530 ? 00:00:00 ncsa_auth unconfined_u:system_r:squid_t:s0 2531 ? 00:00:00 unlinkd
squid
プロセスに関連する SELinux コンテキストはunconfined_u:system_r:squid_t:s0
です。 コンテキストの最後から 2 番目の部分、squid_t
がタイプになります。 プロセスのドメインやファイルのタイプを定義するのがタイプです。 この例の場合、squid
プロセスはsquid_t
ドメイン内で実行しています。
squid_t
などの制限ドメイン内で実行しているプロセスがファイルや他のプロセス、 システムなどとどのように交信するのかをSELinux ポリシーで定義します。squid によるアクセスを許可するには、 ファイルに適切なラベルを付けを行なう必要があります。
/etc/squid/squid.conf
を設定して、squid
にデフォルトの TCP ポート 3128、3401、4827 以外のポートでリッスンさせる場合は、semanage port
コマンドを使って SELinux ポリシー設定にそのポート番号を追加する必要があります。以下では、SELinux ポリシー設定では最初 squid
用には定義されていなかったポートでリッスンするよう squid
を設定したため、squid
の起動に失敗する例を示します。また、SELinux システムを設定し、ポリシーではまだ定義されていなかった非標準のポートで squid
によるリッスンを許可する方法についても示します。ここでは、squid パッケージがインストールされていることを前提としています。各コマンドは root ユーザーで実行してください。
service squid status
を実行し、squid
が実行中ではないことを確認します。# service squid status squid is stopped
出力が上記と異なる場合は、service squid stop
を実行してプロセスを停止します。# service squid stop Stopping squid: [ OK ]
semanage port -l | grep -w squid_port_t
を実行して、 SELinux でsquid
にリッスンを許可しているポートを表示させます。semanage port -l | grep -w -i squid_port_t squid_port_t tcp 3401, 4827 squid_port_t udp 3401, 4827
- root ユーザーで
/etc/squid/squid.conf
を編集します。SELinux ポリシー設定ではsquid
用に設定していないポートをリッスンするようhttp_port
オプションを設定します。この例では、ポート 10000 でリッスンするようsquid
を設定しています。# Squid normally listens to port 3128 http_port 10000
setsebool
コマンドを実行し、squid_connect_any
Boolean をオフに設定します。 これで、 squid の動作は特定ポート上に限られることになります。setsebool -P squid_connect_any 0
service squid start
を実行し、squid
を起動します。# service squid start Starting squid: .................... [FAILED]
以下のような SELinux 拒否がログ記録されます。localhost setroubleshoot: SELinux is preventing the squid (squid_t) from binding to port 10000. For complete SELinux messages. run sealert -l 97136444-4497-4fff-a7a7-c4d8442db982
squid
によるポート 10000 のリッスンを SELinux で許可するには、例で使用しているものと同じ次のコマンドが必要になります。# semanage port -a -t squid_port_t -p tcp 10000
- もう一度
service squid start
を実行して、squid
を起動させ新しいポートをリッスンするようにします。# service squid start Starting squid: [ OK ]
- これで、
squid
による非標準のポート (この例では TCP 10000) でのリッスンを許可する SELinux 設定が完了しました。squid
はこのポートで正常に起動するようになります。
9.2. タイプ
Type Enforcement が SELinux の targeted ポリシーで使用されるメインのパーミッション制御になります。全ファイルおよびプロセスにタイプのラベルが付けられます。ファイルの場合はタイプ、プロセスの場合はドメインを定義します。任意のタイプにアクセスするドメインなのか、 別のドメインにアクセスするドメインなのかなど、SELinux のポリシールールではタイプによって互いがアクセスしあう方法を定義します。 アクセスを許可する特定の SELinux ポリシールールが存在する場合にのみ、 そのアクセスが許可されます。
squid
で使用されるタイプを以下に示します。 タイプに応じて柔軟なアクセス設定ができます。
httpd_squid_script_exec_t
- このタイプは、
cachemgr.cgi
などのユーティリティに使用されます。 squid とその設定に関するさまざまな統計値を提供します。 squid_cache_t
- このタイプは、
/etc/squid/squid.conf
内のcache_dir
ディレクティブで定義されているように、 squid によってキャッシュされるデータに使用されます。 デフォルトでは、/var/cache/squid
と/var/spool/squid
にコピーまたは作成されるファイルにはsquid_cache_t
タイプのラベルが付けられます。 また、/var/squidGuard
にコピーまたは作成される squidGuard URL リダイレクト用のファイルやsquid
用のプラグインにもsquid_cache_t
タイプのラベルが付けられます。 squid のキャッシュデータ用として使用できるのは、このラベルが付いたファイルやディレクトリのみなります。 squid_conf_t
squid
の設定用に使用されるディレクトリおよびファイルに対して使用されます。エラーメッセージやアイコンなどを含め、/etc/squid
と/usr/share/squid
内に既存するファイルや、 ここに作成またはコピーされるファイルにはこのタイプのラベルが付けられます。squid_exec_t
- このタイプは squid バイナリの
/usr/sbin/squid
に使用されます。 squid_log_t
- このタイプはログに使用されます。
/var/log/squid
または/var/log/squidGuard
内に既存するファイル、 ここに作成またはコピーされるファイルにはこのタイプのラベルを付けなければなりません。 squid_initrc_exec_t
- このタイプは、
squid
の起動に必要となる初期設定ファイルに使用します。初期設定ファイルは/etc/rc.d/init.d/squid
にあります。 squid_var_run_t
- このタイプは
/var/run
内のファイルに使用されます。 特に、 squid の実行時に作成される/var/run/squid.pid
という名前のプロセス ID (PID) にはこのタイプが付けられます。
9.3. Boolean
SELinux は実行するサービスに必要な最小限レベルのアクセスに基づいています。サービスの実行手段は複数あるため、サービスをどのように実行するのかを SELinux に指示する必要があります。 次の Boolean を使って Squid の動作方法を SELinux に指示します。
squid_connect_any
- この Boolean を有効にすると、 ポートを問わず squid によるリモートホストへの接続開始を許可します。
9.4. 設定例
9.4.1. Squid を非標準のポートに接続させる
前述の Boolean を施行し、特定のポートに限ったアクセスをデフォルトで許可することで SELinux が Squid を補完している実践的な例を以下に示します。また、Boolean を変更する方法、およびその変更により許可されるアクセスについても示します。
以下に示す例は、 シンプルな Squid 設定に対してどのように SELinux が影響を与えることができるのかを示す一例に過ぎません。 Squid に関する総合的な説明は本ガイドの範疇を越えてしまいますので、 詳細については、 公式の Squid ドキュメント を参照してください。 ここでは、 Squid ホストにはインターネットアクセスがあり、2 種類のネットワークインターフェースが備わっていることを前提としています。 また、ファイアウォールでは、Squid がリッスンするデフォルトの TCP ポート (TCP 3128) を使った内部インターフェース上のアクセスを許可するよう設定されていることを前提としています。
- root ユーザーになり squid パッケージをインストールします。
rpm -q squid
を実行して squid パッケージがインストールされているか確認します。 インストールされていない場合は、 root ユーザーでyum install squid
を実行しインストールを行ないます。 - メインの設定ファイル
/etc/squid/squid.conf
を編集し、cache_dir
ディレクティブが以下のようにアンコメントされているか確認します。cache_dir ufs /var/spool/squid 100 16 256
上記では、 この設定例で使用するcache_dir
ディレクティブのデフォルト設定を定義しています。 Squid ストレージフォーマット (ufs)、 キャッシュを配置するシステム上のディレクトリ (/var/spool/squid)、 キャッシュに使用するメガバイト単位のディスク領域 (100)、 第一レベルのキャッシュディレクトリ数と第二レベルのキャッシュディレクトリ数 (16 と 256) の設定情報で構成されています。 - 同じ設定ファイル内の
http_access allow localnet
ディレクティブもアンコメントされているか確認してください。 Red Hat Enterprise Linux では、 Squid のデフォルトインストールで自動的に設定されるlocalnet
ACL からのトラフィックを許可します。 既存する RFC1918 ネットワーク上のクライアントマシンにプロキシを通過できるアクセスを許可します (この設定例ではこれで充分です)。 - 同じ設定ファイル内の
visible_hostname
ディレクティブもアンコメントされ、 マシンのホスト名が設定されているか確認してください。 値はホストの完全修飾ドメイン名にします。visible_hostname squid.example.com
- root ユーザーで
service squid start
を実行し、squid
を起動します。 はじめてsquid
を起動すると、 前のステップでcache_dir
ディレクティブに指定したキャッシュディレクトリがこのコマンドにより初期化されてからsquid
デーモンが起動されます。squid
の起動に成功すると、 以下のような出力となります。# /sbin/service squid start init_cache_dir /var/spool/squid... Starting squid: . [ OK ]
squid
プロセス ID (PID) が制限のあるサービスとして起動されているか確認します。この例ではsquid_var_run_t
の値で確認します。# ls -lZ /var/run/squid.pid -rw-r--r--. root squid unconfined_u:object_r:squid_var_run_t:s0 /var/run/squid.pid
- この時点で、前に設定していた
localnet
ACL に接続しているクライアントマシンは、そのプロキシとしてこのホストの内部インターフェースを使用できるようになります。これはシステム全体または一般的な全 Web ブラウザのセッティングで設定することができます。これで Squid では目的のマシンのデフォルトポートでリッスンするようになりますが (TCP 3128)、目的のマシンで許可されるのは、一般的なポートを介したインターネット上の他のサービスへの発信接続のみになります。これが SELinux 自体で定義されているポリシーになります。SELinux では、次のステップで示すように非標準のポートへのアクセスは拒否されます。 - TCP ポート 10000 での web サイトのリスニングなど、 Squid プロキシを介し非標準のポートを使った要求がクライアントによって行なわれると、 次のような拒否がログ記録されます。
SELinux is preventing the squid daemon from connecting to network port 10000
- このアクセスを許可する場合は、 デフォルトでは無効になっている
squid_connect_any
Boolean を変更する必要があります。squid_connect_any
Boolean をオンにするには、 root ユーザーで次のコマンドを実行します。# setsebool -P squid_connect_any on
注記
再起動後、setsebool
による変更を維持したくない場合は-P
オプションを使用しないでください。 - クライアントの代わりとして、いずれのポートでも Squid による接続の開始が許可されるようになるため、 クライアントはインターネット上の非標準のポートにアクセスできるようになります。
第10章 MySQL
MySQL プロジェクトページより抜粋:
原文: "The MySQL® database has become the world's most popular open source database because of its consistent fast performance, high reliability and ease of use. It's used on every continent -- Yes, even Antarctica! -- by individual Web developers as well as many of the world's largest and fastest-growing organizations to save time and money powering their high-volume Web sites, business-critical systems and packaged software -- including industry leaders such as Yahoo!, Alcatel-Lucent, Google, Nokia, YouTube, and Zappos.com." (訳文: 安定した高速パフォーマンス、高い信頼性、 そしてその使いやすさで、 MySQL® データベースは世界でもっともポピュラーなオープンソースのデータベースとなりました。すべての大陸で (南極大陸をも含め!)、web 開発者そして急速な成長を遂げている世界でも有数の企業の多くにより (Yahoo、Alcatel-Lucent、Google、Nokia、YouTube、Zappos.com など) 、時間的、金銭的な効率性を高めながら大量の web サイト、ビジネスに不可欠なシステム、パッケージ化されたソフトウェアなどを供給するために利用されています。)
Red Hat Enterprise Linux では、 MySQL は mysql-server パッケージで提供されます。
rpm -q mysql-server
を実行して、 mysql-server パッケージがインストールされているか確認してください。 インストールされていない場合は、 root ユーザーで次のコマンドを実行してインストールを行ないます。
yum install mysql-server
10.1. MySQL と SELinux
MySQL を有効にすると、 デフォルトで制限のあるサービスとして実行されます。 制限のあるプロセスはそれ自体のドメイン内で実行され、 他の制限のあるプロセスとは分離されます。 制限のあるプロセスが攻撃を受けると、 SELinux ポリシー設定に応じて、 攻撃側がリソースにアクセスして加えることができる被害は限定されます。 以下に、 MySQL 自体のドメイン内で実行している MySQL プロセスの例を示します。 ここでは mysql パッケージがインストールされていることを前提としています。
getenforce
を実行して、 SELinux が enforcing モードで実行していることを確認します。$ getenforce Enforcing
SELinux が enforcing モードで実行している場合は、getenforce
コマンドを実行するとEnforcing
が返されます。- root ユーザーで
service mysqld start
を実行し、mysqld
を起動します。# service mysqld start Initializing MySQL database: Installing MySQL system tables... [ OK ] Starting MySQL: [ OK ]
ps -eZ | grep mysqld
を実行し、mysqld
プロセスを表示させます。$ ps -eZ | grep mysqld unconfined_u:system_r:mysqld_safe_t:s0 6035 pts/1 00:00:00 mysqld_safe unconfined_u:system_r:mysqld_t:s0 6123 pts/1 00:00:00 mysqld
mysqld
プロセスに関連する SELinux コンテキストはunconfined_u:system_r:mysqld_t:s0
です。 コンテキストの最後から 2 番目の部分、mysqld_t
がタイプになります。 プロセスのドメインやファイルのタイプを定義するのがタイプです。 この例の場合、mysqld
プロセスはmysqld_t
ドメイン内で実行しています。
10.2. タイプ
Type Enforcement が SELinux の targeted ポリシーで使用されるメインのパーミッション制御になります。全ファイルおよびプロセスにタイプのラベルが付けられます。ファイルの場合はタイプ、プロセスの場合はドメインを定義します。任意のタイプにアクセスするドメインなのか、 別のドメインにアクセスするドメインなのかなど、SELinux のポリシールールではタイプによって互いがアクセスしあう方法を定義します。 アクセスを許可する特定の SELinux ポリシールールが存在する場合にのみ、 そのアクセスが許可されます。
mysqld
で使用されるタイプを以下に示します。 タイプに応じて柔軟なアクセス設定ができます。
mysqld_db_t
- このタイプは MySQL データベースの場所に使用します。 Red Hat Enterprise Linux では、 データベースのデフォルトの場所は
/var/lib/mysql
になりますが、 この場所は変更することができます。 MySQL データベース用の場所を変更する場合は、 新しい場所にこのタイプのラベルを付ける必要があります。 デフォルトのデータベースの場所を変更する方法、 新しいセクションに適切にラベル付けを行なう方法について以下の例で説明していきます。 mysqld_etc_t
- このタイプは、 MySQL のメイン設定ファイル
/etc/my.cnf
および/etc/mysql
ディレクトリにある他の設定ファイルすべてに使用されます。 mysqld_exec_t
- このタイプは
/usr/libexec/mysqld
にあるmysqld
バイナリに使用されます。 Red Hat Enterprise Linux では MySQL バイナリのデフォルトの場所になります。 他のシステムでは、 このバイナリは/usr/sbin/mysqld
に配置されることがあります。 この場合にもこのタイプのラベルを付けるようにしてください。 mysqld_initrc_exec_t
- このタイプは、 Red Hat Enterprise Linux ではデフォルトで
/etc/rc.d/init.d/mysqld
に配置されている MySQL の初期設定ファイルに使用されます。 mysqld_log_t
- 正常に動作させるため、 MySQL のログにはこのタイプのラベルを付ける必要があります。
/var/log/
内にあるログファイルで、mysql.*
のワイルドカードに一致するログファイルはすべて、このタイプのラベルを付ける必要があります。 mysqld_var_run_t
- このタイプは
/var/run/mysqld
内のファイルで使用されます。特に、mysqld
デーモンの実行時に作成される/var/run/mysqld/mysqld.pid
と言う名前のプロセス ID (PID) に使用されます。また、/var/lib/mysql/mysql.sock
などの関連ソケットファイルにも使用されます。このようなファイルには、 制限のあるサービスとして正常に動作させるため適切なラベル付けが必要になります。
10.3. Boolean
SELinux は実行するサービスに必要な最小限レベルのアクセスに基づいています。サービスの実行手段は複数あるため、サービスをどのように実行するのかを SELinux に指示する必要があります。 次の Boolean を使って MySQL の動作方法を SELinux に指示します。
allow_user_mysql_connect
- この Boolean を有効にすると、 ユーザーによる MySQL への接続が可能になります。
exim_can_connect_db
- この Boolean を有効にすると、
exim
メーラーによるデータベースサーバーへの接続開始を許可します。 ftpd_connect_db
- この Boolean を有効にすると、
ftp
デーモンによるデータベースサーバーへの接続開始を許可します。 httpd_can_network_connect_db
- この Boolean を有効にすると、 データベースサーバーとの通信に web サーバーが必要になります。
10.4. 設定例
10.4.1. MySQL のデータベース格納場所を変更する
Red Hat Enterprise Linux 6 を使用する場合、MySQL のデフォルトのデータベース格納場所は
/var/lib/mysql
になります。この場所は SELinux でデータベースが配置される場所として期待される場所となるため、この領域にはすでに mysqld_db_t
タイプを使った適切なラベル付けが行なわれています。
データベースを格納する場所は、それぞれの環境要件や設定に応じて変更することもできますが、SELinux に変更後の新しい場所を認識させる、つまりラベル付けを行なうことが重要となります。MySQL データベースの格納場所を変更する方法、また SELinux によるコンテンツに応じた保護メカニズムを新しい格納場所にも適用できるようラベル付けを行なう方法を以下の例で説明していきます。
以下に示す例は、MySQL に対してどのように SELinux が影響を与えることができるのかを示す一例に過ぎません。MySQL に関する総合的な説明は本ガイドの範疇を越えてしまいますので、詳細については、公式の MySQL ドキュメント を参照してください。ここでは、mysql-server パッケージと setroubleshoot-server パッケージがインストールされていること、
auditd
サービスが実行されていること、有効なデータベースがデフォルトの場所である /var/lib/mysql
にあることを前提としています。
ls -lZ /var/lib/mysql
を実行し、mysql
デフォルトデータベース格納場所の SELinux コンテキストを表示させます。# ls -lZ /var/lib/mysql drwx------. mysql mysql unconfined_u:object_r:mysqld_db_t:s0 mysql
データベースファイルの格納場所にデフォルトで付けられるコンテキストエレメントのmysqld_db_t
が表示されています。本例で使用する新しいデータベース格納場所が期待通り正常に動作するよう、このコンテキストをその新しい場所に手作業で適用する必要があります。mysqlshow -u root -p
を入力し、使用できるデータベースを表示させるためmysqld
の root パスワードを入力します。# mysqlshow -u root -p Enter password: ******* +--------------------+ | Databases | +--------------------+ | information_schema | | mysql | | test | | wikidb | +--------------------+
- root ユーザーで
service mysqld stop
を実行し、mysqld
デーモンをシャットダウンさせます。# service mysqld stop Stopping MySQL: [ OK ]
- データベース格納場所となるディレクトリを新規作成します。この例では
/mysql
を使用しています。# mkdir -p /mysql
- 古い場所にあるデータベースファイルを新しい場所にコピーします。
# cp -R /var/lib/mysql/* /mysql/
- mysql ユーザーおよび mysql グループによるアクセスを許可するため所有権を変更します。この変更は従来の Unix パーミッションに対する変更であり、SELinux による制限はそのまま変更されていません。
# chown -R mysql:mysql /mysql
ls -lZ /opt
を実行し、新規ディレクトリの初期コンテキストを表示してみます。# ls -lZ /opt drwxr-xr-x. mysql mysql unconfined_u:object_r:usr_t:s0 mysql
コンテキストusr_t
は、現在、MySQL データベースファイルの格納場所として適したタイプではありません。コンテキストを変更すると、MySQL がこの場所で正しく動作できるようになります。- MySQL のメインとなる設定ファイル
/etc/my.cnf
をテキストエディターで開き、新しい格納場所を参照するようdatadir
オプションを編集します。この例の場合なら、新しい格納場所として入力するのは/mysql
になります。[mysqld] datadir=/mysql
このファイルを保存してから終了します。 - root ユーザーで
service mysqld start
を実行し、mysqld
を起動します。サービスの起動は失敗し、/var/log/messages
ファイルに拒否のログが記録されます。ただし、audit
デーモンおよびsetroubleshoot
サービスが実行されている場合は、/var/log/audit/audit.log
ファイルの方に拒否のログが記録されます。SELinux is preventing /usr/libexec/mysqld "write" access on /mysql. For complete SELinux messages. run sealert -l b3f01aff-7fa6-4ebe-ad46-abaef6f8ad71
拒否の理由は、/mysql
が MySQL データファイル用として適切なラベルが付けられていないためです。SELinux で、MySQL によるusr_t
タイプのラベルが付いたコンテンツへのアクセスが阻止されています。この問題を解決するため次の手順を行なってください。 - 次の
semanage
コマンドを実行し、/mysql
のコンテキストマッピングを追加します。semanage
はデフォルトではインストールされていないため注意してください。インストールされていない場合は、policycoreutils-python パッケージをインストールします。semanage fcontext -a -t mysqld_db_t "/mysql(/.*)?"
- このマッピングは
/etc/selinux/targeted/contexts/files/file_contexts.local
ファイルに書き込まれます。# grep -i mysql /etc/selinux/targeted/contexts/files/file_contexts.local /mysql(/.*)? system_u:object_r:mysqld_db_t:s0
restorecon
コマンドを使ってこのコンテキストマッピングを実行中のシステムに適用します。restorecon -R -v /mysql
- これで
/mysql
のデータ格納場所に MySQL 用の正しいコンテキストがラベル付けされました。mysqld
デーモンを起動します。# service mysqld start Starting MySQL: [ OK ]
- コンテキストが確かに
/mysql
用に正しく変更されているか確認します。ls -lZ /opt drwxr-xr-x. mysql mysql system_u:object_r:mysqld_db_t:s0 mysql
- データ格納場所の変更そしてラベル付けが正しく行なわれたため、
mysqld
デーモンが正常に起動するようになりました。ここまでの設定が完了したら、実行中の全サービスが正常に動作しているか確認テストを行なってください。
第11章 PostgreSQL
PostgreSQL プロジェクトページより抜粋:
原文: "PostgreSQL is a powerful, open source object-relational database system. It has more than 15 years of active development and a proven architecture that has earned it a strong reputation for reliability, data integrity, and correctness." (訳文: PostgreSQL はオープンソースでありパワフルなオブジェクト関係データベースシステムになります。15年以上に渡り活発な開発が行なわれ、信頼性、データ整合性、正確性に強化な評判を得ている実績のあるアーキテクチャを提供しています。)
Red Hat Enterprise Linux 6 では、PostgreSQL は postgresql-server パッケージで提供されます。
rpm -q postgresql-server
を実行して、postgresql-server パッケージがインストールされているか確認してください。インストールされていない場合は、root ユーザーで次のコマンドを実行してインストールを行ないます。
yum install postgresql-server
11.1. PostgreSQL と SELinux
PostgreSQL を有効にすると、デフォルトで制限のあるサービスとして実行されます。制限のあるプロセスはそれ自体のドメイン内で実行され、他の制限のあるプロセスとは分離されます。制限のあるプロセスが攻撃を受けると、SELinux ポリシー設定に応じて、攻撃側がリソースにアクセスして加えることができる被害は限定されます。以下に、PostgreSQL 自体のドメイン内で実行している PostgreSQL プロセスの例を示します。 ここでは postgresql-server パッケージがインストールされていることを前提としています。
getenforce
を実行して、SELinux が enforcing モードで実行しているか確認します。$ getenforce Enforcing
SELinux が enforcing モードで実行している場合は、getenforce
コマンドを実行するとEnforcing
が返されます。- root ユーザーで
service postgresql start
を実行し、postgresql
を起動します。service postgresql start Starting postgresql service: [ OK ]
ps -eZ | grep postgres
を実行して、postgresql
プロセスを表示させます。ps -eZ | grep postgres unconfined_u:system_r:postgresql_t:s0 395 ? 00:00:00 postmaster unconfined_u:system_r:postgresql_t:s0 397 ? 00:00:00 postmaster unconfined_u:system_r:postgresql_t:s0 399 ? 00:00:00 postmaster unconfined_u:system_r:postgresql_t:s0 400 ? 00:00:00 postmaster unconfined_u:system_r:postgresql_t:s0 401 ? 00:00:00 postmaster unconfined_u:system_r:postgresql_t:s0 402 ? 00:00:00 postmaster
postgresql
プロセスに関連する SELinux コンテキストはunconfined_u:system_r:postgresql_t:s0
です。コンテキストの最後から 2 番目の部分、postgresql_t
がタイプになります。プロセスのドメインやファイルのタイプを定義するのがタイプです。この例の場合、postgresql
プロセスはpostgresql_t
ドメイン内で実行しています。
11.2. タイプ
Type Enforcement が SELinux の targeted ポリシーで使用されるメインのパーミッション制御になります。全ファイルおよびプロセスにタイプのラベルが付けられます。ファイルの場合はタイプ、プロセスの場合はドメインを定義します。任意のタイプにアクセスするドメインなのか、 別のドメインにアクセスするドメインなのかなど、SELinux のポリシールールではタイプによって互いがアクセスしあう方法を定義します。アクセスを許可する特定の SELinux ポリシールールが存在する場合にのみ、そのアクセスが許可されます。
postgresql
で使用されるタイプを以下に示します。タイプに応じて柔軟なアクセス設定ができます。
postgresql_db_t
- このタイプは複数の場所で使用されます。このタイプでラベル付けされた場所は PostgreSQL のデータファイル用に使用されます。
/usr/lib/pgsql/test/regres
/usr/share/jonas/pgsql
/var/lib/pgsql/data
/var/lib/postgres(ql)?
postgresql_etc_t
- このタイプは
/etc/postgresql
内の設定ファイルに使用されます。 postgresql_exec_t
- このタイプは複数の場所で使用されます。このタイプでラベル付けされた場所は PostgreSQL のバイナリに使用されます。
/usr/bin/initdb(.sepgsql)?
/usr/bin/(se)?postgres
/usr/lib(64)?/postgresql/bin/.*
/usr/lib/phsql/test/regress/pg_regress
postgresql_initrc_exec_t
- このタイプは
/etc/rc.d/init.d/postgresql
にある PostgreSQL 初期設定ファイルに使用されます。 postgresql_log_t
- このタイプは複数の場所で使用されます。このタイプでラベル付けされた場所はログファイルに使用されます。
/var/lib/pgsql/logfile
/var/lib/pgsql/pgstartup.log
/var/lib/sepgsql/pgstartup.log
/var/log/postgresql
/var/log/postgres.log.*
/var/log/rhdb/rhdb
/var/log/sepostgresql.log.*
postgresql_var_run_t
- このタイプは、
/var/run/postgresql
内のプロセス ID (PID) など PostgreSQL のランタイムファイルに使用されます。
11.3. Boolean
SELinux は実行するサービスに必要な最小限レベルのアクセスに基づいています。サービスの実行手段は複数あるため、サービスをどのように実行するのかを SELinux に指示する必要があります。 次の Boolean を使って PostgreSQL の動作方法を SELinux に指示します。
allow_user_postgresql_connect
- この Boolean を有効にすると、いずれのユーザードメイン (PostgreSQL の定義) からのデータサーバーへの接続も許可します。
11.4. 設定例
11.4.1. PostgreSQL のデータベース格納場所を変更する
Red Hat Enterprise Linux 6 を使用する場合、PostgreSQL のデフォルトのデータベース格納場所は
/var/lib/pgsql/data
になります。この場所は SELinux でデータベースが配置される場所として期待される場所となるため、この領域にはすでに postgresql_db_t
タイプを使った適切なラベル付けが行なわれています。
データベースを格納する場所は、それぞれの環境要件や設定に応じて変更することもできますが、SELinux に変更後の新しい場所を認識させる、つまりラベル付けを行なうことが重要となります。PostgreSQL データベースの格納場所を変更する方法、また SELinux によるコンテンツに応じた保護メカニズムを新しい格納場所にも適用できるようラベル付けを行なう方法を以下の例で説明していきます。
以下に示す例は、PostgreSQL に対してどのように SELinux が影響を与えることができるのかを示す一例に過ぎません。PostgreSQL に関する総合的な説明は本ガイドの範疇を越えてしまいますので、詳細については、公式の PostgreSQL ドキュメント を参照してください。ここでは、postgresql-server パッケージがインストールされていることを前提としています。
ls -lZ /var/lib/pgsql
を実行し、postgresql
デフォルトデータベース格納場所の SELinux コンテキストを表示させます。# ls -lZ /var/lib/pgsql drwx------. postgres postgres system_u:object_r:postgresql_db_t:s0 data
データベースファイルの格納場所にデフォルトで付けられるコンテキストエレメントのpostgresql_db_t
が表示されています。本例で使用する新しいデータベース格納場所が期待通り正常に動作するよう、このコンテキストをその新しい場所に手作業で適用する必要があります。- データベース格納場所となるディレクトリを新規作成します。この例では
/opt/postgresql/data
を使用しています。別の場所を使用する場合は、次のコマンドを使用する際に置換してください。# mkdir -p /opt/postgresql/data
- 新規に作成したディレクトリを表示させまます。このディレクトリの初期コンテキストは usr_t になっている点に注意してください。このコンテキストでは、SELinux による PostgreSQL への保護メカニズムを実施するには不十分です。コンテキストを変更することにより、新規に作成したディレクトリをデータ格納場所として適切に動作させることができるようになります。
# ls -lZ /opt/postgresql/ drwxr-xr-x. root root unconfined_u:object_r:usr_t:s0 data
- postgres ユーザーおよび postgres グループによるアクセスを許可するため所有権を変更します。この変更は従来の Unix パーミッションに対する変更であり、SELinux による制限はそのまま変更されていません。
# chown -R postgres:postgres /opt/postgresql
- テキストエディターで PostgreSQL の初期設定ファイル
/etc/rc.d/init.d/postgresql
を開き、新しい場所をポイントするようPGDATA
とPGLOG
を変更します。# vi /etc/rc.d/init.d/postgresql PGDATA=/opt/postgresql/data PGLOG=/opt/postgresql/data/pgstartup.log
このファイルを保存してからテキストエディターを終了します。 - 新しい場所にあるデータベースを初期化します。
su - postgres -c "initdb -D /opt/postgresql/data"
- データベースの場所を変更したことにより、サービスの起動に失敗します。
# service postgresql start Starting postgresql service: [FAILED]
サービスが起動しない原因は SELinux にあります。新しい場所に適切なラベル付けが行なわれていないためです。以下の手順で、新しい場所 (/opt/postgresql
) にラベルを付け、postgresql サービスを正常に起動させます。 semanage
コマンドを実行し、/opt/postgresql
および配下にあるすべてのディレクトリとファイルに対するコンテキストマッピングを追加します。semanage fcontext -a -t postgresql_db_t "/opt/postgresql(/.*)?"
- このマッピングは
/etc/selinux/targeted/contexts/files/file_contexts.local
ファイルに書き込まれます。# grep -i postgresql /etc/selinux/targeted/contexts/files/file_contexts.local /opt/postgresql(/.*)? system_u:object_r:postgresql_db_t:s0
restorecon
コマンドを使ってこのコンテキストマッピングを実行中のシステムに適用します。restorecon -R -v /opt/postgresql
- これで
/opt/postgresql
のデータ格納場所に PostgreSQL 用の正しいコンテキストがラベル付けされました。postgresql
サービスが正常に起動するようになります。# service postgresql start Starting postgreSQL service: [ OK ]
- コンテキストが確かに
/opt/postgresql
用に正しく変更されているか確認します。ls -lZ /opt drwxr-xr-x. root root system_u:object_r:postgresql_db_t:s0 postgresql
ps
コマンドを使って、postgresql
プロセスで新しい場所が表示されるか確認します。# ps aux | grep -i postmaster postgres 21564 0.3 0.3 42308 4032 ? S 10:13 0:00 /usr/bin/postmaster -p 5432 -D /opt/postgresql/data
- データ格納場所の変更そしてラベル付けが正しく行なわれたため、
postgresql
デーモンが正常に起動するようになりました。ここまでの設定が完了したら、実行中の全サービスが正常に動作しているか確認テストを行なってください。
第12章 rsync
Rsync プロジェクトページより抜粋:
原文: "rsync is an open source utility that provides fast incremental file transfer." (訳文: rsync は、高速な増分ファイル転送を実現するオープンソースのユーティリティです。)
Red Hat Enterprise Linux を使用する場合、rsync は rsync パッケージで提供されます。
rpm -q rsync
を実行して、rsync パッケージがインストールされているか確認してください。インストールされていない場合は、root ユーザーで次のコマンドを実行してインストールを行ないます。
yum install rsync
12.1. rsync と SELinux
Red Hat Enterprise Linux 6 SELinux rsync_selinux(8) man ページより抜粋: "SELinux requires files to have an extended attribute to define the file type. Policy governs the access daemons have to these files. If you want to share files using the rsync daemon, you must label the files and directories public_content_t." (訳文: SELinux にはファイルタイプ定義の拡張属性を持たせるためのファイルが必要になります。ポリシーでは、こうしたファイルに対してデーモンに持たせるアクセス権を管理します。rsync デーモンを使ってファイルの共有をする場合は、ファイルやディレクトリにpublic_content_t タイプのラベルをつける必要があります。 )
ほとんどのサービスと同様、
rsync
に対して SELinux による保護メカニズムを適用させるには、適切なラベル付けが必要になります。
12.2. タイプ
Type Enforcement が SELinux の targeted ポリシーで使用されるメインのパーミッション制御になります。全ファイルおよびプロセスにタイプのラベルが付けられます。ファイルの場合はタイプ、プロセスの場合はドメインを定義します。任意のタイプにアクセスするドメインなのか、 別のドメインにアクセスするドメインなのかなど、SELinux のポリシールールではタイプによって互いがアクセスしあう方法を定義します。 アクセスを許可する特定の SELinux ポリシールールが存在する場合にのみ、 そのアクセスが許可されます。
rsync
で使用されるタイプを以下に示します。 タイプに応じて柔軟なアクセス設定ができます。
public_content_t
rsync
で共有するファイルの場所に使用する汎用タイプになります。rsync
で共有するファイルの格納用に特殊なディレクトリを作成する場合は、そのディレクトリおよびコンテンツにはこのラベルを適用する必要があります。rsync_exec_t
/usr/bin/rsync
システムバイナリに使用されるタイプです。rsync_log_t
- デフォルトで
/var/log/rsync.log
にあるrsync
ログファイルに使用されます。rsync によりログが記録されるファイルの場所を変更する場合は、ランタイム時にrsync
コマンドに対して--log-file=FILE
オプションを使用します。 rsync_var_run_t
/var/run/rsyncd.lock
にあるrsyncd
ロックファイルに使用されるタイプです。このロックファイルはrsync
サーバーで接続関連の制限を管理する際に使用されます。rsync_data_t
- ファイルやディレクトリを rsync ドメインとして使用し、他のサービスのアクセス範囲とは分離させたい場合、このタイプを使用します。また、
public_content_t
は汎用の SELinux コンテキストになります。複数のサービスとやりとりを行なうファイルやディレクトリに使用します (rsync ドメインとしての FTP ディレクトリおよび NFS ディレクトリ)。 rsync_etc_t
/etc/
ディレクトリ内にある rsync 関連のファイルに使用されます。
12.3. Boolean
SELinux は実行するサービスに必要な最小限レベルのアクセスに基づいています。サービスの実行手段は複数あるため、サービスをどのように実行するのかを SELinux に指示する必要があります。次の Boolean を使って rsync の動作方法を SELinux に指示します。
allow_rsync_anon_write
- この Boolean を有効にすると、rsync_t ドメイン内の
rsync
による public_content_rw_t タイプのファイル、リンク、ディレクトリなどの管理を許可します。多くの場合、パブリック転送サービスに使用されるパブリックファイルになります。ファイルおよびディレクトリにはpublic_content_rw_t
のラベルを付ける必要があります。 rsync_client
- この Boolean を有効にすると、rsync_port_t で定義されるポートへの
rsync
による接続開始を許可し、また rsync_data_t タイプのファイル、リンク、ディレクトリの管理も許可されます。rsync
を SELinux の管理下に置くため、rsync
デーモンは rsync_t ドメイン内になければならない点に注意してください。本章では、rsync_t ドメインで実行しているrsync
の設定例を示します。 rsync_export_all_ro
- この Boolean を有効にすると、rsync_t ドメイン内の
rsync
による NFS および CIFS のエクスポートを許可します。クライアントに付与するアクセス権は読み取り専用になります。
12.4. 設定例
12.4.1. デーモンとして rsync を使用する
Red Hat Enterprise Linux を使用する場合、rsync をデーモンとして使用し、一元的にファイルを格納、継続的に同期しておくためのセントラルサーバーとして複数のクライアントが直接通信を行なえるようにすることができます。以下では、rsync を適切なドメイン内のネットワークソケット全体でデーモンとして実行させようした場合、事前定義された TCP ポート (SELinux ポリシー内) での実行を期待している SELinux がどのような反応を示すかについて見ていきます。次に、非標準のポートでの
rsync
デーモンによる正常な実行を許可するため SELinux を編集する方法について説明していきます。
SELinux ポリシーとローカルのデーモンおよびプロセスに対する制御力を示すため、本例は単一のシステム上で行います。以下に示す例は、rsync に対してどのように SELinux が影響を与えることができるのかを示す一例に過ぎません。rsync に関する総合的な説明は本ガイドの範疇を越えてしまいますので、詳細については、公式の rsync ドキュメント を参照してください。ここでは、rsync パッケージ、setroubleshoot-server パッケージ、audit パッケージがインストールされていること、SELinux targeted ポリシーを使用していること、SELinux が enforcing モードで実行されていることを前提としています。
rsync を rsync_t として起動させる
getenforce
を実行して、 SELinux が enforcing モードで実行していることを確認します。$ getenforce Enforcing
SELinux が enforcing モードで実行している場合は、getenforce
コマンドを実行するとEnforcing
が返されます。which
コマンドを実行し、rsync バイナリがシステムパス内にあるか確認します。$ which rsync /usr/bin/rsync
rsync
をデーモンとして実行する場合、/etc/rsyncd.conf
と言う名前を付けた設定ファイルを使用する必要があります。ここで使用している設定ファイルは非常に簡潔なファイルになっているため、利用できるすべてのオプションが表示されているわけではありません。rsync
デーモンの事例として必要なものを備えているだけです。log file = /var/log/rsync.log pid file = /var/run/rsyncd.pid lock file = /var/run/rsync.lock [files] path = /srv/files comment = file area read only = false timeout = 300
- これで、デーモンモードで動作させる rsync 用の簡単な設定ファイルができました。このステップでは、SELinux による保護メカニズムを rsync に適用させるには、
rsync --daemon
を実行するだけでは不十分であることを確認します。次の出力を見てみてください。# rsync --daemon # ps x | grep rsync 8231 ? Ss 0:00 rsync --daemon 8233 pts/3 S+ 0:00 grep rsync # ps -eZ | grep rsync unconfined_u:unconfined_r:unconfined_t:s0-s0:c0.c1023 8231 ? 00:00:00 rsync
最後のps
コマンドからの出力に注目してください。コンテキストではrsync
デーモンはunconfined_t
デーモン内で実行していることを示しています。つまり、rsync がrsync --daemon
コマンドで起動されたため、rsync_t
には遷移していないということです。この状態では、SELinux はこのデーモンに対してルールとポリシーを施行することができません。この問題を解決するため次のステップを見てみます。次のステップでは、rsync
を適切にラベル付けした init スクリプトから起動させるため、rsync_t
に遷移するようになります。これではじめて SELinux とその保護メカニズムをrsync
に適用できるようになります。rsync
プロセスを終了してから、次のステップに進みます。 - rsync 用のカスタムの init スクリプトには次のステップが必要になります。次を
/etc/rc.d/init.d/rsyncd
に保存します。#!/bin/bash # Source function library. . /etc/rc.d/init.d/functions [ -f /usr/bin/rsync ] || exit 0 case "$1" in start) action "Starting rsyncd: " /usr/bin/rsync --daemon ;; stop) action "Stopping rsyncd: " killall rsync ;; *) echo "Usage: rsyncd {start|stop}" exit 1 esac exit 0
以下のようにして、このスクリプトにinitrc_exec_t
タイプのラベルを付けます。 semanage
コマンドを実行し、/etc/rc.d/init.d/rsyncd
のコンテキストマッピングを追加します。semanage fcontext -a -t initrc_exec_t "/etc/rc.d/init.d/rsyncd"
- このマッピングは
/etc/selinux/targeted/contexts/files/file_contexts.local
ファイルに書き込まれます。# grep rsync /etc/selinux/targeted/contexts/files/file_contexts.local /etc/rc.d/init.d/rsyncd system_u:object_r:initrc_exec_t:s0
restorecon
コマンドを使ってこのコンテキストマッピングを実行中のシステムに適用します。restorecon -R -v /etc/rc.d/init.d/rsyncd
ls -lZ
コマンドを実行して、確かにスクリプトに適切なタイプのラベルが付けられているかを確認します。以下の出力では、スクリプトにはinitrc_exec_t
タイプのラベルが付けられています。ls -lZ /etc/rc.d/init.d/rsyncd -rwxr-xr-x. root root system_u:object_r:initrc_exec_t:s0 /etc/rc.d/init.d/rsyncd
- 新しいスクリプトで
rsyncd
を起動します。rsync が適切にラベル付けした init スクリプトから起動されるようになりました。プロセスはrsync_t
として開始されるようになります。# service rsyncd start Starting rsyncd: [ OK ] ps -eZ | grep rsync unconfined_u:system_r:rsync_t:s0 9794 ? 00:00:00 rsync
これで、rsync がrsync_t
ドメイン内で実行するようになったため、SELinux ではその保護メカニズムをrsync
デーモンに適用できるようになります。
rsyncd
を rsync_t
ドメイン内で実行させる方法について説明してきました。次に、このデーモンをデフォルト以外のポートで適切に実行させる方法について見ていきます。ここでは TCP ポート 10000 を使用します。
デフォルト以外のポートで rsync デーモンを実行する
/etc/rsyncd.conf
ファイルを変更して、port = 10000
の行をグローバル設定エリア内にあるファイルの冒頭に追加します (file エリアが定義される直前)。新しい設定ファイルは次のようになります。log file = /var/log/rsyncd.log pid file = /var/run/rsyncd.pid lock file = /var/run/rsync.lock port = 10000 [files] path = /srv/files comment = file area read only = false timeout = 300
- この新しい設定の init スクリプトから rsync を起動すると、次のような拒否が SELinux によりログ記録されます。
Jul 22 10:46:59 localhost setroubleshoot: SELinux is preventing the rsync (rsync_t) from binding to port 10000. For complete SELinux messages. run sealert -l c371ab34-639e-45ae-9e42-18855b5c2de8
semanage
コマンドを実行して、TCP ポート 10000 をrsync_port_t
の SELinux ポリシーに追加します。# semanage port -a -t rsync_port_t -p tcp 10000
- これで TCP ポート 10000 が
rsync_port_t
の SELinux ポリシーに追加されました。rsyncd
がこのポートで正常に起動し動作するようになります。# service rsyncd start Starting rsyncd: [ OK ]
# netstat -lnp | grep 10000 tcp 0 0 0.0.0.0:10000 0.0.0.0:* LISTEN 9910/rsync
SELinux のポリシーが修正されたため、
rsyncd
による TCP ポート 10000 での動作が許可されるようになりました。
第13章 Postfix
Postfix プロジェクトページより抜粋:
原文: "What is Postfix? It is Wietse Venema's mailer that started life at IBM research as an alternative to the widely-used Sendmail program. Postfix attempts to be fast, easy to administer, and secure. The outside has a definite Sendmail-ish flavor, but the inside is completely different." (訳文: Postfix とは? 幅広く利用されていた Sendmail プログラムの代替となるプログラムの調査が IBM によって行なわれたのが始まりとなる Wietse Venema のメーラーです。Postfix では高速で管理が容易でありながら安全なメーラーを目指しています。外観は Sendmail 色を色濃く残していますが、プログラム自体はまったく異なる仕様になっています。)
Red Hat Enterprise Linux では、 postfix は postfix パッケージで提供されます。
rpm -q postfix
を実行して、 postfix パッケージがインストールされているか確認してください。 インストールされていない場合は、 root ユーザーで次のコマンドを実行してインストールを行ないます。
yum install postfix
13.1. Postfix と SELinux
Postfix を有効にすると、デフォルトで制限のあるサービスとして実行されます。制限のあるプロセスはそれ自体のドメイン内で実行され、他の制限のあるプロセスとは分離されます。制限のあるプロセスが攻撃を受けると、SELinux ポリシー設定に応じて、攻撃側がリソースにアクセスして加えることができる被害は限定されます。以下に、Postfix 自体のドメイン内で実行している Postfix プロセスの例を示します。 ここでは postfix パッケージがインストールされていること、また Postfix サービスが起動されていることを前提としています。
getenforce
を実行して SELinux が enforcing モードで実行しているか確認します。$ getenforce Enforcing
SELinux が enforcing モードで実行している場合は、getenforce
コマンドを実行するとEnforcing
が返されます。- root ユーザーで
service postfix start
を実行し、postfix
を起動します。service postfix start Starting postfix: [ OK ]
ps -eZ | grep postfix
を実行し、postfix
プロセスを表示させます。ps -eZ | grep postfix system_u:system_r:postfix_master_t:s0 1651 ? 00:00:00 master system_u:system_r:postfix_pickup_t:s0 1662 ? 00:00:00 pickup system_u:system_r:postfix_qmgr_t:s0 1663 ? 00:00:00 qmgr
たとえば、Postfixmaster
プロセスに関連する SELinux コンテキストはunconfined_u:system_r:postfix_master_t:s0
です。 コンテキストの最後から 2 番目の部分、postfix_master_t
がこのプロセスのタイプになります。 プロセスのドメインやファイルのタイプを定義するのがタイプです。 この例の場合、master
プロセスはpostfix_master_t
ドメイン内で実行しています。
13.2. タイプ
Type Enforcement が SELinux の targeted ポリシーで使用されるメインのパーミッション制御になります。全ファイルおよびプロセスにタイプのラベルが付けられます。ファイルの場合はタイプ、プロセスの場合はドメインを定義します。任意のタイプにアクセスするドメインなのか、 別のドメインにアクセスするドメインなのかなど、SELinux のポリシールールではタイプによって互いがアクセスしあう方法を定義します。アクセスを許可する特定の SELinux ポリシールールが存在する場合にのみ、そのアクセスが許可されます。
Postfix
で使用されるタイプを以下に示します。 タイプに応じて柔軟なアクセス設定ができます。
postfix_etc_t
/etc/postfix/
ディレクトリ内にある Postfix 用の設定ファイルに使用されるタイプです。postfix_data_t
/var/lib/postfix/
ディレクトリ内にある Postfix データファイル用に使用されるタイプです。postfix_var_run_t
/run/
ディレクトリ内に格納される Postfix ファイルに使用されるタイプです。postfix_initrc_exec_t
- Postfix 実行可能ファイルの
postfix_initrc_t
ドメインへの遷移に使用されるタイプです。 postfix_spool_t
/var/spool/
ディレクトリ内に格納される Postfix ファイルに使用されるタイプです。
注記
次のコマンドを実行すると、Postfix 用のタイプとファイルの全一覧を表示させることができます。
$ grep postfix /etc/selinux/targeted/contexts/files/file_contexts
13.3. Boolean
SELinux は実行するサービスに必要な最小限レベルのアクセスに基づいています。サービスの実行手段は複数あるため、サービスをどのように実行するのかを SELinux に指示する必要があります。 次の Boolean を使って Postfix の動作方法を SELinux に指示します。
allow_postfix_local_write_mail_spool
- この Boolean を有効にすると、Postfix によるシステム上のローカルメールスプールへの書き込みを許可します。ローカルスプールを使用する際、Postfix を正常に動作させるためにはこの Boolean を有効にする必要があります。
13.4. 設定例
13.4.1. SpamAssassin と Postfix
SpamAssassin プロジェクトページより抜粋:
原文: "Open Source mail filter, written in Perl, to identify spam using a wide range of heuristic tests on mail headers and body text. Free software." (訳文: Perl で記述されたオープンソースのメールフィルターです。メールのヘッダーおよび本文で幅広い範囲の発見的テストを使用してスパムを識別するフリーソフトウェアです。)
Red Hat Enterprise Linux を使用する場合、SpamAssassin は spamassassin パッケージで提供されます。
rpm -q spamassassin
を実行して、spamassassin パッケージがインストールされているか確認してください。インストールされていない場合は、root ユーザーで次のコマンドを実行してインストールを行ないます。
yum install spamassassin
SpamAssassin は Postfix などのメーラーと連携してスパムフィルタリング機能を提供します。メールの効果的な遮断、分析、フィルタリングが行なわれるためには、SpamAssassin はネットワークインターフェース上でリッスンを行なう必要があります。SpamAssassin のデフォルトポートは TCP/783 ですが、変更することもできます。SELinux で特定のポートに限ったアクセスをデフォルトで許可することにより SpamAssassin を補完している実践的な例を以下に示します。次に、ポートを変更する方法およびデフォルト以外のポートで SpamAssassin を正常に動作させる方法について説明していきます。
以下に示す例は、 シンプルな SpamAssassin 設定に対してどのように SELinux が影響を与えることができるのかを示す一例に過ぎません。 SpamAssassin に関する総合的な説明は本ガイドの範疇を越えてしまいますので、 詳細については、 公式の SpamAssassin ドキュメント を参照してください。 ここでは、spamassassin がインストールされていること、使用しているポートでのアクセス許可がファイアウォールで設定されていること、SELinux が enforcing モードで実行されていることを前提としています。
デフォルト以外のポートで SpamAssassin を実行する
semanage
コマンドを実行して、SELinux でspamd
によるリッスンをデフォルトで許可しているポートを表示させます。# semanage port -l | grep spamd spamd_port_t tcp 783
上記の出力では、SpamAssassin が動作するポートとして TCP/783 がspamd_port_t
で定義されていることを示しています。/etc/sysconfig/spamassassin
設定ファイルを編集し、SpamAssassin が TCP/10000 で起動するよう変更します。# Options to spamd SPAMDOPTIONS="-d -p 10000 -c m5 -H"
上記の行は、SpamAssassin がポート 10000 で動作するよう指定しています。ここからは、このソケットを開くよう SELinux ポリシーを変更する方法を見ていきます。- SpamAssassin を起動すると、次のようなエラーメッセージが表示されます。
# service spamassassin start Starting spamd: [2203] warn: server socket setup failed, retry 1: spamd: could not create INET socket on 127.0.0.1:10000: Permission denied [2203] warn: server socket setup failed, retry 2: spamd: could not create INET socket on 127.0.0.1:10000: Permission denied [2203] error: spamd: could not create INET socket on 127.0.0.1:10000: Permission denied spamd: could not create INET socket on 127.0.0.1:10000: Permission denied [FAILED]
上記の出力は、このポートへのアクセスが SELinux によってブロックされたことを表しています。 - SELinux により次のような拒否がログ記録されます。
SELinux is preventing the spamd (spamd_t) from binding to port 10000.
- root ユーザーで
semanage
コマンドを実行し、SpamAssassin のサンプルポート (TCP/10000) での動作を許可するよう SELinux ポリシーを変更します。semanage port -a -t spamd_port_t -p tcp 10000
- SpamAssassin が起動し、TCP ポート 10000 で動作していることを確認します。
# service spamassassin start Starting spamd: [ OK ] # netstat -lnp | grep 10000 tcp 0 0 127.0.0.1:10000 0.0.0.0:* LISTEN 2224/spamd.pid
- SELinux ポリシーで
spamd
による TCP ポート 10000 へのアクセスが許可されたため、SpamAssassin がこのポートで正常に動作するようになりました。
第14章 DHCP
クライアントに第 3 層 TCP/IP を動的に提供、詳細を設定するため Red Hat Enterprise Linux で使用されるデーモンが DHCPD になります。
DHCP サーバーの
dhcpd
は、 dhcp パッケージで提供されます。rpm -q dhcp
を実行して、 dhcp パッケージがインストールされているか確認します。 インストールされていない場合は、 root ユーザーで次のコマンドを実行してインストールしてください。
yum install dhcp
14.1. DHCP と SELinux
DHCP を有効にすると、デフォルトで制限のあるサービスとして実行されます。制限のあるプロセスはそれ自体のドメイン内で実行され、他の制限のあるプロセスとは分離されます。制限のあるプロセスが攻撃を受けると、SELinux ポリシー設定に応じて、攻撃側がリソースにアクセスして加えることができる被害は限定されます。以下に、DHCPD 自体のドメイン内で実行している DHCPD と関連プロセスの例を示します。ここでは dhcp パッケージがインストールされていること、また DHCPD サービスが起動されていることを前提としています。
getenforce
を実行して、 SELinux が enforcing モードで実行しているか確認します。$ getenforce Enforcing
SELinux が enforcing モードで実行されている場合は、getenforce
コマンドによりEnforcing
が返されます。- root ユーザーで
service dhcpd start
を実行し、DHCPD
を起動します。service dhcpd start Starting dhcpd: [ OK ]
ps -eZ | grep dhcpd
を実行し、dhcpd
プロセスを表示させます。ps -eZ | grep dhcpd unconfined_u:system_r:dhcpd_t:s0 5483 ? 00:00:00 dhcpd
dhcpd プロセスに関連する SELinux コンテキストはunconfined_u:system_r:dhcpd_t:s0
です。
14.2. タイプ
dhcpd
で使用されるタイプを以下に示します。
dhcp_etc_t
- 設定ファイルなど、
/etc
内のファイルに主に使用されるタイプです。 dhcpd_var_run_t
/var/run
内にある dhcpd 用の PID ファイルに使用されるタイプです。dhcpd_exec_t
- DHCP 実行可能ファイルの
dhcpd_t
ドメインへの遷移に使用されるタイプです。 dhcpd_initrc_exec_t
- DHCP 実行可能ファイルの
dhcpd_initrc_t
ドメインへの遷移に使用されるタイプです。
注記
次のコマンドを実行すると、dhcp 用のタイプとファイルの全一覧を表示させることができます。
$ grep dhcp /etc/selinux/targeted/contexts/files/file_contexts
第15章 参考文献
本ガイドではその範疇を越えてしまう SELinux 関連の詳細が記述されている書籍および資料などを以下にいくつか挙げておきます。SELinux は急速なスピードで開発されているため、記述の一部は Red Hat Enterprise Linux の特定リリースにしか適用できない場合があるため注意してください。
書籍
- SELinux by Example
- Mayer、MacMillan、Caplan 著2007年、Prentice Hall 出版
- SELinux: NSA's Open Source Security Enhanced Linux
- Bill McCarty 著2004年、O'Reilly Media Inc. 出版
チュートリアルとヘルプ
- Russell Coker 氏によるチュートリアルとトーク
- Dan Walsh 氏のジャーナル
- Red Hat ナレッジベース
全般情報
- NSA SELinux メイン web サイト
- NSA SELinux FAQ
メーリングリスト
- NSA SELinux メーリングリスト
- Fedora SELinux メーリングリスト
コミュニティ
- SELinux プロジェクト Wiki
- SELinux コミュニティページ
- IRC
- irc.freenode.net, #selinux
付録A 改訂履歴
改訂履歴 | |||
---|---|---|---|
改訂 4-2.2.400 | 2013-10-31 | ||
| |||
改訂 4-2.2 | Fri Aug 9 2013 | ||
| |||
改訂 4-2.1 | Wed Jul 10 2013 | ||
| |||
改訂 4-2 | Fri Feb 22 2013 | ||
| |||
改訂 3-0 | Wed Jun 20 2012 | ||
| |||
改訂 2-0 | Tue Dec 6 2011 | ||
| |||
改訂 1-0 | Thu May 19 2011 | ||
| |||
改訂 0-0 | Tue Nov 9 2010 | ||
|
法律上の通知
Copyright © 2011 Red Hat, Inc.
This document is licensed by Red Hat under the Creative Commons Attribution-ShareAlike 3.0 Unported License. If you distribute this document, or a modified version of it, you must provide attribution to Red Hat, Inc. and provide a link to the original. If the document is modified, all Red Hat trademarks must be removed.
Red Hat, as the licensor of this document, waives the right to enforce, and agrees not to assert, Section 4d of CC-BY-SA to the fullest extent permitted by applicable law.
Red Hat, Red Hat Enterprise Linux, the Shadowman logo, JBoss, OpenShift, Fedora, the Infinity logo, and RHCE are trademarks of Red Hat, Inc., registered in the United States and other countries.
Linux® is the registered trademark of Linus Torvalds in the United States and other countries.
Java® is a registered trademark of Oracle and/or its affiliates.
XFS® is a trademark of Silicon Graphics International Corp. or its subsidiaries in the United States and/or other countries.
MySQL® is a registered trademark of MySQL AB in the United States, the European Union and other countries.
Node.js® is an official trademark of Joyent. Red Hat Software Collections is not formally related to or endorsed by the official Joyent Node.js open source or commercial project.
The OpenStack® Word Mark and OpenStack logo are either registered trademarks/service marks or trademarks/service marks of the OpenStack Foundation, in the United States and other countries and are used with the OpenStack Foundation's permission. We are not affiliated with, endorsed or sponsored by the OpenStack Foundation, or the OpenStack community.
All other trademarks are the property of their respective owners.