SELinux のルールを確認してみよう

Linux を導入した時に、まず最初にやる作業が「SELinux の無効化」というのはいかがなものかと思っています。 開発環境ならまだしもプロダクション環境で何も考えず無効化しちゃうのは思考停止もいいところ。 しかし、SELinux がとっつきにくいのも確かなわけで、何故とっつきにくいかを自分の経験から考えてみると「現在適用されているルールがよくわからない」ということがあるのではないかと思いました。 世の中に SELinux に関する記事は溢れていますが、そのほとんどは boolean を設定したり、ファイルにタイプを設定したりみたいな枝葉末節を説明しているように思います。 IT系のエンジニアならば、まずは自分の手元の SELinux がどのようなポリシー/ルールで動いているのか知りたくなると思うのですが、それを知ろうとしても、該当する情報はなかなか見つけることができません。

というわけで今回は SELinux の「現在適用されているルールをどうやって知るか」という点をまとめてみたいと思います。

前提として:なぜ SELinux を有効化にするのか

SELinux はファイヤーウォールの置き換えでもアンチウィルスソフトの置き換えでもありません。 なので、それとは別の追加のセキュリティ機構として有効化しておくべきです。 この部分はあちらこちらで説明されているので (例えばちょっと古いですが日経 BP の記事)、詳細は割愛しますが、多層での防御 (defence in depth) ということを考えると、大事な情報を扱うサーバでは SELinux を有効化して運用すべきです。

SELinux のポリシーの構成

SELinux のポリシーの肝となる部分は AV (Access Vector) ルールと呼ばれるルールにより構成されています。 一つの AV ルールは以下のように表されますが、これが複数集まってセキュリティポリシーを構成します。

種類  ソースタイプ(ドメイン)  ターゲットタイプ  :  クラス  パーミッション;

AV ルールには 4種類 (3つの基本ルール+特殊ルール) あります。

allow ルール
このルールにより許可されたアクセスはログに記録されません。一番基本となるルールです。
auditallow ルール
ログあり許可ルール。allow ルールによって許可されたアクセスはログに記録されませんが、auditallow ルールならば記録されます。
dontaudit ルール
ログ出力抑止ルール。通常、ルールにより許可されなかったアクセスは拒否されログに記録されるのですが、dontaudit ルールで定められたアクセスについてはアクセスが拒否されてもログに記録されません。ログ出力を無視してよいアクセスをこのルールで規定します。
neverallow ルール
このルールは他の3つとは別格で、ルールのコンパイル時に許さないルールを規定します。allow/auditallow ルールで許可されていても neverallow に引っかかったらコンパイル時にエラーとなります。

現在のポリシーを把握するには allow ルールと auditallow ルールを中心に確認することになります。

現在のポリシーを確認してみよう

現在設定されている AV ルールを表示するには sesearch を使用します。 以下のコマンドで現システムのデフォルトポリシーの allow ルールを表示することができます。

# sesearch --allow -C
Found 133955 av rules:
   allow rpm_t httpd_squid_script_exec_t : sock_file { ioctl read write create getattr setattr lock relabelfrom relabelto append unlink link rename };
   allow rpm_script_t xenstored_var_run_t : sock_file { ioctl read write create getattr setattr lock append unlink link rename };
   allow restorecond_t evolution_alarm_exec_t : sock_file { getattr relabelfrom relabelto }
(以下略)

実行するとこのように万単位のルールが出力されます。 例えば Apache 関連だけを見ようと grep http としても数千行台というレベルで、確かに一つ一つを把握しておけるようなものではありません。 しかし、このようなルールに基づいて SELinux が動作しているということは理解しておくべきです。

{} は複数の値をまとめるために用いられるので、先の実行例の 1行目は以下のようになります。

ソースタイプ rpm_t
ターゲットタイプ httpd_squid_script_exec_t
クラス sock_file
パーミッション ioctl, read, write, create, getattr, setattr, lock,
relabelfrom, relabelto, append, unlink, link, rename

オブジェクトクラスとパーミッションの一覧はこちらにあります

また、以下の例の様に ET や DT から始まる行は boolean によって有効化/無効化できるルールを示しています。

 ET allow named_t init_t : process sigchld ; [ init_systemd ]

このように boolean 設定できるルールは行末に [ boolean名 ] が付き、現在有効になっているルールは行頭には ET が、無効になっているルールには DT が付きます。 この例では init_systemd という boolean が設定され有効化されているということになります。 「boolean を semanage でセットしましょう」という記事はあちこちで見かけますが、実際に何が変わるかはこのように sesearch で知ることができるのです。 その boolean 値に関連するルールのみ表示したければ以下のコマンドを使用することができます。

sesearch --allow -C -b boolean名

また、sesearch で表示されるルールの中には @ が付いた「@ttr0141」のような表記も見られることがありますが、これは attribute です。 attribute はタイプをグループ化するのに用いられ、その attribute が付与されたタイプ一覧は以下のコマンドで確認できます。

# seinfo -a@ttr0141 -x

ソースファイルではきちんと名前がついていますが、コンパイル後なのでこのような表示となってしまうのでしょう。

ポリシーはモジュール化されている

SELinux のフレームワークは NSA が中心となって開発しましたが、ポリシーは民間中心で開発されています。 そして、ポリシーには種類があり、主要なものとしては広く使われている targeted ポリシーとより厳しい strict ポリシーがあります。 身の回りにある CentOS や Fedora ではデフォルトで targeted ポリシーが適用されています。 /etc/selinux/config を見ると確認できます。

また、ポリシーはモジュール化されています。 targeted ポリシーのモジュール関連ファイルは /etc/selinux/targeted/modules 以下に置かれています。 更にその下の active/modules にある *.pp ファイルがモジュールの実体となっています。

この .pp ファイルを先の sesearch のパラメータとして渡し、モジュール内のルールを見ることはできるようなのですが、.pp ファイルに依存関係があり、依存するファイル全てを列挙しなければなりません。 列挙する際は base.pp を一番先に記述する必要があります。

モジュールの依存関係は module_deps で調べることができるので、その結果を sesearch に利用して各モジュールごとの AV ルールを確認することもできそうですが、手元の Fedora ではこのあたりがうまく動かず動作確認できませんでした。

カスタマイズの仕方

ポリシーの変更が必要なときは以下の順序で検討します。

  1. boolean の設定で対処できるかの検討
  2. カスタムポリシーの作成

実際問題としてカスタムポリシーが必要となるのは自作のデーモンを導入するなど既存の枠組みに収めることができない場合のみで、基本的なデーモン類については大抵 boolean の設定で足ります。 それほど様々な boolean 値が用意されています。

問題はどのような boolean 値が存在しているかをどのように知るかというところですが、いきなり sesearch で細かく見るのではなく、まずマニュアルを探してみるとよいでしょう。 大抵、デーモン名_selinux (httpd_selinux、squid_selinux、…) というマニュアルエントリが用意されているので、例えば Apache については以下のコマンドでマニュアルを確認します。

$ man httpd_selinux 

まとめと参考記事

IT 系の仕事をする立場として「SELinux は有効化しておくのが当たり前」という状況になって欲しいですし、「無効化」以外の SELinux の記事が世の中に増えれば良いと願っています。 この記事は SELinux の一部しか説明していないですが、ちょうど今売っているSoftware Design 2012年 9月号で SELinux の仕組みが包括的にわかりやすく説明されているので、興味があればこれをお勧めします。 記事を書くにあたって以下のエントリを参考にさせていただきました。

Apache のポート番号を変えると Permission Denied でエラーとなる件

Fedora 14 で Apache のポート番号を標準の 80番から 8001番に変えて起動しようとしたところ、以下のようにエラーとなってしまいました。

# service httpd start
Starting httpd: (13)Permission denied: make_sock: could not bind to address [::]:8001
(13)Permission denied: make_sock: could not bind to address 0.0.0.0:8001
no listening sockets available, shutting down
Unable to open logs

他のプログラムがこのポートを使っているわけでもないし、権限も root で実行しています。 何故かと思ったところこれは SELinux の機能でした。 SELinux という名前はディストリビューションっぽいですが、そうではなくセキュリティ強化のためのモジュールですね。

SELinux が有効 (enforcing mode) になっているかどうかは以下のコマンドの結果で確認できます。 endorcing mode であれば 1が表示されます。

# cat /selinux/enforce

現在の各サービスで使用できるポートは以下のコマンドで出力されます。

# semanage port -l

Apache の使えるポート (http_port_t) に 8001番を追加しなければなりません。 以下のコマンドを実行します。

# semanage port -a -t http_port_t -p tcp 8001

これで無事起動することができました。 このあたりのセキュリティ機能は「よくわからないから機能切っちゃえ~」というのではなく、きちんと理解して設定しておかねばなりません。 というわけで SELinux の仕組みを一通り見ておかねば、と思ったのでした。

参考記事