Info: Version 1.6.x is available.

English Page

# TOMOYO Linux ポリシー解説書

Last modified: $Date: 2011-07-01 13:55:23 +0900 (Fri, 01 Jul 2011) $

# 目次

## 1. はじめに

1.1 用語の定義

1.2 ドメインの定義およびドメインの遷移

## 2. ポリシーファイルの分類と構文

2.1 ポリシーマネージャ定義（manager.conf）

2.2 プロファイル定義（profile.conf）

2.3 システムポリシー（system_policy.conf）

2.4 ドメイン別ポリシー（domain_policy.conf）

2.5 例外ポリシー（exception_policy.conf）

## 3. /proc/ccs/ インタフェース

3.1 profile

3.2 system_policy

3.3 domain_policy

3.4 exception_policy

3.5 query

3.6 manager

3.7 .domain_status

3.8 meminfo

3.9 grant_log

3.10 reject_log

3.11 self_domain

3.12 .process_status

3.13 .updates_counter

# 1. はじめに

## 1.1 用語の定義

正規化されたパス名 | "/" で始まり、シンボリックリンクや "/./" や "//" や "/../" を含まないパス名。（ただし、現在のプロセスに関する情報にアクセスするための "/proc/self/" ディレクトリに関してはそのまま "/proc/self/" とする。） プロセスが chroot された環境下で動作する場合であっても、 chroot する前のパス名で指定される。 正規化されたパス名は、全てアスキーコードの表示可能な範囲（0x21～0x7E）で構成されている。 従って、\ 文字（0x5C）は \\ 、その他の表示不可能な文字（0x01～0x20、0x7F～0xFF）は \ooo 形式の8進数で表記する。 （例えば、空白文字（0x20）は \040 と表記する。）
正規化されたディレクトリ名 | 正規化されたパス名の内、"/"で終わるもの。
正規化されたファイル名 | 正規化されたパス名の内、"/"で終わらないもの。 正規化されたファイル名は、ディレクトリ以外の全てのファイルタイプ（通常ファイル、キャラクタ型デバイスファイル、ブロック型デバイスファイル、ＦＩＦＯ、シンボリックリンク、ソケット）を含む。
プログラム | 正規化されたファイル名の内、実行可能なもの。
ドメイン | ＭＡＣ（強制アクセス制御）を行うための属性
遷移先ドメイン | プログラムが正常に開始された場合にプロセスが遷移するドメイン
操作対象ドメイン | 操作対象となるプロセスの属しているドメイン

## 1.2 ドメインの定義およびドメインの遷移

TOMOYO Linux においては、全てのプロセスがそれぞれ1つのドメインに属し、全てのプログラムがそれぞれ異なるドメインに属する。現在実行されている2つのプロセスが同一のプログラムであっても、それぞれのプロセスの直前のドメインが異なっていれば異なるドメインに属する。

全てのドメインはカーネルが属するドメイン「<kernel>」を基点として定義される。 /sbin/init はカーネルの属するドメインから起動されるので、 /sbin/init のドメインは「<kernel> /sbin/init」と定義される。 /etc/rc.d/rc はカーネルから起動された /sbin/init の属するドメインから起動されるので、 /etc/rc.d/rc のドメインは「<kernel> /sbin/init /etc/rc.d/rc」と定義される。

実行時のプログラムの名前により異なる動作をするプログラムが存在する。例えば /sbin/pidof は /sbin/killall5 へのシンボリックリンクである。 TOMOYO Linux は正規化したパス名を使用するので、 /sbin/pidof を実行すると /sbin/killall5 が実行されたものとしてドメインが定義される。

プロセスがプログラムを実行しようとすると、以下の処理が行われる。

Step | 内容
プログラム名の取得 | 実行しようとするプログラムの「正規化されたファイル名」を取得して「パス名候補１」とする。ただし、実行しようとするプログラムがシンボリックリンクの場合は、シンボリックリンクを解決したパス名を取得する。 実行しようとするプログラムの「正規化されたファイル名」を取得して「パス名候補２」とする。ただし、実行しようとするプログラムがシンボリックリンクの場合は、シンボリックリンクを解決する前のパス名を取得する。
シンボリックリンクの識別 | 「パス名候補１」と「パス名候補２」が一致しない場合、例外ポリシーから alias 「パス名候補１」 「パス名候補２」 というエントリを探す。見つかった場合は「パス名候補２」を「パス名候補１」とする。
argv[0] のチェック | 「パス名候補１」の最後の / 以降の部分と argv[0] の最後の / 以降の部分が異なっている場合、ドメイン別ポリシーから allow_argv0 「パス名候補１」 「argv[0]の最後の / 以降の部分」 というエントリを探す。見つからなければ拒否する。
類似するプログラムの集約 | 例外ポリシーから aggregator 「パス名候補１」 「集約されたパス名」 というエントリを探す。見つかった場合は、「集約されたパス名」を「パス名候補１」とする。
権限のチェック | ドメイン別ポリシーから 1 「パス名候補１」 3 「パス名候補１」 5 「パス名候補１」 7 「パス名候補１」 1 @「パス名候補１」を含むグループ名 3 @「パス名候補１」を含むグループ名 5 @「パス名候補１」を含むグループ名 7 @「パス名候補１」を含むグループ名 というエントリを探す。見つからなければ拒否する。
遷移先の決定 | (1) 例外ポリシーから no_initialize_domain 「パス名候補１」 from 「現在のプロセスが属しているドメインのドメイン名」 no_initialize_domain 「パス名候補１」 from 「現在のプロセスが属しているドメインのドメイン名」の最後の要素 no_initialize_domain 「パス名候補１」 というエントリを探す。見つかった場合は (3) へ進む。 (2) 例外ポリシーから initialize_domain 「パス名候補１」 from 「現在のプロセスが属しているドメインのドメイン名」 initialize_domain 「パス名候補１」 from 「現在のプロセスが属しているドメインのドメイン名」の最後の要素 initialize_domain 「パス名候補１」 というエントリを探す。見つかった場合は「カーネルが属しているドメインのドメイン名（<kernel>）」と「パス名候補１」とを連結して「遷移先ドメイン」として (6) へ進む。 (3) 例外ポリシーから no_keep_domain 「パス名候補１」 from 「現在のプロセスが属しているドメインのドメイン名」 no_keep_domain 「パス名候補１」 from 「現在のプロセスが属しているドメインのドメイン名」の最後の要素 no_keep_domain 「現在のプロセスが属しているドメインのドメイン名」 no_keep_domain 「現在のプロセスが属しているドメインのドメイン名」の最後の要素 というエントリを探す。見つかった場合は (5) へ進む。 (4) 例外ポリシーから keep_domain 「パス名候補１」 from 「現在のプロセスが属しているドメインのドメイン名」 keep_domain 「パス名候補１」 from 「現在のプロセスが属しているドメインのドメイン名」の最後の要素 keep_domain 「現在のプロセスが属しているドメインのドメイン名」 keep_domain 「現在のプロセスが属しているドメインのドメイン名」の最後の要素 というエントリを探す。見つかった場合は「現在のプロセスが属しているドメインのドメイン名」を「遷移先ドメイン」とし、 (6) へ進む。 (5) 「現在のプロセスが属しているドメインのドメイン名」と「パス名候補１」とを連結して「遷移先ドメイン」とし、(6)へ進む。 (6) ドメイン別ポリシーから「遷移先ドメイン」を探す。見つからなければ拒否する。 (7)通常のプログラム実行処理を行い、正常に終了した場合は「遷移先ドメイン」に遷移する。

# 2. ポリシーファイルの分類と構文

ポリシーファイルは全て /etc/ccs/ ディレクトリに作成しておく。このディレクトリに存在するファイルが /sbin/init の開始時に /sbin/ccs-init によって読み込まれるようになっている。

## 2.1 ポリシーマネージャ定義（manager.conf）

全てのプログラムがポリシーの変更を行えるのは危険であるため、このファイルには /proc/ccs/ インタフェースへの書き込みアクセスを許可するプログラムまたはドメインを定義しておく。

このファイルに定義されていないプログラムやドメインからは /proc/ccs/ インタフェースへの書き込みアクセスができない。システム運用時にポリシーの変更を許可しない場合はこのファイルを削除しておく。

（例）
/usr/lib/ccs/loadpolicy
/usr/lib/ccs/editpolicy
/usr/lib/ccs/setlevel
/usr/lib/ccs/setprofile
/usr/lib/ccs/ld-watch
/usr/lib/ccs/ccs-queryd
<kernel> /sbin/mingetty /usr/lib/bin/bash

## 2.2 プロファイル定義（profile.conf）

TOMOYO Linuxでは、ファイル以外にもいくつかの項目について強制アクセス制御を行うことができるが、ポリシー管理の負担を減らすために、必要の無い機能を無効化できるようになっている。

項目 | 内容 | 自動学習対応
MAC_FOR_FILE | ファイルに対する強制アクセス制御を有効にする。 | ○
MAC_FOR_ARGV0 | プログラム実行時の argv[0] のチェックを有効にする。 | ○
MAC_FOR_CAPABILITY::*** | ケイパビリティに対する強制アクセス制御を有効にする。 *** の部分にはドメイン別ポリシーの allow_capability キーワードで指定可能な値が入る。 | ○
MAC_FOR_NETWORK | ネットワークに対する強制アクセス制御を有効にする。 | ○
MAC_FOR_SIGNAL | シグナルの送信に対する強制アクセス制御を有効にする。 | ○
DENY_CONCEAL_MOUNT | 既存のマウントを隠蔽するようなマウントを禁止する。 | ×
RESTRICT_CHROOT | chroot で移動可能なディレクトリの制限を有効にする。 | ○
RESTRICT_MOUNT | mount で指定可能なパラメータの制限を有効にする。 | ○
RESTRICT_UNMOUNT | 指定されたディレクトリのアンマウントを禁止する。 | ×
RESTRICT_PIVOT_ROOT | pivot_root で交換可能なディレクトリの制限を有効にする。 | ○
RESTRICT_AUTOBIND | ローカルのポート番号を自動選択させる際に、特定のポート番号を選択させないようにする。 | ×
MAX_ACCEPT_ENTRY | 学習モードで自動的に追加されるアクセス許可の上限を指定する。 | －
MAX_GRANT_LOG | アクセスが許可されたログの上限を指定する。 | －
MAX_REJECT_LOG | アクセスが拒否されたログの上限を指定する。 | －
TOMOYO_VERBOSE | ドメイン別ポリシーに対する違反を syslog に表示する。 | －
ALLOW_ENFORCE_GRACE | ポリシーに違反するアクセス要求を対話的に許可する。 | －

RESTRICT_AUTOBIND については以下の値を指定できる。

値 | 内容
0 | 無効。通常のカーネルと同様に動作する。
1 | 有効。

MAX_ACCEPT_ENTRY については以下の値を指定できる。

値 | 内容
任意の整数 | 学習モードで自動的に追加されるアクセス許可の上限。デフォルトはデフォルトはカーネルのコンパイル時に指定。

MAX_GRANT_LOG および MAX_REJECT_LOG については以下の値を指定できる。

値 | 内容
任意の整数 | カーネル内に保持するアクセスログの上限。デフォルトはカーネルのコンパイル時に指定。

TOMOYO_VERBOSE については以下の値を指定できる。

値 | 内容
0 | ドメイン別ポリシーに対する違反を表示しない。
1 | ドメイン別ポリシーに対する違反を表示する。

ALLOW_ENFORCE_GRACE については以下の値を指定できる。

値 | 内容
0 | 強制モードでポリシーに違反したら直ちに拒否する。
1 | 強制モードでポリシーに違反しても、対話的な操作により許可することを可能にする。

上記以外については以下の値を指定できる。

値 | 内容
0 | 無効。通常のカーネルと同様に動作する。
1 | 学習モード。ポリシーに違反してもエラーにせず、ポリシーへの自動追加を行う。
2 | 確認モード。ポリシーに違反してもエラーにせず、ポリシーへの自動追加も行わない。
3 | 強制モード。ポリシーに違反したらエラーとする。

有効にしたい機能とそのモードを「プロファイル番号-項目=値」という形式で定義する。 プロファイル番号は 0 ～ 255 が指定可能である。プロファイルを切り替えるには setprofile コマンドを使用する。また、現在割り当てられているプロファイル番号は ドメイン別ポリシー（domain_policy.conf） の中に use_profile というキーワードで保持される。

## 2.3 システムポリシー（system_policy.conf）

このファイルでは、システム全体に対して適用されるアクセス許可を定義する。以下の 4 種類のアクセス許可を指定できる。

- マウントを許可するデバイスおよびマウントポイント
- アンマウントを許可しないマウントポイント
- chroot で移動できるディレクトリ
- pivot_root で交換できるディレクトリ
- ローカルポート番号の自動選択時に選択させないポート

### マウントを許可するデバイスおよびマウントポイント

マウント許可を指定するには、 allow_mount というディレクティブに続けて、「デバイスファイル マウントポイント ファイルシステム オプション」を指定する。 デバイスファイルを必要とするファイルシステムを指定する場合は、デバイスファイルは正規化されたファイル名でなければいけない。マウントポイントは正規化されたディレクトリ名でなければいけない。オプションは数値で指定する。

「any マウントポイント --remount オプション」と指定すると、「mount -o remount マウントポイント」が許可される。

「複製元 複製先 --bind オプション」と指定すると、「mount --bind 複製元 複製先」が許可される。
「移動元 移動先 --move オプション」と指定すると、「mount --move 移動元 移動先」が許可される。
複製元／複製先／移動元／移動先は正規化されたディレクトリ名でなければならない。

カーネル 2.6.15 以降では、 Shared Subtree という機能が利用できる。
「any マウントポイント --make-unbindable オプション」と指定すると、「mount --make-unbindable マウントポイント」が許可される。
「any マウントポイント --make-private オプション」と指定すると、「mount --make-private マウントポイント」が許可される。
「any マウントポイント --make-slave オプション」と指定すると、「mount --make-slave マウントポイント」が許可される。
「any マウントポイント --make-shared オプション」と指定すると、「mount --make-shared マウントポイント」が許可される。

### アンマウントを許可しないマウントポイント

アンマウント禁止を指定するには、 deny_unmount というディレクティブに続けて、アンマウントを許可しない正規化されたディレクトリ名を指定する。
通常、 /sbin/mingetty が使用する /dev/tty? を含む /dev/ ディレクトリと、リモートログインする場合に pty デバイスファイルが作成される /dev/pts/ ディレクトリを指定する。

/dev が読み込み専用になってしまったり、 /dev/pts がアンマウントされてしまうと、ログインができなくなる。そのため、 / が読み込み専用のシステムでは、 /dev/ や /dev/pts/ がアンマウントされないようにしなければならない。

### chroot で移動できるディレクトリ

chroot 許可を指定するには、 allow_chroot というディレクティブに続けて、 chroot で移動することを許可したい正規化されたディレクトリ名を指定する。
通常、 sshd が使用する /var/empty/sshd/ を指定する。 その他に chroot 環境で動かしたいアプリケーションや、 chroot を行うアプリケーション（ vsftpd の場合 /usr/share/empty/ ）が存在する場合は、それらも指定する。

### pivot_root で交換できるディレクトリ

pivot_root 許可を指定するには、 allow_pivot_root というディレクティブに続けて、新しいルートとなる正規化されたディレクトリ名と古いルートディレクトリとなる正規化されたディレクトリ名を指定する。
通常、このディレクティブを使う必要は無い。

### ローカルポート番号の自動選択時に選択させないポート

ローカルポートの自動選択で特定のポート番号が選択させるのを禁止するには、 deny_autobind というディレクティブに続けて、ローカルポート番号を指定する。 このディレクティブは、特定のポート番号が一時的な用途で割り当てられるのを防ぐのが狙いである。 例えば、一部のプロキシサーバはポート8080を使用するので、ポート8080が一時的な用途のために割り当てられるべきではない。

### ポリシー例

allow_mount | none | /dev/pts/ | devpts | 0x0
allow_mount | /proc | /proc/ | proc | 0x0
allow_mount | usbdevfs | /proc/bus/usb/ | usbdevfs | 0x0
allow_mount | none | /data/ | tmpfs | 0xE
allow_mount | none | /dev/shm/ | tmpfs | 0xE
allow_mount | /dev/hdc | /var/www/ | ext2 | 0xF
allow_mount | any | / | --remount | 0x0
deny_unmount | /dev/
deny_unmount | /dev/pts/
deny_unmount | /proc/
allow_chroot | /var/empty/sshd/
allow_chroot | /usr/share/empty/
allow_chroot | /var/www/html/
allow_chroot | /
deny_autobind | 1-1023
deny_autobind | 8080

## 2.4 ドメイン別ポリシー（domain_policy.conf）

このファイルでは、全てのドメインを定義し、各ドメインに対して与えるアクセス許可を定義する。 以下の 5 種類のアクセス許可を指定できる。

- ファイルに対するアクセス許可
- 指定可能な argv[0] の組み合わせ
- 使用可能なケイパビリティ
- 使用可能なネットワークアドレスとポート
- 使用可能なシグナル

それぞれのアクセス許可について、必要に応じて追加の条件を指定することができる。そのための構文は後述する。

ドメインを定義している行（<kernel>で始まる行）の次行から次のドメインを定義している行の前行までが、そのドメインに対するアクセス許可である。

### ファイルに対するアクセス許可

ファイルに対するアクセス許可としては、以下のディレクティブが存在する。

ディレクティブ | 許可されるアクセス | 指定例
1 | プログラムの実行 | 1 /bin/ls
2 | ファイルの書き込み | 2 /dev/null
3 | ファイルの書き込みと実行 |
4 | ファイルの読み込み | 4 /proc/meminfo
5 | ファイルの読み込みと実行 |
6 | ファイルの読み書き | 6 /dev/null
7 | ファイルの読み書きと実行 |
allow_create | ファイルの新規作成 | allow_create /var/lock/subsys/crond
allow_unlink | ファイルの削除 | allow_unlink /var/lock/subsys/crond
allow_mkdir | ディレクトリの作成 | allow_mkdir /tmp/logwatch.\*/
allow_rmdir | ディレクトリの削除 | allow_rmdir /tmp/logwatch.\*/
allow_mkfifo | FIFO の作成 | allow_mkfifo /dev/initctl
allow_mksock | UNIX ドメインソケットの作成 | allow_mksock /dev/log
allow_mkblock | ブロック型デバイスファイルの作成 | allow_mkblock /dev/\*
allow_mkchar | キャラクタ型デバイスファイルの作成 | allow_mkchar /dev/\*
allow_truncate | ファイルの切り詰めと伸長 | allow_truncate /etc/mtab
allow_symlink | シンボリックリンクの作成 | allow_symlink /dev/cdrom
allow_link | ハードリンクの作成 | allow_link /etc/mtab~\$ /etc/mtab~
allow_rename | ファイル名の変更 | allow_rename /etc/mtab.tmp /etc/mtab
allow_rewrite | ファイル内容の上書き | allow_rewrite /var/log/messages

1 3 5 7 以外のディレクティブではワイルドカードを使用できる。なお、ディレクティブ 3 5 7 の指定は極力避けるべきである。

### 指定可能な argv[0] の組み合わせ

argv[0] の組み合わせを制限するには、 allow_argv0 というディレクティブに続けて、「正規化されたファイル名」と「argv[0] の最後の / より後ろの部分」を指定する。

プログラムを実行する関数である execve() には filename と argv[] と envp[] を渡すことができる。いくつかのプログラム（例えば busybox ）は argv[0] の内容によって振る舞いを変化させる。 プログラムへのシンボリックリンクを経由してプログラムを実行する場合、 TOMOYO Linux のドメイン遷移は filename が指すパス名を正規化した内容に基づいて行われるのに対し、振る舞いは argv[0] （通常は filename が指すパス名と同じ内容）に基づいて行われてしまう。例えば、 /bin/ls と /bin/cat が busybox へのハードリンクとして提供されている環境において、 /tmp/cat という /bin/ls へのシンボリックリンクを作成して /tmp/cat を実行することにより、 /bin/ls のためのドメインで cat として振舞うことができてしまうという抜け穴になる。

このディレクティブの目的は、 filename と argv[0] の内容の組み合わせを制限することでそのような抜け穴を塞ぐことである。

### 使用可能なケイパビリティ

ケイパビリティのアクセス許可を指定するには、 allow_capability というディレクティブに続けて、ケイパビリティを指定する。以下のケイパビリティが指定できる。

値 | 内容
inet_tcp_create | TCP ソケットの使用を許可
inet_tcp_listen | TCP ソケットの listen を許可
inet_tcp_connect | TCP ソケットの connect を許可
use_inet_udp | UDP ソケットの使用を許可
use_inet_ip | RAW ソケットの使用を許可
use_route | ROUTE ソケットの使用を許可
use_packet | PACKET ソケットの使用を許可
use_kernel_module | create_module(2) init_module(2) delete_module(2) の使用を許可
create_fifo | mknod(2) で FIFO の作成を許可
create_block_dev | mknod(2) でブロック型デバイスの作成を許可
create_char_dev | mknod(2) でキャラクタ型デバイスの作成を許可
create_unix_socket | mknod(2) で UNIX ドメインソケットの作成を許可
SYS_MOUNT | mount(2) の使用を許可
SYS_UMOUNT | umount(2) の使用を許可
SYS_REBOOT | reboot(2) の使用を許可
SYS_CHROOT | chroot(2) の使用を許可
SYS_KILL | 0 以外のシグナルで kill(2) tkill(2) tgkill(2)の使用を許可
SYS_VHANGUP | vhangup(2) の使用を許可
SYS_TIME | stime(2) settimeofday(2) adjtimex(2) の使用を許可
SYS_NICE | nice(2) setpriority(2) の使用を許可
SYS_SETHOSTNAME | sethostname(2) setdomainname(2) の使用を許可
SYS_LINK | link(2) の使用を許可
SYS_SYMLINK | symlink(2) の使用を許可
SYS_RENAME | rename(2) の使用を許可
SYS_UNLINK | unlink(2) の使用を許可
SYS_CHMOD | chmod(2) fchmod(2) の使用を許可
SYS_CHOWN | chown(2) fchown(2) lchown(2) の使用を許可
SYS_IOCTL | ioctl(2) compat_sys_ioctl(2) の使用を許可
SYS_KEXEC_LOAD | kexec_load(2) の使用を許可
SYS_PIVOT_ROOT | pivot_root(2) の使用を許可

allow_capability ディレクティブの目的は、プログラムが呼び出すことができるシステムコールを制限することである。幾つかのシステムコールに対しては他のディレクティブやポリシーファイルを使用してより詳細な制限が可能になっている。

- 作成を許可するキャラクタ型デバイスファイルのパス名を allow_mkblock ディレクティブを使用して制限することができる。
- 作成を許可するブロック型デバイスファイルのパス名を allow_mkchar ディレクティブを使用して制限することができる。
- 作成を許可する FIFO のパス名を allow_mkfifo ディレクティブを使用して制限することができる。
- 作成を許可する UNIX ドメインソケットのパス名を allow_mksock ディレクティブを使用して制限することができる。
- 作成を許可するシンボリックリンクのパス名を allow_symlink ディレクティブを使用して制限することができる。
- 削除を許可するパス名を allow_unlink ディレクティブを使用して制限することができる。
- ハードリンクを許可する組み合わせを allow_link ディレクティブを使用して制限することができる。
- パス名の変更を許可する組み合わせを allow_rename ディレクティブを使用して制限することができる。
- 使用を許可する IP アドレスの範囲ととポート番号の範囲を allow_network ディレクティブを使用して制限することができる。
- 送信可能なシグナルの番号と送信先のドメインを allow_signal ディレクティブを使用して制限することができる。
- マウントを許可するデバイスおよびマウントポイントを allow_mount ディレクティブを使用して制限することができる。
- アンマウントを許可しないマウントポイントを deny_unmount ディレクティブを使用して指定することができる。
- chroot で移動できるディレクトリを allow_chroot ディレクティブを使用して制限することができる。
- pivot_root で交換できるディレクトリを allow_pivot_root ディレクティブを使用して制限することができる。

### 使用可能なネットワークアドレスとポート

ネットワークのアクセス許可を指定するには、 allow_network というディレクティブに続けて、プロトコル（TCP UDP RAW の何れか）、 IP アドレス、ポート番号（TCP UDP の場合）またはプロトコル番号（RAW の場合）を指定する。 IPv4 プロトコルおよび IPv6 プロトコルで使用するローカルポート番号が対象である。

ディレクティブ | 許可されるアクセス | 指定例
allow_network TCP bind | ローカルの TCP アドレス／ポートの割り当て | allow_network TCP bind 0.0.0.0 80
allow_network TCP listen | ローカルの TCP アドレス／ポートでの待機 | allow_network TCP listen 0.0.0.0 80
allow_network TCP accept | リモートの TCP アドレス／ポートからの接続受付および通信 | allow_network TCP accept 10.0.0.0-10.255.255.255 1024-65535
allow_network TCP connect | リモートの TCP アドレス／ポートへの接続および通信 | allow_network TCP connect 127.0.0.1 1024-65535
allow_network UDP bind | ローカルの UDP アドレス／ポートの割り当て | allow_network UDP bind 0.0.0.0 53
allow_network UDP connect | リモートの UDP アドレス／ポートとの通信 | allow_network UDP connect 127.0.0.1 53
allow_network RAW bind | ローカルの IP アドレス／プロトコルの割り当て | allow_network RAW bind 127.0.0.1 255
allow_network RAW connect | リモートの IP アドレス／プロトコルとの通信 | allow_network RAW connect 10.0.0.1 1

IPv6 で使われる "::" という表記はサポートされていない。 "::1" ではなく "0:0:0:0:0:0:0:1" のように表記する必要がある。

### 使用可能なシグナル

シグナルのアクセス許可を指定するには、 allow_signal というディレクティブに続けて、シグナルの番号および操作対象ドメインを指定する。
例外が2つ存在する。シグナル番号が0の場合は常に許可される。また、自分の属するドメインへのシグナルの場合には常に許可される。
その他の場合、このファイルに指定されたシグナル番号とドメイン名で始まる場合のみそのシグナルを送信できる。
操作対象ドメインとして <kernel> を指定すると、全てのドメインに指定された番号のシグナルを送信できる。

### 条件付きアクセス許可の指定方法

アクセス許可にユーザＩＤ等に基づいた条件を付加することができる。条件は個々のアクセス許可の末尾に if というディレクティブを用いて指定する。

指定例 | 意味
4 /etc/passwd | /etc/passwd の参照を許可
4 /etc/passwd if task.uid=0 | プロセスのユーザIDが0の場合に限り、/etc/passwd の参照を許可
4 /etc/passwd if task.uid!=0 | プロセスのユーザIDが0ではない場合に限り、/etc/passwd の参照を許可
allow_network TCP connect 10.0.0.1 80 | TCP プロトコルで 10.0.0.1 ポート 80 への接続を許可
allow_network TCP connect 10.0.0.1 80 if task.uid=100 | プロセスのユーザIDが100の場合に限り、TCP プロトコルで 10.0.0.1 ポート 80 への接続を許可
allow_capability SYS_KILL | kill(2) の使用を許可
allow_capability SYS_KILL if task.ppid=1 task.uid=0 task.euid=0 | プロセスが /sbin/init の子であり、かつ、プロセスのユーザIDと実効ユーザIDが0の場合に限り、kill(2) の使用を許可

以下の変数を指定できる。

変数 | 意味
task.uid | 呼び出したプロセスのユーザＩＤ
task.euid | 呼び出したプロセスの実効ユーザＩＤ
task.suid | 呼び出したプロセスの保存ユーザＩＤ
task.fsuid | 呼び出したプロセスのファイルシステムユーザＩＤ
task.gid | 呼び出したプロセスのグループＩＤ
task.egid | 呼び出したプロセスの実効グループＩＤ
task.sgid | 呼び出したプロセスの保存グループＩＤ
task.fsgid | 呼び出したプロセスのファイルシステムグループＩＤ
task.pid | 呼び出したプロセスのプロセスＩＤ
task.ppid | 呼び出したプロセスの親プロセスのプロセスＩＤ
path1.uid | 許可されるパス名の所有者ＩＤ
path1.gid | 許可されるパス名のグループＩＤ
path1.ino | 許可されるパス名のｉノード番号
path1.parent.uid | 許可されるパス名の親ディレクトリの所有者ＩＤ
path1.parent.gid | 許可されるパス名の親ディレクトリのグループＩＤ
path1.parent.ino | 許可されるパス名の親ディレクトリのｉノード番号
path2.parent.uid | 作成されるパス名の親ディレクトリの所有者ＩＤ
path2.parent.gid | 作成されるパス名の親ディレクトリのグループＩＤ
path2.parent.ino | 作成されるパス名の親ディレクトリのｉノード番号

path1 はパス名を必要とする操作の１個目のパス名に対応し、 path2 はパス名を必要とする操作の２個目のパス名に対応する。 例えば、「allow_rename ファイル１ ファイル２」というアクセス許可の場合、 path1 がファイル１に、 path2 がファイル２に対応する。

path1.uid および path1.gid は存在しないパス名に対しては指定できない。つまり、ファイル等の作成時（allow_create 等）には使用できない。

path1.parent.uid および path1.parent.gid は常に指定可能である。

path2.parent.uid および path2.parent.gid はパス名を２つ必要とする操作（つまり allow_link および allow_rename ）に限り指定できる。

path2.uid および path2.gid はサポートしていない。（ rename 操作に於いて、 path2 が存在する場合には暗黙のうちに unlink または rmdir が実行される。）

sysctl による読み書き（ /proc/sys/ ディレクトリ以下のファイルを open ではなく sysctl を用いてアクセス）を行う場合については、 path1 path2 ともにサポートしていない。

## 2.5 例外ポリシー（exception_policy.conf）

このファイルでは、ドメイン単位でのアクセス制御の例外を定義する。以下の 10 種類のアクセス例外を指定できる。

- パス名のパターン
- パス名のグループ
- アドレスのグループ
- 無条件に読み込みを許可するファイル
- 書き換えを禁止するファイル
- シンボリックリンクの名前で実行するプログラム
- 集約するプログラム
- ドメイン遷移を初期化するプログラム
- ドメイン遷移を初期化させないプログラム
- ドメイン遷移を行わないドメイン
- ドメイン遷移を行わせるドメイン

### パス名のパターン

パス名のパターン化を指示するには、 file_pattern というディレクティブに続けて、パス名のパターンを指定する。パス名は正規化されたパス名でなければならない。このディレクティブは実行許可を与える場合とドメイン定義には適用されない。
例えば、プロセスＩＤを含む正規化されたパス名（/proc/PID/）は、アクセス制御が正しく行われるようにグループ化されなければならない。
以下のワイルドカードが指定可能である。

値 | 意味
\\ | \ 自身
\* | / 以外の0文字以上
\@ | / と . 以外の0文字以上
\? | / 以外の1文字
\$ | 1桁以上の10進数
\+ | 10進数1桁
\X | 1桁以上の16進数
\x | 16進数1桁
\A | 1文字以上のアルファベット
\a | アルファベット1文字
\- | パス名を除外する演算子

\- は以下のように使用する。

指定 | 意味
/etc/\* | /etc/ 直下の全ファイル
/etc/\*\-\*shadow\* | /etc/\*shadow\* 以外の /etc/\*
/\*\-proc\-sys/ | /proc/ と /sys/ 以外の /\*/

### パス名のグループ

パス名のグループを定義するには、 path_group というディレクティブに続けて、グループ名とパス名のパターンを指定する。
例えば、ホームディレクトリ以下の全ファイルをまとめたい場合、

path_group HOME-DIR-FILE /home/\*/\* path_group HOME-DIR-FILE /home/\*/\*/\* path_group HOME-DIR-FILE /home/\*/\*/\*/\* path_group HOME-DIR-FILE /home/\*/\*/\*/\*/\* path_group HOME-DIR-FILE /home/\*/\*/\*/\*/\*/\* path_group HOME-DIR-FILE /home/\*/\*/\*/\*/\*/\*/\*

のように定義しておくことで、ドメイン別ポリシーのファイルに対するアクセス許可を指定する際に

4 @HOME-DIR-FILE

のように指定できる。

### アドレスのグループ

アドレスのグループを定義するには、 address_group というディレクティブに続けて、グループ名とIPアドレスのパターンを指定する。
例えば、ローカルアドレスをまとめたい場合、

address_group local-address 10.0.0.0-10.255.255.255 address_group local-address 172.16.0.0-172.31.255.255 address_group local-address 192.168.0.0-192.168.255.255

のように定義しておくことで、ドメイン別ポリシーのネットワークに対するアクセス許可を指定する際に

allow_network TCP accept @local-address 1024-65535

のように指定できる。

### 無条件に読み込みを許可するファイル

無条件に読み込みを許可するファイルを指定するには、 allow_read というディレクティブに続けて、正規化されたファイル名を指定する。このディレクティブの目的は、 GLIBC がプログラム実行時に参照するファイルやエラーメッセージを表示する際に参照するファイルを指定することで、ドメイン別ポリシーの記述量を減らすことである。ＤＡＣで許可されれば全てのプロセスが読み込めるので、くれぐれも /etc/passwd のようなファイルを指定しないこと。

### 書き換えを禁止するファイル

deny_rewrite というキーワードを使用して、既に記録されている部分の書き換えを禁止したいファイル（ログファイル等）のパス名を登録する。パターンが使用できる。 deny_rewrite というキーワードを使用して登録されたファイルは、ドメイン用ポリシーの中で明示的に allow_rewrite というキーワードを用いて許可が与えられない限り、追記ではない書き込みモードでのオープンとファイルの切り詰めが禁止される。

### シンボリックリンクの名前で実行するプログラム

シンボリックリンクを解決した名前ではなくシンボリックリンクの名前のまま実行させるプログラムを指定するには、 alias というディレクティブに続けてシンボリックリンクを解決したパス名とシンボリックリンクを解決する前のパス名を指定する。このディレクティブの目的は、実行時の名前によって異なる振る舞いをするプログラムが、ハードリンクではなくシンボリックリンクで参照される場合に、シンボリックリンクの名前でドメインを遷移できるようにすることである。

例えば /sbin/pidof は /sbin/killall5 へのシンボリックリンクであるため、通常は /sbin/pidof を実行すると /sbin/killall5 が実行されたものとしてドメインが定義される。しかし、 alias /sbin/killall5 /sbin/pidof という指定をすることで、 /sbin/pidof を実行すると /sbin/pidof が実行されたものとしてドメインが定義されるようにできる。

### 集約するプログラム

複数のプログラムを単一のプログラム名で扱うには、 aggregator というディレクティブに続けて集約前のプログラム名と集約後のプログラム名を指定する。このディレクティブの目的は、同様のプログラムを集約することである。

例えば、 /usr/bin/tac と /bin/cat は似ているので、 aggregator /usr/bin/tac /bin/cat という指定をすることで /usr/bin/tac を /bin/cat のドメインで実行することができるようになる。

例えば、Fedora Core 3 の /usr/sbin/logrotate は /tmp/logrotate.\?\?\?\?\?\? というパターンのプログラムを作成して実行するが、 TOMOYO Linux では安全上の理由からプログラムの実行許可を与える場合とドメインを定義する場合にパターンを使用することを認めていない。しかし、 aggregator /tmp/logrotate.\?\?\?\?\?\? /tmp/logrotate.tmp という指定をすることで /tmp/logrotate.\?\?\?\?\?\? を /tmp/logrotate.tmp のドメインで実行することができるようになる。

### ドメイン遷移を初期化するプログラム

特定のプログラムが実行された場合にドメイン遷移を初期化させるには、 initialize_domain というディレクティブを使用する。

- initialize_domain プログラム名 from ドメイン名
- initialize_domain プログラム名 from ドメイン名の最後のプログラム名
- initialize_domain プログラム名

from 以降が指定されていない場合は任意のドメインから実行された場合に適用される。ドメイン名が <kernel> で始まらない場合は、ドメイン名の最後のプログラム名が一致する全てのドメインに適用される。

このディレクティブの目的は、常駐型プログラムや必要に応じてカーネルから起動されるプログラムを、通常とは異なるドメインに遷移させることで、ドメイン遷移を集約することである。

### ドメイン遷移を初期化させないプログラム

initialize_domain の効力を打ち消すには、 no_initialize_domain というディレクティブを指定する。

- no_initialize_domain プログラム名 from ドメイン名
- no_initialize_domain プログラム名 from ドメイン名の最後のプログラム名
- no_initialize_domain プログラム名

このディレクティブはドメイン遷移を初期化させたくない場合に使用する。

### ドメイン遷移を行わないドメイン

特定のドメインからプログラムが実行されてもドメイン遷移を行わないようにするには、 keep_domain というディレクティブを使用する。

- keep_domain プログラム名 from ドメイン名
- keep_domain プログラム名 from ドメイン名の最後のプログラム名
- keep_domain ドメイン名
- keep_domain ドメイン名の最後のプログラム名

from 以前が指定されていない場合は任意のプログラムが実行された場合に適用される。ドメイン名が <kernel> で始まらない場合は、ドメイン名の最後のプログラム名が一致する全てのドメインに適用される。

このディレクティブの目的は、不要なドメイン遷移の発生を抑制することでドメイン数とメモリ消費を抑えることである。

### ドメイン遷移を行わせるドメイン

keep_domain の効力を打ち消すには、 no_keep_domain というディレクティブを指定する。

- no_keep_domain プログラム名 from ドメイン名
- no_keep_domain プログラム名 from ドメイン名の最後のプログラム名
- no_keep_domain ドメイン名
- no_keep_domain ドメイン名の最後のプログラム名

このディレクティブはドメイン遷移を行わせたい場合に使用する。

# 3. /proc/ccs/ インタフェース

これは、起動後にポリシーを読み出し／追加／削除を行うためのインタフェースである。ポリシーマネージャ定義で定義されたプログラムのみがポリシーの追加と削除を行える。

## 3.1 profile

現在の制御レベルを取得または変更する。

（例）
cat /proc/ccs/profile
echo 'MAC_FOR_FILE=1' > /proc/ccs/profile

## 3.2 system_policy

現在のシステムポリシーを読み出しまたは追加または削除する。

（例）
echo 'allow_mount /proc /proc/ proc' > /proc/ccs/system_policy
echo 'delete allow_mount /proc /proc/ proc' > /proc/ccs/system_policy
cat /proc/ccs/system_policy

## 3.3 domain_policy

現在のドメイン別ポリシーを読み出しまたは追加または削除する。

（例）ドメインを選択してアクセス許可を追加（ドメインが存在しない場合は作成される）
printf "<kernel> /sbin/init\n4 /etc/passwd\n" > /proc/ccs/domain_policy

（例）ドメインを選択してアクセス許可を追加（ドメインが存在しない場合は作成されない）
printf "select <kernel> /sbin/init\n4 /etc/passwd\n" > /proc/ccs/domain_policy

（例）ドメインを選択してアクセス許可を削除
printf "select <kernel> /sbin/init\ndelete 4 /etc/passwd\ndelete 4 /etc/shadow\n" > /proc/ccs/domain_policy

（例）特定のドメインを削除
printf "delete <kernel> /sbin/init\n" > /proc/ccs/domain_policy

（例）ドメイン別ポリシーの読み出し
cat /proc/ccs/domain_policy

## 3.4 exception_policy

現在の例外ポリシーを読み出しまたは追加または削除する。

（例）
echo 'file_pattern /proc/\$/status' > /proc/ccs/exception_policy
echo 'delete file_pattern /proc/\$/status' > /proc/ccs/exception_policy
cat /proc/ccs/exception_policy

## 3.5 query

強制モードで動作中にポリシー違反が発生した場合に、そのアクセス要求を個別に許可するかどうかの指定を行うために使用する。 ALLOW_ENFORCE_GRACE=1 に設定されているプロファイルが割り当てられているドメインに対して強制モードでポリシー違反が発生した場合、 ccs-queryd を用いて対話的に諾否を指定できる。

## 3.6 manager

ポリシーの読み書きを行えるプログラムまたはドメインの一覧を取得または追加する。

## 3.7 .domain_status

setprofile コマンドが行単位での処理を行いやすくするために domain_policy の内容からプロファイル番号とドメイン名の部分だけを抽出したもの。ＤＢＭＳのビューに相当する機能を提供する。

## 3.8 meminfo

TOMOYO Linuxがポリシーを保持するために使用しているカーネルのメモリ情報を取得する。

（例）
cat /proc/ccs/meminfo

## 3.9 grant_log

ドメイン別ポリシーに対するアクセス許可ログを取得する。 取得すべきログが無い場合はすぐに戻ってくるので、ログが発生するまで待機させるには select(2) を使うこと。 記憶できる件数はMAX_GRANT_LOG件までである。 それ以上は記録されないので、随時読み出すようにする必要がある。

（例）
cat /proc/ccs/grant_log

## 3.10 reject_log

ドメイン別ポリシーに対するアクセス拒否ログを取得する。 取得すべきログが無い場合はすぐに戻ってくるので、ログが発生するまで待機させるには select(2) を使うこと。 記憶できる件数はMAX_REJECT_LOG件までである。 それ以上は記録されないので、随時読み出すようにする必要がある。

（例）
cat /proc/ccs/reject_log

## 3.11 self_domain

呼び出し元プロセスが属しているドメインの名前を取得する。

（例）
cat /proc/ccs/self_domain

## 3.12 .process_status

ccstree コマンド（「現在動作中のプロセス」と「そのプロセスが属しているドメイン」と「そのドメインに割り当てられているプロファイル番号」を pstree のように一覧表示する）のためのインタフェース。例外的にポリシーマネージャとして登録されていないプログラムでも書き込みを行える。

## 3.13 .updates_counter

ポリシーの変更を検出するためのカウンタ。参照されるたびに 0 にリセットされる。ポリシーの更新を監視するプログラムのためのインタフェース。

目次へ戻る