newrole -r role_r -t domain_t を実行しなければいけません (通常は与えられたロールに対して単一のドメインだけが許されているため -t パラメータは省略されることが多いです)。このコマンドはユーザに自分のパスワードを入力させることで認証を行います。この機能のおかげで、プログラムが自動的にロールを切り替えることを禁止できます。ロールの変更を行えるのは、ユーザが SELinux ポリシーに基づいてロール変更を許可されている場合に限ります。
ssh は ssh_exec_t でラベル付けされています。ssh プログラムが起動すると ssh プログラムは ssh_t ドメインに自動的に切り替わります)。この自動ドメイン遷移メカニズムによって、それぞれのプログラムに対して必要な権限だけを認めることが可能です。これが SELinux の基本原則です。
apt install selinux-basics selinux-policy-default コマンドで、SELinux システムを設定するために必要なパッケージが自動的にインストールされます。
行動を制限されていないモジュールを無効化しなければいけません (モジュール管理はこの節でより詳しく説明されています)。
fixfiles relabel を使って手作業で開始しなければいけません。
selinux=1 security=selinux パラメータを 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.bz2 を使うべきです。pp.bz2 拡張子は bzip2 で圧縮されたポリシーパッケージを意味しています。
semodule -r module を使います。最後に、semodule -l コマンドは現在インストールされているモジュールとそのバージョンをリストします。モジュールを選択的に有効化するには semodule -e、無効化するには semodule -d を使います。
#semodule -i /usr/share/selinux/default/abrt.pp.bz2#semodule -labrt 1.5.0 Disabled accountsd 1.1.0 acct 1.6.0 [...]#semodule -e abrt#semodule -d accountsd#semodule -labrt 1.5.0 accountsd 1.1.0 Disabled acct 1.6.0 [...]#semodule -r abrt#semodule -laccountsd 1.1.0 Disabled acct 1.6.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 -lLogin Name SELinux User MLS/MCS Range Service __default__ unconfined_u SystemLow-SystemHigh * rhertzog user_u SystemLow * root unconfined_u SystemLow-SystemHigh * system_u system_u SystemLow-SystemHigh * #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 -lLabeling MLS/ MLS/ SELinux User Prefix MCS Level MCS Range SELinux Roles root sysadm SystemLow SystemLow-SystemHigh staff_r sysadm_r system_r staff_u staff SystemLow SystemLow-SystemHigh staff_r sysadm_r sysadm_u sysadm SystemLow SystemLow-SystemHigh sysadm_r system_u user SystemLow SystemLow-SystemHigh system_r test_u staff SystemLow SystemLow staff_r user_r unconfined_u unconfined SystemLow SystemLow-SystemHigh system_r unconfined_r user_u user SystemLow SystemLow 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_homedirshttpd_enable_homedirs --> off #setsebool -P httpd_enable_homedirs on#getsebool httpd_enable_homedirshttpd_enable_homedirs --> on
/usr/share/doc/selinux-policy-doc/html/) と新しいモジュールを作成するためのテンプレートとして使えるサンプルファイルが含まれます。これらのファイルをインストールし、さらにしっかりと勉強してください。
$cp /usr/share/doc/selinux-policy-doc/Makefile.example Makefile$cp /usr/share/doc/selinux-policy-doc/example.fc ./$cp /usr/share/doc/selinux-policy-doc/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/devel/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 permissive=1表 14.1 SELinux メッセージの解析
| メッセージ | 説明 |
|---|---|
avc: denied | 操作が拒否されました。 |
{ read write } | この操作には read と write パーミッションが必要です。 |
pid=1876 | PID 1876 のプロセスがこの操作を実行しました (または実行を試行しました)。 |
comm="syslogd" | プロセスは syslogd プログラムのインスタンスです。 |
name="xconsole" | 対象のオブジェクトは xconsole と名付けられました。場合によってはこれの代わりにフルパスを含む「path」変数が設定されていることもあります。 |
dev=tmpfs | 対象のオブジェクトをホストしているデバイスは tmpfs (メモリ内ファイルシステム) です。実ディスクの場合、オブジェクトをホストしているパーティション (たとえば「sda3」) になります。 |
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」ルールを追加するだけに留めることがより良い解決策かもしれません。こうすることで、実際の実行を拒否するのではなくログエントリの記録だけが拒否されます。