TOMOYO Linux導入手順

Last modified: $Date: 2006-11-25 10:18:46 +0900 (Sat, 25 Nov 2006) $

目次


準備

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

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

カーネルのインストール

TOMOYO Linux では、いくつかのコンパイル済みのカーネルをパッケージにして提供しています。コンパイル済みのカーネルを利用する場合は、以下のファイルをダウンロードしてインストールしてください。

RedHat Linux 9 (80386以降用) http://osdn.dl.sourceforge.jp/tomoyo/21518/kernel-2.4.20-46.9.legacy_tomoyo_1.2.i386.rpm
Fedora Core 3 (80586以降用) http://osdn.dl.sourceforge.jp/tomoyo/21518/kernel-2.6.12-2.3.legacy_FC3_tomoyo_1.2.i586.rpm
Fedora Core 4 (80586以降用) http://osdn.dl.sourceforge.jp/tomoyo/21518/kernel-2.6.17-1.2142_FC4_tomoyo_1.2.i586.rpm
Fedora Core 5 (80586以降用) http://osdn.dl.sourceforge.jp/tomoyo/21518/kernel-2.6.18-1.2200_FC5_tomoyo_1.2.i586.rpm
Fedora Core 6 (80586以降用) http://osdn.dl.sourceforge.jp/tomoyo/21518/kernel-2.6.18-1.2798_tomoyo_1.2.i586.rpm
CentOS 4.4 (80586以降用) http://osdn.dl.sourceforge.jp/tomoyo/21518/kernel-2.6.9-42.0.3.EL_tomoyo_1.2.i586.rpm
Debian Sarge (80586以降用) http://osdn.dl.sourceforge.jp/tomoyo/21518/kernel-image-2.4.27-10sarge4-ccs_1.2_i586.deb
http://osdn.dl.sourceforge.jp/tomoyo/21518/kernel-image-2.6.8-16sarge5-ccs_1.2_i586.deb
OpenSUSE 10.1 (80586以降用) http://osdn.dl.sourceforge.jp/tomoyo/21518/kernel-default-2.6.16.21-0.25_tomoyo_1.2.i586.rpm

アーキテクチャが異なる場合やカスタマイズしたい場合には、カーネルをコンパイルする必要があります。カーネルをコンパイルする方法については、TOMOYO Linuxカーネルの作成手順を参照してください。

ツールのインストール

TOMOYO Linux では、いくつかのコンパイル済みのツールを提供しています。コンパイル済みのツールを利用する場合は、以下のファイルをダウンロードして /root/ ディレクトリの下に展開してください。

RedHat Linux 9 (80386以降用) http://osdn.dl.sourceforge.jp/tomoyo/21518/ccs-tools-1.2-i386-RHL9.tar.gz
Fedora Core 3 (80386以降用) http://osdn.dl.sourceforge.jp/tomoyo/21518/ccs-tools-1.2-i386-FC3.tar.gz
Fedora Core 4 (80386以降用) http://osdn.dl.sourceforge.jp/tomoyo/21518/ccs-tools-1.2-i386-FC4.tar.gz
Fedora Core 5 (80386以降用) http://osdn.dl.sourceforge.jp/tomoyo/21518/ccs-tools-1.2-i386-FC5.tar.gz
Fedora Core 6 (80386以降用) http://osdn.dl.sourceforge.jp/tomoyo/21518/ccs-tools-1.2-i386-FC6.tar.gz
CentOS 4.4 (80386以降用) http://osdn.dl.sourceforge.jp/tomoyo/21518/ccs-tools-1.2-i386-CentOS4.4.tar.gz
Debian Sarge (80386以降用) http://osdn.dl.sourceforge.jp/tomoyo/21518/ccs-tools-1.2-i386-Sarge.tar.gz
OpenSUSE 10.1 (80386以降用) http://osdn.dl.sourceforge.jp/tomoyo/21518/ccs-tools-1.2-i386-SUSE10.1.tar.gz

アーキテクチャが異なる場合には、ツールをコンパイルする必要があります。ツールをコンパイルするには、以下のコマンドを実行してください。

# TOMOYO Linux ツールのソースをダウンロードする。
wget http://osdn.dl.sourceforge.jp/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によるログイン認証の強化手法」を参照してください。

追加的な防御手段で使用するプログラムは、管理者が自由な仕様で作成することができます。 この段階でそのためのプログラムを作成して、意図したとおりの使い方ができることを確認しておいてください。

ログイン認証を複数回行えるようにすることで、資源の保護レベルに応じたアクセス制限も提供できるようになります。通常は下の図のようにログイン認証を通過しただけで、重要に保護する必要のある資源にもその必要が無い資源にもアクセスできてしまいます。

Normal Authentication

しかし、下の図のように /opt/bin/auth1 および /opt/bin/auth2 という認証を追加することにより、ログイン認証を通過しただけなら厳重に保護する必要の無い資源へのアクセスのみを許可し、全ての認証を通過した場合のみ厳重に保護しなければいけない資源へのアクセスも許可することが可能になります。

Chained Authentication

管理者権限を必要とする業務の一部委託(任意)

サーバ管理業務の一部だけを他人に委託したい場合に使用します。 例えば、 HTTP サーバのコンテンツの管理と httpd プロセスの再起動のみを委託したい場合に利用します。

管理者としてログインしてもらい、前述した「ログイン認証の強化」で使用したプログラムと組み合わせることで、委託された人だけがその業務をできるようにすることができます。この段階で、誰にどの業務を委託するかを決定し、どのようにドメインを分割するかを設計し、ドメインの分割点として使用するためのプログラムを決定します。 /bin/bash や /bin/tcsh をドメインの分割点として使用するためのプログラムとして利用することも可能ですが、無断で他人の担当業務用のドメインに遷移できてしまうので望ましくありません。 そのため、「ログイン認証の強化」で説明したのと同じ要領で認証機構を備えたプログラムを作成して、意図したとおりの使い方ができることを確認しておいてください。

例えば、システム上に SAKURA TOMOYO SYAORAN CERBERUS YUE というユーザが登録されており、それぞれが ssh でログインして作業を行う場合に、下の図のようにドメインを分割することによりユーザ単位のアクセス許可を登録できます。

Embedding User

同様に、例えばシステム上で manager webmaster auditor user anonymous というロールが必要であり、それぞれが ssh でログインして作業を行う場合に、下の図のようにドメインを分割することによりロール単位のアクセス許可を登録できます。

Embedding Role

デバイスファイルの保護(任意)

デバイスファイルの改ざん防止機能(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 というファイルから取り出すことができます。

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

スワップパーティション用のデバイスファイルはマウントされる際にオープンされないため、何らかの方法で明示的にオープンしないと .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 の5つを指定してください。

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

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

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

項目制御する内容自動学習対応
MAC_FOR_FILEファイルの読み書き実行
MAC_FOR_CAPABILITY::inet_tcp_createTCP ソケットの使用
MAC_FOR_CAPABILITY::inet_tcp_listenTCP ソケットの listen
MAC_FOR_CAPABILITY::inet_tcp_connectTCP ソケットの connect
MAC_FOR_CAPABILITY::use_inet_udpUDP ソケットの使用
MAC_FOR_CAPABILITY::use_inet_ipRAW ソケットの使用
MAC_FOR_CAPABILITY::use_routeROUTE ソケットの使用
MAC_FOR_CAPABILITY::use_packetPACKET ソケットの使用
MAC_FOR_CAPABILITY::use_kernel_moduleカーネルモジュールの使用
MAC_FOR_CAPABILITY::create_fifoFIFO の作成
MAC_FOR_CAPABILITY::create_block_devブロック型デバイスの作成
MAC_FOR_CAPABILITY::create_char_devキャラクタ型デバイスの作成
MAC_FOR_CAPABILITY::create_unix_socketUNIX ドメインソケットの作成
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_VHANGUPvhangup の使用
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_IOCTLioctl の使用
MAC_FOR_CAPABILITY::SYS_KEXEC_LOAD新しいカーネルのロード
MAC_FOR_NETWORKプログラムが使用できるIPアドレスとポート番号
MAC_FOR_BINDPORTプログラムが使用できるローカルポート番号
MAC_FOR_CONNECTPORTプログラムが使用できるリモートポート番号
MAC_FOR_SIGNAL自分自身以外へのシグナルの送信
DENY_CONCEAL_MOUNT既存のマウントを隠蔽するようなマウントの禁止×
RESTRICT_CHROOTchroot で移動可能なディレクトリ
RESTRICT_MOUNTマウント可能な「デバイスファイルとマウントポイントとファイルシステム」の組み合わせ
RESTRICT_UNMOUNT指定されたディレクトリのアンマウントの禁止×
DENY_PIVOT_ROOTpivot_root 呼び出しの禁止×
RESTRICT_AUTOBINDTCP/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 というキーワードを使用して登録されたパス名のパターンと一致した場合、パターン化されたパス名でアクセス許可が学習されます。
目安としては以下のものが挙げられます。

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

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

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

電源オフの処理に必要なアクセス許可を自動学習することはできないため、電源オフを行うためのドメインを信頼済みとして指定します。
具体的な修正箇所はディストリビューション毎に異なります。多くの場合、 /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 を開き、以下のようにジョブの実行間隔を5分に変更します。 1分間隔だと前回のジョブが終了する前に次回のジョブが開始されてしまう可能性が高いので、 適当な時間を空ける必要があります。

変更前変更後
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 を以下のように修正してください。

以下の3行を追加します。 /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 から起動されるプログラムだけを強制アクセス制御の対象としたい場合、以下の3行を残してその他の 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= に指定して起動します。1回目は TOMOYO_NOLOAD パラメータも指定してください。 TOMOYO_NOLOAD というパラメータを指定すると、ドメイン単位のポリシー(domain_policy.txt)をロードしないで再起動することができます。(つまり、起動時のブートプロンプトで TOMOYO Linuxカーネルを選択し、学習モード用のプロファイル番号を CCS= に指定するのに加えて、 TOMOYO_NOLOAD も指定して起動します。)

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

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

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

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

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

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

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

学習モード

パターンの洗い出しが完了したと判断したら、ドメイン別ポリシーを最初から学習しなおします。1回目は 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未満の番号を持つポート)をランダムに使用するアプリケーションが存在します。ランダムにネットワークポート番号を選択するアプリケーションに対しては、必要なポート番号を学習モードで学習させることはできません。何度か学習モードで実行することで1個ずつ学習させた後、学習結果からどのような範囲のポート番号を使用しているかを推測し、範囲を指定してポート番号の使用を許可してやる必要があります。
例えば、以下のような範囲が考えられます。実際に許可する必要のある範囲はディストリビューションや設定により異なる可能性がありますので、以下の設定をそのままコピーしないようにしてください。

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

匿名ではない 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= に指定して起動します。