tomoyotitle.png

Chapter 4: TOMOYO Linux はどのように動きますか?

4.1. ドメインを理解する

TOMOYO Linux では、強制アクセス制御の適用はドメインという単位で行われます。これは重要な概念です。システム上に存在する全てのプロセスはそれぞれ1個のドメインに属しています。ドメインはプロセスの実行履歴により決定されます。大まかに言うと、プログラムが実行されるたびに新しいドメインが作成されます。あるドメインの名前はそのドメインに到達するまでに実行された全てのプログラムのパス名を連結したものとして定義されます。このドメインを作成することはドメイン遷移と呼ばれています。以下の図を見てください:

domain_transition.png

カーネルは常に最初のドメインであり、 TOMOYO Linux においては <kernel> というドメイン名で定義されます。この例では、カーネルが /sbin/init を実行します。プログラムが実行されたことにより、新しいドメイン、この場合は <kernel> /sbin/init という名前を持つドメインが作成されます。起動スクリプトが実行されると、より多くのドメインが作成されていきます。

このプロセス実行履歴は重要です。以下のドメインを考えてください:

<kernel> /sbin/init /etc/rc.d/rc
<kernel> /sbin/init /etc/rc.d/rc.sysinit /etc/rc.d/rc

どちらのドメインも /etc/rc.d/rc というプログラムが実行されることにより作成されています。しかし、プロセス実行履歴が異なるため、これらは2つの異なるドメインとして扱われます。これは、あるドメインから実行できるプログラムを制御できることを、また、そのプロセスがどのように実行されたかにより異なるレベルの制限を行う柔軟なポリシーを記述できることを示しています。また、とても正確なドメイン遷移を行いつつ、例えばプロセスがどのように実行されたかによらずに同じ制限を適用することも可能であることを示しています。この項目については後述します。

4.2. ポリシーエディタを用いてドメインを確認する

よりドメインについて理解するために、ポリシーエディタを見てみましょう。ポリシーエディタは TOMOYO Linux で使用する中心的なツールであり、使い方に慣れることが重要です。このページの説明を補足するものとして、ポリシーエディタの使い方も参照してください。

システムを TOMOYO Linux カーネルで起動させてから、( /etc/ccs/ ディレクトリに存在しているポリシーファイルを編集するために) /etc/ccs/ というオプションを指定してポリシーエディタを実行してください:

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

ポリシーエディタにはいくつもの画面が存在し、それぞれが異なる役割を提供しています。デフォルトで最初に表示される画面は Domain Transition Editor です。以下の画面は上記のコマンドを実行することで表示されるドメインのツリーです。現時点では <kernel> ドメインだけが定義されています:

editpolicy-domain-list1.png

初期化されたばかりのポリシーであるため、 /etc/ccs/ ディレクトリに存在するポリシーファイルは空っぽです。TOMOYO Linux には2種類のポリシーのセットが存在しています:1つは現在カーネル内にロードされているポリシーのセットであり、もう1つは /etc/ccs/ ディレクトリ内に保存されているポリシーのセットです。 /etc/ccs/ ディレクトリには複数のポリシーのセットを保存することができ、起動時または必要な時にカーネル内へと読み込ませることができます。ポリシーをディスクに保存する方法については後述します。 q キーを押してポリシーエディタを終了してください。

今度は、(現在カーネル内にロードされているポリシーを閲覧するために) /etc/ccs/ というオプションを指定しないでポリシーエディタを実行してください:

# /usr/sbin/ccs-editpolicy

システムが動作するにつれて、 TOMOYO Linux は新しいドメインが作成されたことを記録して、ドメインのツリーへと追加していきます。上記のコマンドを実行することにより、システム起動時から現在までに作成された全てのドメインを含むドメインのツリーが表示されます:

editpolicy-domain-list2.png

1行目は現在表示されている画面の名前と、存在しているドメインの数が表示されます。
2行目はメッセージを表示するための領域です。
3行目は現在カーソルのある行のドメイン名が表示されます。
4行目以降は現在定義されているドメインのツリーが表示されます。

適当にコマンドを実行してどのようにドメインが作成されるかを確認してみてください。コマンドを別の画面などで実行する場合は、ポリシーエディタを終了させる必要はありません。

矢印キーHome/End/PageUp/PageDown キーを使って画面をスクロールすることができます。
r キーを押すと、最新の状態に更新されます。
f キーを押すと、検索ができます。
? キーを押すと、利用可能なコマンドが表示されます。再度 ? キーを押すと元の画面に戻ります。

新しいドメインは同じ名前のドメインが存在しない場合だけ作成されます。そのため、同じコマンドを何度も実行しても、繰り返した数だけドメインが作成されるわけではありません。

4.3. プロファイルを理解する

それぞれのドメインはプロファイルというものを指定することにより制限が行われるようになります。プロファイルは他のドメインに割り当てられているプロファイルとは無関係に自由にドメインに割り当てることができます。そのため、ドメインに対するアクセス制限の設定を1個ずつ順番に行っていくことも可能です。また、特定のドメインに対して専用のプロファイルを割り当てることも可能です。この応用についてはここではまだ説明しません。

ポリシーエディタの画面で、それぞれの行の2番目に表示されている数値に注目してください:

editpolicy-domain-profile-number.png

この数値はプロファイル番号と呼ばれています。プロファイル番号は0~255の整数値です。デフォルトのプロファイル番号は0であり、プロファイル0は無効モードとも呼ばれています。無効モードのプロファイルが割り当てられたドメインでは全く制限が行われません。

w キーを押してポリシーエディタで利用可能な画面の一覧を表示してみましょう:

editpolicy-window-list.png

p キーを押して Profile Editor 画面を表示すると、以下のようなプロファイルの一覧が表示されます:

editpolicy-profile-list.png

それぞれのプロファイルには3種類の行が存在しています:

名前

内容

COMMENT

プロファイルの用途を表すコメント

CONFIG

アクセス制御モードの設定

PREFERENCE

各種オプションの設定

CONFIG 行の mode パラメータには以下の何れかの値を指定できます:

意味

disabled

通常のカーネルのように動作します。

learning

アクセス要求がポリシーで許可されていなくても拒否しません。また、同じアクセス要求を次回以降は許可するためにポリシーに追加します。

permissive

アクセス要求がポリシーで許可されていなくても拒否しません。ただし、ポリシーへの追加も行いません。

enforcing

アクセス要求がポリシーで許可されていない場合には拒否します。また、ポリシーへの追加も行いません。

PREFERENCE 行には以下のオプションを指定できます:

名前

内容

max_audit_log

カーネルが保持するアクセスログの件数の上限

max_learning_entry

学習モードによりドメインポリシーへと自動的に追加されるアクセス許可の件数の上限

enforcing_penalty

強制モードでポリシー違反を起こしたプロセスに対して強制的にスリープさせる時間

デフォルトでは役割の異なる4つのプロファイルが定義されています:

default_profiles-ja.png

これらのプロファイルをドメインへと割り当てていきます:

kernel_namespace.png

学習モード用プロファイルというのはポリシーの作成を容易にするための TOMOYO Linux の特徴です。学習モードが割り当てられたドメインではドメインポリシーが自動的に作成されます。学習モードで作成されたポリシーを精製していくことでしっかりとしたポリシーを作成することができます。他のプロファイル(確認モード用と強制モード用)は後でドメインの動作に制限をかける際に利用します。

プロファイル管理の詳細については Chapter 9: より詳細なプロファイルの管理を参照してください。

4.4. ドメインポリシーを理解する

それぞれのドメインに対する制限の内容は Domain Policy Editor 画面で確認できます。この画面は Domain Transition Editor 画面でドメインを選択して Enter キーを押すことで表示されます。現時点ではまだポリシーが定義されていないので、空っぽです。以下の写真は Apache 用のドメインポリシーの例です:

(クリックすると全体を表示します。)
editpolicy-httpd-acl1.png

ドメインポリシーのパーミッションは file read や file write などのディレクティブと一緒にこの画面に表示されます。ドメインに対して強制モード用のプロファイルを割り当てることにより、ここで定義されているアクセス許可(および例外ポリシーで定義されているアクセス許可( 4.5: 例外ポリシーを理解する)を参照してください)だけが許可されるようになります。正常な動作をするのに必要最小限の権限を持ったポリシーを作成するために、学習モードと確認モードを使うことができます。ドメインポリシーで指定できるディレクティブについての詳細は Appendix B: ポリシー仕様の中のドメインポリシー仕様を参照してください。

4.5. 例外ポリシーを理解する

w キーを押して、次に e キーを押すと、 Exception Policy Editor という画面が表示されます:

(クリックすると全体を表示します。)
editpolicy-exception-list1.png

矢印キーや Home/End/PageUp/PageDown キーを使って画面をスクロールすることができます。

この画面で表示されるパーミッションはドメインポリシーで表示されるパーミッションと似ていますが、全てのドメインに対して適用されるという点が異なります。この画面で定義されたパーミッションはドメインポリシーには表示されません。また、例外ポリシーで与えられているアクセス許可に一致するアクセス要求は自動的に許可されます。また、例外ポリシーはグループ化ディレクティブを指定することによりドメインポリシーを削減および単純化するためにも利用されます。

例外ポリシーで指定できるディレクティブについての詳細は Appendix B: ポリシー仕様の中の例外ポリシー仕様を参照してください。

4.6. アクセスログを保存する(任意)

あるドメインに属しているプロセスがそのドメインのドメインポリシーまたは例外ポリシーで許可されているアクセスを要求した場合、その要求は許可されます。ポリシーで許可されておらず、なおかつ、そのドメインに対して強制モードが割り当てられている場合には、その要求は拒否されます。

ポリシーを作成中は、ドメインポリシーや例外ポリシーで許可されていないアクセス要求が発生する度にログとして残しておくと有用かもしれません。ポリシーが完成して強制モードが割り当てられた後はログに残しておくことが特に重要ですが、学習モードの時点でもポリシーを作成するためにログに残しておくことができます。

TOMOYO Linux ではアクセス許可ログ(ドメインポリシーまたは例外ポリシーで許可されたアクセス要求)とアクセス拒否ログ(ドメインポリシーと例外ポリシーのどちらでも許可されなかったアクセス要求)という2種類のログが存在します。これらのログは、ドメインポリシーの形式で出力されます。これは、現在のポリシーでは許可されていないアクセス要求を行った際にその要求をポリシーとして許可したい場合に便利です。アクセス拒否ログはドメインポリシーにパーミッションを追加する用途で利用できます。次の章で説明する学習モードは、学習モードが割り当てられているドメインで発生したアクセス拒否ログをドメインポリシーへと追加するという作業をほとんど自動的に行ってくれます。

CONFIG 行の grant_log パラメータには以下の値を指定できます:

意味

no

アクセス許可ログを生成しない。ただし、個別のアクセス許可で grant_log=yes と指定されている場合には生成する。

yes

アクセス許可ログを生成する。ただし、個別のアクセス許可で grant_log=no と指定されている場合には生成しない。

CONFIG 行の reject_log パラメータには以下の値を指定できます:

意味

no

アクセス拒否ログを生成しない。

yes

アクセス拒否ログを生成する。

/proc/ccs/audit からアクセスログを読み出して指定されたログファイルに保存するために ccs-auditd というデーモンプログラムが提供されています。このデーモンプログラムを利用する場合、 /etc/rc.local 等に /usr/sbin/ccs-auditd という行を追加してください。

このデーモンの設定ファイルは /etc/ccs/tools/auditd.conf です。 /proc/ccs/audit から読みだされたアクセスログはこの設定ファイルの内容に従って振り分けが行われ、指定されたファイルへと書き出されます。幾つかの有用なデフォルトルールが定義されていますが、上級者はより管理しやすくするために様々なルールを定義することができます。以下に初期設定を示します:

# This file contains sorting rules used by ccs-auditd command.

# An audit log consists with three lines. You can refer the first line
# using 'header' keyword, the second line using 'domain' keyword, and the
# third line using 'acl' keyword.
#
# Words in each line are separated by a space character. Therefore, you can
# use 'header[index]', 'domain[index]', 'acl[index]' for referring index'th
# word of the line. The index starts from 1, and 0 refers the whole line
# (i.e. 'header[0]' = 'header', 'domain[0]' = 'domain', 'acl[0]' = 'acl').
#
# Three operators are provided for conditional sorting.
# '.contains' is for 'fgrep keyword' match.
# '.equals' is for 'grep ^keyword$' match.
# '.starts' is for 'grep ^keyword' match.
#
# Sorting rules are defined using multi-lined chunks. A chunk is terminated
# by a 'destination' line which specifies the pathname to write the audit
# log. A 'destination' line is processed only when all preceding 'header',
# 'domain' and 'acl' lines in that chunk have matched.
# Evaluation stops at the first processed 'destination' line.
# Therefore, no audit logs are written more than once.
#
# More specific matches should be placed before less specific matches.
# For example:
#
# header.contains profile=3
# domain.contains /usr/sbin/httpd
# destination     /var/log/tomoyo/reject_003_httpd.log
#
# This chunk should be placed before the chunk that matches logs with
# profile=3. If placed after, the audit logs for /usr/sbin/httpd will be
# sent to /var/log/tomoyo/reject_003.log .

# Please use TOMOYO Linux's escape rule (e.g. '\040' rather than '\ ' for
# representing a ' ' in a word).

# Discard all granted logs.
header.contains granted=yes
destination     /dev/null

# Save rejected logs with profile=0 to /var/log/tomoyo/reject_000.log
header.contains profile=0
destination     /var/log/tomoyo/reject_000.log

# Save rejected logs with profile=1 to /var/log/tomoyo/reject_001.log
header.contains profile=1
destination     /var/log/tomoyo/reject_001.log

# Save rejected logs with profile=2 to /var/log/tomoyo/reject_002.log
header.contains profile=2
destination     /var/log/tomoyo/reject_002.log

# Save rejected logs with profile=3 to /var/log/tomoyo/reject_003.log
header.contains profile=3
destination     /var/log/tomoyo/reject_003.log

アクセス許可ログはあっという間に大きくなるのでアクセス許可ログを保存する場合にはディスクのスペースに注意してください。理解していないのならばアクセス許可ログを保存するべきではありません。

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

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

アクセスログを保存する必要が無い場合は、 ccs-auditd を実行する必要はありません。また、プロファイルで PREFERENCE={ max_audit_log=0 } という指定をすることにより、消費メモリの節約と応答速度の向上が期待できます。ドメインに対して強制モードを割り当てるまでアクセスログは保存しないという選択肢もありますが、より厳密なアクセス制御を行うためのポリシーを作成できるようにするために、現時点でアクセス拒否ログを保存するように設定しておくことをお勧めします。

ディストリビュータはデーモンやサービスのための設定をパッケージの中に含めたいと思うかもしれません。 /usr/sbin/ccs-auditd という単一のコマンドを実行するだけでデーモンを起動できるので、そのための設定を含めることは簡単です。もし systemd を利用している場合、以下のような内容を含む /lib/systemd/system/ccs-auditd.service というファイルを作成してください:

[Unit]
Description=TOMOYO Linux Auditing Daemon

[Service]
Type=forking
ExecStart=/usr/sbin/ccs-auditd
ExecReload=/bin/kill -HUP $MAINPID

[Install]
WantedBy=multi-user.target