Info: Version 1.8.x is available.
Last modified: $Date: 2024-03-30 11:25:00 +0000 (Sat, 30 Mar 2024) $
第2回は, TOMOYO Linux における制御モードとプロファイルについて紹介し,それらを組み合わせて実際に強制アクセス制御を行う手順について紹介しました.やや駆け足でしたが,実はこれまでの部分で TOMOYO Linux の基本部分の説明は終わっています.今回からは必要に応じて説明を補足しながら,詳細,応用的な使い方について紹介していくことにします.どうぞおつきあいください.今回のテーマは,ドメイン遷移についてです.
第1回で説明したように, TOMOYO Linux では原則としてプログラムを実行するたびにドメイン遷移が発生します(図1).
■図1 TOMOYO Linux におけるドメイン遷移 (プログラムの実行により新たなドメインに遷移する.) |
つまりすべてのプログラムはそれぞれが独立なドメインになります.ドメインの名称は,基点である <kernel> から現在に至るまでに実行された全てのプログラムのパス名を結合したものになります.これに対して, SELinux におけるドメインは,階層的な構造を持っておらずフラットに並んでいます.プログラムとドメインの対応はポリシー策定者が定めますが,通常はドメインには複数のプログラムが含まれます.各ドメインであらかじめ定義されたプログラムを実行することにより定められたドメインに遷移します(図2.その結果アクセス制御の内容が変わります).
■図2 SELinuxにおけるドメイン遷移 |
TOMOYO Linux におけるドメインの遷移は,必要に応じて初期化したり抑制したりすることができます.
「 initialize_domain プログラム名」という構文により指定されたプログラムが実行された場合, <kernel> 直下のドメインへ無条件に遷移します(図3).
■図3 initialize_domain の効果 ( /some/where/baz が実行されると無条件に <kernel> 直下の /some/where/baz ドメインに遷移する.) |
前述したように,「 initialize_domain プログラム名」と指定しておくと, 「プログラム名」で指定されたプログラムが実行された場合,「 <kernel> プログラム名」というドメインへ遷移します.(図4).
■図4 無条件にドメイン遷移を初期化する |
しかし,「 initialize_domain プログラム名 from ドメイン名」のように「ドメイン名」と一緒に指定しておくと,「プログラム名」で指定されたプログラムが「ドメイン名」で指定されたドメインから実行された場合に限り「 <kernel> プログラム名」というドメインへ遷移します(図5).
■図5 特定のドメインから実行された場合のみドメイン遷移を初期化する ( initialize_domain /usr/sbin/sshd from <kernel> /etc/rc.d/init.d/sshd という指定により, <kernel> /etc/rc.d/init.d/sshd ドメインから /usr/sbin/sshd が実行された場合に限り, <kernel> /usr/sbin/sshd ドメインへ遷移する.) |
「ドメイン名」の部分は <kernel> で始まる完全なドメイン名ではなく,ドメイン名の最後のパス名だけでもかまいません.
「 no_initialize_domain プログラム名 from ドメイン名」と指定しておくと, 「ドメイン名」で指定されたドメインから「プログラム名」が実行される場合には initialize_domain キーワードによる指定を無視します.
たとえば,メールを送信するための「 /bin/mail 」は「 /usr/sbin/sendmail.sendmail 」を実行しますが,メールを受信するために「 /usr/sbin/sendmail.sendmail 」を実行するのとは別の権限を与えたい場合には,「 no_initialize_domain /usr/sbin/sendmail.sendmail from /bin/mail 」と指定しておくことで「 <kernel> /usr/sbin/sendmail.sendmail 」ドメインへ遷移させないようにすることができます(図6).(ドメイン名が /bin/mail で終わる場合のみ機能します. /bin/mail が keep_domain に指定されたシェルのドメインから呼ばれる場合には /bin/mail の代わりにシェルのドメインを指定する必要があります.)
■図6 no_initialize_domain との組み合わせ |
「 keep_domain ドメイン名」という構文により指定されたドメインに属しているプロセスは, initialize_domain に指定されたプログラムが実行されない限り,そのドメインに留まります(図7).複数のプログラムが同一ドメインに所属するという意味では SELinux のドメインに近い部分があります.
■図7 keep_domain の効果 ( <kernel> /sbin/init ・・・ foo bar ドメインは keep_domain 指定されているため,プログラムを実行してもドメイン遷移は起こらない. initialize_domain 指定されている /some/where/baz が実行されることにより <kernel> /some/where/baz に遷移している.) |
「ドメイン名」の部分は <kernel> で始まる完全なドメイン名ではなく,ドメイン名の最後のパス名だけを指定することも可能です.たとえば, 「ドメイン名」として /bin/bash を指定した場合,ドメイン名が /bin/bash で終わるすべてのドメインに対してkeep_domainが指定されたものとして扱われます(図8).
■図8 keep_domain の効果 |
前述したように,「 keep_domain ドメイン名」と指定しておくと, 「ドメイン名」で指定されたドメインに到達した場合には, initialize_domain で指定されたプログラムが実行されない限りドメイン遷移が行われなくなります(図9).
■図9 無条件にドメイン遷移を抑制する |
しかし,「 keep_domain プログラム名 from ドメイン名」のように指定した場合, 「ドメイン名」で指定されたドメインから「プログラム名」で指定されたプログラムが実行された場合に限り,ドメイン遷移が発生しなくなります(図10).
■図10 特定のプログラムが実行された場合だけドメイン遷移を抑制する |
ログイン後にはどのようなコマンドをどのような順序で実行するかを事前に知ることはできないため, keep_domain というキーワードを指定してドメイン遷移を行わせないようにすることができます.しかし,パスワードの変更のためにパスワードファイルへのアクセスを必要とする場合や,デーモンとして動作するサービスを再スタートさせる場合などはドメイン遷移を再開させたい場合があります.
「 no_keep_domain プログラム名 from ドメイン名」と指定しておくと, 「ドメイン名」で指定されたドメインから「プログラム名」が実行される場合には keep_domain キーワードによる指定を無視します.
たとえば,「 keep_domain <kernel> /usr/sbin/sshd /bin/bash 」という指定がされている場合に「 no_keep_domain /bin/cat from <kernel> /usr/sbin/sshd /bin/bash 」という指定を行うことで,デフォルトではドメイン遷移をさせないようにしながら「 /bin/cat 」を実行する場合には「 <kernel> /usr/sbin/sshd /bin/bash /bin/cat 」ドメインへ遷移させるようにすることができます(図11).
■図11 no_keep_domain との組み合わせ |
ドメイン遷移は原則としてプログラムの実行時に発生しますが,プログラムの中からドメイン遷移を行うための処理を呼び出すことにより,プログラムの実行を伴わずにドメイン遷移を行うことが可能です.
例えば, Apache はCGIをサポートしていますが, Apache とは別プロセスとして動作する(プログラムの実行を必要とする)CGIと Apache プロセス内で動作する(プログラムの実行を必要としない)CGIがあります. Apache がリクエストを処理する前にバーチャルホスト名や実行されるCGIの名前などに基づいてドメイン遷移を行うことにより, Apache プロセス内で動作するCGIに対しても権限の分割を行うことができます.手順については第10回で紹介します.
initialize_domain と keep_domain という2つの例外を組み合わせることにより,柔軟なアクセス制御の指定が可能になります.以下,例を挙げて説明します.ログインして ccs-editpolicy を実行してください.そして, /etc/rc.d/init.d/network の実行されるドメイン( <kernel> /etc/rc.d/init.d/network )を探してください. /etc/rc.d/init.d/network から /etc/sysconfig/network-scripts/ifup や /bin/touch など,たくさんのプログラムが実行されているのがおわかりだと思います(図12).
■図12 keep_domain 指定前のドメイン遷移 |
ここで,「 Tab 」を押してください.「 <<< Domain Transition Editor >>> 」から「 <<< Exception Policy Editor >>> 」という画面に切り替わったと思います.この画面をスクロールしていくと, initialize_domain で始まる行が現れます.一番下までスクロールしてください.この位置で,「 A 」を押してから keep_domain <kernel> /etc/rc.d/init.d/network と入力して「 Enter 」を押してください.すると,入力した内容が現れるはずです(図13).
■図13 keep_domain を指定 |
再度,「 Tab 」を押してください.「 <<< Exception Policy Editor >>> 」から「 <<< Domain Transition Editor >>> 」という画面に切り替わったと思います.そこから,「 <kernel> /etc/rc.d/init.d/network 」ドメインを探してください(図14).
■図14 keep_domain 指定直後のドメイン遷移 |
「 * 」という表示が「 #* 」に変化しました.「 # 」は「このドメインは keep_domain に指定されているので複数のプログラムがこのドメインで動作する可能性がある」ことを,「 * 」は「このドメインは initialize_domain に指定されているので複数のドメインからこのドメインへ遷移する可能性がある」ことを意味します.ここで, /etc/rc.d/init.d/network の実行されるドメインを keep_domain に指定したことで,そのドメインのアクセス許可を学習し直す必要が生じます.「 ! 」という表示が付いている行(図14の86~189行)へは「 keep_domain <kernel> /etc/rc.d/init.d/network 」という指定が行われたことにより到達できなくなったので削除します.カーソルを合わせて「スペース」キーを押すと,行頭に & マークが表示されます.最後に「 D 」を押すと図15のように聞かれるので「 Y 」を押します.
■図15 ドメインを削除するかどうかの確認メッセージ |
すると,行頭に & マークが表示されているドメインが削除されます.「 Q 」を押して ccs-editpolicy を終了し, /etc/rc.d/init.d/network restart を実行します.再度 ccs-editpolicy を実行して <kernel> /etc/rc.d/init.d/network ドメインを探してみてください.今度は /etc/sysconfig/network-scripts/ifup や /bin/touch などは現れなくなります(図16).
■図16 再学習後のドメイン遷移 |
TOMOYO Linux の自動ドメイン定義機能は強力です.しかし,実行するプログラムの限定とそのアクセス制御は行いたいけれども,プログラムの実行順序が特定できないような場合(典型的なものとしてはログイン後の作業)はポリシーの策定が大変です.グループ化を行うことで,ログイン後のドメインをグループ化してから,そのドメインに強制モード用のプロファイルを割り当てれば,コマンドの実行順序は制限せずにアクセス可能な資源だけを制限することができます.また,強制モード用以外のプロファイルを割り当てれば,従来の Linux と同様に自由に振る舞うことができるようになります.
今回はドメイン遷移について紹介しました.次回は,ポリシーのチューニングについて紹介していきます.どうぞお楽しみに.