情報フロー分析再考:パス名ベースのセキュアOSの弱点とSELinuxの留意点

http://d.hatena.ne.jp/himainu/20060419#1145484710
の続き。
ラベル vs パス名論争で、ラベルのほうがいい根拠として、
パス名は、情報フロー分析が不可能(ハードリンクがあるから)
というのがある。
seedit的にも分からなくなってきたので、ここでじっくり考察。

結論を言ってしまうと、
「パス名ベースのセキュアOSで継続的にセキュリティを保つには、
ハードリンクの生成を常に監視しつづけなければならない。」
というパス名ベースのセキュアOSの弱点が導かれた。

以下、結論に至る過程。

ハードリンクされた情報への情報フロー分析

/etc/shadow というファイルがあったとする。
このファイルの中身には、パスワード(のハッシュ)が格納されている。
/etc/shadowへのアクセスパスは、一意に定まらない。
/var/shadowにハードリンクされてたら、
/var/shadowからもパスワードにアクセスできてしまう。
このように、情報へのアクセスパスは複数存在する。

  • パス名ベースのセキュアOSで、パスワードに誰がアクセスできるか?を分析したいとする。
    • /etc/shadowにアクセスできるドメイン一覧をポリシ検索
    • ファイルシステム全探索。
      • /var/shadowがハードリンクされてた!
    • ハードリンクされたファイル(この場合は/var/shadow)にアクセスできるドメインをポリシ探索
  • ラベルパス名ベースのセキュアOSで、パスワードに誰がアクセスできるか?を分析したいとする。
    • /etc/shadowのラベルにアクセスできるドメイン一覧を検索
    • 終わり。

となる。

パス名ベースのセキュアOSの情報フロー分析は大変で、
ラベルベースの情報フロー分析は簡単という主張になる。
この話が成り立つには、
パス名ベースのセキュアOSで、
「/etc/shadowに適切なラベル(タイプ)が割り当てられている」ことが大前提となる。
この前提がSELinuxで本当に満たされているのかを考察してみた。

初期状態について

初期状態とは、インストール時の「file_contexts」
/etc/shadow system_u:object_r:shadow_t
/var(|/.*) system_u:object_r:var_t
と書いてたとする。
すると、
/var/shadowに付与されるタイプは不定
shadow_t, var_tのどっちがつくか分からない!
もしvar_tが付与されてしまったら、パー。
初期状態では、以下のように、全てのハードリンクに正しくタイプを付与する必要がある。
/etc/shadow system_u:object_r:shadow_t
/var/shadow system_u:object_r:shadow_t

で、インストール直後にfixfiles restoreを走らせ、ラベルを付ける。
ちなみに、ハードリンクがあって、ラベル付けが不定になる場合は、
ちゃんと警告が出てくる。

初期状態の後に作られたハードリンク

さて、この初期状態の後にハードリンクが作られた場合はどうなるのか?
ln /etc/shadow /usr/shadow
してみる。
/usr/shadowのラベルは、/etc/shadowと同じ。
これは、セキュリティ的には素晴らしい振る舞い。
情報フロー分析の前提が崩れることはない(パスワードの情報にshadow_tが付与されているという前提)

ただ、restorecon -R /var
をしてしまうと、
/var/shadow、/etc/shadowのラベルが、var_tになっちゃう!
初期状態後のrestoreconは望ましくないのである。

SELinuxで情報フロー分析可能の留意点

以上をまとめると、
SELinuxで情報フロー分析可能な状態にするには。。

  • インストール時のfile_contextsをしっかり設定。
    • 全ハードリンクを洗い出す必要がある(!) ← 重要
  • 運用時にはrestoreconを使ってはいけない
    • restoreconを使うときは,自分がどんなファイルのどんなラベルを変えようとしているのか正しく認識する必要がある

パス名ベースが劣る点は実際?

  • 結局、SELinuxでも「初期状態」構築時に、全ハードリンクを洗い出す必要がある。
  • パス名ベースは,「初期状態後」に弱味が。
    • 初期状態後に、/etc/shadowのハードリンクを作られたら、穴ができてしまう。
    • ★結論★これを防ぐには、常にハードリンクが作られてないか監視する必要がある

おお、パス名ベースが困る点がついに分かった!

LIDSは、ファイルの中身の識別にiノードを使ってるのでOK。
AppArmor, TOMOYO Linuxにはこの弱点が当てはまると思う(間違ってたら教えてください)
現実的に、この問題が起こる可能性、インパクトがどの程度あるのかが鍵だろう。

seeditのハードリンクの扱い見直し

上記考察を元に、seeditのハードリンクの扱いを見直すことに。
今のseeditはまずいことが分かった。
restoreconが設定の反映のたびに走るので、
ハードリンク経由で変なラベルがつく可能性がある。
備忘録。

seedit-restorecon

ってのを作った。
ハードリンクされた可能性があるファイルのラベルづけをスキップするもの。
既存のrestoreconのソースをちょろっと改造して作った。

seeditのラベル生成規則は、ファイル名の/を_に置き換えるという単純なもの。
この規則に反したラベルを持っているファイルは、
ハードリンクされているか、mvされたか、ファイルタイプ遷移で作られたかのどれか。
seeditは、こういったファイルに対しては、ラベル付けを保留する。

具体的には、以下の基準を満たすときのみ,restreconする。

  • a)親,先祖ディレクトリのラベルがついている時(default_t,rootdir_t含む)
  • b)unlabeled_tがついてる時
  • c)親、先祖ディレクトリのラベルがついてないが,ディレクトリラベルの時はラベル付け
    • ハードリンクされてても、ファイル単位でアクセス制御かけるようになってない

例:
ln /etc/shadow /var/chroot/etc/shadow
したとする。
すると、
/var/chroot/etc/shadow のタイプはetc_shadow_t。

named_tに対して、
allow /var/chroot/etc/* r,s
としたとする。
seedit-loadすると、
/var/chroot/etc/

var_chroot_etc_tラベルをつけるルールが生成され、
seedit-restorecon -R /var/chroot/etc
が走る。しかし、
/var/chroot/etc/shadow のタイプはetc_shadow_tであり、
/var/chroot/etc,/var/chroot, /var ,/いずれのラベルでもないので、
ラベル付けをスキップ。
そのほかの/var/chroot/etc以下には、ラベル付けが走る。
#普通にrestoreconすると/etc/shadowにvar_chroot_etc_tがついてしまう!

seeditでのハードリンクの扱いは?

ハードリンクを作った場合は、
「元からあるファイル名を記述しないとアクセスできない」
ことになる。
例えば、seeditインストール後に
/etc/shadow -> /var/chroot/etc/shadow
なるハードリンクを作った場合,
/var/chroot/etc/shadow
という名前のファイルにアクセスしたい人は、
allow /etc/shadow r;
と書かなければいけない。

「初期状態」について

問題は、「元からあるファイル名」の扱い。
もし、
/etc/shadow, /var/chroot/etc/shadowハードリンクが
seeditインストール時に同時に存在したとすると、
インストール時の
seedit-load -i(fixfiles relabel)の時
ラベル付けがコンフリクトして、不定になる。

どっちを「元からあるファイル名」にするかのルールを決めた。
以下、/etc/shadow, /var/shadowがハードリンクと仮定。

  • deny/allowが明示的に記述されたファイルについては、そのファイルのラベルが付与される。

allow /etc/shadowは書かれてるが、
allow /var/shadowはどこにも書かれてないと、
etc_shadow_tが付与される。-> /etc/shadowを「元からあるファイル名」

  • 両方記述されてる場合、名前が若いほうが優先。

allow /etc/shadow
allow /var/shadowが記述されていると、
etc_shadow_tが付与。-> /etc/shadowを「元からあるファイル名」
#chroot環境は/var/に置くことが多いので..

  • 両方記述されてない場合、ディレクトリの名前が後のほうが優先。

allow /etc/shadow,/var/shadow両方がどこにも書いてない時。
/etc/shadow,/var/shadowには、var_tが付与される。-> /var/shadowを「元からあるファイル名」
しかし、条件c)により、どちらかに対するallowが書かれ次第、ラベルが付与されなおされる。

  • これに伴う変更
    • seedit-converterのfile_label.c
      • file_contextsファイルのソート順番を変更
      • ディレクトリ全体ラベル(昇順), ファイル単体ラベル(降順), 動的生成ラベル、ディレクトリラベル の順番


「初期状態」を設定する人(私か。。)は,
ハードリンクに対しては、一つだけ設定したほうがいいな。
例えば、/etc/shadow, /var/chroot/etc/shadow
というハードリンクがある場合は、
「常に/etc/shadowだけを使う」ようにしよう。

うーんハードリンクは厄介だ。
が、デフォルトではハードリンクは使わないので、あまりユーザには関係ないかな。
この強化は、「何かあった場合に安全側にころぶため」のもの。
さらに、audit2spdlに頑張ってもらって、ユーザに見えないようにしないとな。。

結論

今日の変更でseeditから生成されるSELinuxポリシも情報フロー分析可能になった気がする。
(あいまいな結論だ)
設定反映時のrestoreconで、ラベル名が変わらなくなったので。

2.0.0b2

関係者用にアップ> 関係者様(汗

http://prdownloads.sourceforge.net/seedit/seedit-converter-2.0.0.b2-1.i386.rpm?download
http://prdownloads.sourceforge.net/seedit/seedit-policy-2.0.0.b2-FC5.noarch.rpm?download

  • マニュアル

http://seedit.sourceforge.net/test/tutorial_jp/

変更点

が、実装して1時間でアップしたので、怪しいかも。。

メモ

audit2spdlがallownetをうまく提示してくれない。。。(まだ)
allownet -protocol udp client、recv_msgが抜けてた(修正)