Info: Version 1.4.1 is available.
Last modified: $Date: 2011-07-01 13:55:23 +0900 (Fri, 01 Jul 2011) $
2.3 システムポリシー(system_policy.txt)
2.4 ドメイン別ポリシー(domain_policy.txt)
2.5 例外ポリシー(exception_policy.txt)
正規化されたパス名 | "/" で始まり、シンボリックリンクや "/./" や "//" や "/../" を含まないパス名。(ただし、現在のプロセスに関する情報にアクセスするための "/proc/self/" ディレクトリに関してはそのまま "/proc/self/" とする。) プロセスが chroot された環境下で動作する場合であっても、 chroot する前のパス名で指定される。 正規化されたパス名は、全てアスキーコードの表示可能な範囲(0x21~0x7E)で構成されている。 従って、\ 文字(0x5C)は \\ 、その他の表示不可能な文字(0x01~0x20、0x7F~0xFF)は \ooo 形式の8進数で表記する。 (例えば、空白文字(0x20)は \040 と表記する。) |
正規化されたディレクトリ名 | 正規化されたパス名の内、"/"で終わるもの。 |
正規化されたファイル名 | 正規化されたパス名の内、"/"で終わらないもの。 正規化されたファイル名は、ディレクトリ以外の全てのファイルタイプ(通常ファイル、キャラクタ型デバイスファイル、ブロック型デバイスファイル、FIFO、シンボリックリンク、ソケット)を含む。 |
プログラム | 正規化されたファイル名の内、実行可能なもの。 |
ドメイン | MAC(強制アクセス制御)を行うための属性 |
遷移先ドメイン | プログラムが正常に開始された場合にプロセスが遷移するドメイン |
操作対象ドメイン | 操作対象となるプロセスの属しているドメイン |
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 | 内容 |
プログラム名の取得 |
実行しようとするプログラムの「正規化されたファイル名」を取得して「パス名候補1」とする。ただし、実行しようとするプログラムがシンボリックリンクの場合は、シンボリックリンクを解決したパス名を取得する。 実行しようとするプログラムの「正規化されたファイル名」を取得して「パス名候補2」とする。ただし、実行しようとするプログラムがシンボリックリンクの場合は、シンボリックリンクを解決する前のパス名を取得する。 |
シンボリックリンクの識別 |
「パス名候補1」と「パス名候補2」が一致しない場合、例外ポリシーから
というエントリを探す。見つかった場合は「パス名候補2」を「パス名候補1」とする。 |
類似するプログラムの集約 |
例外ポリシーから
というエントリを探す。見つかった場合は、「集約されたパス名」を「パス名候補1」とする。 |
argv[0] のチェック |
「パス名候補2」の最後の / 以降の部分と argv[0] の最後の / 以降の部分が異なっている場合、ドメイン別ポリシーから
というエントリを探す。見つからなければ拒否する。 |
権限のチェック |
ドメイン別ポリシーから
というエントリを探す。見つからなければ拒否する。 |
遷移先の決定 |
(1) 例外ポリシーから
というエントリを探す。見つかった場合は (3) へ進む。 (2) 例外ポリシーから
というエントリを探す。見つかった場合は「カーネルが属しているドメインのドメイン名(<kernel>)」と「パス名候補1」とを連結して「遷移先ドメイン」として (6) へ進む。 (3) 例外ポリシーから
というエントリを探す。見つかった場合は (5) へ進む。 (4) 例外ポリシーから
というエントリを探す。見つかった場合は「現在のプロセスが属しているドメインのドメイン名」を「遷移先ドメイン」とし、 (6) へ進む。 (5) 「現在のプロセスが属しているドメインのドメイン名」と「パス名候補1」とを連結して「遷移先ドメイン」とし、(6)へ進む。 (6) ドメイン別ポリシーから「遷移先ドメイン」を探す。見つからなければ拒否する。 (7)通常のプログラム実行処理を行い、正常に終了した場合は「遷移先ドメイン」に遷移する。 |
ポリシーファイルは全て /etc/ccs/ ディレクトリに作成しておく。このディレクトリに存在するファイルが /sbin/init の開始時に /.init によって読み込まれるようになっている。
全てのプログラムがポリシーの変更を行えるのは危険であるため、このファイルには /proc/ccs/ インタフェースへの書き込みアクセスを許可するプログラムまたはドメインを定義しておく。
このファイルに定義されていないプログラムやドメインからは /proc/ccs/ インタフェースへの書き込みアクセスができない。システム運用時にポリシーの変更を許可しない場合はこのファイルを削除しておく。
(例)
/root/ccstools/loadpolicy
/root/ccstools/editpolicy
/root/ccstools/setlevel
/root/ccstools/setprofile
/root/ccstools/ld-watch
/root/ccstools/ccs-queryd
<kernel> /sbin/mingetty /root/bin/bash
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.txt) の中に use_profile というキーワードで保持される。
このファイルでは、システム全体に対して適用されるアクセス許可を定義する。以下の 4 種類のアクセス許可を指定できる。
マウント許可を指定するには、 allow_mount というディレクティブに続けて、「デバイスファイル マウントポイント ファイルシステム オプション」を指定する。 デバイスファイルを必要とするファイルシステムを指定する場合は、デバイスファイルは正規化されたファイル名でなければいけない。マウントポイントは正規化されたディレクトリ名でなければいけない。オプションは dev,nodev,exec,noexec,suid,nosuid,rw,ro,atime,noatime,diratime,nodiratime,recurse,norecurse の組み合わせである。指定されたオプションはマウント時の指定に優先する。 例えば、 rw が指定されていた場合、ユーザが ro を指定したとしても、カーネルは rw が指定されたものとしてマウントする。オプションは省略可能である。
「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 マウントポイント」が許可される。
オプションは recurse または norecurse のどちらかである。指定されたオプションはマウント時の指定に優先する。 例えば、 recurse が指定されていた場合、ユーザが norecurse を指定したとしても、カーネルは recurse が指定されたものとしてマウントする。オプションは省略可能である。
アンマウント禁止を指定するには、 deny_unmount というディレクティブに続けて、アンマウントを許可しない正規化されたディレクトリ名を指定する。
通常、 /sbin/mingetty が使用する /dev/tty? を含む /dev/ ディレクトリと、リモートログインする場合に pty デバイスファイルが作成される /dev/pts/ ディレクトリを指定する。
/dev が読み込み専用になってしまったり、 /dev/pts がアンマウントされてしまうと、ログインができなくなる。そのため、 / が読み込み専用のシステムでは、 /dev/ や /dev/pts/ がアンマウントされないようにしなければならない。
chroot 許可を指定するには、 allow_chroot というディレクティブに続けて、 chroot で移動することを許可したい正規化されたディレクトリ名を指定する。
通常、 sshd が使用する /var/empty/sshd/ を指定する。 その他に chroot 環境で動かしたいアプリケーションや、 chroot を行うアプリケーション( vsftpd の場合 /usr/share/empty/ )が存在する場合は、それらも指定する。
pivot_root 許可を指定するには、 allow_pivot_root というディレクティブに続けて、新しいルートとなる正規化されたディレクトリ名と古いルートディレクトリとなる正規化されたディレクトリ名を指定する。
通常、このディレクティブを使う必要は無い。
ローカルポートの自動選択で特定のポート番号が選択させるのを禁止するには、 deny_autobind というディレクティブに続けて、ローカルポート番号を指定する。 このディレクティブは、特定のポート番号が一時的な用途で割り当てられるのを防ぐのが狙いである。 例えば、一部のプロキシサーバはポート8080を使用するので、ポート8080が一時的な用途のために割り当てられるべきではない。
allow_mount | none | /dev/pts/ | devpts |
allow_mount | /proc | /proc/ | proc |
allow_mount | usbdevfs | /proc/bus/usb/ | usbdevfs |
allow_mount | none | /data/ | tmpfs nosuid,nodev,noexec |
allow_mount | none | /dev/shm/ | tmpfs nosuid,nodev,noexec |
allow_mount | /dev/hdc | /var/www/ | ext2 ro,nosuid,nodev,noexec |
allow_mount | any | / | --remount |
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 |
このファイルでは、全てのドメインを定義し、各ドメインに対して与えるアクセス許可を定義する。 以下の 5 種類のアクセス許可を指定できる。
それぞれのアクセス許可について、必要に応じて追加の条件を指定することができる。そのための構文は後述する。
ドメインを定義している行(<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 の指定は極力避けるべきである。
なお、マッピング定義を使って、 allow_ で始まるディレクティブを 2 3 6 7 のいずれかに対するアクセス許可で代用することも可能である。
argv[0] の組み合わせを制限するには、 allow_argv0 というディレクティブに続けて、「シンボリックリンクを解決する前の / から始まるパス名」と「argv[0] の最後の / より後ろの部分」を指定する。
プログラムを実行する関数である execve() には filename と argv[] と envp[] を渡せるが、たまに argv[0] の内容によって振る舞いを変化させるプログラムが存在する。 busybox はその一例である。 TOMOYO Linux のドメイン遷移は filename の内容に基づいて行われている。たいていの場合、 filename と argv[0] は同じ内容なので問題無いが、バイナリラッパのように意図的に filename と argv[0] で異なる内容を指定する場合がある。例えば、 filename に /sbin/busybox へのシンボリックリンクである /bin/ls を、 argv[0] に /sbin/busybox へのシンボリックリンクである /bin/cat を指定した場合、 /bin/ls のドメインで /bin/cat として振る舞うというちぐはぐな状況が発生する。攻撃者が意図的に filename と argv[0] で異なる内容を指定できれば、穴になってしまうわけである。このディレクティブの目的は、 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_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" のように表記する必要がある。
msg_name == NULL での recvmsg() および read() の場合はパーミッションのチェックは行われない。
シグナルのアクセス許可を指定するには、 allow_signal というディレクティブに続けて、シグナルの番号および操作対象ドメインを指定する。
例外が2つ存在する。シグナル番号が0の場合は常に許可される。また、自分の属するドメインへのシグナルの場合には常に許可される。
その他の場合、このファイルに指定されたシグナル番号とドメイン名で始まる場合のみそのシグナルを送信できる。
操作対象ドメインとして <kernel> を指定すると、全てのドメインに指定された番号のシグナルを送信できる。
アクセス許可にユーザID等に基づいた条件を付加することができる。条件は個々のアクセス許可の末尾に 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 | 呼び出したプロセスのユーザID |
task.euid | 呼び出したプロセスの実効ユーザID |
task.suid | 呼び出したプロセスの保存ユーザID |
task.fsuid | 呼び出したプロセスのファイルシステムユーザID |
task.gid | 呼び出したプロセスのグループID |
task.egid | 呼び出したプロセスの実効グループID |
task.sgid | 呼び出したプロセスの保存グループID |
task.fsgid | 呼び出したプロセスのファイルシステムグループID |
task.pid | 呼び出したプロセスのプロセスID |
task.ppid | 呼び出したプロセスの親プロセスのプロセスID |
path1.uid | 許可されるパス名の所有者ID |
path1.gid | 許可されるパス名のグループID |
path1.ino | 許可されるパス名のiノード番号 |
path1.parent.uid | 許可されるパス名の親ディレクトリの所有者ID |
path1.parent.gid | 許可されるパス名の親ディレクトリのグループID |
path1.parent.ino | 許可されるパス名の親ディレクトリのiノード番号 |
path2.parent.uid | 作成されるパス名の親ディレクトリの所有者ID |
path2.parent.gid | 作成されるパス名の親ディレクトリのグループID |
path2.parent.ino | 作成されるパス名の親ディレクトリのiノード番号 |
path1 はパス名を必要とする操作の1個目のパス名に対応し、 path2 はパス名を必要とする操作の2個目のパス名に対応する。 例えば、「allow_rename ファイル1 ファイル2」というアクセス許可の場合、 path1 がファイル1に、 path2 がファイル2に対応する。
path1.uid および path1.gid は存在しないパス名に対しては指定できない。つまり、ファイル等の作成時(allow_create 等)には使用できない。
path1.parent.uid および path1.parent.gid は常に指定可能である。
path2.parent.uid および path2.parent.gid はパス名を2つ必要とする操作(つまり allow_link および allow_rename )に限り指定できる。
path2.uid および path2.gid はサポートしていない。( rename 操作に於いて、 path2 が存在する場合には暗黙のうちに unlink または rmdir が実行される。)
sysctl による読み書き( /proc/sys/ ディレクトリ以下のファイルを open ではなく sysctl を用いてアクセス)を行う場合については、 path1 path2 ともにサポートしていない。
このファイルでは、ドメイン単位でのアクセス制御の例外を定義する。以下の 10 種類のアクセス例外を指定できる。
パス名のパターン化を指示するには、 file_pattern というディレクティブに続けて、パス名のパターンを指定する。パス名は正規化されたパス名でなければならない。このディレクティブは実行許可を与える場合とドメイン定義には適用されない。
例えば、プロセスIDを含む正規化されたパス名(/proc/PID/)は、アクセス制御が正しく行われるようにグループ化されなければならない。
以下のワイルドカードが指定可能である。
値 | 意味 |
\\ | \ 自身 |
\* | / 以外の0文字以上 |
\@ | / と . 以外の0文字以上 |
\? | / 以外の1文字 |
\$ | 1桁以上の10進数 |
\+ | 10進数1桁 |
\X | 1桁以上の16進数 |
\x | 16進数1桁 |
\A | 1文字以上のアルファベット |
\a | アルファベット1文字 |
パス名のグループを定義するには、 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 がプログラム実行時に参照するファイルやエラーメッセージを表示する際に参照するファイルを指定することで、ドメイン別ポリシーの記述量を減らすことである。DACで許可されれば全てのプロセスが読み込めるので、くれぐれも /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 というディレクティブを使用する。
from 以降が指定されていない場合は任意のドメインから実行された場合に適用される。ドメイン名が <kernel> で始まらない場合は、ドメイン名の最後のプログラム名が一致する全てのドメインに適用される。
このディレクティブの目的は、常駐型プログラムや必要に応じてカーネルから起動されるプログラムを、通常とは異なるドメインに遷移させることで、ドメイン遷移を集約することである。バージョン 1.3.1 までは initializer というディレクティブであったが、 1.3.2 では initialize_domain というディレクティブに変更された。
initialize_domain または initializer の効力を打ち消すには、 no_initialize_domain というディレクティブを指定する。
このディレクティブはドメイン遷移を初期化させたくない場合に使用する。
特定のドメインからプログラムが実行されてもドメイン遷移を行わないようにするには、 keep_domain というディレクティブを使用する。
from 以前が指定されていない場合は任意のプログラムが実行された場合に適用される。ドメイン名が <kernel> で始まらない場合は、ドメイン名の最後のプログラム名が一致する全てのドメインに適用される。
このディレクティブの目的は、不要なドメイン遷移の発生を抑制することでドメイン数とメモリ消費を抑えることである。
keep_domain の効力を打ち消すには、 no_keep_domain というディレクティブを指定する。
このディレクティブはドメイン遷移を行わせたい場合に使用する。
このファイルでは、ファイルに対する書き込みアクセス許可のチェック方法を定義する。 どれくらい厳密にファイルに対する書き込みアクセス許可を制御したいかに応じて、書き込みアクセス許可の粒度をこのファイルを使用して切り替えられるようになっている。
このファイルの書式は、「チェック項目=チェック方法」を列挙した形式である。以下に例を示す。
create=generic-write unlink=generic-write mkdir=mkdir rmdir=rmdir mkfifo=mkfifo mksock=mksock mkblock=mkblock mkchar=mkchar truncate=generic-write symlink=symlink link=link rename=rename rewrite=rewrite |
チェック方法として generic-write を指定した場合、そのチェック項目は、ディレクティブ 2 3 6 7 で与えられているアクセス許可でチェックされる。 チェック方法として no-check を指定した場合、そのチェック項目はチェックされなくなる。 チェック方法としてチェック項目と同じ値を指定した場合、そのチェック項目はそのディレクティブで与えられているアクセス許可でチェックされる。
このファイルは起動時に1度だけ読み込まれ、起動後に変更することはできない。
これは、起動後にポリシーを読み出し/追加/削除を行うためのインタフェースである。ポリシーマネージャ定義で定義されたプログラムのみがポリシーの追加と削除を行える。
現在の制御レベルを取得または変更する。
(例)
cat /proc/ccs/status
echo 'MAC_FOR_FILE=1' > /proc/ccs/status
現在のシステムポリシーを読み出しまたは追加または削除する。
(例)
echo 'allow_mount /proc /proc/ proc' > /proc/ccs/policy/system_policy
echo 'delete allow_mount /proc /proc/ proc' > /proc/ccs/policy/system_policy
cat /proc/ccs/policy/system_policy
現在のドメイン別ポリシーを読み出しまたは追加または削除する。
(例)ドメインを選択してアクセス許可を追加(ドメインが存在しない場合は作成される)
printf "<kernel> /sbin/init\n4 /etc/passwd\n" > /proc/ccs/policy/domain_policy
(例)ドメインを選択してアクセス許可を追加(ドメインが存在しない場合は作成されない)
printf "select <kernel> /sbin/init\n4 /etc/passwd\n" > /proc/ccs/policy/domain_policy
(例)ドメインを選択してアクセス許可を削除
printf "select <kernel> /sbin/init\ndelete 4 /etc/passwd\ndelete 4 /etc/shadow\n" > /proc/ccs/policy/domain_policy
(例)特定のドメインを削除
printf "delete <kernel> /sbin/init\n" > /proc/ccs/policy/domain_policy
(例)ドメイン別ポリシーの読み出し
cat /proc/ccs/policy/domain_policy
現在の例外ポリシーを読み出しまたは追加または削除する。
(例)
echo 'file_pattern /proc/\$/status' > /proc/ccs/policy/exception_policy
echo 'delete file_pattern /proc/\$/status' > /proc/ccs/policy/exception_policy
cat /proc/ccs/policy/exception_policy
強制モードで動作中にポリシー違反が発生した場合に、そのアクセス要求を個別に許可するかどうかの指定を行うために使用する。 ALLOW_ENFORCE_GRACE=1 に設定されているプロファイルが割り当てられているドメインに対して強制モードでポリシー違反が発生した場合、 ccs-queryd を用いて対話的に諾否を指定できる。
ポリシーの読み書きを行えるプログラムまたはドメインの一覧を取得または追加する。
setprofile コマンドが行単位での処理を行いやすくするために policy/domain_policy の内容からプロファイル番号とドメイン名の部分だけを抽出したもの。DBMSのビューに相当する機能を提供する。
TOMOYO Linuxがポリシーを保持するために使用しているカーネルのメモリ情報を取得する。
(例)
cat /proc/ccs/info/meminfo
ドメイン別ポリシーに対するアクセス許可ログを取得する。 取得すべきログが無い場合はすぐに戻ってくるので、ログが発生するまで待機させるには select(2) を使うこと。 記憶できる件数はMAX_GRANT_LOG件までである。 それ以上は記録されないので、随時読み出すようにする必要がある。
(例)
cat /proc/ccs/info/grant_log
ドメイン別ポリシーに対するアクセス拒否ログを取得する。 取得すべきログが無い場合はすぐに戻ってくるので、ログが発生するまで待機させるには select(2) を使うこと。 記憶できる件数はMAX_REJECT_LOG件までである。 それ以上は記録されないので、随時読み出すようにする必要がある。
(例)
cat /proc/ccs/info/reject_log
呼び出し元プロセスが属しているドメインの名前を取得する。
(例)
cat /proc/ccs/info/self_domain
MAC_FOR_FILE における書き込みアクセス許可のチェック方法を取得する。
(例)
cat /proc/ccs/info/mapping
ccstree コマンド(「現在動作中のプロセス」と「そのプロセスが属しているドメイン」と「そのドメインに割り当てられているプロファイル番号」を pstree のように一覧表示する)のためのインタフェース。例外的にポリシーマネージャとして登録されていないプログラムでも書き込みを行える。
ポリシーの変更を検出するためのカウンタ。参照されるたびに 0 にリセットされる。ポリシーの更新を監視するプログラムのためのインタフェース。