Info: Version 1.8.x is available.
Last modified: $Date: 2024-03-30 20:25:00 +0900 (Sat, 30 Mar 2024) $
前回は,システムにログインして行う操作を制限する手順のうち,ドメイン遷移とファイルアクセスに関する制限について解説しました.今回は,ネットワーク(通信)の制限と実際の操作手順を説明します.
システムにログインしたユーザはファイルへのアクセスだけでなくネットワークにもアクセスすることでしょう.そこで,ログインしたユーザに対してどのサーバへのアクセスを許可するかを設計します.ネットワークに関するアクセス許可の構文は,「 allow_network プロトコル IPアドレス ポート番号」となっています.プロトコルは TCP または UDP または RAW のいずれか,IPアドレスはIPv4またはIPv6アドレスを指定します.IPアドレスの部分は前回の記事で説明したファイルのグループ化と同様にグループ化が可能です.ここではHTTP,DNS,FTP,SSHの設定について説明します.
最初に,HTTPサーバのIPアドレスを HTTP_SERVERS という名前でグループ化することにします.グループ化することにより,ポリシーファイルを読みやすくすることができ,また,サーバのIPアドレスの変更や追加や削除が発生した場合にも修正個所が1ヵ所で済みます.IPアドレスをグループ化するには, address_group というキーワードを使います.HTTPサーバのアドレスが 192.168.1.100 と 192.168.1.200 の場合,例外ポリシーで図1のように定義してから,ログインシェルのドメイン( <kernel> /usr/sbin/sshd /bin/bash )に対して図2という許可を与えます(以降に登場する DNS_SERVERS や FTP_SERVERS や SSH_SERVERS も, HTTP_SERVERS と同様に定義してください).
■図1 アドレスをグループ化する
address_group HTTP_SERVERS 192.168.1.100 address_group HTTP_SERVERS 192.168.1.20 |
■図2 HTTPサーバと通信するためのアクセス許可
allow_network TCP connect @HTTP_SERVERS 80 |
DNSサーバとの通信ではUDPプロトコルのポート 53 を使うので,ログインシェルのドメインに対して図3という許可を与えます.
■図3 DNSサーバと通信するためのアクセス許可
allow_network UDP connect @DNS_SERVERS 53 |
FTPサーバとの通信ではTCPプロトコルのポート 21 を使うので,図4という許可を与えます.
■図4 FTP制御用のアクセス許可
allow_network TCP connect @FTP_SERVERS 21 |
FTPプロトコルではサーバ側からクライアント側へ向けてTCPコネクションを張る場合があるので,図5の許可が必要になる場合があります.
■図5 FTPデータ(アクティブモード)用のアクセス許可
allow_network TCP accept @FTP_SERVERS 20 |
ファイアウォールの内側にいる場合など,サーバ側からクライアント側へ向けてTCPコネクションを張ることができない場合にはパッシブモードを使うので,図5の代わりに図6という許可を与えることになるでしょう.
■図6 FTPデータ(パッシブモード)用のアクセス許可
allow_network TCP connect @FTP_SERVERS 1024-65535 |
SSHサーバとの通信ではTCPプロトコルでポート 22 へコネクションを張るので,図7という許可を与えることになります.
■図7 SSHサーバと通信するためのアクセス許可
allow_network TCP connect @SSH_SERVERS 1024-65535 |
ただし,前回のドメイン遷移の設計では,SSHの秘密鍵へのアクセスを認める必要がある /usr/bin/ssh コマンドはログインシェルとは別のドメインで動作させるように指定している(図8)ので,このアクセス許可はログインシェルのドメインにではなく, /usr/bin/ssh のドメイン(図9)に対して与えることに注意してください.ポリシーエディタを実行して,「 A 」を押してからリスト9の内容を入力して「 Enter 」を押すことで /usr/bin/ssh のドメインを作成できます.
■図8 ログインシェルとは別のドメインで実行する
no_keep_domain /usr/bin/ssh from <kernel> /usr/bin/sshd /bin/bash |
■図9 /usr/bin/ssh 用のドメイン
<kernel> /usr/sbin/sshd /bin/bash /usr/bin/ssh |
さて,これまでの作業でアクセス許可の基本的な設定が完了しました.しかし,これだけではまだアクセス許可が不足していますから,学習モードを用いて不足しているアクセス許可を追加していくことにします.ポリシーエディタを用いてログインシェルのドメインとその子孫ドメインに対してプロファイル1を割り当てます(ポリシーエディタを使わずに, root ユーザで図10のコマンドラインを実行しても結構です).
■図10 学習モード用プロファイルを割り当てる
# /usr/sbin/ccs-setprofile -r 1 '<kernel> /usr/sbin/sshd /bin/bash' |
そして,許可したい操作(具体的には,前回定義した COMMANDS_FOR_LOGIN_SESSION に含まれているコマンドを実行したり, HOME_FILE に該当するファイルを編集したり,ネットワークへアクセスしたりなど)を行ってください.操作例として,図11~図15の内容を参考にしてください.
■図11 SSHの鍵ペアを作成する
$ ssh-keygen Generating public/private rsa key pair. Enter file in which to save the key (/home/example/.ssh/id_rsa): Created directory '/home/example/.ssh'. Enter passphrase (empty for no passphrase): Enter same passphrase again: Your identification has been saved in /home/example/.ssh/id_rsa. Your public key has been saved in /home/example/.ssh/id_rsa.pub. The key fingerprint is: c7:4f:53:39:6f:7e:17:fb:ec:94:0d:02:09:84:d5:67 example@tomoyo |
■図12 SSHで接続する
$ ssh 192.168.99.138 id example@192.168.99.138's password: uid=500(example) gid=500(example) groups=500(example) |
■図13 パスワードを変更する
$ passwd Changing password for user example. Changing password for example (current) UNIX password: New UNIX password: Retype new UNIX password: passwd: all authentication tokens updated successfully. |
■図14 HTTPサーバにアクセスする
$ wget http://192.168.1.100/ Length: unspecified [text/html] Saving to: `index.html' [ <=> ] 2,997 --.-K/s in 0s 14:22:14 (286 MB/s) - `index.html' saved [2997] |
■図15 ホームディレクトリ内のファイルにアクセスする
$ ls .bashrc | xargs /bin/cat > /dev/null |
ここでは,一般ユーザとして example ユーザを使用しています.前回の手順で図16のようにホームディレクトリ以下のファイルの読み書きに関するアクセス許可をあらかじめ与えているため,図16に含まれるアクセス要求は学習されません.
■図16 あらかじめ与えておいたアクセス許可
allow_execute @COMMANDS_FOR_LOGIN allow_read/write @HOME_FILE if task.uid=path1.uid allow_create @HOME_FILE 00-0666 if task.uid=path1.parent.uid allow_unlink @HOME_FILE if task.uid=path1.uid allow_symlink @HOME_FILE if task.uid=path1.parent.uid allow_link @HOME_FILE @HOME_FILE if task.uid=path1.uid task.uid=path1.parent.uid task.uid=path2.parent.uid allow_rename @HOME_FILE @HOME_FILE if task.uid=path1.uid task.uid=path1.parent.uid task.uid=path2.parent.uid allow_truncate @HOME_FILE if task.uid=path1.uid allow_rewrite @HOME_FILE if task.uid=path1.uid allow_mkdir @HOME_DIR 00-0777 if task.uid=path1.parent.uid allow_rmdir @HOME_DIR if task.uid=path1.uid allow_rename @HOME_DIR @HOME_DIR if task.uid=path1.uid task.uid=path1.parent.uid task.uid=path2.parent.uid |
ただし,図17に示したようにSSHの秘密鍵を保存するディレクトリは HOME_FILE から除外してあるので,図11の操作を行うと /home/example/.ssh/id_rsa のように個別に学習されます.
■図17 ホームディレクトリに含まれる範囲
path_group HOME_FILE /home/\{\*\-.ssh\}/\*
path_group HOME_DIR /home/\{\*\-.ssh\}/
|
ポリシーエディタを用いてログインシェルのドメインとその子孫ドメインに対してプロファイル2を割り当てます.ここから先は必要に応じて学習モード(プロファイル1)と確認モード(プロファイル2)を切り替えながら使います.ポリシーエディタを起動して,ログインシェルのドメインに対して与えられたアクセス許可の内容を確認してください.実は,前回の連載の手順では解説を行うために意図的にいくつかの設定を不完全なものにしています.この後,順に内容を見ながら修正していきますので,読みながら一緒に考えてみてください.
前回, /usr/bin/ssh をログインシェルとは別のドメインで実行するように指定しました.しかし,よくよく考えてみると,SSHの秘密鍵へのアクセスを認めなければいけないのは /usr/bin/ssh-keygen も同じです.せっかく /usr/bin/ssh をログインシェルとは別のドメインで動作させることで /bin/cat などでアクセスできないようにしようとしているのに, /usr/bin/ssh-keygen がログインシェルのドメインで動作してしまうと,ログインシェルのドメインからもSSHの秘密鍵へアクセスできるようになってしまいます.そこで, /usr/bin/ssh-keygen も /usr/bin/ssh と同様にログインシェルとは別のドメインで実行させるように修正します.単純に図18の指定を追加するだけでも可能ですが,「SSHの秘密鍵へのアクセスを認めなければいけないプログラム」という意味で /usr/bin/ssh と /usr/bin/ssh-keygen を同じようにまとめて扱うという考え方もあります.
■図18 ログインシェルとは別のドメインで実行する
no_keep_domain /usr/bin/ssh-keygen from <kernel> /usr/sbin/sshd /bin/bash |
そのような目的のために TOMOYO Linux では, aggregator というキーワードが利用できます.構文は「 aggregator 集約前のプログラム名 集約後のプログラム名」で,このように指定すると「集約前のプログラム」は「集約後のプログラム名」と同様に扱われます.図19のように指定すると, /usr/bin/ssh-keygen の実行が要求された場合,実行許可のチェックとドメイン遷移処理は /usr/bin/ssh の実行が要求されたものとして行われるようになります.
■図19 /usr/bin/ssh-keygen を /usr/bin/ssh と同様に扱う
aggregator /usr/bin/ssh-keygen /usr/bin/ssh |
そのため,図20のようなドメインを作成したり,図18という指定を追加したりする必要がなくなります.
■図20 /usr/bin/ssh-keygen 用のドメイン
<kernel> /usr/sbin/sshd /bin/bash /usr/bin/ssh-keygen |
今回は aggregator を使うことにしますので,図19の内容を例外ポリシーに追加してください.その後,ログインシェルのドメインからSSH関連ファイルへのアクセス許可を削除しておいてください.
ログインシェルのドメインに与えられたプログラムの実行許可を見ると,図21の内容も学習されていることがわかります.これは前回,実行を許可するコマンドを定義したときに想定していなかったものです. /usr/bin/xargs は複数のファイルに対して一括操作を行うときに便利なコマンドですので,ログインセッションでの実行を許可することにします.このまま図21の内容を残しておいてもかまいませんが, xargs コマンドは argv[0] をチェックしなくても問題にならないので COMMANDS_FOR_LOGIN_SESSION グループに追加してみましょう.
■図21 想定していなかったコマンドの実行許可
allow_execute /usr/bin/xargs |
例外ポリシーの画面に移動して,図22のエントリを追加してから,ログインシェルのドメインに戻って図21の内容を削除します.
■図22 想定していなかったコマンドの実行許可
path_group COMMANDS_FOR_LOGIN_SESSION /usr/bin/xargs |
学習モードで操作を行うと,図23のように allow_capability で始まる行が学習されたと思います.ケイパビリティは許可する操作種別を指定するだけであるため,操作対象を指定する必要はありません.学習モードで必要だったものは運用中にも必要になるのでそのまま残しておきます.
■図23 学習されたケイパビリティの例
allow_capability SYS_CHMOD allow_capability SYS_IOCTL allow_capability SYS_KILL allow_capability SYS_LINK allow_capability SYS_RENAME allow_capability SYS_SYMLINK allow_capability SYS_UNLINK |
なお, TOMOYO Linux で扱うケイパビリティは,普通の Linux が扱うPOSIXケイパビリティとは異なり,独自に定義したものですのでご注意ください.
学習モードで操作中に, allow_signal で始まる行が学習されたかもしれません. TOMOYO Linux ではシグナルの送信先を制限することもできます.シグナルを送信する場合には /bin/kill というコマンドを使用します.しかし, /bin/bash などのシェルは,内部コマンドとして kill というコマンドを提供しているため,実際には /bin/bash から /bin/kill を実行することなくシグナルを送信することができます.そのため,シグナルの送信を制限しない場合, COMMANDS_FOR_LOGIN_SESSION に /bin/kill が含まれていないにもかかわらず, root ユーザとしてログインして /bin/bash の内部コマンドとしての kill コマンドを使用することで任意のプロセスを強制終了させてしまうことができてしまいます.シグナルのアクセス制御を行うにはプロファイル中で CONFIG::ipc::signal を有効にします.今回使用しているプロファイルでは有効になっているので,シグナルの送信要求を制限することができます.シグナルに関するアクセス許可の構文は,「 allow_signal シグナル番号 送信先ドメイン名」となっています.シグナルの送信先となるプロセスが属しているドメインのドメイン名が「送信先ドメイン名」で始まる場合に,「シグナル番号」の種類のシグナルを送信できます(いくつか例外がありますが,通常は気にする必要はありません.詳細についてはプロジェクトのWebページのポリシー仕様書を参照ください).
再度学習モードで学習を行い,確認モードで許可したい操作を行ってください.警告メッセージが表示されないようになれば学習は完了です.確認モードでポリシーエディタを実行し,ログインシェルのドメインに対して不適切なアクセス許可(たとえば /etc/shadow へのアクセス許可やSSH秘密鍵へのアクセス許可など)がないことを確認してください.
ポリシーエディタを用いてログインシェルのドメインとその子孫ドメインに対してプロファイル3を割り当てます.ポリシーエディタなどを用いてポリシーを変更できるのは(設定により一般ユーザによる変更を認めるようにもできますが,デフォルトでは) root ユーザだけです. root ユーザの操作を制限するつもりがないのならこのままでもかまいませんが, root ユーザで行う作業の一部を委託する場合,SSHログインしたログインシェルからポリシーエディタを用いてアクセス制御を無効化されてしまっては困ります.そのため,自分以外に root ユーザとしてSSHログインさせる場合には,ログインシェルのドメイン( <kernel> /usr/sbin/sshd /bin/bash )からポリシーエディタ( ccs-editpolicy や ccs-setprofile など)の実行許可および /proc/ccs/\* へのアクセス許可を削除しておくのを忘れないでください.
以上で TOMOYO Linux を用いてログインセッションを制限する方法の説明は終わりです.
次回は Apache の権限をより詳細に分割する方法について紹介します.