TOMOYO Linuxでドメインを管理とポリシー学習をする

1年近く放置してますが、[前回](https://qiita.com/phase-d/items/9e309b149891710ba42e)の続きです。
実際にTOMOYO Linuxを動かしてみて、ポリシーエディタなどを見るとどういう動きをしてるのかはなんとなくわかると思います。適当に動かしてるだけでも、かなり細かくLinuxの挙動が学習される様子がわかるでしょう。何はともあれ、インストールしてちょっと動かしてみただけではなく、ポリシーのチューニングをしないことには始まりません。
TOMOYO Linuxを使う上で最大のキモになるのは、この学習されたドメインの挙動を「いい感じにまとめる」というところにあります。この「いい感じ」が何とも説明しづらくて、公式のドキュメントを見てみてもいまいちよくわからなくなってしまいます。


## TOMOYO Linuxのドメイン管理とポリシー学習の流れ
もちろん最終的にはLinuxの挙動すべてがTOMOYOのenforcingされた管理下に置かれて、規定された動作以外できないというのが理想ですが、さすがにそれは難しいのでちょっとずつ始めます。
まずは
```# tomoyo-editpolicy```
を見てみましょう。TOMOYO Linuxが動作していれば、すでにいろいろなドメインが自動学習されているはずです。

### そのサーバの主要な役割だけinitialize_domainする
最初の一歩はこれです。例えばそのサーバがWebサーバであれば、「w」を押下の後さらに「e」を押下するとException Policy Editorに行くので、そこで「a」を押下して

```html:ExceptionPolicyEditor
initialize_domain    /usr/sbin/apache2 from any
```

を定義します。するとどのような方法で起動されても、Apache関連のプロセスは/usr/sbin/apache2のドメインか、さらにその配下のドメインとして定義されます。
具体的にはこんな感じ。

```html:DomainPolicyEditor
  342:  0  *      /usr/sbin/apache2
  343:  0             /usr/bin/php-cgi
  344:  0                 /bin/sh
  345:  0                     /usr/sbin/sendmail
  346:  0                         /usr/sbin/postdrop
```

この場合、/usr/sbin/apache2の配下でphp-cgiが動いていて、さらにその配下にシェルがキックされてsendmailが呼ばれたという挙動が学習されています。
あまり細かく別のドメインとして分かれるのが嫌だという場合は、keep_domainを使うとドメインがまとめられます。この辺りは好みかなぁ。例えば

```html:ExceptionPolicyEditor
keep_domain          any from /usr/bin/php-cgi
```

と定義してやると

```html:DomainPolicyEditor
  342:  0  *      /usr/sbin/apache2
  343:  0             /usr/bin/php-cgi
```
これだけになります。どの粒度・単位で分割・統合をするかにあまり正解はないような気がしています。好みとやりやすさの問題かなと。これでドメインがまとめられたら「s」を押下して、プロファイルを0「Disable Mode」から1の「Learning Mode」に切り替えます。これでそのドメイン内の細かい挙動の学習が始まります。

### 対象のドメイン内で学習されたポリシーをパターン化する
ドメインの統廃合ができたらそのままさらにしばらく動かしてみて、挙動の学習を進めます。
そして例えばポリシーエディタで先程の「/usr/sbin/apache2」のところにカーソルを持っていってEnterを押すと、そのドメイン内で学習された挙動がいっぱい表示されます。本当にいっぱいされますね。この学習・許可された挙動をパターン化するわけですが、方法としては[公式のドキュメント](https://tomoyo.osdn.jp/2.5/tool-editpolicy.html.ja#make_pattern)がわかりやすいでしょうか。


抑えておくポイントとしては
・ファイルに対するアクセスと言っても、read,create,append,unlinkなどなどすべて別々の挙動として扱われる
・ネットワークについてもbind,listen,connect,sendなどが別々の挙動として扱われる
というところで、それぞれが別々に学習されますし、許可もそれに応じて行われます。公式のドキュメントとしては[この辺り](https://tomoyo.osdn.jp/2.5/policy-specification/domain-policy-syntax.html.ja)を参照すると良いです。

プログラムによっては単に「ファイルを作る」という挙動でも、いきなりcreateだけする場合もありますし、createした後にappendしたり、一時ファイルをcreateして最後にrenameしたりといろんなパターンがありえます。その辺りの違いは自動的に学習されるので直接は気にかける必要はありませんが、内部の挙動の多種多様さが垣間見れて面白いです。

パターンを作る時によく使うTipsで、特に幅広く許可してしまうやり方としてはこの辺をよく使います。

```
/var/www/\{\*\}/\* /var/www以下のディレクトリにある全ファイル
/var/www/\{\*\}/\*/ /var/www以下の全ディレクトリ
0.0.0.0-255.255.255.255 IPv4ですべてのIPアドレス
::-ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff IPv6ですべてのIPアドレス
```

こんな感じで
1. パターン化できそうな挙動を探す
2. パターン化したポリシーを定義する
3. それにより不要になったポリシーを削除（oを押下）
を繰り返します。この加減も何とも説明しづらいですが、適度に厳密に、それでいて広い範囲でパターン化を行うというのがキモかなと思います。/var/libの下や/tmpに一時ファイルを作ることというのもザラにありますし、いざEnforceにした時に許可漏れがあるとプログラム全体が正しく動作してくれないということが起こりえます。

この流れでパターン化されたポリシーを作っていくというのが、TOMOYO Linuxを実運用する上でのポイントということでしょう。

### 動作モードをPermissiveやEnforcingにする
これでプログラムやデーモンの挙動がほとんど学習されてすべてパターン化されたという段階まで行ければ、そのドメインに対するモードを1の「Learning Mode」から2の「Permissive Mode」に切り替えます。この状態ではポリシー外の挙動が自動学習されることはありませんが、動作自体は許可され、かつログの出力が行われます。ですので通常の運用ではこのモードにして、ログ監視を行っておくというアプローチもありかなと思います。いわばIDS的な使い方ですね。
さらに3の「Enforcing Mode」にするとポリシー外の挙動はブロックされます。こちらはIPS的な使い方ということになります。ポリシーの定義が完璧な状態であればこの方がいいのは言うまでもありませんが、そこはそのサーバの使い方やセキュリティに対するポリシーやいろんな要素が絡むので難しいところですね。
動作が比較的限定的なドメインに対しては「Enforcing」にして、逆にかなり自由度の高い挙動が想定されるドメインの場合には「Permissive」や「Learning」のままにしてログ監視と合わせるという使い方もできるというのがTOMOYO Linuxの柔軟性と言えるかもしれません。

### 最後に
私の文章力の問題なのか、実はTOMOYO Linuxの特徴なのかわかりませんが、説明しようとすると説明しづらいです。公式のドキュメントですらよく読んでもわからないところがあるので、後者だと思いたいところです。ただし実際にポリシーエディタを触ってみると何となくわかるようにできてるというのもまたTOMOYO Linuxの特徴なのではないかと思います。
自動学習やログ出力をするだけでも有用だと思いますので、是非動かして触ってみましょう。