newrole -r role_r -t domain_t
を実行しなければいけません (通常は与えられたロールに対して単一のドメインだけが許されているため -t
パラメータは省略される事が多いです)。このコマンドはユーザに自分のパスワードを入力させることで認証を行います。この機能のお陰で、プログラムが自動的にロールを切り替える事を禁止できます。ロールの変更を行えるのは、ユーザが SELinux ポリシーに基いてロール変更を許可されている場合に限ります。
ssh
は ssh_exec_t
でラベル付けされています。ssh
プログラムが起動すると ssh
プログラムは ssh_t
ドメインに自動的に切り替わります)。この自動ドメイン遷移メカニズムによって、それぞれのプログラムに対して必要な権限だけを認める事が可能です。これが SELinux の基本原則です。
aptitude install selinux-basics selinux-policy-default
コマンドで、SELinux システムを設定するために必要なパッケージが自動的にインストールされます。
行動を制限されていない
モジュールを無効化しなければいけません (モジュール管理はこの節でより詳しく説明されています)。
fixfiles relabel
を使って手作業で開始しなければいけません。
selinux=1
パラメータを Linux カーネルに追加する必要があります。audit=1
パラメータは SELinux のログ記録を有効化します。これはすべての拒否された操作を記録するものです。最後にenforcing=1
パラメータはルールをアプリケーションに強制します: enforcing=1
パラメータがなければ、SELinux はデフォルトの permissive モードで動作します。permissive モードの場合、拒否された操作はログ記録され、実行されます。GRUB ブートローダ設定ファイルを変更して、必要なパラメータを追加するべきです。これ簡単に行うには、/etc/default/grub
の中の GRUB_CMDLINE_LINUX
変数を変更します。その後 update-grub
を実行します。SELinux は再起動後に動作状態になります。
selinux-activate
スクリプトがこれらの操作を自動化し、次回起動時にラベル付けを強制する (これは SELinux がまだ動作していなかった時とラベル付けの実行中にラベル付けされていないファイルが新しく作成される事を避ける) 点は注目に値します。
semodule
コマンドです。さらに、管理者はそれぞれのユーザに与えるロールを定義する能力を持っていなければいけません。これは semanage
を使って行います。
semodule
と semanage
コマンドは /etc/selinux/default/
に保存されている現在の SELinux 設定を変更するために使われます。/etc/
に見つかる他の設定ファイルと異なり、すべてのファイルは手作業で修正しなければいけません。管理者はこれらのファイルを編集するために設計されたプログラムを使うべきです。
/usr/share/selinux/default/
ディレクトリに保存されています。現在の設定の中で SELinux モジュールの 1 つを有効化するには、semodule -i module.pp
を使うべきです。pp 拡張子はポリシーパッケージを意味しています。
semodule -r module
を使います。最後に、semodule -l
コマンドは現在有効化されているモジュールとそのバージョンをリストします。
#
semodule -i /usr/share/selinux/default/aide.pp
#
semodule -l
aide 1.4.0 apache 1.10.0 apm 1.7.0 [...]
#
semodule -r aide
#
semodule -l
apache 1.10.0 apm 1.7.0 [...]
semodule
は -n
オプションを付けない限り、すぐさま新しい設定を読み込みます。semodule
プログラムがデフォルトで現在の設定に対して操作を行う点は注目に値します (現在の設定は /etc/selinux/config
内の SELINUXTYPE
変数によって表されます)。しかし、-s
オプションを使えば、これを他のものに変更する事が可能です。
semanage
コマンドを使って設定する事が可能です。
-a
は追加、-d
は削除、-m
は修正、-l
はリスト、-t
はタイプ (またはドメイン) の指定を表します。
semanage login -l
はユーザ識別情報と SELinux 識別情報の現在の対応付けをリストします。明確なエントリを持たないユーザは __default__
エントリであらわされる識別情報を獲得します。semanage login -a -s user_u user
コマンドは user_u 識別情報を指定されたユーザに対応付けます。最後に、semanage login -d user
は対指定したユーザに関連付けられた対応付けエントリを削除します。
#
semanage login -a -s user_u rhertzog
#
semanage login -l
Login Name SELinux User MLS/MCS Range __default__ unconfined_u s0-s0:c0.c1023 rhertzog user_u None root unconfined_u s0-s0:c0.c1023 system_u system_u s0-s0:c0.c1023 #
semanage login -d rhertzog
semanage user -l
は SELinux ユーザ識別情報と許可されたロールの対応付けをリストします。新しい識別情報を追加した場合、識別情報に対応するロールと、個人ファイル (/home/user/*
) にタイプを割り当てるために使われるプレフィックスのラベル付けが必要になります。このプレフィックスは user
、staff
、sysadm
のどれか 1 つを選ばなければいけません。「staff
」プレフィックスをつけるとファイルのタイプは「staff_home_dir_t
」になります。新しい SELinux ユーザ識別情報を作成するには semanage user -a -R roles -P prefix identity
を使います。最後に、SELinux ユーザ識別情報を削除するには semanage user -d identity
を使います。
#
semanage user -a -R 'staff_r user_r' -P staff test_u
#
semanage user -l
Labeling MLS/ MLS/ SELinux User Prefix MCS Level MCS Range SELinux Roles root sysadm s0 s0-s0:c0.c1023 staff_r sysadm_r system_r staff_u staff s0 s0-s0:c0.c1023 staff_r sysadm_r sysadm_u sysadm s0 s0-s0:c0.c1023 sysadm_r system_u user s0 s0-s0:c0.c1023 system_r test_u staff s0 s0 staff_r user_r unconfined_u unconfined s0 s0-s0:c0.c1023 system_r unconfined_r user_u user s0 s0 user_r #
semanage user -d test_u
/srv/www/
ファイル階層内のファイルを読む事を許可する場合、semanage fcontext -a -t httpd_sys_content_t "/srv/www(/.*)?"
を実行し、その後 restorecon -R /srv/www/
を実行します。最初のコマンドで新しいラベル付けルールを登録し、次のコマンドで現在のラベル付けルールに基いてファイルタイプを再設定します。
semanage port -m -t http_port_t -p tcp 8080
を実行します。
getsebool
ユーティリティを使ってブール値オプションを調査します (getsebool boolean
は 1 つのオプションを表示し、getsebool -a
はすべてのオプションを表示します)。setsebool boolean value
コマンドはブール値オプションの現在の値を変更します。-P
オプションを付けるとこの修正が永続的なものになります。つまり、新しい値がデフォルトになり、再起動後も適用される事になります。以下の例では、ウェブサーバにホームディレクトリに対するアクセス権を与えています (ユーザが個人的なウェブサイトを ~/public_html/
の下に作る場合、この設定を使うと便利です)。
#
getsebool httpd_enable_homedirs
httpd_enable_homedirs --> off #
setsebool -P httpd_enable_homedirs on
#
getsebool httpd_enable_homedirs
httpd_enable_homedirs --> on
/usr/share/doc/selinux-policy-doc/html/
) と新しいモジュールを作成するためのテンプレートとして使えるサンプルファイルが含まれます。これらのファイルをインストールし、更にしっかりと勉強して下さい:
$
zcat /usr/share/doc/selinux-policy-doc/Makefile.example.gz >Makefile
$
zcat /usr/share/doc/selinux-policy-doc/example.fc.gz >example.fc
$
zcat /usr/share/doc/selinux-policy-doc/example.if.gz >example.if
$
cp /usr/share/doc/selinux-policy-doc/example.te ./
.te
ファイルは最も重要なファイルです。これがルールを定義します。.fc
ファイルは「ファイルコンテキスト」を定義します。「ファイルコンテキスト」はこのモジュールに関連するファイルに割り当てるタイプを意味します。.fc
ファイルに含まれるデータはファイルのラベル付け中に使われます。最後に、.if
ファイルはモジュールのインターフェースを定義します: これは一連の「公開関数」で、他のモジュールはこの関数を使ってここで作成されたモジュールと情報をやり取りします。
.fc
ファイルの構造を十分に理解する事が可能です。復数のファイルおよび完全なディレクトリツリーに対して、同じセキュリティコンテキストを割り当てるために、正規表現を使う事が可能です。
myapp_domtrans
」) はアプリケーションを実行できるユーザを制御します。2 番目のインターフェース (「myapp_read_log
」) はアプリケーションのログファイルに対する読み込み権限を制御します。
.te
ファイルに組み込む事が可能な有効なルール群を生成しなければいけません。そんなわけで、管理者は (gen_require
マクロを使って) 使用するすべてのタイプを宣言し、権限を取得するために標準的な指示文を使うべきです。しかしながら、他のモジュールが提供するインターフェースを使う事が可能な点に注意してください。次の節では、これらの権限を表現する方法についてより詳しく説明します。
例14.3 example.if
ファイル
## <summary>Myapp example policy</summary> ## <desc> ## <p> ## More descriptive text about myapp. The <desc> ## tag can also use <p>, <ul>, and <ol> ## html tags for formatting. ## </p> ## <p> ## This policy supports the following myapp features: ## <ul> ## <li>Feature A</li> ## <li>Feature B</li> ## <li>Feature C</li> ## </ul> ## </p> ## </desc> # ######################################## ## <summary> ## Execute a domain transition to run myapp. ## </summary> ## <param name="domain"> ## Domain allowed to transition. ## </param> # interface(`myapp_domtrans',` gen_require(` type myapp_t, myapp_exec_t; ') domtrans_pattern($1,myapp_exec_t,myapp_t) ') ######################################## ## <summary> ## Read myapp log files. ## </summary> ## <param name="domain"> ## Domain allowed to read the log files. ## </param> # interface(`myapp_read_log',` gen_require(` type myapp_log_t; ') logging_search_logs($1) allow $1 myapp_log_t:file r_file_perms; ')
example.te
を見てみましょう:
policy_module(myapp,1.0.0)######################################## # # Declarations # type myapp_t;
type myapp_exec_t; domain_type(myapp_t) domain_entry_file(myapp_t, myapp_exec_t)
type myapp_log_t; logging_log_file(myapp_log_t)
type myapp_tmp_t; files_tmp_file(myapp_tmp_t) ######################################## # # Myapp local policy # allow myapp_t myapp_log_t:file { read_file_perms append_file_perms };
allow myapp_t myapp_tmp_t:file manage_file_perms; files_tmp_filetrans(myapp_t,myapp_tmp_t,file)
モジュールは名前とバージョン番号で識別されます。この指示文は必須です。
| |
モジュールによって新しいタイプが導入される場合、この種の指示文を使って新しいタイプを必ず宣言してください。多くの無駄な権限を与えるのでなく、必要な多くのタイプを作成してください。遠慮はいりません。
| |
これらのインターフェースは myapp_exec_t ラベルを付けられた実行ファイルによって使われるプロセスドメインとして myapp_t タイプを定義します。暗黙のうちに、これはオブジェクトに exec_type 属性を追加します。このお陰で、他のモジュールは myapp_exec_t ラベルを付けられたプログラムを実行する権限を取得する事が可能になります: 例えば、userdomain モジュールを使うことで、user_t 、staff_t 、sysadm_t ドメインを持つプロセスは自分を実行する事が可能になります。他の閉じ込められたアプリケーションのドメインは、そのドメインに割り当てられたルールが同様の権限を取得しない限り (例えば dpkg_t ドメインを持つ dpkg がこの場合に相当します)、myapp_exec_t ラベルを付けられたプログラムを実行する権限を持ちません。
| |
logging_log_file はリファレンスポリシーによって提供されるインターフェースです。これは指定されたタイプでラベル付けされたファイルはタイプに対応するルールから恩恵を受ける義務があるログファイルである事を表します (例えば、logrotate がログファイルを処理する事を可能にするために、logrotate に権限を与えます)。
| |
allow 指示文は操作を許可するために使われる基本的な指示文です。1 番目のパラメータはこの操作を実行する事を許されたプロセスドメインです。2 番目のパラメータは 1 番目のパラメータはで指定したドメインのプロセスが操作する事が可能なオブジェクトを定義します。2 番目のパラメータは「type:class」の形で定義します。ここで type は SELinux タイプで class はオブジェクトの種類 (ファイル、ディレクトリ、ソケット、名前付きパイプなど) です。最後に、3 番目のパラメータはパーミッション (許可された操作) を表現します。
パーミッションは許可された操作の一式として定義され、以下のテンプレートに従います: { operation1 operation2 } 。しかしながら、最も役に立つパーミッションを表すマクロを使う事も可能です。/usr/share/selinux/default/include/support/obj_perm_sets.spt には、利用可能なパーミッションのマクロが説明されています。
以下のウェブページでは、オブジェクトクラスと取得されるパーミッションの比較的包括的なリストが載せられています。
|
avc: denied { read write } for pid=1876 comm="syslogd" name="xconsole" dev=tmpfs ino=5510 scontext=system_u:system_r:syslogd_t:s0 tcontext=system_u:object_r:device_t:s0 tclass=fifo_file
表14.1 SELinux メッセージの解析
メッセージ | 説明 |
---|---|
avc: denied | 操作が拒否されました。 |
{ read write } | この操作には read と write パーミッションが必要です。 |
pid=1876 | PID 1876 のプロセスがこの操作を実行しました (または実行を試行しました)。 |
comm="syslogd" | プロセスは syslogd プログラムのインスタンスです。 |
name="xconsole" | 対象のオブジェクトは xconsole と名付けられていました。 |
dev=tmpfs | 対象のオブジェクトをホストしているデバイスは tmpfs (メモリ内ファイルシステム) です。実ディスクの場合、オブジェクトをホストしているパーティション (例:「hda3」) になります。 |
ino=5510 | オブジェクトは inode 番号 5510 で識別されています。 |
scontext=system_u:system_r:syslogd_t:s0 | これは操作を実行したプロセスのセキュリティコンテキストです。 |
tcontext=system_u:object_r:device_t:s0 | これは対象オブジェクトのセキュリティコンテキストです。 |
tclass=fifo_file | 対象オブジェクトは FIFO ファイルです。 |
allow syslogd_t device_t:fifo_file { read write }
。この作業は自動化する事が可能です。これが (policycoreutils パッケージに含まれる) audit2allow
コマンドの役割です。設定する必要のある内容に応じて、様々なオブジェクトが既に正しくラベル付けされている場合にのみ、このアプローチは役に立ちます。いずれにせよ、管理者は必ず、生成されたルールを注意深く確認し、アプリケーションに対する知識に基いてルールの妥当性を検査しなければいけません。事実上、このアプローチはアプリケーションが本当に必要としている権限よりも多くの権限を与えようとします。ほとんどの場合、新しいタイプを作成し、作成したタイプだけに権限を与える事が適切な解決策と言えます。また、拒否された操作がアプリケーションにとって致命的でない場合もあります。この場合、「dontaudit
」ルールを追加するだけに留める事がより良い解決策かもしれません。こうすることで、実際の実行を拒否するのではなくログエントリの記録だけが拒否されます。