読者です 読者をやめる 読者になる 読者になる

めもめも

このブログに記載の内容は個人の見解であり、必ずしも所属組織の立場、戦略、意見を代表するものではありません。

SELinux 入門 (1) - まずは全体像を理解する。

パーソナルメモです。。。。執筆中。(整理できたら、もうちょっとフォーマルなものにします。)

参考資料 SELinux Project Wiki

環境は RHEL6.0 前提です。

# rpm -qa | grep -E "(policy|selinux)" | sort
checkpolicy-2.0.22-1.el6.i686
libselinux-2.0.94-2.el6.i686
libselinux-devel-2.0.94-2.el6.i686
libselinux-python-2.0.94-2.el6.i686
libselinux-utils-2.0.94-2.el6.i686
policycoreutils-2.0.83-19.1.el6.i686
policycoreutils-newrole-2.0.83-19.1.el6.i686
policycoreutils-python-2.0.83-19.1.el6.i686
polkit-desktop-policy-0.96-2.el6.noarch
selinux-policy-3.7.19-54.el6.noarch
selinux-policy-targeted-3.7.19-54.el6.noarch

SELinux の動作モデル

『サブジェクト(動作主体)、オブジェクト(動作対象)、アクション(動作内容)』の 3 つ組に対して、それを許可するかどうかを判定する。

・サブジェクトは、基本的には個々のプロセスのこと。他に、ログイン中のユーザもサブジェクトに分類される(*1)
・オブジェクトは、ディレクトリ、ファイル、プロセス、ファイルディスクリプタ(ソケットを含む)など
・アクションのことを『アクセス・ベクタ』という。(厳密には、アクションに対する許可リストのことですが、慣用的に。)

(*1) ログイン中のユーザの SID は、実行中のシェルのプロセスの SID としてセットされる。

オブジェクトは、いくつかのオブジェクトクラスに分類されており、オブジェクトクラスごとに、実行可能なアクションが決まっている。

1つのオブジェクトが複数のオブジェクトクラスとして振る舞うこともある。たとえば、ディレクトリ・オブジェクトは、ディレクトリそのものを参照するアクションに対しては、ディレクトリのオブジェクトクラスであるが、ディレクトリ内にファイルを作成するアクションに対しては、ファイルのオブジェクトクラスになる。(ファイルを作成するというアクションは、ファイルのオブジェクトクラスで定義されている。ディレクトリがファイルのオブジェクトクラスというのは、気持ち悪いが、これから作るファイルはまだ存在していないので、そのファイルに対するアクションという判定はできない。)

サブジェクトとオブジェクトをまとめてエンティティという。プロセスなどのエンティティは、サブジェクトとして振る舞う場合とオブジェクトとして振る舞う場合がある。

セキュリティコンテキスト

(ユーザ属性、ロール属性、タイプ属性)の 3 つ組をセキュリティコンテキストと呼ぶ。

※サブジェクトのタイプ属性のことを慣習的に『ドメイン』と呼ぶ。同じく、オブジェクトのタイプ属性のことを慣習的に『タイプ』と呼ぶ。1つのエンティティがサブジェクトとなることもオブジェクトとなることもあるので、これは、呼び方だけの問題である。(サブジェクトとして振る舞う際のタイプ属性はドメインであり、オブジェクトとして振る舞う際のタイプ属性はタイプである。)

内部的には、個々のセキュリティコンテキストに対して、対応する SID の値が決まっている。以下、セキュリティコンテキストと SID を同じ意味で用いる。

すべてのエンティティには、SID が付与されており、以下のような目的で利用される。(SELinux の動作モデルは大きく RBAC と TE に分類される。RBAC と TE の詳細は後述。さらに、制限型ルールと遷移型ルールがある。)

1.制限型ルール

・ロール制限 (RBAC) : サブジェクトのユーザ属性に対して、割り当て可能なロール属性を定義する
・ドメイン制限 (RBAC):サブジェクトのロール属性に対して、割り当て可能なタイプ属性(ドメイン)を定義する
・アクション制限 (TE):サブジェクトのドメインとオブジェクトのタイプに応じて、アクションの実行を許可/拒否する

2.遷移型ルール

・ロール遷移(RBAC):サブジェクトのロール属性の変更を制御する。サブジェクト自身のロール属性の変更の許可/拒否、および、あたらしいサブジェクトが生成される際に割り当てられるロール属性を制御する。(*2)
・タイプ(ドメイン)遷移(TE) : あたらしいエンティティが生成される際に割り当てられるタイプ属性(ドメイン)を制御する。(*3)

(*2)新しいサブジェクトのロール属性は、デフォルトでは、その親となるサブジェクトのロール属性を引き継ぐ。新しく付与するロール属性を明示的に指定することも可能。この場合は、親のロール属性から新しいロール属性への切り替えの許可設定も必要。

(*3)新しいエンティティのタイプ属性は、デフォルトでは、その親となるエンティティのタイプ属性を引き継ぐ。新しく付与するタイプ属性を明示的に指定することも可能。この場合は、親のタイプ属性から新しいタイプ属性への切り替えの許可設定も必要。

遷移型ルールに従って、エンティティに新しく付与される SID は、制限型ルールも満たす必要があることに注意。

※ちょっとした注意。

以上の例から分かるように、SID の全ての要素が常に参照されるわけではなく、必要に応じて、必要な属性が参照される。とくにオブジェクトのロール属性は参照されることがないので、オブジェクトとしてのみ振る舞うエンティティ(ファイルなど)のロール属性は、通常、ダミーの object_r を付与する。

ポリシーファイル

SELinux の内部設定(ポリシー)は、sendmail の mc ファイルと cf ファイルのように 2 段階で生成される方式になっている。

目的に応じたさまざまなポリシーのソースファイル(mc ファイルみたいなもの)を元に make すると、テキストのポリシーファイル base.conf (cf ファイルみたいなもの)ができる。これをさらに make するとバイナリのポリシーファイル xxxx.pp ができて、これが実際に利用される。

ソースファイル内では、m4 マクロを駆使した記述をするので、SELinux エキスパートとしては、本来の base.conf が持つネイティブな設定と、マクロによるメタな設定の違いを理解しておきたい。

RBAC と TE の考え方

・ユーザにロールを割り当てる。ロールによって利用可能なドメインを制限する。(ここまでが RBAC の考え方)
・ドメインによって、オブジェクトのタイプごとに実行可能なアクションを制限する。(ここまでが TE の考え方)

という発想で、階層的な設定を行うのが目的。セキュリティツールではよくある発想。

※SELinuxのユーザは、Linuxのログインユーザとは異なります。ログインユーザとSELinuxのユーザは別途、マッピングを定義します。

諸々の管理コマンド

・ディレクトリ、ファイルの SID を確認

# ls -lZ /root/
-rw-------. root root system_u:object_r:admin_home_t:s0 anaconda-ks.cfg
-rw-r--r--. root root system_u:object_r:admin_home_t:s0 install.log
-rw-r--r--. root root system_u:object_r:admin_home_t:s0 install.log.syslog
drwxr-xr-x. root root unconfined_u:object_r:admin_home_t:s0 rpmbuild
-rw-r--r--. root root unconfined_u:object_r:admin_home_t:s0 selinux-policy-3.7.19-54.el6.src.rpm

・プロセスの SID を確認

# ps -Z
LABEL                             PID TTY          TIME CMD
unconfined_u:unconfined_r:unconfined_t:s0-s0:c0.c1023 9026 pts/2 00:00:00 bash
unconfined_u:unconfined_r:unconfined_t:s0-s0:c0.c1023 9193 pts/2 00:00:00 ps

・ログインユーザの SID を確認

# id -Z
unconfined_u:unconfined_r:unconfined_t:s0-s0:c0.c1023

・Linux ユーザと SELinux ユーザのマッピングを確認

# semanage login -l

ログイン名                     SELinux ユーザー              MLS/MCS 範囲

__default__               unconfined_u              s0-s0:c0.c1023
root                      unconfined_u              s0-s0:c0.c1023
system_u                  system_u                  s0-s0:c0.c1023

・Enforcing モードと Permissive モードの切り替え

# setenforce
usage:  setenforce [ Enforcing | Permissive | 1 | 0 ]