Info: Version 1.3 is available.

# TOMOYO Linux導入手順

Last modified: $Date: 2011-11-20 09:56:56 +0900 (Sun, 20 Nov 2011) $

# 目次

- 準備
- カーネルのインストール
- ツールのインストール
- 起動テスト
- 制御範囲の決定
- ログインして行う操作の設計
- デバイスファイルの保護（任意）
- ポリシーの作成準備
- デフォルトポリシーについて
- ポリシーの変更を許可するプログラムの指定
- シャットダウン処理の修正
- 監査ログの取得準備
- プロファイルの作成
- 例外ポリシーの作成
- logrotate への対応
- prelink への対応
- anacron への対応
- cron への対応
- Targeted Policy への対応
- ポリシーの作成
- 学習モード
- logrotate への対応
- anacron への対応
- 例外ポリシーの更新
- 学習モード
- ポリシーのチューニング
- 監査ログからの生成
- アクセス許可のパターン化
- ネットワークのパターン化
- アクセス許可条件の付与
- 確認モード
- ポリシーの利用
- 強制モード

# 準備

使用するディストリビューションの制限はありません。しかし、全てのディストリビューションで共通に使える手順書を作成することはできないため、この手順書では「RedHat Linux 9」「Fedora Core 3」「Debian Sarge」の３種類について記述します。

不要なアプリケーションは事前にアンインストールしておくことで、ポリシーのサイズを小さくすることができます。 どのアプリケーションが必要かを事前に把握しておくことを推奨します。

## カーネルのインストール

カーネルをコンパイルする方法については、TOMOYO Linuxカーネルの作成手順を参照してください。

## ツールのインストール

ツールをコンパイルするには、以下のコマンドを実行してください。

cd /root/ # TOMOYO Linux ツールのソースをダウンロードする。 wget -O ccs-tools-1.2-20060903.tar.gz 'http://sourceforge.jp/frs/redir.php?m=jaist&f=/tomoyo/21579/ccs-tools-1.2-20060903.tar.gz' # 展開する。 tar -zxf ccs-tools-1.2-20060903.tar.gz # コンパイルする。 make -sC ccstools/

## 起動テスト

TOMOYO Linux カーネルで起動して、正常に動作できることを確認できたら、 /proc/ccs/status の内容を /root/security/status.txt というファイルに保存しておいてください。このファイルに含まれる項目が、このカーネルで制御できる項目になります。このファイルは、後述する手順でプロファイルを作成する際のヒントとして使用します。

mkdir -p /root/security cat /proc/ccs/status > /root/security/status.txt

## 制御範囲の決定

TOMOYO Linux のドメイン単位のアクセス制御機能（TOMOYO (Domain-Based Mandatory Access Control) support）は、 /sbin/init の開始時から電源が切れるまでの間に実行される全てのソフトウェアを対象に適用することが可能です。しかし、 http サーバや ssh サーバなど、特定のソフトウェアだけを対象に適用することも可能です。

以後、全てのソフトウェアを対象とするポリシーを Strict Policy 、特定のソフトウェアだけを対象とするポリシーを Targeted Policy と呼びます。

全てのソフトウェアを対象に適用する方がより安全ですが、特定のソフトウェアだけを対象に適用する方が簡単です。 この時点で、アクセス制御機能を適用する範囲を決定してください。

なお、 TOMOYO Linux のシステム全体のアクセス制御機能（SAKURA (Domain-Free Mandatory Access Control) support）および デバイスファイルの改ざん防止機能（SYAORAN (Tamper-Proof Device Filesystem) support）は、全てのソフトウェアを対象に適用されます。

## ログインして行う操作の設計

メンテナンスなどのために、サーバへ ssh でログインして作業を行うことがあると思います。そこで、このステップでは、ログインしてどのような操作を行うかを決定します。

### ログイン認証の強化（任意） ssh を使用してログインする際のセキュリティを向上させるのが目的です。この手順は任意ですが、簡単に実現できるので活用することを推奨します。 TOMOYO Linux では、 SELinux のように sshd を改造してバッファオーバーフロー対策などを行うことはできません。 そのため、 sshd または認証モジュールに脆弱性が存在した場合、 SELinux よりも簡単に侵入を許してしまいます。 しかし、脅威はバッファオーバーフローなどだけではありません。正規のユーザ名とパスワードを使用してログインされるという可能性も存在します。 ssh でログインする場合、パスワードまたは公開鍵認証を使用している場合が圧倒的に多いと思います。しかし、ブルートフォース攻撃により侵入されてフィッシングなどに悪用されるなどの被害が増えてきています。そのため、ログイン認証は突破されることを前提として、追加のログイン認証が行われるようにすることが大切です。 詳細については、論文「セキュリティ強化OSによるログイン認証の強化手法」を参照してください。 追加的な防御手段で使用するプログラムは、管理者が自由な仕様で作成することができます。 この段階でそのためのプログラムを作成して、意図したとおりの使い方ができることを確認しておいてください。 ログイン認証を複数回行えるようにすることで、資源の保護レベルに応じたアクセス制限も提供できるようになります。通常は下の図のようにログイン認証を通過しただけで、重要に保護する必要のある資源にもその必要が無い資源にもアクセスできてしまいます。 しかし、下の図のように /opt/bin/auth1 および /opt/bin/auth2 という認証を追加することにより、ログイン認証を通過しただけなら厳重に保護する必要の無い資源へのアクセスのみを許可し、全ての認証を通過した場合のみ厳重に保護しなければいけない資源へのアクセスも許可することが可能になります。
### 管理者権限を必要とする業務の一部委託（任意） サーバ管理業務の一部だけを他人に委託したい場合に使用します。 例えば、 HTTP サーバのコンテンツの管理と httpd プロセスの再起動のみを委託したい場合に利用します。 管理者としてログインしてもらい、前述した「ログイン認証の強化」で使用したプログラムと組み合わせることで、委託された人だけがその業務をできるようにすることができます。この段階で、誰にどの業務を委託するかを決定し、どのようにドメインを分割するかを設計し、ドメインの分割点として使用するためのプログラムを決定します。 /bin/bash や /bin/tcsh をドメインの分割点として使用するためのプログラムとして利用することも可能ですが、無断で他人の担当業務用のドメインに遷移できてしまうので望ましくありません。 そのため、「ログイン認証の強化」で説明したのと同じ要領で認証機構を備えたプログラムを作成して、意図したとおりの使い方ができることを確認しておいてください。 例えば、システム上に SAKURA TOMOYO SYAORAN CERBERUS YUE というユーザが登録されており、それぞれが ssh でログインして作業を行う場合に、下の図のようにドメインを分割することによりユーザ単位のアクセス許可を登録できます。 同様に、例えばシステム上で manager webmaster auditor user anonymous というロールが必要であり、それぞれが ssh でログインして作業を行う場合に、下の図のようにドメインを分割することによりロール単位のアクセス許可を登録できます。

## デバイスファイルの保護（任意）

デバイスファイルの改ざん防止機能（SYAORAN (Tamper-Proof Device Filesystem) support）を利用する場合、この時点で設定を行います。

以下の操作を行い、/.syaoranというスクリプトを作成します。

echo '#! /bin/sh' > /.syaoran echo 'mount -n -t syaoran -o accept=/root/security/syaoran.conf none /dev' >> /.syaoran echo 'exec /sbin/init "$@"' >> /.syaoran chmod 700 /.syaoran

/sbin/init を起動する直前にマウントされるようにするために、 TOMOYO Linux カーネルの起動時に init=/.syaoran というパラメータを追加してください。毎回指定するのは面倒なので、ブートローダの設定ファイルで指定しておくことを推奨します。

以下の操作を行い、全てのエントリを含んだ初期状態の /root/security/syaoran.conf を作成します。

/root/ccstools/makesyaoranconf > /root/security/syaoran.conf

udev を使用するディストリビューションの場合は、以下の操作も行ってください。

echo DENY_CONCEAL_MOUNT=3 > /root/security/profile0.txt

TOMOYO Linux カーネルで再起動してシステムを稼動させると、実際にオープンされたデバイスファイルだけが学習されていきます。学習結果はマウントポイント直下の .syaoran というファイルから取り出すことができます。

以下の２点に注意する必要があります。

スワップパーティション用のデバイスファイルはマウントされる際にオープンされないため、何らかの方法で明示的にオープンしないと .syaoran から除外されてしまい、スワップパーティションをマウントできなくなります。以下のコマンドを実行してスワップパーティションを明示的にオープンするようにしてください。（スワップパーティション用のデバイスファイルが /dev/sda3 の場合です。実際のスワップパーティション名にあわせて読み替えてください。）

touch /dev/sda3

ssh ログインで pty の使用を許可したい場合は必ず一度ログインしてください。 ssh ログインをしないと /dev/ptmx がオープンされないため、 .syaoran から除外されてしまい、ssh ログインした際に pty を使うことができなくなります。

ssh localhost

以下のコマンドを実行して、学習結果を /root/security/syaoran.conf に反映します。

cat /dev/.syaoran > /root/security/syaoran.conf

TOMOYO Linux カーネルで再起動し、必要なエントリが全て含まれていることを確認してください。 もし、システムが正常に動作しない場合は、必要なエントリが削除されてしまった可能性がありますので、初期状態の /root/security/syaoran.conf を作成するところからやり直してください。

/root/security/syaoran.conf に含まれているデッドリンクや不要なディレクトリは削除しても構いません。ただし、マウントポイント（通常は shm と pts ディレクトリ）を削除しないように注意してください。

# ポリシーの作成準備

この章の作業は通常のカーネルで行うようにしてください。
TOMOYO Linux カーネルで行うと、シャットダウン時に /root/ccstools/savepolicy が実行されるために /root/security/exception_policy.txt に加えた変更内容が失われてしまいます。

## デフォルトポリシーについて

TOMOYO Linux には、ソフトウェアと一緒に配布されるデフォルトポリシーはありません。学習モードを使用して策定する必要があります。
参考までに、サンプルのポリシーを置いてあります。参照は自由ですが、デフォルトポリシーとしての利用はしないでください。

## ポリシーの変更を許可するプログラムの指定

/root/security/manager.txt を作成し、その中にポリシーの変更を許可したいプログラムを指定します。
具体的には、ポリシーを再読み込みする loadpolicy 、ポリシーを編集する editpolicy 、制御レベルを変更する setlevel 、無条件読み込み許可を更新する ld-watch 、対話的にアクセス要求を許可する ccs-queryd の５つを指定してください。

cat > /root/security/manager.txt << EOF /root/ccstools/loadpolicy /root/ccstools/editpolicy /root/ccstools/setlevel /root/ccstools/ld-watch /root/ccstools/ccs-queryd EOF

## シャットダウン処理の修正

電源が切れる直前にメモリ上のポリシーをディスク上に保存するために、シャットダウンスクリプトの中で /root/ccstools/savepolicy が実行されるように修正します。具体的な修正箇所はディストリビューション毎に異なります。多くの場合、 /etc/init.d/ ディレクトリ直下にあるシャットダウンを行うスクリプトの最後に実行されるプログラムが電源を切るためのプログラムなので、その直前で保存するように修正します。

RedHat Linux 9 および Fedora Core 3 の場合は以下のように修正してください。

/etc/rc.d/init.d/halt
修正前 | 修正後
exec $command $HALTARGS | /root/ccstools/savepolicy exec $command $HALTARGS

Debian Sarge の場合は以下のように修正してください。 savepolicy の前に halt/reboot を一度実行しているのは halt/reboot を実行するドメインを作成するためです。

/etc/init.d/halt | /etc/init.d/reboot
修正前 | 修正後 | 修正前 | 修正後
halt -d -f -i $poweroff $hddown | halt --help 2> /dev/null /root/ccstools/savepolicy halt -d -f -i $poweroff $hddown | reboot -d -f -i | reboot --help 2> /dev/null /root/ccstools/savepolicy reboot -d -f -i

## 監査ログの取得準備

ドメイン単位のアクセス制御機能に関して、アクセスが許可された要求のログ（アクセス許可ログ）とアクセスが拒否された要求のログ（アクセス拒否ログ）を取得することができます。 取得したログは、そのままドメイン用ポリシーとして追加可能な形式になっています。 アクセス拒否ログの内容を吟味して、許可すべきであればドメイン用ポリシーに追加します。

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

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

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

アクセス拒否ログを保存する必要が無い場合は、保存場所として /dev/null を指定することができます。

どちらも保存しない場合は ccs-auditd を実行する必要はありませんが、アクセス拒否ログは保存しておくことを推奨します。 この手順書では、アクセス拒否ログを /var/log/tomoyo/reject_log.txt に保存するものとします。

/root/ccstools/ccs-auditd /dev/null /var/log/tomoyo/reject_log.txt

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

mkdir -p /var/log/tomoyo

logrotate によるローテーションを行わせたい場合は、以下のような内容のファイルを /etc/logrotate.d/tomoyo に作成してください。

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

## プロファイルの作成

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

有効にしたい機能とそのモードを記述した初期制御レベル定義ファイルを１つ以上作成し、カーネル起動時のコマンドラインから番号を指定することで切り替えができるようになっています。具体的には、カーネル起動時のコマンドラインで CCS=$INDEX （$INDEX は整数）というパラメータを指定すると、対応する /root/security/profile$INDEX.txt が読み込まれます。

以下の説明を参照しながら、用途毎のプロファイルを作成してください。 /root/security/status.txt に含まれる項目だけが指定可能です。 /root/security/status.txt に含まれる項目の数は、カーネルコンパイル時の設定により変化します。

項目 | 制御する内容 | 自動学習対応
MAC_FOR_FILE | ファイルの読み書き実行 | ○
MAC_FOR_CAPABILITY::inet_tcp_create | TCP ソケットの使用 | ○
MAC_FOR_CAPABILITY::inet_tcp_listen | TCP ソケットの listen | ○
MAC_FOR_CAPABILITY::inet_tcp_connect | TCP ソケットの connect | ○
MAC_FOR_CAPABILITY::use_inet_udp | UDP ソケットの使用 | ○
MAC_FOR_CAPABILITY::use_inet_ip | RAW ソケットの使用 | ○
MAC_FOR_CAPABILITY::use_route | ROUTE ソケットの使用 | ○
MAC_FOR_CAPABILITY::use_packet | PACKET ソケットの使用 | ○
MAC_FOR_CAPABILITY::use_kernel_module | カーネルモジュールの使用 | ○
MAC_FOR_CAPABILITY::create_fifo | FIFO の作成 | ○
MAC_FOR_CAPABILITY::create_block_dev | ブロック型デバイスの作成 | ○
MAC_FOR_CAPABILITY::create_char_dev | キャラクタ型デバイスの作成 | ○
MAC_FOR_CAPABILITY::create_unix_socket | UNIX ドメインソケットの作成 | ○
MAC_FOR_CAPABILITY::SYS_MOUNT | ファイルシステムのマウント | ○
MAC_FOR_CAPABILITY::SYS_UMOUNT | ファイルシステムのアンマウント | ○
MAC_FOR_CAPABILITY::SYS_REBOOT | システムの再起動 | ○
MAC_FOR_CAPABILITY::SYS_CHROOT | ルートディレクトリの変更 | ○
MAC_FOR_CAPABILITY::SYS_KILL | シグナルの送信 | ○
MAC_FOR_CAPABILITY::SYS_VHANGUP | vhangup の使用 | ○
MAC_FOR_CAPABILITY::SYS_TIME | システム時刻の変更 | ○
MAC_FOR_CAPABILITY::SYS_NICE | プロセスの優先度の変更 | ○
MAC_FOR_CAPABILITY::SYS_SETHOSTNAME | ホスト名・ドメイン名の変更 | ○
MAC_FOR_CAPABILITY::SYS_LINK | ハードリンクの作成 | ○
MAC_FOR_CAPABILITY::SYS_SYMLINK | シンボリックリンクの作成 | ○
MAC_FOR_CAPABILITY::SYS_RENAME | ファイル名の変更 | ○
MAC_FOR_CAPABILITY::SYS_UNLINK | ファイルの削除 | ○
MAC_FOR_CAPABILITY::SYS_CHMOD | ファイルのパーミッションの変更 | ○
MAC_FOR_CAPABILITY::SYS_CHOWN | ファイルの所有者・グループの変更 | ○
MAC_FOR_CAPABILITY::SYS_IOCTL | ioctl の使用 | ○
MAC_FOR_CAPABILITY::SYS_KEXEC_LOAD | 新しいカーネルのロード | ○
MAC_FOR_NETWORK | プログラムが使用できるＩＰアドレスとポート番号 | ○
MAC_FOR_BINDPORT | プログラムが使用できるローカルポート番号 | ○
MAC_FOR_CONNECTPORT | プログラムが使用できるリモートポート番号 | ○
MAC_FOR_SIGNAL | 自分自身以外へのシグナルの送信 | ○
DENY_CONCEAL_MOUNT | 既存のマウントを隠蔽するようなマウントの禁止 | ×
RESTRICT_CHROOT | chroot で移動可能なディレクトリ | ○
RESTRICT_MOUNT | マウント可能な「デバイスファイルとマウントポイントとファイルシステム」の組み合わせ | ○
RESTRICT_UNMOUNT | 指定されたディレクトリのアンマウントの禁止 | ×
DENY_PIVOT_ROOT | pivot_root 呼び出しの禁止 | ×
RESTRICT_AUTOBIND | TCP/IP ネットワークで自動的に割り当てられるローカルポート | ×
TRACE_READONLY | ファイルシステムが読み込み専用であることで失敗したファイル名を表示する。 | －
MAX_ACCEPT_FILES | 学習モードで自動的に追加されるアクセス許可の上限を指定する。 | －
MAX_GRANT_LOG | メモリ上に保持するアクセス許可ログの上限を指定する。 | －
MAX_REJECT_LOG | メモリ上に保持するアクセス拒否ログの上限を指定する。 | －
TOMOYO_VERBOSE | ドメイン別ポリシーに対する違反を syslog に表示する。 | －
MAX_ENFORCE_GRACE | 強制モードでポリシー違反が発生した場合に、アクセス要求を拒否するまでの猶予時間を指定する。 | －

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

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

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

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

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

値 | 内容
任意の整数 | カーネル内に保持するアクセスログの件数。デフォルトはカーネルのコンパイル時に指定。ログが不要ならば 0 を指定する。

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

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

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

値 | 内容
任意の整数 | 強制モードで動作中にポリシー違反が発生してから、そのアクセス要求を拒否するまでの猶予期間を秒単位で指定する。この時間内に管理者がそのアクセス要求を許可するように指示した場合、そのアクセス要求は許可される。

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

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

udev を使用するディストリビューションで SYAORAN ファイルシステムを利用している場合は、 DENY_CONCEAL_MOUNT=3 を指定してください。

以下に例を示します。

/root/security/profile1.txt | /root/security/profile2.txt | /root/security/profile3.txt
MAC_FOR_FILE=1 | DENY_CONCEAL_MOUNT=3 MAC_FOR_FILE=2 TOMOYO_VERBOSE=1 | DENY_CONCEAL_MOUNT=3 MAC_FOR_FILE=3 TOMOYO_VERBOSE=1

## 例外ポリシーの作成

全てのシステムに共通して存在している可能性が高いパス名のパターンを事前に登録しておきます。
/root/security/exception_policy.txt に file_pattern というキーワードを使用してパス名のパターンを登録します。
アクセス許可を学習する際に、要求されたパス名が file_pattern というキーワードを使用して登録されたパス名のパターンと一致した場合、パターン化されたパス名でアクセス許可が学習されます。
目安としては以下のものが挙げられます。

- /proc/PID/ ディレクトリ以下に存在するファイルのパス名
- /sys/ ディレクトリ以下に存在するファイルのパス名（カーネル 2.6 系の場合のみ）
- /dev/ ディレクトリ以下の一部のパス名
- ポリシーファイルのパス名
- マニュアルページのパス名
- スプールディレクトリのパス名
- メールの送受信時に作成されるテンポラリファイルのパス名
- man コマンドが作成するテンポラリファイルのパス名
- mount コマンドが作成するテンポラリファイルのパス名

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

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

- ldconfig に登録されている共有ライブラリ
- /proc/ ディレクトリ以下に存在するファイルの一部
- /usr/share/locale/ ディレクトリ以下に存在するロケールデータの一部

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

- /etc/init.d/ ディレクトリ以下にあるデーモンプログラム等を起動・終了させるためのスクリプト
- 上記スクリプトから起動されるデーモンプログラムの内、ドメイン名を短くしたいもの（httpd や sshd など）

電源オフの処理に必要なアクセス許可を自動学習することはできないため、電源オフを行うためのドメインを信頼済みとして指定します。
具体的な修正箇所はディストリビューション毎に異なります。多くの場合、 /etc/init.d/ ディレクトリ以下にあるシャットダウンを行うスクリプトの最後に実行されるプログラムが電源オフを行うためのプログラムです。

以上の操作を自動的に行うためのスクリプトが用意されています。 /root/ccstools/make_exception.sh を実行すると候補が表示されますので、それを元に /root/security/exception_policy.txt を作成してください。なお、自動生成された結果には不要なエントリや危険なエントリが含まれる場合があるので、必ず内容を吟味してください。

### logrotate への対応

コマンドラインから logrotate を起動して必要なアクセス許可を学習させるので、 /usr/sbin/logrotate を initializer として例外ポリシーに登録しておきます。

initializer /usr/sbin/logrotate

### prelink への対応

不特定多数のプログラムファイルを読み書きする cron ジョブは、 cron から除外することを検討してください。

例えば、 Fedora Core 3 以降に付属の cron で毎日実行するように設定されている /usr/sbin/prelink は非常に多数の実行可能ファイルを読み書きするため、ポリシーファイルの肥大化（消費メモリの増加）の原因になります。また、実行可能ファイルに対して書き込み許可を与えることは、望ましくありません。

cron を使って毎日 /usr/sbin/prelink を実行させなくても、「信頼済みドメイン」からパッケージのアップデートを行った後に /usr/sbin/prelink を実行すれば事足りると思いますので、以下のように cron ジョブから除外することをお勧めします。

mv /etc/cron.daily/prelink /usr/sbin/prelink.cron

### anacron への対応

コマンドラインから anacron を起動して必要なアクセス許可を学習させるので、 /usr/sbin/anacron を initializer として例外ポリシーに登録しておきます。

initializer /usr/sbin/anacron

anacron は /usr/bin/run-parts を実行するので、 /usr/bin/run-parts を initializer として例外ポリシーに登録しておきます。

initializer /usr/bin/run-parts

### cron への対応

cron は /usr/bin/run-parts を実行するので、 /usr/bin/run-parts を initializer として例外ポリシーに登録しておきます。

initializer /usr/bin/run-parts

/etc/crontab を開き、以下のようにジョブの実行間隔を５分に変更します。 １分間隔だと前回のジョブが終了する前に次回のジョブが開始されてしまう可能性が高いので、 適当な時間を空ける必要があります。

変更前 | 変更後
SHELL=/bin/bash PATH=/sbin:/bin:/usr/sbin:/usr/bin MAILTO=root HOME=/ # run-parts 01 * * * * root run-parts /etc/cron.hourly 02 4 * * * root run-parts /etc/cron.daily 22 4 * * 0 root run-parts /etc/cron.weekly 42 4 1 * * root run-parts /etc/cron.monthly | SHELL=/bin/bash PATH=/sbin:/bin:/usr/sbin:/usr/bin MAILTO=root HOME=/ # run-parts */5 * * * * root run-parts /etc/cron.hourly */5 * * * * root run-parts /etc/cron.daily */5 * * * * root run-parts /etc/cron.weekly */5 * * * * root run-parts /etc/cron.monthly

学習が終わったら元に戻すのを忘れないでください。

## Targeted Policy への対応

上記の手順により作成された /root/security/exception_policy.txt は Strict Policy として使用するためのものです。もし、 Targeted Policy に相当する方法で利用したい場合、 /root/security/exception_policy.txt を以下のように修正してください。

以下の３行を追加します。 /sbin/modprobe や /sbin/hotplug がシンボリックリンクの場合は、そのリンク先を指定してください。

trust_domain <kernel> /sbin/init trust_domain <kernel> /sbin/modprobe trust_domain <kernel> /sbin/hotplug

initializer というキーワードで指定されているプログラムの内、強制アクセス制御対象から除外したいものを除外します。 例えば、 /usr/sbin/httpd と /usr/sbin/httpd から起動されるプログラムだけを強制アクセス制御の対象としたい場合、以下の３行を残してその他の initializer というキーワードで始まる行を除外します。

initializer /usr/sbin/httpd initializer /sbin/modprobe initializer /sbin/hotplug

このようにすると、 /usr/sbin/httpd および /usr/sbin/httpd から起動されるプログラムは「<kernel> /usr/sbin/httpd」ドメインおよびその子孫ドメインに属することで強制アクセス制御が適用され、その他のプログラムは「<kernel> /sbin/init」「<kernel> /sbin/modprobe」「<kernel> /sbin/hotplug」ドメインの何れかに属することで強制アクセス制御が適用されない状態になります。

# ポリシーの作成

## 学習モード

起動時のブートプロンプトで TOMOYO Linuxカーネルを選択し、学習モード用のプロファイル番号を CCS= に指定して起動します。１回目は TOMOYO_NOLOAD パラメータも指定してください。 TOMOYO_NOLOAD というパラメータを指定すると、ドメイン単位のポリシー（domain_policy.txt）をロードしないで再起動することができます。（つまり、起動時のブートプロンプトで TOMOYO Linuxカーネルを選択し、学習モード用のプロファイル番号を CCS= に指定するのに加えて、 TOMOYO_NOLOAD も指定して起動します。）

許可したい操作に必要なアクセス許可を学習させます。

１回で全てのアクセスパターンを学習できるとは限らないので、何度か繰り返します。
また、起動時や終了時にのみ行われる操作も存在するため、再起動も何度か繰り返します。

学習モードで動作中には、以下のようなメッセージが表示される場合があります。

TOMOYO-WARNING: Domain '<kernel> ...' has so many ACLs to hold. Stopped auto-append mode.

これは、特定のプログラムがあまりにも多くのファイルにアクセスしたものだから、メモリの浪費と応答速度の悪化を防ぐために安全装置が作動したことを知らせるメッセージです。安全装置が作動すると、このドメインに対してはファイルに対するアクセス許可がこれ以上自動的に追加されないようになります。

このメッセージに対処するには、手作業でアクセス許可を修正する必要があります。
例えば、以下のメッセージが表示された場合、適切なパターンを利用してグループ化することで <kernel> /usr/sbin/hald というドメインに対するアクセス許可の数を減らす必要があります。

TOMOYO-WARNING: Domain '<kernel> /usr/sbin/hald' has so many ACLs to hold. Stopped auto-append mode.

/root/ccstools/editpolicy を使用してポリシーの編集を行うことができます。

### logrotate への対応

コマンドラインから logrotate を起動し、必要なアクセス許可を学習させます。 現在のシステム時刻に関係なく logrotate のジョブを実行させるために、 -f オプションを指定してください。

/usr/sbin/logrotate -f /etc/logrotate.conf

一度で全てのアクセス許可を学習できるとは限らないので、何度か繰り返します。

### anacron への対応

コマンドラインから anacron を起動し、必要なアクセス許可を学習させます。 現在のシステム時刻に関係なく anacron のジョブを実行させるために、 -d -f -n オプションを指定してください。

anacron -dfn

一度で全てのアクセス許可を学習できるとは限らないので、何度か繰り返します。

## 例外ポリシーの更新

通常のカーネルで再起動します。

以下のコマンドを実行すると、テンポラリであると思われるパス名が表示されます。適切にパターン化した上で /root/security/exception_policy.txt に file_pattern として追加します。

/root/ccstools/findtemp < /root/security/domain_policy.txt | sort | uniq

テンポラリの基準としては、「最後の６文字だけが異なるパス名が複数存在している」「パス名の中の数値部分だけが異なるパス名が複数存在している」等があります。
パターン化する際の例を以下に示します。これらはインストールされているアプリケーションや設定により存在しなかったり違うディレクトリに存在していたりすることがあります。

- file_pattern /etc/.fstab.hal.\?
- file_pattern /etc/blkid.tab-\?\?\?\?\?\?
- file_pattern /etc/mrtg/mrtg.cfg_l_\$
- file_pattern /root/.emacs.d/auto-save-list/.saves-\$-\*
- file_pattern /root/Mail/inbox/\$
- file_pattern /tmp/auto\?\?\?\?\?\?/
- file_pattern /tmp/autofs.\?\?\?\?\?\?
- file_pattern /tmp/logrotate.\?\?\?\?\?\?
- file_pattern /tmp/logwatch.\*/
- file_pattern /tmp/logwatch.\*/\*
- file_pattern /tmp/makewhatis\?\?\?\?\?\?/
- file_pattern /tmp/makewhatis\?\?\?\?\?\?/w
- file_pattern /tmp/sh-thd-\$
- file_pattern /tmp/spamassassin-\$/
- file_pattern /tmp/spamassassin-\$/.spamassassin/
- file_pattern /tmp/spamassassin-\$/.spamassassin/auto-whitelist\*
- file_pattern /tmp/whatis.\?\?\?\?\?\?
- file_pattern /var/lib/dhcp/dhcpd.leases.\$
- file_pattern /var/lock/autofs.\$
- file_pattern /var/lock/mrtg/mrtg_l_\$
- file_pattern /var/log/ksymoops/\*
- file_pattern /var/log/sa/sa\*
- file_pattern /var/mailman/locks/gate_news.lock.\*
- file_pattern /var/run/gpm\?\?\?\?\?\?

initializer や allow_read で追加したいものがあれば追加します。

メンテナンス等のために特定のドメイン以下を信頼済みに設定したい場合は trust_domain を追加します。

## 学習モード

パターンの洗い出しが完了したと判断したら、ドメイン別ポリシーを最初から学習しなおします。１回目は TOMOYO_NOLOAD パラメータも指定してください。

# ポリシーのチューニング

通常のカーネルで再起動します。

## 監査ログからの生成

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

/root/ccstools/sortpolicy < /var/log/tomoyo/reject_log.txt

この結果から、追加すべきか否かを判断し、追加すべきであると判断した場合は /root/security/domain_policy.txt に追加します。

## アクセス許可のパターン化

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

<kernel> /usr/sbin/httpd 4 /var/www/html/\* 4 /var/www/html/\*/\* 4 /var/www/html/\*/\*/\* 4 /var/www/html/\*/\*/\*/\* 4 /var/www/html/\*/\*/\*/\*/\*

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

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

## ネットワークのパターン化

portmap のように特権ポート（1024未満の番号を持つポート）をランダムに使用するアプリケーションが存在します。ランダムにネットワークポート番号を選択するアプリケーションに対しては、必要なポート番号を学習モードで学習させることはできません。何度か学習モードで実行することで１個ずつ学習させた後、学習結果からどのような範囲のポート番号を使用しているかを推測し、範囲を指定してポート番号の使用を許可してやる必要があります。
例えば、以下のような範囲が考えられます。実際に許可する必要のある範囲はディストリビューションや設定により異なる可能性がありますので、以下の設定をそのままコピーしないようにしてください。

<kernel> /sbin/portmap allow_bind TCP/0 allow_bind TCP/111 allow_bind TCP/600-1023 allow_bind UDP/0 allow_bind UDP/111 allow_bind UDP/600-1023 allow_connect UDP/32768-65535 allow_connect UDP/600-1023 <kernel> /sbin/rpc.statd allow_bind TCP/0 allow_bind TCP/600-1023 allow_bind UDP/0 allow_bind UDP/600-1023 allow_connect UDP/111 <kernel> /usr/sbin/rpc.mountd allow_bind TCP/0 allow_bind TCP/600-1023 allow_bind UDP/0 allow_bind UDP/600-1023 allow_connect UDP/111 <kernel> /usr/sbin/rpc.nfsd allow_capability inet_tcp_create allow_capability use_inet_udp allow_connect UDP/111 allow_connect UDP/32768-65535 <kernel> /usr/sbin/rpc.rquotad allow_bind TCP/600-1023 allow_bind UDP/600-1023 allow_connect UDP/111 <kernel> /usr/sbin/rpcinfo allow_bind UDP/600-1023 allow_connect UDP/111 allow_connect UDP/2049 <kernel> /usr/sbin/xinetd allow_bind TCP/0 allow_bind UDP/69 allow_bind UDP/600-1023 allow_connect UDP/111

なお、 NFS や NIS のように RPC を必要とするサービスを動作させないのであれば、無効にしておくことを推奨します。

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

修正前 | 修正後
<kernel> /usr/sbin/sshd 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 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

## アクセス許可条件の付与

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

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

修正前
<kernel> /usr/sbin/vsftpd 6 /home/\*/ftp/\* 6 /home/\*/ftp/\*/\* 6 /home/\*/ftp/\*/\*/\* 6 /home/\*/ftp/\*/\*/\*/\* allow_mkdir /home/\*/ftp/\*/ allow_mkdir /home/\*/ftp/\*/\*/ allow_mkdir /home/\*/ftp/\*/\*/\*/ allow_rmdir /home/\*/ftp/\*/ allow_rmdir /home/\*/ftp/\*/\*/ allow_rmdir /home/\*/ftp/\*/\*/\*/ allow_create /home/\*/ftp/\* allow_create /home/\*/ftp/\*/\* allow_create /home/\*/ftp/\*/\*/\* allow_create /home/\*/ftp/\*/\*/\*/\* allow_truncate /home/\*/ftp/\* allow_truncate /home/\*/ftp/\*/\* allow_truncate /home/\*/ftp/\*/\*/\* allow_truncate /home/\*/ftp/\*/\*/\*/\* allow_unlink /home/\*/ftp/\* allow_unlink /home/\*/ftp/\*/\* allow_unlink /home/\*/ftp/\*/\*/\* allow_unlink /home/\*/ftp/\*/\*/\*/\* allow_rename /home/\*/ftp/\* /home/\*/ftp/\* allow_rename /home/\*/ftp/\*/\* /home/\*/ftp/\*/\* allow_rename /home/\*/ftp/\*/\*/\* /home/\*/ftp/\*/\*/\* allow_rename /home/\*/ftp/\*/\*/\*/\* /home/\*/ftp/\*/\*/\*/\* allow_rename /home/\*/ftp/\*/ /home/\*/ftp/\*/ allow_rename /home/\*/ftp/\*/\*/ /home/\*/ftp/\*/\*/ allow_rename /home/\*/ftp/\*/\*/\*/ /home/\*/ftp/\*/\*/\*/

修正後
<kernel> /usr/sbin/vsftpd 6 /home/\*/ftp/\* if task.uid=path1.uid 6 /home/\*/ftp/\*/\* if task.uid=path1.uid 6 /home/\*/ftp/\*/\*/\* if task.uid=path1.uid 6 /home/\*/ftp/\*/\*/\*/\* if task.uid=path1.uid allow_mkdir /home/\*/ftp/\*/ if task.uid=path1.parent.uid allow_mkdir /home/\*/ftp/\*/\*/ if task.uid=path1.parent.uid allow_mkdir /home/\*/ftp/\*/\*/\*/ if task.uid=path1.parent.uid allow_rmdir /home/\*/ftp/\*/ if task.uid=path1.uid allow_rmdir /home/\*/ftp/\*/\*/ if task.uid=path1.uid allow_rmdir /home/\*/ftp/\*/\*/\*/ if task.uid=path1.uid allow_create /home/\*/ftp/\* if task.uid=path1.parent.uid allow_create /home/\*/ftp/\*/\* if task.uid=path1.parent.uid allow_create /home/\*/ftp/\*/\*/\* if task.uid=path1.parent.uid allow_create /home/\*/ftp/\*/\*/\*/\* if task.uid=path1.parent.uid allow_truncate /home/\*/ftp/\* if task.uid=path1.uid allow_truncate /home/\*/ftp/\*/\* if task.uid=path1.uid allow_truncate /home/\*/ftp/\*/\*/\* if task.uid=path1.uid allow_truncate /home/\*/ftp/\*/\*/\*/\* if task.uid=path1.uid allow_unlink /home/\*/ftp/\* if task.uid=path1.uid allow_unlink /home/\*/ftp/\*/\* if task.uid=path1.uid allow_unlink /home/\*/ftp/\*/\*/\* if task.uid=path1.uid allow_unlink /home/\*/ftp/\*/\*/\*/\* if task.uid=path1.uid allow_rename /home/\*/ftp/\* /home/\*/ftp/\* if task.uid=path1.parent.uid task.uid=path2.parent.uid allow_rename /home/\*/ftp/\*/\* /home/\*/ftp/\*/\* if task.uid=path1.parent.uid task.uid=path2.parent.uid allow_rename /home/\*/ftp/\*/\*/\* /home/\*/ftp/\*/\*/\* if task.uid=path1.parent.uid task.uid=path2.parent.uid allow_rename /home/\*/ftp/\*/\*/\*/\* /home/\*/ftp/\*/\*/\*/\* if task.uid=path1.parent.uid task.uid=path2.parent.uid allow_rename /home/\*/ftp/\*/ /home/\*/ftp/\*/ if task.uid=path1.parent.uid task.uid=path2.parent.uid allow_rename /home/\*/ftp/\*/\*/ /home/\*/ftp/\*/\*/ if task.uid=path1.parent.uid task.uid=path2.parent.uid allow_rename /home/\*/ftp/\*/\*/\*/ /home/\*/ftp/\*/\*/\*/ if task.uid=path1.parent.uid task.uid=path2.parent.uid

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

修正前
<kernel> /usr/sbin/smbd 6 /home/\*/samba/\* 6 /home/\*/samba/\*/\* 6 /home/\*/samba/\*/\*/\* 6 /home/\*/samba/\*/\*/\*/\* allow_mkdir /home/\*/samba/\*/ allow_mkdir /home/\*/samba/\*/\*/ allow_mkdir /home/\*/samba/\*/\*/\*/ allow_rmdir /home/\*/samba/\*/ allow_rmdir /home/\*/samba/\*/\*/ allow_rmdir /home/\*/samba/\*/\*/\*/ allow_create /home/\*/samba/\* allow_create /home/\*/samba/\*/\* allow_create /home/\*/samba/\*/\*/\* allow_create /home/\*/samba/\*/\*/\*/\* allow_truncate /home/\*/samba/\* allow_truncate /home/\*/samba/\*/\* allow_truncate /home/\*/samba/\*/\*/\* allow_truncate /home/\*/samba/\*/\*/\*/\* allow_unlink /home/\*/samba/\* allow_unlink /home/\*/samba/\*/\* allow_unlink /home/\*/samba/\*/\*/\* allow_unlink /home/\*/samba/\*/\*/\*/\* allow_rename /home/\*/samba/\* /home/\*/samba/\* allow_rename /home/\*/samba/\*/\* /home/\*/samba/\*/\* allow_rename /home/\*/samba/\*/\*/\* /home/\*/samba/\*/\*/\* allow_rename /home/\*/samba/\*/\*/\*/\* /home/\*/samba/\*/\*/\*/\* allow_rename /home/\*/samba/\*/ /home/\*/samba/\*/ allow_rename /home/\*/samba/\*/\*/ /home/\*/samba/\*/\*/ allow_rename /home/\*/samba/\*/\*/\*/ /home/\*/samba/\*/\*/\*/

修正後
<kernel> /usr/sbin/smbd 6 /home/\*/samba/\* if task.euid=path1.uid 6 /home/\*/samba/\*/\* if task.euid=path1.uid 6 /home/\*/samba/\*/\*/\* if task.euid=path1.uid 6 /home/\*/samba/\*/\*/\*/\* if task.euid=path1.uid allow_mkdir /home/\*/samba/\*/ if task.euid=path1.parent.uid allow_mkdir /home/\*/samba/\*/\*/ if task.euid=path1.parent.uid allow_mkdir /home/\*/samba/\*/\*/\*/ if task.euid=path1.parent.uid allow_rmdir /home/\*/samba/\*/ if task.euid=path1.uid allow_rmdir /home/\*/samba/\*/\*/ if task.euid=path1.uid allow_rmdir /home/\*/samba/\*/\*/\*/ if task.euid=path1.uid allow_create /home/\*/samba/\* if task.euid=path1.parent.uid allow_create /home/\*/samba/\*/\* if task.euid=path1.parent.uid allow_create /home/\*/samba/\*/\*/\* if task.euid=path1.parent.uid allow_create /home/\*/samba/\*/\*/\*/\* if task.euid=path1.parent.uid allow_truncate /home/\*/samba/\* if task.euid=path1.uid allow_truncate /home/\*/samba/\*/\* if task.euid=path1.uid allow_truncate /home/\*/samba/\*/\*/\* if task.euid=path1.uid allow_truncate /home/\*/samba/\*/\*/\*/\* if task.euid=path1.uid allow_unlink /home/\*/samba/\* if task.euid=path1.uid allow_unlink /home/\*/samba/\*/\* if task.euid=path1.uid allow_unlink /home/\*/samba/\*/\*/\* if task.euid=path1.uid allow_unlink /home/\*/samba/\*/\*/\*/\* if task.euid=path1.uid allow_rename /home/\*/samba/\* /home/\*/samba/\* if task.euid=path1.parent.uid task.euid=path2.parent.uid allow_rename /home/\*/samba/\*/\* /home/\*/samba/\*/\* if task.euid=path1.parent.uid task.euid=path2.parent.uid allow_rename /home/\*/samba/\*/\*/\* /home/\*/samba/\*/\*/\* if task.euid=path1.parent.uid task.euid=path2.parent.uid allow_rename /home/\*/samba/\*/\*/\*/\* /home/\*/samba/\*/\*/\*/\* if task.euid=path1.parent.uid task.euid=path2.parent.uid allow_rename /home/\*/samba/\*/ /home/\*/samba/\*/ if task.euid=path1.parent.uid task.euid=path2.parent.uid allow_rename /home/\*/samba/\*/\*/ /home/\*/samba/\*/\*/ if task.euid=path1.parent.uid task.euid=path2.parent.uid allow_rename /home/\*/samba/\*/\*/\*/ /home/\*/samba/\*/\*/\*/ if task.euid=path1.parent.uid task.euid=path2.parent.uid

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

修正前 | 修正後
<kernel> /usr/sbin/sshd 1 /bin/bash | <kernel> /usr/sbin/sshd 1 /bin/bash if task.uid!=0 task.euid!=0

指定可能な条件については条件付きアクセス許可を参照してください。

## 確認モード

起動時のブートプロンプトで TOMOYO Linux カーネルを選択し、確認モード用のプロファイル番号を CCS= に指定して起動します。

許可したい操作を行ってもエラーメッセージが表示されないことを確認してください。

正常に動作すればポリシーの完成です。

# ポリシーの利用

## 強制モード

起動時のブートプロンプトで TOMOYO Linux カーネルを選択し、強制モード用のプロファイル番号を CCS= に指定して起動します。