📢 Webサイト閉鎖と移転のお知らせ
このWebサイトは2026年9月に閉鎖いたします。
新しい記事は移転先で追加しております。(旧サイトでは記事を追加しておりません)

概要

SELinux (Security-Enhanced Linux) は、Linuxのセキュリティ拡張機能であり、強制アクセス制御 (MAC) の仕組みを提供する。 (Linux 2.6以降でサポート)
外部に侵入されないための仕組みではなく、侵入された後にアクセスできる範囲を最小限に抑えるための仕組みである。

SELinuxの特徴を以下に示す。

  • 強制アクセス制御 (MAC)
    従来の任意アクセス制御 (DAC) に加えて、より厳格なアクセス制御を実現する。

  • 最小権限の原則
    プロセスやユーザに必要最小限の権限のみを与えることで、潜在的な被害を制限する。

  • ポリシーベースの制御
    システム管理者が定義したセキュリティポリシーに基づいてアクセスを制御する。

  • コンテキストラベル
    ファイル、プロセス、ポート等のリソースにセキュリティコンテキストを割り当てる。

  • 動作モード
    Enforcing (強制)、Permissive (許容)、Disabled (無効) の3つのモードがある。

  • ログ機能
    セキュリティ違反の試みを詳細にログに記録する。


SELinuxの参考書
 
SELinux System Administration 3rd Edition
ソフトウェアやユーザ等を保護するための強制アクセス制御(MAC)の実装
 
SELinux Cookbook



SELinuxの役割

SELinuxは、Linux上で動作するプロセスからファイル等のリソースに対するアクセスを制御するのが主な機能である。
通常のLinuxシステムでは、ユーザやグループのファイルに対するアクセス権で制御されますが、スーパーユーザは特権ユーザとして全てのファイル等にアクセスすることができる。

これに対して、SELinuxは"強制アクセス制御"(MAC: Mandatory Access Control)と呼ばれる方式を採用している。
MACは、スーパーユーザに対しても設定されたアクセス制御を超えた特権を与えることがない。

多くのセキュリティ攻撃がスーパーユーザ権限を奪取することを第一の目的とし、その後の攻撃に繋げていることを考えると、セキュリティ対策として必要な機能といえる。


SELinuxの機能

TE(Type Enforcement)

プロセスがアクセスできるリソースを制限する機能である。

プロセスにドメインを、リソースにタイプを割り当て、その組み合わせごとにアクセス権を設定する。
このアクセス権の設定の集合を、アクセスベクタという。

子プロセス生成時には、基本的には親プロセスのドメインが引き継がれる。
子プロセスのドメインを変更することを、ドメイン遷移と呼ぶ。

RBAC(Role Based Access Controle)

ユーザがアクセスできるリソースを制限する機能である。

ユーザごとにアクセス可能なロールが決まっており、ロールごとにアクセス可能なドメインが決まっている。
TEにより、ドメインごとにアクセス可能なタイプが決まっているため、最終的には、ユーザがアクセス可能なオブジェクトを制御することができる。

RHELでは、全てのLinuxユーザがunconfined_uに対応しており、unconfined_uにはアクセス制限が掛けられない。
したがって、RHELではRBACは意味をなさない。


SELinuxの機能

セキュリティコンテキストの構造

セキュリティコンテキストの形式:user:role:type:level
要素 識別子の例 説明
ユーザ識別子 system_u SELinuxユーザを表す。
Linuxユーザとは異なる概念
ロール識別子 object_r ユーザが遷移可能なドメインを制限する
RBAC (ロールベースアクセス制御) で使用する。
タイプ/ドメイン識別子 lib_t プロセス (ドメイン)やファイル (タイプ)を識別
Type Enforcementで使用する。
レベル識別子 s0 MLS (Multi Level Security) および MCS (Multi Category Security) で使用。
情報の機密性を表す。


SELinuxユーザ

SELinuxユーザ 説明 備考
unconfined_u アクセス制限のないユーザ RHELでは全てのLinuxユーザがデフォルトでunconfined_uにマッピングされる。
user_u 制限された一般ユーザ 限定的な権限のみ持つ。
staff_u 管理者補助ユーザ user_uより権限が多いが、完全な管理者権限はない。
sysadm_u システム管理者ユーザ システム管理タスクを実行可能。
system_u システムプロセス用ユーザ デーモンやシステムサービスで使用する。
guest_u ゲストユーザ 最も制限されたユーザ
ネットワークアクセスやsudoの使用不可。
xguest_u X Window System用ゲストユーザ guest_uより少し権限が多い
GUIアプリケーション使用可能。


ロール

ロール 対象 説明
object_r ファイル 一般的なファイルのロール
ファイルにとってロールは実質的な意味を持たない。(常にobject_r)
system_r プロセス システムプロセスやデーモンのロール
/procディレクトリ下のプロセス関連ファイルにも使用する。
user_r プロセス 一般ユーザ (user_u) が起動するプロセスのロール
staff_r プロセス スタッフユーザ (staff_u) が起動するプロセスのロール
sysadm_r プロセス システム管理者 (sysadm_u) が起動するプロセスのロール
管理タスクを実行可能
unconfined_r プロセス 制限のないロール
unconfined_uユーザに関連付けられる。


ドメイン (プロセス用)

分類 ドメイン 説明
制限のないドメイン
(Unconfined Domain)
unconfined_t ログインユーザが起動するプロセスのドメイン
SELinuxによるアクセス制限を受けない。
通常のDACによるアクセス制御は有効。
initrc_t initまたはsystemdで開始されたシステムプロセスのドメイン
SELinuxによる制限なし。
kernel_t カーネルプロセスのドメイン
カーネルスレッドやカーネル内部処理で使用する。
制限のあるドメイン
(Confined Domain)
httpd_t Apache HTTP Server (httpd)プロセスのドメイン
Webサーバとして必要な最小限の権限のみ付与。
sshd_t SSH デーモン (sshd)のドメイン
リモートアクセスに必要な権限のみ。
crond_t cronデーモンのドメイン
スケジュールされたタスク実行に必要な権限のみ。
mysqld_t MySQLデータベースサーバーのドメイン
データベース操作に必要な権限のみ。
ftpd_t FTPサーバー (vsftpd等)のドメイン
ファイル転送に必要な権限のみ。
named_t DNS サーバー (BIND)のドメイン
DNS問い合わせ処理に必要な権限のみ。
postfix_t Postfix メールサーバーのドメイン
メール配送に必要な権限のみ。
samba_t Sambaサーバーのドメイン
ファイル共有に必要な権限のみ。


※注意
制限のないドメインは、SELinuxによる防御が無効となるため、システムが侵害された場合のセキュリティリスクが高い。
可能な限り制限のあるドメインを使用することが推奨される。

タイプ (ファイル/オブジェクト用)

タイプ 分類 説明
file_t デフォルト/未設定 タイプが明示的に割り当てられていないファイル
制限されたドメインからはアクセス不可。
セキュリティ上の問題を示す可能性がある。
default_t デフォルト/未設定 割り当てるべきタイプが設定されていない場合にデフォルトで付与されるタイプ
制限されたドメインからはアクセス不可。
httpd_sys_content_t Webコンテンツ Apache HTTP Serverが読み取り可能なWebコンテンツファイル
静的HTMLファイル等に使用する。
httpd_sys_script_exec_t Webスクリプト Apache HTTP ServerがCGIスクリプトとして実行可能なファイル
httpd_sys_rw_content_t Webコンテンツ (R/W) Apache HTTP Serverが読み書き可能なWebコンテンツ
アップロードディレクトリ等に使用する。
admin_home_t 管理者ホーム 管理者のホームディレクトリ内のファイル
一般ドメインからはアクセス不可。
user_home_t ユーザホーム 一般ユーザのホームディレクトリ内のファイル
ユーザ自身のドメインからのみアクセス可能。
tmp_t 一時ファイル /tmpディレクトリ内の一般的な一時ファイル
var_log_t ログファイル /var/logディレクトリ内のログファイル
特定のドメインのみ書き込み可能。
etc_t 設定ファイル /etcディレクトリ内の一般的な設定ファイル
多くのドメインから読み取り可能。
bin_t 実行ファイル /bin、/usr/binディレクトリ内の一般的な実行可能ファイル
lib_t ライブラリ /lib、/usr/libディレクトリ内の共有ライブラリファイル
device_t デバイスファイル /devディレクトリ内のデバイスファイル
sysfs_t sysfs /sysディレクトリ内のファイル
カーネルパラメータやデバイス情報


MLSレベル (Multi Level Security)

レベル 形式 説明 使用例
単一レベル s0 最低機密性レベル (Unclassified相当) 一般的なシステムオブジェクト
単一レベル s1, s2, ... s15 より高い機密性レベル 機密情報
s1 : Confidential
s2 : Secret
s3 : Top Secret相当
範囲指定 s0〜s15 レベル範囲 (s0〜s15まで) プロセスがアクセス可能なレベル範囲
カテゴリ付き s0:c0.c1023 レベル + カテゴリ (MCS) プロジェクトやテナントの分離
範囲+カテゴリ s0〜s15:c0.c1023 完全なMLS / MCS形式 最も詳細な分類


※注意
標準的なSELinuxポリシー (targeted policy) ではMLSは有効化されておらず、全てs0となる。
MLSを使用する場合は、mls policyを使用する必要がある。


各ソフトウェアのポリシー設定

SELinuxを有効にしている場合、サービスが起動しない問題は、SELinuxポリシーによる制限が原因となる場合がある。
SELinuxはセキュリティ上の観点から、プログラムが実行できるアクションを制限することがある。

まず、ポリシーファイルを作成するために必要なライブラリをインストールする。

# RHEL
sudo dnf install checkpolicy policycoreutils-python

# SUSE
sudo zypper install checkpolicy python3-policycoreutils policycoreutils-devel
                    selinux-tools selinux-policy-devel  # その他SELinux関連のツールもインストールする場合


SELinuxのログを確認する。
SELinuxがサービスをブロックしている場合、SELinuxのログにその旨のエラーメッセージが表示される。

まず、SELinuxログを確認する。

sudo tail -f /var/log/audit/audit.log


次に、ポリシーモジュール(TEファイル : Type Enforcement)とポリシーパッケージファイル (PPファイル : Policy Package) ファイルを作成する。
TEファイルとは、特定のドメインに対する全てのタイプとルールを定義するものである。

sudo grep <サービス名> /var/log/audit/audit.log | audit2allow -M <任意のポリシーファイル名>


必要であれば、TEファイルをコンパイルして、ポリシーモジュールファイル(.mod拡張子)を生成する。

checkmodule -M -m -o <任意のポリシーモジュール名>.mod <任意のポリシーモジュール名>.te


または、TEファイルから直接ポリシーパッケージファイル(.pp拡張子)を生成することもできる。

make -f /usr/share/selinux/devel/Makefile


もし、上記でTEファイルからポリシーモジュールファイル(.mod拡張子)を生成した場合、ポリシーパッケージ(.pp拡張子)を生成する。

semodule_package -o <任意のポリシーパッケージ名>.pp -m <任意のポリシーモジュール名>.mod


作成したポリシーモジュールをSELinuxにロードして、ポリシーを有効にする。

sudo semodule -i <任意のポリシーパッケージ名>.pp



ポリシーモジュールの有効化 / 無効化 / 削除

追加したポリシーは、有効化 / 無効化 / 削除することができる。

# ポリシーの有効化
sudo semodule -e <任意のポリシー名>

# ポリシーの無効化
sudo semodule -d <任意のポリシー名>

# ポリシーの削除
sudo semodule -r <任意のポリシー名>



ポリシーモジュールファイル (TEファイル)

ポリシーモジュールファイル (TEファイル) を作成することにより、特定のソフトウェアやサービスに対するカスタムポリシーを作成できる。
以下に示す要素を組み合わせて、特定のアプリケーションやサービスに対するSELinuxポリシーモジュールを作成することができる。

モジュール宣言

ポリシーパッケージの名前とバージョンを定義する。
これは、TEファイルの最初に記述する必要がある。

policy_moduleマクロを使用すると、自動的にrequire文が追加され、system_rロール、全てのカーネルクラスとパーミッション・オプションでMLS / MCS情報 (sensitivityおよびcategoryステートメント) が含まれる。

  • モジュール名
    ポリシーパッケージの名前
    モジュールレイヤー内で一意である必要がある
  • バージョン
    ポリシーの更新管理に使用される
    M.m.m形式 (Mはメジャーバージョン、mはマイナーバージョン)


policy_module(<モジュール名>, <バージョン>)
# または
module <モジュール名> <バージョン>;

例:
policy_module(myapp, 1.0.0)


タイプ定義

セキュリティコンテキストの一部となるタイプを定義する。

  • タイプ
    SELinuxのセキュリティコンテキストの一部である。
    一般的に、プロセス用のタイプ (_t)、実行ファイル用のタイプ (_exec_t)、データ用のタイプ (_data_t) 等を定義する。
    タイプ名は、アンダースコアで区切られた意味のある名前にすること。
    タイプ識別子は、全て _t で終わることが慣例である。(強制ではない)
  • エイリアス
    オプションでエイリアスを定義できる。
    複数のエイリアスはスペース区切りで中括弧で囲む。
  • 属性
    オプションで事前に宣言された属性を関連付けできる。
    複数の属性はカンマ区切りで指定する。


type <タイプ名>;
type <タイプ名> alias <エイリアス名>;
type <タイプ名>, <属性名>;
type <タイプ名> alias <エイリアス名>, <属性名>;

例:
type myapp_t;
type myapp_exec_t;
type myapp_data_t;
type myapp_log_t alias myapp_log_file_t;
type httpd_t, domain, daemon;


属性定義

複数のタイプをグループ化するための属性を定義する。

  • 属性名
    複数のタイプをグループ化するために使用される
    これにより、複数のタイプに対して1度にルールを適用できる
    例えば、全てのネットワークデーモンに共通のルールを適用する場合等に便利である
    属性識別子は、タイプと同じ名前空間を共有する
    慣例として、属性は _t 以外で終わることでタイプと区別される


attribute <属性名>;

例:
attribute domain;
attribute daemon;
attribute file_type;


タイプ属性の割り当て

事前に宣言されたタイプを、事前に宣言された属性に関連付ける。

typeattribute <タイプ名> <属性名> [, <属性名>];

例:
attribute domain;
attribute daemon;
type myapp_t;
typeattribute myapp_t domain, daemon;


ドメイン遷移ルール

プロセスのドメイン変更を定義する。

type_transitionルール

このルールにより、特定のタイプの実行ファイルが実行された時に、プロセスのドメインが自動的に変更される。

以下の例では、unconfined_tドメインのプロセスがmyapp_exec_tタイプの実行ファイルを実行する時、新しいプロセスはmyapp_tドメインで動作する。

type_transition <ソースタイプ> <ターゲットタイプ>:<クラス> <デフォルトタイプ>;
# ファイル名遷移 (ポリシーバージョン25以降)
type_transition <ソースタイプ> <ターゲットタイプ>:<クラス> <デフォルトタイプ> <オブジェクト名>;

例:
type_transition unconfined_t myapp_exec_t:process myapp_t;
# ファイル名遷移の例
type_transition unconfined_t etc_t:file system_conf_t eric;


type_transitionルールは、以下に示す3つのallowルールとともに使用される必要がある。

  • ソースドメインがターゲットタイプに対してtransitionパーミッションを持つ。
  • ソースドメインが実行ファイルタイプに対してread、execute、getattr等のパーミッションを持つ。
  • デフォルトドメインが実行ファイルタイプに対してentrypointパーミッションを持つ。


※注意
Reference Policyでは、domain_auto_transマクロがこれらのルールを自動的に生成する。

type_changeルール

ユーザ空間のSELinux対応アプリケーションがオブジェクトのラベルを変更する時に使用される。
これらのアプリケーションは、security_compute_relabel(3) と ポリシー内のtype_changeルールを使用して、適用すべき新しいコンテキストを決定する。

type_change <ソースタイプ> <ターゲットタイプ>:<クラス> <変更後タイプ>;

例:
type_change auditadm_t sysadm_devpts_t:chr_file auditadm_devpts_t;
type_change staff_t server_ptynode:chr_file staff_devpts_t;


type_memberルール

SELinux対応アプリケーションがオブジェクトの新しいポリインスタンス化されたラベルを定義する時に使用される。
これらのアプリケーションは、avc_compute_member(3) または security_compute_member(3)とポリシー内のtype_memberルールを使用して、適用すべきコンテキストを決定する。

type_member <ソースタイプ> <ターゲットタイプ>:<クラス> <メンバータイプ>;

例:
type_member sysadm_t user_home_dir_t:dir user_home_dir_t;


allowルール

基本的なアクセス制御を定義する。
ソースタイプ (通常はプロセス) がターゲットタイプ (ファイルやディレクトリ等) に対して特定の操作を行うことを許可する。

  • クラス
    ファイル、ディレクトリ、ソケット等のリソースタイプを指定する。
  • パーミッション
    read、write、execute等の操作を指定する。
    ワイルドカード演算子 (*) は、そのオブジェクトクラスのすべてのパーミッションを指定する。
    補完演算子 (~) は、明示的にリストされたパーミッション以外のすべてのパーミッションを指定する。
  • self キーワード
    ターゲットタイプにselfを指定すると、ソースタイプと同じタイプを意味する。


allow <ソースタイプ> <ターゲットタイプ>:<クラス> { <パーミッション> };

例:
allow myapp_t myapp_data_t:file { read write getattr };
allow kernel_t filesystem_type:filesystem mount;
allow staff_t self:capability { setgid chown fowner };

# ワイルドカード演算子の例
allow bootloader_t system_dbusd_t:dbus *;

# 補完演算子の例
allow files_unconfined_type file_type:{ file chr_file } ~execmod;


auditallowルール

イベントを監査記録として記録する。
監査目的で有用な場合に使用する。

このルールはイベントを監査するのみであり、アクセスを許可するにはallowルールが依然として必要である。

auditallow <ソースタイプ> <ターゲットタイプ>:<クラス> { <パーミッション> };

例:
auditallow ada_t self:process execstack;


dontauditルール

拒否メッセージの監査を停止する。
このイベントが常に発生することが既知であり、実際の問題を引き起こさない場合に使用する。

これにより、既知のイベントを除外することで監査ログの管理を支援する。

dontaudit <ソースタイプ> <ターゲットタイプ>:<クラス> { <パーミッション> };

例:
dontaudit traceroute_t { port_type -port_t }:tcp_socket name_bind;


neverallowルール

allowルールが操作に対して生成されてはならないことを指定する。
これは以前に許可されていた場合でも同様である。

neverallow文は、コンパイラで強制されるアクションであり、checkpolicyまたはcheckmoduleコンパイラは、ポリシーソース内にallowルールが生成されているかを確認して、生成されている場合は警告を発して停止する。

neverallow <ソースタイプ> <ターゲットタイプ>:<クラス> { <パーミッション> };

例:
neverallow ~can_read_shadow_passwords shadow_t:file read;
neverallow { domain -mmap_low_domain_type } self:memprotect mmap_zero;


※注意
neverallowステートメントはモジュール内で許可されているが、これらを検出するにはsemanage.confファイルにexpand-check=1エントリが存在する必要がある。

require文

モジュールポリシーソースファイル内で、外部ソースファイルから必要なポリシーコンポーネントを示すために使用される。

require {
   <要求リスト>
};

例:
require {
   role system_r;
   type httpd_t, httpd_exec_t;
   class file { read write };
};


有効なrequire文キーワード
キーワード 書式 説明
識別子リスト型 role カンマ区切りの識別子リスト
最後はセミコロンで終わる。
require { role system_r, user_r; };
type カンマ区切りの識別子リスト
最後はセミコロンで終わる。
require { type httpd_t, httpd_exec_t; };
attribute カンマ区切りの識別子リスト
最後はセミコロンで終わる。
require { attribute domain, daemon; };
user カンマ区切りの識別子リスト
最後はセミコロンで終わる。
require { user user_u, staff_u; };
bool カンマ区切りの識別子リスト
最後はセミコロンで終わる。
require { bool httpd_enable_cgi; };
sensitivity カンマ区切りの識別子リスト
最後はセミコロンで終わる。
require { sensitivity s0, s1; };
category カンマ区切りの識別子リスト
最後はセミコロンで終わる。
require { category c0, c1; };
class 単一のクラス識別子 + パーミッションリスト クラスキーワードの後に、単一のオブジェクトクラス識別子が続き、
その後に1つ以上のパーミッションが続く。
複数のパーミッションは中括弧で囲まれたスペース区切りのリスト
require { class file { read write }; };


複数のキーワードを同一のrequireブロック内で使用することができる。

require {
   role system_r;
   type httpd_t, httpd_exec_t;
   class file { read write getattr };
   class dir { search };
};


※注意
requireステートメントキーワードのみが、require {...} ブロック内で許可される。

gen_requireマクロ

Reference Policyマクロとして、モジュールファイル内でrequireブロックを挿入するために使用される。

gen_require(`
    <要求ステートメント>
')

例:
gen_require(`
    type ftpd_etc_t;
')


インタフェース使用

再利用可能なポリシールールを活用する。
インタフェースは、再利用可能なポリシールールの集合である。

共通の操作 (例: 設定ファイルの読み取り、ログの書き込み) に対して定義されている。
これにより、ポリシーの記述が簡潔になり、一貫性が保たれる。

インタフェース名(<引数1>, <引数2>, ...)

例:
files_read_etc_files(myapp_t)
logging_log_file(myapp_log_t)
domain_type(myapp_t)
domain_entry_file(myapp_t, myapp_exec_t)


一般的に使用されるインタフェースの例
インタフェース名 カテゴリ 説明 引数 使用例
files_read_etc_files() ファイルアクセス /etcディレクトリ内のファイルの読み取りを許可 ドメインタイプ files_read_etc_files(myapp_t)
files_type() タイプ宣言 ファイルシステムタイプとして宣言する。
ファイルシステム関連の共通属性を自動的に割り当てる。
タイプ識別子 files_type(myapp_data_t)
logging_log_file() タイプ宣言 ログファイルタイプとして宣言する。
ログディレクトリへのアクセス権限を設定
タイプ識別子 logging_log_file(myapp_log_t)
domain_type() タイプ宣言 ドメインタイプとして宣言する。
プロセスドメインとしての属性を付与する。
タイプ識別子 domain_type(myapp_t)
domain_entry_file() ドメイン遷移 ドメインエントリポイントとして宣言する。
指定した実行ファイルからドメインへの遷移を設定
ドメインタイプ、実行ファイルタイプ domain_entry_file(myapp_t, myapp_exec_t)
corecmd_exec_bin() コマンド実行 /bin、/usr/bin内のコマンドの実行を許可 ドメインタイプ corecmd_exec_bin(myapp_t)
files_search_etc() ファイルアクセス /etcディレクトリの検索を許可 ドメインタイプ files_search_etc(myapp_t)
files_read_usr_files() ファイルアクセス /usrディレクトリ内のファイルの読み取りを許可 ドメインタイプ files_read_usr_files(myapp_t)
kernel_read_system_state() システムアクセス カーネルシステム状態の読み取りを許可 ドメインタイプ kernel_read_system_state(myapp_t)
corenet_tcp_bind_generic_node() ネットワーク 任意のネットワークノードへのTCPバインドを許可 ドメインタイプ corenet_tcp_bind_generic_node(myapp_t)
logging_search_logs() ファイルアクセス ログディレクトリの検索を許可 ドメインタイプ logging_search_logs(myapp_t)
init_daemon_domain() タイプ宣言 initデーモンドメインとして宣言する。
systemdから起動されるサービス用
ドメインタイプ、実行ファイルタイプ init_daemon_domain(myservice_t, myservice_exec_t)


※注意
これらはReference Policyマクロであり、.ifファイル内で定義されたインタフェースである。
使用時には、各インタフェースのドキュメントを参照して、必要な引数と動作を確認すること。

ブール値の定義

ランタイムでのポリシー調整を可能にする。
ブール値は、ランタイムでポリシーの動作を変更するために使用される。

管理者は、setseboolコマンドを使用してこれらの値を変更できる。
これにより、システムの再起動やポリシーの再コンパイル無しでポリシーを調整できる。

bool <ブール名> <デフォルト値>;

例:
bool myapp_enable_feature false;
bool allow_execheap false;
bool allow_execstack true;


デフォルト値は、true または false である。

条件付きポリシー

動的なポリシー適用を実現する。
条件付きポリシーは、ブール値の状態に基づいてポリシールールを動的に適用または除外する。

これにより、単一のポリシーモジュール内で異なる設定をサポートすることができる。

if (<条件式>) {
   <trueリスト>
}

if (<条件式>) {
   <trueリスト>
}
else {
   <falseリスト>
}

例:
if (myapp_enable_feature) {
   allow myapp_t user_home_t:file { read write };
}

if (allow_daemons_use_tty) {
   term_use_all_terms(daemon)
}
else {
   term_dontaudit_use_all_terms(daemon)
}


条件式で使用可能な論理演算子:

  • && (論理AND)
  • || (論理OR)
  • ^ (排他的OR、XOR)
  • ! (論理NOT)
  • == (等しい)
  • != (等しくない)


if/else構成内で許可されるステートメントとルール:

  • allow、auditallow、dontaudit
  • type_member、type_change
  • type_transition (ファイル名遷移を除く)
  • require


※注意
neverallowとauditdeny (非推奨) は条件付きステートメント内では許可されない。

optional文

ポリシーステートメントが最終的にコンパイルされたポリシーに存在する場合と存在しない場合を示すために使用される。

optional {...} 内の全てのステートメントが正常に展開できる場合にのみ、ステートメントがポリシーに含まれる。
これは通常、リストの先頭でrequireステートメントを使用することで実現される。

optional {
   <ルールリスト>
}

optional {
   <ルールリスト>
} else {
   <代替ルールリスト>
}

例:
optional_policy(`
   unconfined_domain(ada_t)
')


ロールの割り当て

ユーザのアクセス可能なドメインを制限する。

  • ロール
    ユーザがアクセスできるドメイン (タイプ) を制限するために使用される。
    特定のロールにタイプを関連付けることにより、そのロールを持つユーザのみがそのタイプのプロセスを実行できる。
    ロール識別子は、慣例として _r で終わる。(強制ではない)


role <ロール名> types <タイプ名>;

例:
role system_r types myapp_t;
role user_r types user_t;


role allowルール

ロールの変更が許可されているかどうかを確認する。
許可されている場合、role_transitionのさらなる要求が行われ、プロセスが新しいロールまたはロールセットで実行される。

allow <ソースロール名> <ターゲットロール名>;

例:
allow sysadm_r secadm_r;


role_transitionルール

ロール遷移が必要であることを指定する。
許可されている場合、プロセスは新しいロールで実行される。

ポリシーバージョン25以降、クラスを定義できる。

role_transition <ソースロール> <ターゲットタイプ> <クラス> <デフォルトロール>;

例:
role_transition system_r httpd_exec_t:process system_r;


ファイルコンテキストの指定

ファイルシステムのラベリングルールを定義する。
これは、指定されたタイプをファイルタイプとして宣言する。

ファイルタイプには、ファイルシステム関連の共通属性が自動的に割り当てられる。
これにより、ファイルシステムのラベリングルールを簡単に定義できる。

files_type(<タイプ名>)

例:
files_type(myapp_data_t)
files_type(myapp_log_t)


※注意
files_type()は、Reference Policyマクロであり、ポリシー言語の標準ステートメントではない。

予約語

下表のキーワードは、SELinuxポリシー言語で予約されている。

予約語リスト
alias allow and attribute
attribute_role auditallow auditdeny bool
category cfalse class clone
common constrain ctrue dom
domby dominance dontaudit else
equals false filename filesystem
fscon fs_use_task fs_use_trans fs_use_xattr
genfscon h1 h2 identifier
if incomp inherits iomemcon
ioportcon ipv4_addr ipv6_addr l1
l2 level mlsconstrain mlsvalidatetrans
module netifcon neverallow nodecon
not notequal number object_r
optional or path pcidevicecon
permissive pirqcon policycap portcon
r1 r2 r3 range
range_transition require role roleattribute
roles role_transition sameuser sensitivity
sid source t1 t2
t3 target true type
typealias typeattribute typebounds type_change
type_member types type_transition u1
u2 u3 user validatetrans
version_identifier xor default_user default_role
default_type default_range low high
low_high


ポリシーファイルタイプ別の有効なステートメント

下表に、各タイプのポリシーソースファイルで許可されるステートメントとルールを示す。

ステートメント/ルール モノリシックポリシー ベースポリシー モジュールポリシー 条件付きステートメント optional文 require文
allow 不可
allow - Role 不可 不可
attribute 不可
auditallow 不可
bool 不可
dontaudit 不可
if 不可 不可
neverallow 不可 不可
optional 不可
require 不可 不可
role 不可
role_transition 不可 不可
type 不可 不可
type_change 不可
type_member 不可
type_transition 可 (注1) 不可
typeattribute 不可 不可
user 不可


※注意
ファイル名遷移ルールを除く。

一般的なルール

識別子の命名規則
  • 識別子は一般的に任意の長さにできるが、以下の文字に制限する必要がある。
    a-z、A-Z、0-9、_ (アンダースコア)
  • 慣例により、タイプ識別子は _t で終わる。
  • 慣例により、ロール識別子は _r で終わる。
  • 慣例により、ユーザ識別子は _u で終わる。
  • 属性識別子は、タイプと区別するために _t 以外で終わる。


コメント
  • # はポリシーソースファイルでのコメントの開始を示す。


マクロとスペース
  • マクロ名とそのパラメータの間にスペースは許可されない。
  • 正しい例
    policy_module(ftp, 1.7.0)
  • 誤った例
    policy_module (ftp, 1.7.0)


複数エントリの展開

単一のステートメントまたはルールに複数のソースとターゲットエントリが表示される場合、コンパイラ (checkpolicy または checkmodule) はこれらを個別のステートメントまたはルールに展開する。

例:
allow apm_t { console_device_t tty_device_t }:chr_file { getattr read write };

# コンパイラは以下のように展開する:
allow apm_t console_device_t:chr_file { getattr read write };
allow apm_t tty_device_t:chr_file { getattr read write };



設定例

以下に示すようなアプリケーションがあるとする。

  • ホームディレクトリ内のファイルを作成、編集、削除
  • D-BusおよびPolkitを使用して、/etcディレクトリ内のファイルを作成、編集、削除
  • TCP/IP通信を使用して外部ネットワークに接続し、ファイルをダウンロード・アップロード


このアプリケーションのTEファイルでは、以下に示す設定を行う必要がある。

  • ホームディレクトリアクセス
    <アプリケーション名>_home_tタイプでホームディレクトリ内のファイル管理を許可する。
  • D-Bus / Polkit統合
    システムバスへの接続とPolkit認証を通じた権限昇格をサポート
  • ネットワークアクセス
    TCP/IPによる外部接続、HTTP/HTTPS通信、DNS解決を許可
  • セキュリティ分離
    各リソース(ホーム、/etc、一時ファイル、ログ) に個別のタイプを定義して適切に分離
  • ブール値によるカスタマイズ
    管理者が動作を調整できるようにチューナブルブール値を提供する。
  • オプショナルポリシー
    利用可能な場合のみ適用される追加機能 (X11、GNOME等)


 policy_module(<アプリケーション名>, 1.0.0)
 
 ### 宣言
 
 # プロセスドメインと実行ファイルタイプ
 type <アプリケーション名>_t;
 type <アプリケーション名>_exec_t;
 domain_type(<アプリケーション名>_t)
 domain_entry_file(<アプリケーション名>_t, <アプリケーション名>_exec_t)
 
 # ホームディレクトリ内のアプリケーションデータ
 type <アプリケーション名>_home_t;
 userdom_user_home_content(<アプリケーション名>_home_t)
 
 # 一時ファイル用タイプ
 type <アプリケーション名>_tmp_t;
 files_tmp_file(<アプリケーション名>_tmp_t)
 
 # /etcディレクトリ内の設定ファイル用タイプ
 type <アプリケーション名>_etc_t;
 files_config_file(<アプリケーション名>_etc_t)
 
 # ダウンロード/アップロード用の一時保存領域
 type <アプリケーション名>_var_lib_t;
 files_type(<アプリケーション名>_var_lib_t)
 
 # ログファイル用タイプ
 type <アプリケーション名>_log_t;
 logging_log_file(<アプリケーション名>_log_t)
 
 ### <アプリケーション名> ローカルポリシー
 
 # 基本的なプロセス権限
 allow <アプリケーション名>_t self:process { signal_perms getsched setsched };
 allow <アプリケーション名>_t self:fifo_file rw_fifo_file_perms;
 allow <アプリケーション名>_t self:unix_stream_socket create_stream_socket_perms;
 
 ### ホームディレクトリへのアクセス (一般ユーザ権限)
 
 # ホームディレクトリの検索と読み取り
 userdom_search_user_home_dirs(<アプリケーション名>_t)
 userdom_list_user_home_dirs(<アプリケーション名>_t)
 
 # アプリケーションデータディレクトリの管理
 allow <アプリケーション名>_t <アプリケーション名>_home_t:dir manage_dir_perms;
 allow <アプリケーション名>_t <アプリケーション名>_home_t:file manage_file_perms;
 allow <アプリケーション名>_t <アプリケーション名>_home_t:lnk_file manage_lnk_file_perms;
 
 # ホームディレクトリからの遷移
 userdom_user_home_dir_filetrans(<アプリケーション名>_t, <アプリケーション名>_home_t, dir, ".<アプリケーション名>")
 userdom_user_home_dir_filetrans(<アプリケーション名>_t, <アプリケーション名>_home_t, file, ".<アプリケーション名>rc")
 
 # 一般的なユーザファイルへの読み取りアクセス (必要に応じて)
 userdom_read_user_home_content_files(<アプリケーション名>_t)
 userdom_write_user_tmp_files(<アプリケーション名>_t)
 
 ### /etcディレクトリへのアクセス (D-Bus / Polkit経由)
 
 # D-Busへの接続
 dbus_system_bus_client(<アプリケーション名>_t)
 dbus_connect_system_bus(<アプリケーション名>_t)
 
 # Polkitとの通信
 optional_policy(`
    polkit_dbus_chat(<アプリケーション名>_t)
    polkit_domtrans_auth(<アプリケーション名>_t)
 ')
 
 # /etcディレクトリ内のファイル管理
 # 注意 : 実際にはPolkit経由で権限昇格されたプロセスが操作を行うため、直接的なアクセス権限は最小限に抑える
 files_search_etc(<アプリケーション名>_t)
 allow <アプリケーション名>_t <アプリケーション名>_etc_t:dir manage_dir_perms;
 allow <アプリケーション名>_t <アプリケーション名>_etc_t:file manage_file_perms;
 
 # /etc内での新規ファイル作成時の遷移
 files_etc_filetrans(<アプリケーション名>_t, <アプリケーション名>_etc_t, file)
 files_etc_filetrans(<アプリケーション名>_t, <アプリケーション名>_etc_t, dir)
 
 # Polkit認証のための必要な権限
 auth_use_nsswitch(<アプリケーション名>_t)
 auth_read_passwd(<アプリケーション名>_t)
 
 # sudo/pkexec経由での実行をサポート
 optional_policy(`
    sudo_role_template(<アプリケーション名>, <アプリケーション名>_r, <アプリケーション名>_t)
 ')
 
 ### ネットワークアクセス (TCP/IP)
 
 # 基本的なネットワークソケット権限
 allow <アプリケーション名>_t self:tcp_socket create_stream_socket_perms;
 allow <アプリケーション名>_t self:udp_socket create_socket_perms;
 
 # ネットワークへの接続
 corenet_tcp_sendrecv_generic_if(<アプリケーション名>_t)
 corenet_tcp_sendrecv_generic_node(<アプリケーション名>_t)
 corenet_tcp_connect_all_ports(<アプリケーション名>_t)
 corenet_tcp_bind_generic_node(<アプリケーション名>_t)
 
 # HTTP / HTTPS通信 (ダウンロード/アップロード)
 corenet_tcp_connect_http_port(<アプリケーション名>_t)
 corenet_tcp_connect_http_cache_port(<アプリケーション名>_t)
 
 # DNS解決
 sysnet_dns_name_resolve(<アプリケーション名>_t)
 
 # SSLライブラリへのアクセス
 miscfiles_read_generic_certs(<アプリケーション名>_t)
 miscfiles_read_localization(<アプリケーション名>_t)
 
 ### 一時ファイルの管理
 
 # /tmpディレクトリ内の一時ファイル
 files_tmp_filetrans(<アプリケーション名>_t, <アプリケーション名>_tmp_t, { file dir })
 allow <アプリケーション名>_t <アプリケーション名>_tmp_t:dir manage_dir_perms;
 allow <アプリケーション名>_t <アプリケーション名>_tmp_t:file manage_file_perms;
 
 # /var/lib内のデータ保存領域
 files_search_var_lib(<アプリケーション名>_t)
 allow <アプリケーション名>_t <アプリケーション名>_var_lib_t:dir manage_dir_perms;
 allow <アプリケーション名>_t <アプリケーション名>_var_lib_t:file manage_file_perms;
 
 ### ログ記録
 
 # ログファイルへの書き込み
 logging_search_logs(<アプリケーション名>_t)
 allow <アプリケーション名>_t <アプリケーション名>_log_t:dir { add_name write search };
 allow <アプリケーション名>_t <アプリケーション名>_log_t:file { create write append setattr };
 
 # システムログへの記録
 logging_send_syslog_msg(<アプリケーション名>_t)
 
 ### 共通システムリソースへのアクセス
 
 # カーネル情報の読み取り
 kernel_read_system_state(<アプリケーション名>_t)
 kernel_read_network_state(<アプリケーション名>_t)
 
 # /procファイルシステムの読み取り
 dev_read_urand(<アプリケーション名>_t)
 dev_read_rand(<アプリケーション名>_t)
 
 # 基本的なコマンドの実行
 corecmd_exec_bin(<アプリケーション名>_t)
 corecmd_exec_shell(<アプリケーション名>_t)
 
 # 共有ライブラリの読み取り
 libs_use_ld_so(<アプリケーション名>_t)
 libs_use_shared_libs(<アプリケーション名>_t)
 
 # ローカライゼーションファイルの読み取り
 miscfiles_read_localization(<アプリケーション名>_t)
 
 # /usr内のファイルの読み取り
 files_read_usr_files(<アプリケーション名>_t)
 
 ### デスクトップ環境との統合 (DEの使用時)
 
 optional_policy(`
    # X11との通信
    xserver_user_x_domain_template(<アプリケーション名>, <アプリケーション名>_t, <アプリケーション名>_tmpfs_t)
 ')
 
 optional_policy(`
    # GNOMEキーリングへのアクセス
    gnome_stream_connect_gkeyringd(<アプリケーション名>_t)
 ')
 
 ### ブール値によるオプション機能
 
 ## <desc>
 ## <p>
 ## <アプリケーション名>が全てのユーザファイルへの読み書きを許可する
 ## </p>
 ## </desc>
 gen_tunable(<アプリケーション名>_manage_all_user_content, false)
 
 if (<アプリケーション名>_manage_all_user_content) {
    userdom_manage_user_home_content_files(<アプリケーション名>_t)
    userdom_manage_user_home_content_dirs(<アプリケーション名>_t)
 }
 
 ## <desc>
 ## <p>
 ## <アプリケーション名>がroot権限でのファイル操作を実行することを許可する
 ## </p>
 ## </desc>
 gen_tunable(<アプリケーション名>_allow_privileged_operations, true)
 
 if (<アプリケーション名>_allow_privileged_operations) {
    # Polkit経由での権限昇格を許可
    optional_policy(`
       polkit_domtrans_auth(<アプリケーション名>_t)
    ')
 }
 
 ### オプション : ユーザドメインからの起動を許可
 
 optional_policy(`
    # unconfined_tドメインからの起動
    unconfined_domain(<アプリケーション名>_t)
 ')
 
 # 一般ユーザドメインからのドメイン遷移
 userdom_use_user_terminals(<アプリケーション名>_t)
 
 # ユーザプロセスからの起動を許可
 allow unconfined_t <アプリケーション名>_exec_t:file { execute execute_no_trans };
 domtrans_pattern(unconfined_t, <アプリケーション名>_exec_t, <アプリケーション名>_t)
 
 ### セキュリティ強化オプション
 
 # メモリ実行保護 (必要な場合のみコメント解除)
 # allow <アプリケーション名>_t self:process { execmem execstack };
 
 # ファイルディスクリプタの継承制限
 dontaudit <アプリケーション名>_t domain:process { noatsecure siginh rlimitinh };
 
 # 監査を無効化する一般的な拒否
 dontaudit <アプリケーション名>_t self:capability { sys_resource sys_nice };