Info: Version 1.7.x is available.

English Page

TOMOYO Linux 導入手順書

Last modified: $Date: 2019-02-04 20:23:38 +0900 (Mon, 04 Feb 2019) $

インストール

TOMOYO Linux カーネルとツールのインストール

カーネルをコンパイルする方法については、TOMOYO Linuxカーネルの作成手順を参照してください。ツールパッケージをコンパイルするには以下のコマンドを実行してください。

wget -O ccs-tools-1.6.9-20120301.tar.gz 'https://osdn.jp/frs/redir.php?m=jaist&f=/tomoyo/30298/ccs-tools-1.6.9-20120301.tar.gz'
tar -zxf ccs-tools-1.6.9-20120301.tar.gz
make -C ccstools/ install

ポリシーの作成

以下のコマンドを実行してください。

/usr/lib/ccs/init_policy.sh

再起動

TOMOYO カーネルで再起動します。

reboot

起動したら、 root でログインします。

準備

ドメインについて

TOMOYO Linux におけるアクセス制御はドメインという単位で指定します。全てのプロセスは何れか1個のドメインに属しており、原則としてプログラムを実行する度に異なるドメインへ遷移します。 TOMOYO Linux におけるドメインは、<kernel> を基点としたプロセスの起動履歴を文字列として結合したものになります。例えば、カーネルプロセスのドメインが <kernel> 、カーネルプロセスから起動される /sbin/init のドメインは <kernel> /sbin/init 、 /sbin/init から起動された /etc/rc.d/rc のドメインは <kernel> /sbin/init /etc/rc.d/rc のようになります。例外については後述します。

プロファイルについて

TOMOYO Linux では、ファイル以外にもいくつかの項目について強制アクセス制御を行うことができますが、ポリシー管理の負担を減らすために、必要の無い機能を無効化できるようになっています。制御可能な項目はカーネルのコンパイル時に決定されます。 /proc/ccs/profile に含まれている項目が制御可能です。

項目 内容 デフォルト値 自動学習対応
COMMENT プロファイルの内容を説明するための1行コメント。
MAC_FOR_FILE ファイルに対する強制アクセス制御を有効にする。 disabled
MAC_FOR_ARGV0 プログラム実行時の argv[0] のチェックを有効にする。 disabled
MAC_FOR_ENV プログラム実行時の環境変数名のチェックを有効にする。 disabled
MAC_FOR_CAPABILITY:: ケイパビリティに対する強制アクセス制御を有効にする。31種類ある機能別に有効・無効を指定できる。 disabled
MAC_FOR_NETWORK ネットワークに対する強制アクセス制御を有効にする。 disabled
MAC_FOR_SIGNAL シグナルの送信に対する強制アクセス制御を有効にする。 disabled
DENY_CONCEAL_MOUNT 既存のマウントを隠蔽するようなマウントを禁止する。 disabled ×
RESTRICT_CHROOT chroot で移動可能なディレクトリの制限を有効にする。 disabled
RESTRICT_MOUNT mount で指定可能なパラメータの制限を有効にする。 disabled
RESTRICT_UNMOUNT 指定されたディレクトリのアンマウントを禁止する。 disabled ×
RESTRICT_PIVOT_ROOT pivot_root で交換可能なディレクトリの制限を有効にする。 disabled
RESTRICT_AUTOBIND ローカルのポート番号を自動選択させる際に、特定のポート番号を選択させないようにする。 disabled ×
MAX_ACCEPT_ENTRY 学習モードで自動的に追加される「アクセス許可」の上限を指定する。 2048
MAX_GRANT_LOG 「ポリシーに違反しなかったアクセス要求のログ」の上限を指定する。 1024
MAX_REJECT_LOG 「ポリシーに違反したアクセス要求のログ」の上限を指定する。 1024
TOMOYO_VERBOSE ドメイン別ポリシーに対する違反を syslog に表示する。 enabled
SLEEP_PERIOD 強制モードでポリシー違反が発生した場合に、ポリシー違反を生じさせたプロセスをスリープ状態にしておく時間を 0.1 秒単位で指定する。 0

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

内容
disabled 無効。通常のカーネルと同様に動作する。
enabled 有効。

MAX_ACCEPT_ENTRY および MAX_GRANT_LOG および MAX_REJECT_LOG および SLEEP_PERIOD については 0 以上の任意の整数を指定できます。

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

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

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

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

プロファイルの作成

/etc/ccs/profile.conf の中に無効・学習・確認・強制用のプロファイルを全て定義してください。例えばファイルとネットワークのみアクセス制御したい場合は以下のような内容になります。行頭の数字は、ドメインにプロファイルを割り当てるときに使用するプロファイル番号です。プロファイル番号は 0 から 255 まで使用できます。

0-COMMENT=----- All Disabled -----
1-COMMENT=----- FILE and NETWORK with Learning Mode -----
1-MAC_FOR_FILE=learning
1-MAC_FOR_NETWORK=learning
2-COMMENT=----- FILE and NETWORK with Permissive Mode -----
2-MAC_FOR_FILE=permissive
2-MAC_FOR_NETWORK=permissive
3-COMMENT=----- FILE and NETWORK with Enforce Mode -----
3-MAC_FOR_FILE=enforcing
3-MAC_FOR_NETWORK=enforcing
3-MAX_GRANT_LOG=0

この手順書では、
プロファイル番号 0 をアクセス制御を行わないプロファイル、
プロファイル番号 1 を学習モードで動作させるためのプロファイル、
プロファイル番号 2 を確認モードで動作させるためのプロファイル、
プロファイル番号 3 を強制モードで動作させるためのプロファイル
として使用します。

TOMOYO Linux ではプロファイル番号を切り替えることでドメインを単位としてアクセス制御の方法を指定できるので、一度プロファイルを作成したら、プロファイルを編集する必要はありません。もし、プロファイルを追加したい等の理由で /etc/ccs/profile.conf を編集した場合は以下のように ccs-loadpolicy コマンドを実行してください。

/usr/sbin/ccs-loadpolicy p

現在のプロファイルを確認するには以下のコマンドを実行してください。

cat /proc/ccs/profile

プロファイルの割り当て方

ドメインにプロファイルを割り当てるには ccs-setprofile というコマンドを使用します。例えば

/usr/sbin/ccs-setprofile -r 0 '<kernel>'

のように指定した場合、全てのドメインのプロファイルが 0 に変更されます。また、

/usr/sbin/ccs-setprofile -r 1 '<kernel> /sbin/init'

のように指定した場合、 <kernel> /sbin/init 以下の全てのドメインのプロファイルが 1 に変更されます。また、

/usr/sbin/ccs-setprofile 2 '<kernel> /sbin/init'

のように指定した場合、 <kernel> /sbin/init ドメインのプロファイルだけが 2 に変更されます。

ドメインに割り当てられているプロファイルを確認するには以下のコマンドを実行してください。プロファイル番号とドメイン名がセットになった一覧が表示されます。

cat /proc/ccs/.domain_status

ドメイン単位でプロファイルを割り当てることでアクセス制御モードを変更できるので、起動時にアクセス制御モードを一斉に切り替えする必要は基本的にありません。もし、不適切なプロファイルを割り当ててしまった等の理由によりシステムが起動できなくなってしまった場合には、カーネル起動時のコマンドラインパラメータに CCS=disabled と指定して起動することで、アクセス制御を無効にした状態で起動することができます。

現在実行中のプロセスが属しているドメインとそのドメインに割り当てられているプロファイルを確認するには ccs-ccstree というコマンドを使用します。

/usr/sbin/ccs-ccstree

ccs-ccstree コマンドを実行すると以下のようにプロファイル番号、プロセス名、プロセスID、ドメイン名の順番で pstree のように出力されます。

  0 init (1) <kernel> /sbin/init
  0  +- mingetty (743) <kernel> /sbin/mingetty
  0  +- mingetty (744) <kernel> /sbin/mingetty
  0  +- mingetty (745) <kernel> /sbin/mingetty
  0  +- mingetty (746) <kernel> /sbin/mingetty
  0  +- mingetty (747) <kernel> /sbin/mingetty
  0  +- rc (748) <kernel> /sbin/init /etc/rc.d/rc
  0      +- S91smb (3468) <kernel> /etc/rc.d/init.d/smb
  0          +- initlog (3475) <kernel> /etc/rc.d/init.d/smb /sbin/initlog
  0              +- nmbd (3476) <kernel> /etc/rc.d/init.d/smb /sbin/initlog /usr/sbin/nmbd
  0  +- syslogd (3158) <kernel> /etc/rc.d/init.d/syslog /sbin/initlog /sbin/syslogd
  0  +- klogd (3162) <kernel> /etc/rc.d/init.d/syslog /sbin/initlog /sbin/klogd
  0  +- portmap (3172) <kernel> /etc/rc.d/init.d/portmap /sbin/initlog /sbin/portmap
  0  +- rpc.statd (3191) <kernel> /etc/rc.d/init.d/nfslock /sbin/initlog /sbin/rpc.statd
  0  +- cardmgr (3245) <kernel> /etc/rc.d/init.d/pcmcia /sbin/cardmgr
  0  +- apmd (3270) <kernel> /etc/rc.d/init.d/apmd /sbin/initlog /usr/sbin/apmd
  0  +- sshd (3307) <kernel> /usr/sbin/sshd
  0      +- sshd (3393) <kernel> /usr/sbin/sshd
  0          +- tcsh (3434) <kernel> /usr/sbin/sshd /bin/tcsh
  0              +- ccs-ccstree (3477) <kernel> /usr/sbin/sshd /bin/tcsh /usr/sbin/ccs-ccstree
  0  +- xinetd (3321) <kernel> /usr/sbin/xinetd
  0  +- rpc.rquotad (3342) <kernel> /etc/rc.d/init.d/nfs /sbin/initlog /usr/sbin/rpc.rquotad
  0  +- rpc.mountd (3361) <kernel> /etc/rc.d/init.d/nfs /sbin/initlog /usr/sbin/rpc.mountd
  0  +- vsftpd (3371) <kernel> /usr/sbin/vsftpd
  0  +- sendmail (3395) <kernel> /etc/rc.d/init.d/sendmail /sbin/initlog /usr/sbin/sendmail.sendmail
  0  +- sendmail (3404) <kernel> /etc/rc.d/init.d/sendmail /sbin/initlog /usr/sbin/sendmail.sendmail
  0  +- spamd (3414) <kernel> /etc/rc.d/init.d/spamassassin /sbin/initlog /usr/bin/spamd
  0  +- gpm (3423) <kernel> /etc/rc.d/init.d/gpm /sbin/initlog /usr/sbin/gpm
  0  +- httpd (3455) <kernel> /usr/sbin/httpd
  0  +- crond (3464) <kernel> /usr/sbin/crond
  0  +- smbd (3473) <kernel> /usr/sbin/smbd

ccs-ccstree に -a オプションを指定すると TOMOYO のアクセス制御の対象外であるカーネルプロセスの情報も表示されます。

アクセスログ取得の準備

ドメイン単位のアクセス制御機能に関して、「ポリシーに違反しなかったアクセス要求のログ」(アクセス許可ログ)と「ポリシーに違反したアクセス要求のログ」(アクセス拒否ログ)を取得することができます。

アクセス許可ログとアクセス拒否ログをカーネルから読み出してファイルに保存する為に、 ccs-auditd というデーモンプログラムを利用できます。以下のコマンドを /etc/rc.local 等から実行するようにしてください。

/usr/sbin/ccs-auditd アクセス許可ログの保存場所 アクセス拒否ログの保存場所

アクセス許可ログを保存する必要が無い場合は、プロファイルで MAX_GRANT_LOG=0 という指定をして、アクセス許可ログの保存場所として /dev/null を指定することができます。 ccs-auditd にはフィルタリング機能がありませんので、アクセス許可ログを保存する場合はディスク容量に注意してください。

アクセス拒否ログを保存する必要が無い場合は、プロファイルで MAX_REJECT_LOG=0 という指定をして、アクセス拒否ログの保存場所として /dev/null を指定することができます。アクセス拒否ログは保存しておくことを推奨します。この手順書では、アクセス拒否ログを /var/log/tomoyo/reject_log.conf に保存するものとします。

/usr/sbin/ccs-auditd /dev/null /var/log/tomoyo/reject_log.conf

アクセスログを保存するディレクトリは予め作成しておいてください。

mkdir -p /var/log/tomoyo

logrotate によるローテーションを行わせたい場合は、以下のような内容のファイルを /etc/logrotate.d/tomoyo に作成してください。なお、 nocreate オプションを必ず指定してください。 nocreate オプションを忘れると、最初のローテーションが実行されて以降のログが保存されなくなってしまいます。

/var/log/tomoyo/reject_log.conf {
  weekly
  rotate 9
  missingok
  notifempty
  nocreate
}

アクセス許可ログ・アクセス拒否ログのどちらも保存しない場合には ccs-auditd を実行する必要はありません。また、プロファイルで MAX_GRANT_LOG=0 および MAX_REJECT_LOG=0 を指定しておくことで、消費メモリの節約と応答速度の向上が期待できます。

ポリシー違反通知の準備

TOMOYO Linux は、強制モードに於いてポリシー違反が発生した場合に、即時にそれを通知することができます。ただし、例えばメールのような、通知するための手段を予め設定しておく必要があります。

通知するために、 cron デーモンを利用することができます。例えば、1時間に1回まで、メールで root@example.com に通知したい場合、 /etc/crontab に以下のような内容を指定してください。

00 * * * * root /usr/lib/ccs/misc/ccs-notifyd 0 'mail root@example.com'

例外ポリシーの作成

/etc/ccs/exception_policy.conf を作成します。このファイルには以下の10種類の例外を指定します。

  1. パス名のパターン
  2. パス名のグループ
  3. 無条件に読み込みを許可するファイル
  4. 書き換えを禁止するファイル
  5. シンボリックリンクの名前で実行するプログラム
  6. プログラム名の集約
  7. ドメイン遷移を初期化するプログラム
  8. ドメイン遷移を初期化させないプログラム
  9. ドメイン遷移を行わないドメイン
  10. ドメイン遷移を行うドメイン

(1) パス名のパターン

file_pattern というキーワードを使用して、パス名のパターンを登録します。アクセス許可を学習する際に、要求されたパス名が file_pattern というキーワードを使用して登録されたパス名のパターンと一致した場合、パターン化されたパス名でアクセス許可が学習されます。
目安としては以下のものが挙げられます。

システムにインストールされているアプリケーションやその設定により、上記以外にもパターン化されたパス名が必要になります。不足しているパターンは、実際にどのようなアクセスが行われるかを観察してから、適切にパターン化して追加します。

(2) パス名のグループ

path_group というキーワードを使用して、パス名のパターンを登録します。これは、複数のパス名を集約することでポリシーの記述量を減らすためのマクロです。使い方は後述します。

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

allow_read というキーワードを使用して、全てのプログラムへの読み込みアクセスを許可するファイルのパス名を登録します。パターンも使用できます。読み込みモードで要求されたパス名が allow_read というキーワードを使用して登録されたパス名と一致した場合、その場で読み込みアクセスが許可されます。
目安としては以下のものが挙げられます。

システムにインストールされているアプリケーションやその設定により、上記以外にも常に読み込みアクセスを許可したいファイルがあるかもしれません。不足しているファイルは、実際にどのようなファイルを読み込むかを観察してから、必要に応じてその都度追加していきます。

(4) 書き換えを禁止するファイル

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

システムにインストールされているアプリケーションやその設定により、上記以外にも書き換えを禁止したいファイルがあるかもしれません。不足しているファイルは、実際にどのようなファイルが追記専用で使われているかを観察してから、必要に応じてその都度追加していきます。

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

TOMOYO Linux は、原則としてシンボリックリンクを解決したパス名で実行許可のチェックを行いますが、実行時の名前によって異なる振る舞いをするプログラムがシンボリックリンク経由で実行される場合に対処するために、シンボリックリンクの名前でドメインを遷移できるようにすることができます。
シンボリックリンクの名前でドメインを遷移できるようにするには、 alias というキーワードを使用してシンボリックリンクを解決したパス名とシンボリックリンクを解決する前のパス名を指定します。パターンは使用できません。
例えば /sbin/pidof は /sbin/killall5 へのシンボリックリンクであるため、通常は /sbin/pidof を実行すると /sbin/killall5 が実行されたものとしてドメインが定義されます。しかし、 alias /sbin/killall5 /sbin/pidof という指定をすることで、 /sbin/pidof を実行すると /sbin/pidof が実行されたものとしてドメインが定義されるようにできます。

(6) プログラム名の集約

複数のプログラムを単一のプログラム名で扱うには、 aggregator というキーワードに続けて集約前のプログラム名と集約後のプログラム名を指定します。集約前のプログラム名にはパターンを使用できます。
例えば、 /usr/bin/tac と /bin/cat は似ているので、 aggregator /usr/bin/tac /bin/cat という指定をすることで /usr/bin/tac を /bin/cat のドメインで実行することができるようになります。

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

initialize_domain というキーワードを使用して、ドメイン遷移履歴をリセットするプログラムのパス名を登録します。パターンは使用できません。 initialize_domain というキーワードを使用して登録されたパス名のプログラムが実行された場合、そのプログラムは <kernel> 直下のドメインで動作します。
目安としては以下のものが挙げられます。

システムにインストールされているアプリケーションやその設定により、上記以外にもドメイン遷移履歴をリセットさせたいプログラムがあるかもしれません。最初にドメイン遷移履歴を作成して、実際にどのようなプログラムを指定したらよいかを考慮しながら、必要に応じてその都度追加していきます。その際、他のドメインへの影響に注意してください。例えば、ドメインポリシーとして

<kernel> ・・・ /bin/bash
use_profile 3
allow_execute /bin/tcsh

<kernel> ・・・ /bin/bash /bin/tcsh
use_profile 3
allow_execute /bin/cat

<kernel> ・・・ /bin/bash /bin/tcsh /bin/cat
use_profile 3
allow_read /etc/fstab

というポリシーが既に存在している状態で /bin/tcsh を initialize_domain として追加した場合、 /bin/tcsh は <kernel> /bin/tcsh というドメインへ遷移することになるため、 <kernel> ・・・ /bin/bash /bin/tcsh というドメインへは遷移できなくなってしまいます。 そのような場合は、

<kernel> ・・・ /bin/bash
use_profile 3
allow_execute /bin/tcsh

<kernel> /bin/tcsh
use_profile 3
allow_execute /bin/cat

<kernel> /bin/tcsh /bin/cat
use_profile 3
allow_read /etc/fstab

のように、 <kernel> ・・・ /bin/bash /bin/tcsh で始まる部分を <kernel> /bin/tcsh で始まるようにドメインポリシーを変更してやる必要があります。

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

特定の条件下ではドメイン遷移を初期化させたくない場合に使用します。

(9) ドメイン遷移を行わないドメイン

ドメイン遷移を行わないドメインを指定するには、 keep_domain というキーワードに続けて、ドメイン名を指定します。
例えば、 keep_domain <kernel> /usr/sbin/sshd /bin/tcsh という行が含まれている場合、 <kernel> /usr/sbin/sshd /bin/tcsh というドメインに属しているプロセスは、 initialize_domain というキーワードで指定されたプログラムが実行されない限り、そのドメインに留まります。

(10) ドメイン遷移を行うドメイン

特定の条件下でドメイン遷移を行わせたい場合に使用します。

ドメインポリシーの作成

基本的なポリシーの作成方法

ポリシーを作成する基本的な手順は以下のようになります。

  1. ドメインの作成
  2. アクセス許可の学習
  3. アクセス許可の確認
  4. アクセス制御の実施

一度に全てのアプリケーション用のポリシーを作成する必要はありません。

(1) ドメインの作成

アクセス制御を行わないプロファイル(この手順書では 0 )を割り当ててアプリケーションを起動します。 この手順の目的は、アプリケーションのためのドメインを作成することです。

例えば、 /usr/sbin/httpd を保護したい場合、まずは /usr/sbin/httpd が動作するためのドメインを作成します。 /usr/sbin/httpd が initialize_domain に指定されていれば、 /usr/sbin/httpd を起動することにより <kernel> /usr/sbin/httpd というドメインが作成されます。指定されていなければ、起動元のドメインの子ドメイン(例えば <kernel> /usr/sbin/mingetty /bin/login /bin/bash から起動された場合は <kernel> /usr/sbin/mingetty /bin/login /bin/bash /usr/sbin/httpd)というドメイン)が作成されます。この手順書では initialize_domain に指定されている場合で説明します。

現在のプロセス(通常はシェル)が属しているドメインに、以下のように ccs-setprofile コマンドを使ってアクセス制御を行わないプロファイル(この手順書では 0 )を割り当てます。

xargs -0 /usr/sbin/ccs-setprofile 0 < /proc/ccs/self_domain

これは、現在のプロセスが属しているドメインに強制モードで動作するプロファイルが割り当てられていると、新しく作成されるドメインにも強制モードで動作するプロファイルが割り当てられてしまうからです。

この状態で、 /usr/sbin/httpd を動作させます。

service httpd start

ドメインが作成されたかどうかは以下のようにすることで確認できます。保護したいアプリケーション用のドメインが作成されたことを確認してください。

less /proc/ccs/.domain_status

ドメインが作成されたことを確認したら、次のステップへ進みます。

(2) アクセス許可の学習

ドメインが作成されたことを確認したら、以下のように ccs-setprofile コマンドを使って学習モードで動作するプロファイル(この手順書では 1 )を割り当てます。

/usr/sbin/ccs-setprofile -r 1 '<kernel> /usr/sbin/httpd'

この状態で /usr/sbin/httpd を動作させ、必要なアクセス許可を学習させていきます。

service httpd restart

プロファイルで 1-TOMOYO_VERBOSE=enabled (デフォルト)に設定されていると、ポリシーに違反したことを示す TOMOYO-WARNING: というメッセージがコンソールに表示されます。学習モードの場合は TOMOYO-WARNING: メッセージが表示された後に、必要なアクセス許可が自動的にポリシーに追加されるので、同じ操作をしても TOMOYO-WARNING: メッセージは1回しか表示されません。

許可したい操作を行っても TOMOYO-WARNING: というメッセージが表示されないようであれば、次のステップへ進みます。

(3) アクセス許可の確認

必要なアクセス許可が学習されたと判断したら、以下のように ccs-setprofile コマンドを使って確認モードで動作するプロファイル(この手順書では 2 )を割り当てます。

/usr/sbin/ccs-setprofile -r 2 '<kernel> /usr/sbin/httpd'

この状態で /usr/sbin/httpd を動作させ、必要なアクセス許可が学習されているかどうかを確認します。

プロファイルで 2-TOMOYO_VERBOSE=enabled (デフォルト)に設定されていると、ポリシーに違反したことを示す TOMOYO-WARNING: というメッセージがコンソールに表示されます。確認モードの場合は TOMOYO-WARNING: メッセージが表示されても、必要なアクセス許可が自動的にポリシーに追加されることはないので、同じ操作をすると TOMOYO-WARNING: メッセージは再度表示されます。

許可したい操作を行っても TOMOYO-WARNING: というメッセージが表示されないようであれば、次のステップへ進みます。

(4) アクセス制御の実施

必要なアクセス許可が与えられていると判断したら、以下のように ccs-setprofile コマンドを使って強制モードで動作するプロファイル(この手順書では 3 )を割り当てます。

/usr/sbin/ccs-setprofile -r 3 '<kernel> /usr/sbin/httpd'

以上で、 /usr/sbin/httpd に対して強制アクセス制御が適用された状態になります。

プロファイルで 3-TOMOYO_VERBOSE=enabled (デフォルト)に設定されていると、ポリシーに違反した場合に TOMOYO-ERROR: というメッセージがコンソールに表示されてアクセスが拒否されます。ポリシー違反の内容は、 /proc/ccs/reject_log にも蓄えられます。

確認モードを利用して一括してポリシーを生成する方法

TOMOYO Linux では、アクセスログ拒否ログからドメインポリシーを生成することができます。以下のように ccs-setprofile コマンドを使ってポリシー違反を確認モードで動作するプロファイル(この手順書では 2 )を割り当てます。

/usr/sbin/ccs-setprofile -r 2 '<kernel> /usr/sbin/httpd'

ccs-auditd によって作成された /var/log/tomoyo/reject_log.conf にはアクセスが拒否されたログが時系列で記録されています。 その中から、適当な範囲を切り抜き、以下のようにフィルタに通してください。このフィルタは、ドメイン単位にログを並べ替え、重複しているログを消します。(ドメイン単位でログの sort と uniq を行います。)

/usr/sbin/ccs-sortpolicy < /var/log/tomoyo/reject_log.conf

この結果から、追加すべきか否かを判断し、追加すべきであると判断した場合は /etc/ccs/domain_policy.conf に追加します。追加したら ccs-loadpolicy でドメインポリシーを再読み込みします。

/usr/sbin/ccs-loadpolicy d

ccs-loadpolicy df のように f オプションも指定すると、カーネル内部に保持されているドメインポリシーを消去して読み込みます。

操作例

現在のアクセス拒否ログの名前を変更します。 ccs-auditd は現在のアクセス拒否ログを保存していたファイルが消滅したことを検知して新しいファイルを作成します。

[root@sakura tomoyo]# mv /var/log/tomoyo/reject_log.conf /var/log/tomoyo/reject_log.tmp

内容を確認します。必要に応じて、抽出したい範囲だけをテキストエディタを用いて切り出します。

[root@sakura tomoyo]# cat /var/log/tomoyo/reject_log.tmp
#2006-11-10 10:17:29# pid=4498 uid=0 gid=0 euid=0 egid=0 suid=0 sgid=0 fsuid=0 fsgid=0
<kernel> /usr/sbin/sshd /bin/tcsh /bin/cat
allow_read /etc/inittab

#2006-11-10 10:17:41# pid=4501 uid=0 gid=0 euid=0 egid=0 suid=0 sgid=0 fsuid=0 fsgid=0
<kernel> /usr/sbin/sshd /bin/tcsh /bin/cat
allow_read /etc/resolv.conf

#2006-11-10 10:18:00# pid=4502 uid=0 gid=0 euid=0 egid=0 suid=0 sgid=0 fsuid=0 fsgid=0
<kernel> /usr/sbin/sshd /bin/tcsh
allow_execute /usr/bin/whoami

#2006-11-10 10:18:00# pid=4502 uid=0 gid=0 euid=0 egid=0 suid=0 sgid=0 fsuid=0 fsgid=0
<kernel> /usr/sbin/sshd /bin/tcsh /usr/bin/whoami
allow_read /etc/nsswitch.conf

#2006-11-10 10:18:00# pid=4502 uid=0 gid=0 euid=0 egid=0 suid=0 sgid=0 fsuid=0 fsgid=0
<kernel> /usr/sbin/sshd /bin/tcsh /usr/bin/whoami
allow_read /etc/passwd

内容をドメイン単位で並び替えます。

[root@sakura tomoyo]# /usr/sbin/ccs-sortpolicy < /var/log/tomoyo/reject_log.tmp
<kernel> /usr/sbin/sshd /bin/tcsh

allow_execute /usr/bin/whoami
#2006-11-10 10:18:00# pid=4502 uid=0 gid=0 euid=0 egid=0 suid=0 sgid=0 fsuid=0 fsgid=0

<kernel> /usr/sbin/sshd /bin/tcsh /bin/cat

allow_read /etc/inittab
allow_read /etc/resolv.conf
#2006-11-10 10:17:41# pid=4501 uid=0 gid=0 euid=0 egid=0 suid=0 sgid=0 fsuid=0 fsgid=0
#2006-11-10 10:18:00# pid=4502 uid=0 gid=0 euid=0 egid=0 suid=0 sgid=0 fsuid=0 fsgid=0

<kernel> /usr/sbin/sshd /bin/tcsh /usr/bin/whoami

allow_read /etc/nsswitch.conf
allow_read /etc/passwd
#2006-11-10 10:18:00# pid=4502 uid=0 gid=0 euid=0 egid=0 suid=0 sgid=0 fsuid=0 fsgid=0

タイムスタンプが邪魔なので # で始まる行を除外してから、内容をドメイン単位で並び替えます。

[root@sakura tomoyo]# grep -v '^#' /var/log/tomoyo/reject_log.tmp | /usr/sbin/ccs-sortpolicy > /var/log/tomoyo/diff.tmp

内容を確認します。これはドメインポリシーとしてそのまま追加可能な形式になっています。

[root@sakura tomoyo]# cat /var/log/tomoyo/diff.tmp
<kernel> /usr/sbin/sshd /bin/tcsh

allow_execute /usr/bin/whoami

<kernel> /usr/sbin/sshd /bin/tcsh /bin/cat

allow_read /etc/inittab
allow_read /etc/resolv.conf

<kernel> /usr/sbin/sshd /bin/tcsh /usr/bin/whoami

allow_read /etc/nsswitch.conf
allow_read /etc/passwd

強制モードを利用して対話的にポリシーを生成する方法

TOMOYO Linux では、強制モードのままポリシーの修正を行うことができます。以下のように ccs-queryd コマンドを使ってポリシー違反を対話的に許容できます。 ccs-queryd は、ポリシー違反の発生を検知して、アクセス要求の内容を表示します。管理者は、そのアクセス要求の妥当性を判断して、アクセスを許可するか否か、ドメインポリシーに追加するか否かを指定することができます。

/usr/sbin/ccs-queryd

ccs-queryd が動作している場合、ポリシー違反が発生しても管理者が応答するまでそのアクセス要求は保留状態となります。それ以外の場合は、ポリシー違反が発生するとそのアクセス要求は直ちに拒否されます。

保留状態のまま永遠に停止してしまうことを避けるために、 ccs-queryd が動作している状態のままログアウト(例えば screen(1) プログラムの中で ccs-queryd を動作させたままデタッチ)しないでください。

ccs-queryd を終了させるには Ctrl-C を押してください。

ポリシーの保存方法

カーネル内部に保持されているポリシーをディスクに保存するには、以下のように ccs-savepolicy コマンドを使います。

/usr/sbin/ccs-savepolicy

ccs-savepolicy を実行することで、 /etc/ccs/ ディレクトリに system_policy.conf exception_policy.conf domain_policy.conf の3つのファイルが作成されます。実際にはこれらのファイルは、ファイルの作成日時をファイル名に含んだテキストファイルへのシンボリックリンクになっています。

ポリシーの読み込み方法

/etc/ccs/ ディレクトリに保存されているポリシーをカーネル内部に読み込むには、以下のように ccs-loadpolicy コマンドを使います。

/usr/sbin/ccs-loadpolicy af

a オプションは system_polixy.conf exception_policy.conf domain_policy.conf の3種類を読み込むことを意味します。また、 f オプションはカーネル内部に保持されているポリシーを消去して読み込みます。 f オプションが指定されなかった場合は、カーネル内部に保持されているポリシーに追加される形になります。

ポリシーの編集方法

カーネル内部に保持されているポリシーを編集するには、以下のように ccs-editpolicy コマンドを使います。ポリシーエディタの使い方については、ポリシーエディタの使い方を参照してください。

/usr/sbin/ccs-editpolicy

ディスク上に保存されているポリシーファイルを編集するには、以下のようにポリシーファイルの保存されている /etc/ccs/ ディレクトリを ccs-editpolicy に渡します。ポリシーファイルの保存されている /etc/ccs/ ディレクトリを指定することで、 ccs-editpolicy コマンドは通常のカーネルで動作している場合でも利用できます。

/usr/sbin/ccs-editpolicy /etc/ccs/

ポリシーのチューニング

ファイルのアクセス許可のパターン化

WWW サーバがアクセスするコンテンツのように、自動学習では必ずしもアクセスされないファイルに対するアクセス許可を /etc/ccs/domain_policy.conf に追加します。
以下の例では、 /usr/sbin/httpd に対して /var/www/html/ 以下の読み込みを許可しています。

<kernel> /usr/sbin/httpd
use_profile 3
allow_read /var/www/html/\*
allow_read /var/www/html/\*/\*
allow_read /var/www/html/\*/\*/\*
allow_read /var/www/html/\*/\*/\*/\*
allow_read /var/www/html/\*/\*/\*/\*/\*

TOMOYO Linux 1.3.2 ではパス名のグループ化がサポートされています。上記の指定は例外ポリシーに

path_group WEB-CONTENTS /var/www/html/\*
path_group WEB-CONTENTS /var/www/html/\*/\*
path_group WEB-CONTENTS /var/www/html/\*/\*/\*
path_group WEB-CONTENTS /var/www/html/\*/\*/\*/\*
path_group WEB-CONTENTS /var/www/html/\*/\*/\*/\*/\*

という定義をしておくことにより、

<kernel> /usr/sbin/httpd
use_profile 3
allow_read @WEB-CONTENTS

のように簡単に記述できます。

同様に、パターンを使用して手作業でのグループ化を行います。
以下の例では、 /usr/sbin/smbd に対して全てのログファイルを同様に扱うように指示しています。

修正前修正後
<kernel> /usr/sbin/smbd
use_profile 3
allow_write /var/log/samba/host1.log
allow_write /var/log/samba/host2.log
allow_write /var/log/samba/host3.log
allow_write /var/log/samba/host4.log
allow_write /var/log/samba/host5.log
<kernel> /usr/sbin/smbd
use_profile 3
allow_write /var/log/samba/\*.log

与えられたパターンと一致するディスク上のパス名を一覧表示する ccs-pathmatch コマンドを用いて、パターン化することでアクセス可能になる範囲を確認できます。

[root@sakura ~]# /usr/sbin/ccs-pathmatch '/var/log/samba/\*.log'
/var/log/samba/host1.log /var/log/samba/host2.log /var/log/samba/host3.log /var/log/samba/host4.log /var/log/samba/host5.log

操作例

カーネルに存在するドメインポリシーをディスクに保存します。

[root@sakura ~]# /usr/sbin/ccs-savepolicy d

テンポラリファイルの可能性があるパス名を抽出します。

[root@sakura ~]# /usr/sbin/ccs-findtemp < /etc/ccs/domain_policy.conf
/etc/mtab.tmp
/etc/mtab~
/etc/mtab~2302
/etc/mtab~2328
/etc/mtab~2329
/etc/mtab~2330
/etc/mtab~2331
/etc/mtab~2332
/etc/mtab~2339
/etc/mtab~2383
/halt
/selinux/disable
/selinux/enforce
/selinux/policyvers
/tmp/sh-thd-1163110572
/tmp/sh-thd-1163113704
/var/cache/samba/browse.dat.
/var/lib/nfs/etab.tmp
/var/lib/nfs/xtab.tmp
/var/lock/mrtg/mrtg_l

テンポラリファイルにアクセスしているドメインを探します。

[root@sakura ~]# /usr/sbin/ccs-domainmatch /etc/mtab~2302
<kernel> /sbin/init /etc/rc.d/rc.sysinit /sbin/initlog /etc/rc.d/rc.sysinit /sbin/initlog /bin/mount
allow_create /etc/mtab~2302
allow_write /etc/mtab~2302
allow_link /etc/mtab~2302 /etc/mtab~
allow_unlink /etc/mtab~2302
[root@sakura ~]# domainmatch /tmp/sh-thd-1163113704
<kernel> /etc/rc.d/init.d/smartd /sbin/initlog /usr/sbin/smartd /bin/sh
allow_create /tmp/sh-thd-1163113704
allow_read/write /tmp/sh-thd-1163113704
allow_unlink /tmp/sh-thd-1163113704

カーネルに存在する例外ポリシーをディスクに保存します。

[root@sakura ~]# /usr/sbin/ccs-savepolicy e

必要に応じてディスク上の例外ポリシーにパターンを追加します。

[root@sakura ~]# echo 'file_pattern /etc/mtab~\$' >> /etc/ccs/exception_policy.conf
[root@sakura ~]# echo 'file_pattern /tmp/sh-thd-\$' >> /etc/ccs/exception_policy.conf

ディスク上の例外ポリシーをカーネルに読み込みます。

[root@sakura ~]# /usr/sbin/ccs-loadpolicy ef

/etc/mtab~\$ および /tmp/sh-thd-\$ に一致するパス名のパターン化を行います。

[root@sakura ~]# /usr/sbin/ccs-patternize '/etc/mtab~\$' '/tmp/sh-thd-\$' < /etc/ccs/domain_policy.conf > /etc/ccs/domain_policy.tmp

パターン化されたことを確認します。

[root@sakura ~]# /usr/sbin/ccs-findtemp < /etc/ccs/domain_policy.tmp
/etc/mtab.tmp
/etc/mtab~
/halt
/selinux/disable
/selinux/enforce
/selinux/policyvers
/var/cache/samba/browse.dat.
/var/lib/nfs/etab.tmp
/var/lib/nfs/xtab.tmp
/var/lock/mrtg/mrtg_l

パターン化前後の差分を表示して、パターン化が適切に行われているかどうかを確認します。

[root@sakura ~]# diff /etc/ccs/domain_policy.conf /etc/ccs/domain_policy.tmp
2326,2331c2326,2331
< allow_read/write /tmp/sh-thd-1163110572
< allow_read/write /tmp/sh-thd-1163113704
< allow_create /tmp/sh-thd-1163110572
< allow_create /tmp/sh-thd-1163113704
< allow_unlink /tmp/sh-thd-1163110572
< allow_unlink /tmp/sh-thd-1163113704
---
> allow_read/write /tmp/sh-thd-\$
> allow_read/write /tmp/sh-thd-\$
> allow_create /tmp/sh-thd-\$
> allow_create /tmp/sh-thd-\$
> allow_unlink /tmp/sh-thd-\$
> allow_unlink /tmp/sh-thd-\$
3331,3336c3331,3336
< allow_write /etc/mtab~2328
< allow_write /etc/mtab~2329
< allow_write /etc/mtab~2330
< allow_write /etc/mtab~2331
< allow_write /etc/mtab~2332
< allow_write /etc/mtab~2383
---
> allow_write /etc/mtab~\$
> allow_write /etc/mtab~\$
> allow_write /etc/mtab~\$
> allow_write /etc/mtab~\$
> allow_write /etc/mtab~\$
> allow_write /etc/mtab~\$
3338,3349c3338,3349
< allow_create /etc/mtab~2328
< allow_create /etc/mtab~2329
< allow_create /etc/mtab~2330
< allow_create /etc/mtab~2331
< allow_create /etc/mtab~2332
< allow_create /etc/mtab~2383
< allow_link /etc/mtab~2328 /etc/mtab~
< allow_link /etc/mtab~2329 /etc/mtab~
< allow_link /etc/mtab~2330 /etc/mtab~
< allow_link /etc/mtab~2331 /etc/mtab~
< allow_link /etc/mtab~2332 /etc/mtab~
< allow_link /etc/mtab~2383 /etc/mtab~
---
> allow_create /etc/mtab~\$
> allow_create /etc/mtab~\$
> allow_create /etc/mtab~\$
> allow_create /etc/mtab~\$
> allow_create /etc/mtab~\$
> allow_create /etc/mtab~\$
> allow_link /etc/mtab~\$ /etc/mtab~
> allow_link /etc/mtab~\$ /etc/mtab~
> allow_link /etc/mtab~\$ /etc/mtab~
> allow_link /etc/mtab~\$ /etc/mtab~
> allow_link /etc/mtab~\$ /etc/mtab~
> allow_link /etc/mtab~\$ /etc/mtab~
3351,3356c3351,3356
< allow_unlink /etc/mtab~2328
< allow_unlink /etc/mtab~2329
< allow_unlink /etc/mtab~2330
< allow_unlink /etc/mtab~2331
< allow_unlink /etc/mtab~2332
< allow_unlink /etc/mtab~2383
---
> allow_unlink /etc/mtab~\$
> allow_unlink /etc/mtab~\$
> allow_unlink /etc/mtab~\$
> allow_unlink /etc/mtab~\$
> allow_unlink /etc/mtab~\$
> allow_unlink /etc/mtab~\$
3439,3440c3439,3440
< allow_write /etc/mtab~2302
< allow_write /etc/mtab~2339
---
> allow_write /etc/mtab~\$
> allow_write /etc/mtab~\$
3443,3446c3443,3446
< allow_create /etc/mtab~2302
< allow_create /etc/mtab~2339
< allow_link /etc/mtab~2302 /etc/mtab~
< allow_link /etc/mtab~2339 /etc/mtab~
---
> allow_create /etc/mtab~\$
> allow_create /etc/mtab~\$
> allow_link /etc/mtab~\$ /etc/mtab~
> allow_link /etc/mtab~\$ /etc/mtab~
3449,3450c3449,3450
< allow_unlink /etc/mtab~2302
< allow_unlink /etc/mtab~2339
---
> allow_unlink /etc/mtab~\$
> allow_unlink /etc/mtab~\$

ディスク上のドメインポリシーを更新します。

[root@sakura ~]# cat /etc/ccs/domain_policy.tmp > /etc/ccs/domain_policy.conf

ディスク上のドメインポリシーをカーネルに読み込みます。

[root@sakura ~]# /usr/sbin/ccs-loadpolicy df

カーネルに読み込まれているドメインポリシーが更新されていることを確認します。

[root@sakura ~]# /usr/sbin/ccs-findtemp < /proc/ccs/domain_policy
/etc/mtab.tmp
/etc/mtab~
/halt
/selinux/disable
/selinux/enforce
/selinux/policyvers
/var/cache/samba/browse.dat.
/var/lib/nfs/etab.tmp
/var/lib/nfs/xtab.tmp
/var/lock/mrtg/mrtg_l

ネットワークのアクセス許可のパターン化

同様に、 allow_network も適切にパターン化します。以下の設定をそのままコピーしないようにしてください。

修正前修正後
<kernel> /usr/sbin/sshd
use_profile 7
allow_network TCP accept 0:0:0:0:0:0:0:1 43768
allow_network TCP accept 0:0:0:0:0:ffff:a00:1 35086
allow_network TCP accept 0:0:0:0:0:ffff:a00:a1 47590
allow_network TCP accept 10.0.0.10 56709
allow_network TCP accept 10.0.0.200 16384
<kernel> /usr/sbin/sshd
use_profile 7
allow_network TCP accept 0:0:0:0:0:0:0:1 1024-65535
allow_network TCP accept 0:0:0:0:0:ffff:a00:1-0:0:0:0:0:ffff:a00:ff 1024-65535
allow_network TCP accept 10.0.0.1-10.0.0.255 1024-65535

上記の指定は例外ポリシーに

address_group SSH-CLIENT-ADDRESS 0:0:0:0:0:0:0:1
address_group SSH-CLIENT-ADDRESS 0:0:0:0:0:ffff:a00:1-0:0:0:0:0:ffff:a00:ff
address_group SSH-CLIENT-ADDRESS 10.0.0.1-10.0.0.255

という定義をしておくことにより、

<kernel> /usr/sbin/sshd
use_profile 7
allow_network TCP accept @SSH-CLIENT-ADDRESS 1024-65535

のように簡単に記述できます。

アクセス許可条件の付与

個々のアクセス許可に対して必要に応じて条件を付けることができます。これにより、システムアカウントのユーザIDに基づくアクセス制御が可能です。

例外ポリシーで以下のように path_group が定義されていると仮定します。

path_group HOME-FTP-FILE /home/\*/ftp/\*
path_group HOME-FTP-FILE /home/\*/ftp/\*/\*
path_group HOME-FTP-FILE /home/\*/ftp/\*/\*/\*
path_group HOME-FTP-FILE /home/\*/ftp/\*/\*/\*/\*
path_group HOME-FTP-DIR /home/\*/ftp/\*/
path_group HOME-FTP-DIR /home/\*/ftp/\*/\*/
path_group HOME-FTP-DIR /home/\*/ftp/\*/\*/\*/
path_group HOME-SMB-FILE /home/\*/samba/\*
path_group HOME-SMB-FILE /home/\*/samba/\*/\*
path_group HOME-SMB-FILE /home/\*/samba/\*/\*/\*
path_group HOME-SMB-FILE /home/\*/samba/\*/\*/\*/\*
path_group HOME-SMB-DIR /home/\*/samba/\*/
path_group HOME-SMB-DIR /home/\*/samba/\*/\*/
path_group HOME-SMB-DIR /home/\*/samba/\*/\*/\*/

匿名ではない FTP サーバを保護する場合、以下のように条件を付けることで、当該ユーザのホームディレクトリ以外へのアクセスを禁止することができるようになります。ホームディレクトリ以下全部を FTP でアクセス可能にすることは、侵入された場合に被害が大きくなるため、自分のホームディレクトリにある ftp ディレクトリ以下だけのアクセスを認めます。 vsftpd を用いる場合、例えば以下のように許可を与えます。

修正前修正後
<kernel> /usr/sbin/vsftpd
use_profile 3

allow_read/write @HOME-FTP-FILE
allow_mkdir @HOME-FTP-DIR
allow_rmdir @HOME-FTP-DIR
allow_create @HOME-FTP-FILE
allow_truncate @HOME-FTP-FILE
allow_unlink @HOME-FTP-FILE
allow_rename @HOME-FTP-FILE @HOME-FTP-FILE
allow_rename @HOME-FTP-DIR @HOME-FTP-DIR
<kernel> /usr/sbin/vsftpd
use_profile 3

allow_read/write @HOME-FTP-FILE if task.uid=path1.uid
allow_mkdir @HOME-FTP-DIR if task.uid=path1.parent.uid
allow_rmdir @HOME-FTP-DIR if task.uid=path1.uid
allow_create @HOME-FTP-FILE if task.uid=path1.parent.uid
allow_truncate @HOME-FTP-FILE if task.uid=path1.uid
allow_unlink @HOME-FTP-FILE if task.uid=path1.uid
allow_rename @HOME-FTP-FILE @HOME-FTP-FILE if task.uid=path1.parent.uid task.uid=path2.parent.uid
allow_rename @HOME-FTP-DIR @HOME-FTP-DIR if task.uid=path1.parent.uid task.uid=path2.parent.uid

Samba サーバを保護する場合、以下のように条件を付けることで、当該ユーザのホームディレクトリ以外へのアクセスを禁止することができるようになります。ホームディレクトリ以下全部を Samba でアクセス可能にすることは、侵入された場合に被害が大きくなるため、自分のホームディレクトリにある samba ディレクトリ以下だけのアクセスを認めます。

修正前修正後
<kernel> /usr/sbin/smbd
use_profile 3

allow_read/write @HOME-SMB-FILE
allow_mkdir @HOME-SMB-DIR
allow_rmdir @HOME-SMB-DIR
allow_create @HOME-SMB-FILE
allow_truncate @HOME-SMB-FILE
allow_unlink @HOME-SMB-FILE
allow_rename @HOME-SMB-FILE @HOME-SMB-FILE
allow_rename @HOME-SMB-DIR @HOME-SMB-DIR
<kernel> /usr/sbin/smbd
use_profile 3

allow_read/write @HOME-SMB-FILE if task.euid=path1.uid
allow_mkdir @HOME-SMB-DIR if task.euid=path1.parent.uid
allow_rmdir @HOME-SMB-DIR if task.euid=path1.uid
allow_create @HOME-SMB-FILE if task.euid=path1.parent.uid
allow_truncate @HOME-SMB-FILE if task.euid=path1.uid
allow_unlink @HOME-SMB-FILE if task.euid=path1.uid
allow_rename @HOME-SMB-FILE @HOME-SMB-FILE if task.euid=path1.parent.uid task.euid=path2.parent.uid
allow_rename @HOME-SMB-DIR @HOME-SMB-DIR if task.euid=path1.parent.uid task.euid=path2.parent.uid

SSH サーバを保護する場合、以下のように条件を付けることで、 root ユーザとしてログインすることを禁止できます。

修正前修正後
<kernel> /usr/sbin/sshd
use_profile 3

allow_execute /bin/bash
<kernel> /usr/sbin/sshd
use_profile 3

allow_execute /bin/bash if task.uid!=0 task.euid!=0

ソフトウェアのアップデート

ソフトウェアのアップデートや設定の変更によりポリシーを調整する必要が発生する場合があります。ポリシーを調整する方法については、TOMOYO Linuxメンテナンス手順を参照してください。

sflogo.php