<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html lang="ja-JP">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<meta http-equiv="Content-Style-Type" content="text/css">
<title>TOMOYO Linux の世界　第４回：「ポリシーをチューニングしてみよう」</title>
<link rel="stylesheet" href="http://tomoyo.sourceforge.jp/tomoyo.css" media="all" type="text/css">
</head>
<body>
<p style="text-align:right;"><a href="tutorial-4.html.en">English Page</a></p>
<p style="text-align:right;">Last modified: $Date: 2013-03-09 12:24:36 +0900 (Sat, 09 Mar 2013) $</p>

<h1>TOMOYO Linux の世界<br>第４回：「ポリシーをチューニングしてみよう」</h1>

<h2>今回の内容</h2>

<p>今回のテーマは， TOMOYO Linux を使いこなすうえで必須のポリシーのチューニングと，それを支援する機能についてです．</p>

<h2>ポリシーの修正を支援する機能について</h2>

<p>セキュアOSを導入していれば，プロセスを乗っ取られたり，管理者権限を不正に奪われたりしてもそれがただちに致命的被害にはつながりません．システムのアップデートについて，標準のOSほど神経を使わなくても良くなりますが過信は禁物です．アップデートを適用しシステムを万全な状態に維持しましょう．強制アクセス制御機能を搭載しているOSでは，管理者が定義したポリシーにより振る舞いが制限されます．そのため，ソフトウェアのアップデートなどによりプログラムの依存関係などが変化した場合，ポリシーを修正してやらないと正常に動作できなくなってしまう可能性があります．管理者が自らポリシーを作成するという考え方を持つTOMOYO Linuxでは，ポリシーの修正も自力で行わなければいけません．今回は，ソフトウェアのアップデートに伴って必要となる，ポリシーの修正作業を支援する機能について紹介します．</p>

<p>TOMOYO Linux では，強制モードで運用中にポリシー違反が発生しても，そのアクセス要求を直ちに拒否する（図１）のではなく，管理者による対話的な操作によりそのアクセス要求の諾否を指示する（図２）ことができます．この機能は，強制モードでの動作確認中にポリシー違反が発生した場合や，ソフトウェアのアップデートなどによりポリシーの微調整が必要になった場合に役に立ちます．</p>

<table border="1" summary="fig">
<tr><td>
■図１　ポリシーに違反する要求はすぐに拒否<br>
<img src="tutorial/fig-4-1-ja.png" alt="fig-4-1-ja.png" width="800" height="480">
</td></tr>
</table>

<table border="1" summary="fig">
<tr><td>
■図２　ポリシーに違反する要求は対話的に処理<br>
<img src="tutorial/fig-4-2-ja.png" alt="fig-4-2-ja.png" width="800" height="480">
</td></tr>
</table>

<h3>使用するプログラム</h3>

<p>TOMOYO Linux では，ポリシーの修正を支援するためのツールとして，図３のプログラムを提供しています．</p>

<table border="1" summary="fig">
<tr><td>
■図３　TOMOYO Linux の管理を行うためのプログラム<br>
<table border="1" summary="fig">
<tr><td>プログラム名</td><td>役割</td></tr>
<tr><td>ccs-queryd</td><td>アクセス要求を対話的に許可する</td></tr>
</table>
</td></tr>
</table>

<h3>コンソールでの操作例</h3>

<p>まずはログイン後の操作を制限する場合の例で説明します．操作を間違えてロックアウトされてしまわないようにするため，この連載では example というユーザを作成して作業することにします．また， example ユーザと root ユーザの作業をコンソールウィンドウの切り替えを行いながら進めることにします．コンソールウィンドウの切り替えは「 ALT 」＋「 F1 」～「 F6 」で行います．「 ALT 」＋「 F1 」でウィンドウ１を開き， root ユーザと example ユーザのシェルを異なるものに設定してください．これは，ログインシェルを異なるものにすることによって，ログインシェルのドメインを異なるものにし，特定のログインシェルのドメインだけでアクセス制御を有効にするためです．本連載では root ユーザのシェルは /bin/bash の場合で説明しているので， example ユーザには /bin/tcsh を割り当てます（図４）．</p>

<table border="1" summary="fig">
<tr><td>
■図４　example ユーザに /bin/tcsh を割り当てる
<pre>
# usermod -s /bin/tcsh example
</pre>
</td></tr>
</table>

<p>次に「 ALT 」＋「 F2 」でウィンドウ２を開き， example ユーザとしてログインしてください． CentOS 5 の場合，コンソールからログインしたドメインは「 &lt;kernel&gt; /sbin/mingetty /bin/login /bin/tcsh 」となるはずです．（ /usr/sbin/sshd からログインした場合は「 &lt;kernel&gt; /usr/sbin/sshd /bin/tcsh 」となるはずです．）ウィンドウ１に切り替えて，このドメインに対して強制モード用のプロファイル（プロファイル３）を割り当てます（図５）．</p>

<table border="1" summary="fig">
<tr><td>
■図５　example ユーザのシェル（ウィンドウ２）のドメインに強制モード用プロファイルを割り当て
<pre>
# /usr/sbin/ccs-setprofile -r 3 '&lt;kernel&gt; /sbin/mingetty /bin/login /bin/tcsh'
</pre>
</td></tr>
</table>

<p>これにより， example ユーザのシェル（ウィンドウ２）からは，ほとんど何もできない状態になります（図６）．</p>

<table border="1" summary="fig">
<tr><td>
■図６　図５の適用結果を確認
<pre>
$ ls
/bin/ls: Operation not permitted.
$ cat /etc/passwd
/bin/cat: Operation not permitted.
</pre>
</td></tr>
</table>

<p>ccs-queryd というプログラムを使用する（図７）と，強制モードで動作中のプロセスがポリシーに違反する内容のアクセス要求を行った場合でも，ただちに拒否するのではなく，システム管理者の指示を仰ぐようにすることができます．このモードは， SELinux や AppArmor には存在しない， TOMOYO Linux 特有の機能です．</p>

<table border="1" summary="fig">
<tr><td>
■図７　ccs-queryd の実行
<pre>
# /usr/sbin/ccs-queryd
</pre>
</td></tr>
</table>

<p>ウィンドウ２に切り替えて， /bin/ls コマンドの実行を要求してみましょう（図８）．</p>

<table border="1" summary="fig">
<tr><td>
■図８　ls コマンドを実行
<pre>
$ /bin/ls
</pre>
</td></tr>
</table>

<p>先ほどはただちに拒否されてしまいましたが，今度は拒否されずに止まっています．この状態のままウィンドウ１に切り替えてみましょう．すると，図９のようなプロンプトが表示されているはずです．</p>

<table border="1" summary="fig">
<tr><td>
■図９　図８実行後，ウィンドウ１に表示されるプロンプト
<pre>
#2011/01/17 03:51:10# profile=3 mode=enforcing granted=no (global-pid=3523) task={ pid=3523 ppid=3468 uid=502 gid=502 euid=502 egid=502 suid=502 sgid=502 fsu
id=502 fsgid=502 type!=execute_handler } path1={ uid=0 gid=0 ino=951094 major=8 minor=1 perm=0755 type=file } path1.parent={ uid=0 gid=0 ino=917505 perm=0755
 } exec={ realpath="/bin/ls" argc=1 envc=21 argv[]={ "/bin/ls" } envp[]={ "HOME=/home/example" "PATH=/usr/kerberos/bin:/usr/local/bin:/bin:/usr/bin:/usr/X11R
6/bin" "SHELL=/bin/tcsh" "TERM=linux" "MAIL=/var/spool/mail/example" "LOGNAME=example" "HOSTTYPE=i386-linux" "VENDOR=intel" "OSTYPE=linux" "MACHTYPE=i386" "S
HLVL=1" "PWD=/home/example" "USER=example" "GROUP=example" "HOST=tomoyo" "HOSTNAME=tomoyo" "INPUTRC=/etc/inputrc" "LS_COLORS=no=00:fi=00:di=01;34:ln=01;36:pi
=40;33:so=01;35:bd=40;33;01:cd=40;33;01:or=01;05;37;41:mi=01;05;37;41:ex=01;32:*.cmd=01;32:*.exe=01;32:*.com=01;32:*.btm=01;32:*.bat=01;32:*.sh=01;32:*.csh=0
1;32:*.tar=01;31:*.tgz=01;31:*.arj=01;31:*.taz=01;31:*.lzh=01;31:*.zip=01;31:*.z=01;31:*.Z=01;31:*.gz=01;31:*.bz2=01;31:*.bz=01;31:*.tz=01;31:*.rpm=01;31:*.c
pio=01;31:*.jpg=01;35:*.gif=01;35:*.bmp=01;35:*.xbm=01;35:*.xpm=01;35:*.png=01;35:*.tif=01;35:" "G_BROKEN_FILENAMES=1" "LANG=en_US.UTF-8" "LESSOPEN=|/usr/bin
/lesspipe.sh\040%s" } }
&lt;kernel&gt; /sbin/mingetty /bin/login /bin/tcsh
file execute /bin/ls
Allow? ('Y'es/'N'o/'R'etry/'S'how policy/'A'dd to policy and retry):
</pre>
</td></tr>
</table>

<p>１行目にはポリシーに違反するアクセス要求を行ったプロセスの情報とアクセスしようとしているファイルの情報が，２行目にはポリシーに違反するアクセス要求を行ったプロセスが属しているドメインのドメイン名が，３行目にはアクセス要求の内容が表示されています．このように，ドメイン用ポリシーと同じ構文で要求内容が表示されます．ここで，「 Y 」を押すと，そのアクセス要求を許可することができます．また，「 N 」を押すと，そのアクセス要求を拒否することができます．「 Y 」キーを押した場合， /bin/ls の実行が許可され，図１０のように聞かれます．</p>

<table border="1" summary="fig">
<tr><td>
■図１０　次のポリシー違反が発生した際のプロンプト
<pre>
#2011/01/17 03:51:50# profile=3 mode=enforcing granted=no (global-pid=3523) task={ pid=3523 ppid=3468 uid=502 gid=502 euid=502 egid=502 suid=502 sgid=502 fsu
id=502 fsgid=502 type!=execute_handler } path1={ uid=0 gid=0 ino=328251 major=8 minor=1 perm=0644 type=file } path1.parent={ uid=0 gid=0 ino=327965 perm=0755
 }
&lt;kernel&gt; /sbin/mingetty /bin/login /bin/tcsh /bin/ls
file read /etc/selinux/config
Allow? ('Y'es/'N'o/'R'etry/'S'how policy/'A'dd to policy and retry):
</pre>
</td></tr>
</table>

<p>/bin/ls のドメインは作成されたばかりですから，何もアクセス許可が与えられていません．表示されている内容を見ながら，許可するかどうかを慎重に判断して回答してください．「 A 」を押すと，必要に応じてアクセス許可の内容を編集してポリシーに追加してから再試行することができます．たとえば /etc/passwd だけでなく， /etc/\*shadow\* 以外の /etc/\* に一致するファイルへのアクセスを許可したい場合には， /etc/passwd という内容を /etc/\*\-\*shadow\* に書き換えてから「 Enter 」を押してください．</p>

<p>ccs-querydを終了させるには「CTRL」＋「C」を押してください．</p>

<h3>ccs-queryd 利用時の注意点</h3>

<p>ccs-queryd を利用するうえで注意すべき点が２つあります．１つは，無条件にアクセス要求を許可してはいけない点です．ポリシー違反の原因が悪意あるユーザによる攻撃である可能性があるからです．もし，悪意あるユーザによる攻撃によって発生したアクセス要求に対してアクセスを許可してしまった場合，強制アクセス制御による保護が無意味になってしまいます．もう１つは， ccs-queryd が動作している間は，ポリシー違反が発生しても管理者が応答するまでそのアクセス要求は保留状態となる点です．そのため， ccs-queryd を動作させたまま席を外したりログアウトしたりしないでください．</p>

<h3>実際のサービスに対する操作例</h3>

<p><a href="http://tomoyo.sourceforge.jp/1.8/phase-5.html.ja#5.2">ポリシー違反を対話的に処理する</a>を参照してください．</p>

<h2>ポリシーのゴミを除去する機能について</h2>

<h3>使用するプログラム</h3>

<p>TOMOYO Linux では，ポリシーに含まれる不要なアクセス許可の削除を支援するためのツールとして，図１１のプログラムを提供しています．</p>

<table border="1" summary="fig">
<tr><td>
■図１１　TOMOYO Linux の管理を行うためのプログラム<br>
<table border="1" summary="fig">
<tr><td>プログラム名</td><td>役割</td></tr>
<tr><td>ccs-findtemp</td><td>存在しないパス名を検出する</td></tr>
<tr><td>ccs-domainmatch</td><td>アクセス許可が与えられているドメインを検索する</td></tr>
</table>
</td></tr>
</table>

<p>これらを使うことで，パターン化する前のテンポラリファイルやソフトウェアのアップデートにより削除されたライブラリファイルなどの余計なアクセス許可を検出して除去することができます．</p>

<h3>コンソールでの操作例</h3>

<p>簡単に試してもらうために，コンソールで説明することにします．学習モードの状態で図１２の操作を行ってみてください．</p>

<table border="1" summary="fig">
<tr><td>
■図１２　学習モードで行う操作
<pre>
# touch /tmp/abc12345
# rm -f /tmp/abc12345
</pre>
</td></tr>
</table>

<p>この操作により touch と rm の /tmp/abc12345 に対するアクセスが学習されましたが， /tmp/abc12345 というファイル自体はもう存在しません．この操作が本来不要なものであればポリシーに使われないアクセス許可が残されたことになります．このように，ポリシーには記録されていても存在しないパス名は，テンポラリファイルとして使用されていたか，アップデートにより削除された可能性が高いと言えます． ccs-findtemp コマンドを実行すると，ポリシーには記録されていても存在しないパス名を表示することができます．なお，図１３の実行例では /tmp/abc12345 というパス名しか表示されていませんが，実際には他のパス名も表示されるはずです．</p>

<table border="1" summary="fig">
<tr><td>
■図１３　ccs-findtemp の実行例
<pre>
# /usr/sbin/ccs-findtemp &lt; /proc/ccs/domain_policy
/tmp/abc12345
# /usr/sbin/ccs-findtemp --with-domainname &lt; /proc/ccs/domain_policy
&lt;kernel&gt; /sbin/mingetty /bin/login /bin/bash /bin/touch
/tmp/abc12345
/tmp/abc12345
&lt;kernel&gt; /sbin/mingetty /bin/login /bin/bash /bin/rm
/tmp/abc12345
# /usr/sbin/ccs-domainmatch /tmp/abc12345
&lt;kernel&gt; /sbin/mingetty /bin/login /bin/bash /bin/touch
file create /tmp/abc12345 0666
file write /tmp/abc12345
&lt;kernel&gt; /sbin/mingetty /bin/login /bin/bash /bin/rm
file unlink /tmp/abc12345
</pre>
</td></tr>
</table>

<p>ccs-findtemp により表示されたパス名を引数として ccs-domainmatch コマンドを実行すると，引数で指定されたパス名に対するアクセス許可を含んでいるドメインが表示されます．不要だと判断した場合には， ccs-editpolicy を起動して，当該するドメインへ移動し，不要なアクセス許可を削除します．</p>

<h2>アクセスログを保存する</h2>

<p>TOMOYO Linux では，「ポリシーに違反しなかったアクセス要求のログ」（アクセス許可ログ）と「ポリシーに違反したアクセス要求のログ」（アクセス拒否ログ）を取得することができます．アクセス許可ログとアクセス拒否ログをカーネルから読み出してファイルに保存するために， ccs-auditd というデーモンプログラムを利用できます．</p>

<h3>アクセスログを保存してみよう</h3>

<p>次に， /etc/rc.d/rc.local に図１４の行を追加します．</p>

<table border="1" summary="fig">
<tr><td>
■図１４　/etc/rc.d/rc.local を修正
<pre>
/usr/sbin/ccs-auditd
</pre>
</td></tr>
</table>

<p>次に， logrotate によるローテーションを行わせるために，図１５のような内容のファイルを /etc/logrotate.d/tomoyo として作成してください．なお， nocreate オプションを必ず指定してください． nocreate オプションを忘れると，最初のローテーションが実行されて以降のログが保存されなくなってしまいます．</p>

<table border="1" summary="fig">
<tr><td>
■図１５　logrotate によるローテーションの設定（ /etc/logrotate.d/tomoyo ）
<pre>
/var/log/tomoyo/*.log {
    weekly
    rotate 9
    missingok
    notifempty
    nocreate
}
</pre>
</td></tr>
</table>

<p>アクセスログを保存する必要がない場合は，プロファイルで「 PREFERENCE={ max_audit_log=0 } 」という指定することができ， ccs-auditd を実行する必要もありません．</p>

<h3>アクセスログを閲覧してみよう</h3>

<p>アクセスログは，そのまま /etc/ccs/domain_policy.conf に追記可能な形式になっています（図１６）．</p>

<table border="1" summary="fig">
<tr><td>
■図１６　アクセスログの内容例（ /var/log/tomoyo/reject_003.log ）
<pre>
# cat /var/log/tomoyo/reject_003.log
#2011/01/17 04:23:43# profile=3 mode=enforcing granted=no (global-pid=4793) task={ pid=4793 ppid=4759 uid=500 gid=500 euid=500 egid=500 suid=500 sgid=500 fsuid=500 fsgid=500 type!=execute_handler } path1={ uid=501 gid=501 ino=786913 major=8 minor=1 perm=0664 type=file } path1.parent={ uid=0 gid=0 ino=786433 perm=01777 }
&lt;kernel&gt; /sbin/mingetty /bin/login /bin/bash /bin/cat
file read /tmp/testfile2

#2011/01/17 04:23:51# profile=3 mode=enforcing granted=no (global-pid=4847) task={ pid=4847 ppid=4814 uid=501 gid=501 euid=501 egid=501 suid=501 sgid=501 fsuid=501 fsgid=501 type!=execute_handler } path1={ uid=500 gid=500 ino=786912 major=8 minor=1 perm=0664 type=file } path1.parent={ uid=0 gid=0 ino=786433 perm=01777 }
&lt;kernel&gt; /sbin/mingetty /bin/login /bin/bash /bin/cat
file read /tmp/testfile1
</pre>
</td></tr>
</table>

<p>アクセスログの中にはプロセスのユーザＩＤなどの情報も記録されています．これらの情報は次回説明する条件付きアクセス許可で使用することができます．</p>

<h2>次回予告</h2>

<p>今回はポリシーのチューニング方法について紹介しました．次回は，条件付きアクセス許可について紹介していきます．どうぞお楽しみに．</p>

<p><a href="tutorial-3.html.ja">第３回へ戻る</a>　<a href="tutorial-5.html.ja">第５回へ進む</a></p>

<hr>

<p><a href="index.html.ja#tutorial">目次へ戻る</a></p>
<p><a href="http://sourceforge.jp/"><img src="http://sourceforge.jp/sflogo.php?group_id=1973" width="96" height="31" alt="sflogo.php" title="SourceForge.jp"></a></p>
</body>
</html>
