SSHjailを用いたjail化によるOpenSSHサーバの保護
外部からの攻撃に弱いサービスの1つに侵入されると、それを足がかりにシステム全体を不正利用される可能性があるため、セキュリティ的に不備があったり秘匿性の高いネットワークサービスを運用する場合はchrootを用いたjail化を検討すべきだろう。jail化されたサービスに不正侵入されたとしても、そこから盗み出されるのは、侵入者に読み取られても影響のない情報だけに限定しておけるからである。具体的に何をjail化しておけばいいのかというと、それは不正侵入に使われ易いターゲットであり、例えばBIND、Apache、FTP、SSHといったサービスが挙げられる。そして本稿で紹介するのは、OpenSSHデーモンにjail機能を追加するSSHjailというパッチである。このパッチを適用すると2つのOpenSSHファイル(session.cおよびversion.h)に変更が加えられることでSSHサービスのjail化が可能となるが、その際にSSHの設定を修正する必要はない。
SSHjailを使用する際に必要となるのは、OpenSSHのソースパッケージとSSHjailパッチ本体およびpatchやmakeなどの開発用ツールである。またパッチを当てたSSHデーモンをコンパイルする際には、OpenSSLおよびZlibの開発ライブラリ群をインストールしておく必要もある。下記に説明する手順は、私が試したCentOS 4.2およびFedora 6ディストリビューションでのSSHjailインストールを基にしたものであり、その他のLinux環境では若干の違いがあるかもしれないが、基本的な手順は共通しているはずだ。
最初に行うのはOpenSSHソースパッケージおよびSSHjailパッチのダウンロードである。次にこれらを展開してパッチの適用を実行する。例えばOpenSSHデーモンのバージョン4.5p1の展開先が/usr/localフォルダであれば、下記のようにコマンドを指定すればいい。
~# cd /usr/local
~# tar xvfz openssh-4.5p1.tar.gz
~# patch -p0
パッチの適用が完了したら設定用スクリプトを実行する。
~# cd openssh-4.5p1
~# ./configure
その際に、Zlibライブラリが古くてセキュリティ的な危険性がある旨を告げるエラーメッセージが表示されるケースがあるが、そうした場合は、下記のパラメータを設定用コマンドに指定しておくことでエラーを回避することができる。
~# ./configure --without-zlib-version-check
最後に実施するのは、バイナリファイルのmakeおよびinstall処理である。
~# make && make install
バイナリ類のインストール先は/usr/localフォルダとなるので、ここで新規に作成されたsshdバイナリは/usr/local/sbin/sshdに格納される。
パッチ適用後のデーモンを起動させるには、事前にいくつかの準備をしておく必要がある。それにはまず、jail化の対象とする全ユーザを登録する/etc/sshjail.confファイルを作成しておく。このファイルには、下記のような形式で情報を登録しておけばいい。
chroot=/public/jail1
users=anze,dasa,kimy,pablo
chroot=/public/jail2
users=@testers,raul
このサンプルではjail1およびjail2という2つのjailを作成している。このようにjailは必要な数だけ作成できるが、通常は1つのjailを用意するだけで充分なはずだ。設定ファイルの1行目には、jail化したユーザに使わせる代替用のルートを指定する。同じく2行目には、jail化するユーザを指定する。なおjail2についても同じメンバを登録しているのだが、その際にはtestersというグループに属する各ユーザ名を個別に指定する代わりに「@group_name」という形式による一括登録を行っている。ユーザやグループの登録数に制限はなく、コンマ区切りで指定すればいい。
chroot環境のフォルダ構成 |
以上の準備が整ったら、次にユーザ用のchroot環境のセットアップを施す必要がある。詳細についてはユーザ環境の設定用マニュアルが参考になるだろう。
私の場合、chroot環境をセットアップしたのは/publicフォルダだが、この中にはjail1およびjail2に登録したユーザ用のフォルダを作成しておく。またこれらフォルダ群(binやlibフォルダなどと同階層)の中にhomeというフォルダを1つ作成しておき、その下層にjail化した全ユーザのhomeフォルダ群を格納するようにしておいた(図を参照)。chroot環境のユーザ用に用意するフォルダ群は、基本的に本物の/homeにあるホームフォルダ群をコピーしたものであるが、アクセス権についてもオリジナルと同一の設定にしておく必要がある。その他にもchroot環境に関しては、binおよびlibフォルダも作成して、ユーザにアクセスを許可するバイナリ群をその中に格納しておく必要がある(詳細についてはchrootの環境設定マニュアルを参照)。
最後に行うのは/etc/passwdファイルの設定で、jail化する全ユーザに対するhomeフォルダのパス指定を変更しておかなければならない。以下、先のサンプルで登録したpabloというユーザの場合について、/etc/passwdファイルの変更法を説明していこう。変更前の/etc/passwdファイルにおけるpabloに関する設定は、下記のように記述されているものとする。
pablo:x:501:501::/home/pablo:/bin/bash
この指定は、pabloのhomeフォルダは標準的な/home/pabloという位置に置かれていることを示している。ところがここでは、pabloというユーザをchroot環境にjail化させたい訳であるから、このhomeフォルダのパス指定を下記のように設定し直す必要がある。
pablo:x:501:501::/public/jail1/home/pablo:/bin/bash
設定に関する変更は以上で終了である。次の手順として、パッチを当てたsshdデーモンを起動させる準備をしておかなければならない。変更後のデーモンを使用するには、現在稼働中の古いsshdバイナリを停止させてから(通常の格納位置は/usr/sbin/sshd)、システムのブート時に新しいバイナリを自動起動させるための設定を施しておく必要がある。そのための設定としては、/etc/rc.d/sshdスクリプトファイルにあるsshdファイルのパスを変更するか、あるいは各自の/etc/rc.localファイルにsshdへのパスを登録するかの2通りの方法が存在する。これによりsshdデーモンに関してはstart
パラメータによる起動は不要となるはずである。
動作試験
ここまで説明した設定に問題がなければ、jail化したユーザによるSSHサーバへのログインが可能となり、その際には下記のようなログインメッセージが表示されるようになるはずである。
anze@mac:~$ ssh pablo@srv1.example.com
pablo@srv1.example.com's password:
Last login: Tue Apr 10 17:39:42 2007 from mac.example.com
-bash-3.00$ pwd
/home/pablo
-bash-3.00$ ls /
bin home lib
この表示を見るだけでは、pabloというユーザにごく通常のホームディレクトリ割り当てが行われている場合と特に見分けは付かないだろう(/home/pabloというパス表示に注目)。ところがこの状態でルートのファイルシステムを一覧させようとしても、表示されるのは先に作成しておいた/public/jail1フォルダの内部だけであり、これによりpabloというユーザはchroot化されていて、仮想ルートだけしかアクセスできないことが確認できる。
設定に問題があった場合は、下記のようなエラーメッセージが表示される可能性が高い。
anze@mac:~$ ssh pablo@srv1.example.com
pablo@srv1.example.com's password:
Last login: Tue Apr 10 17:48:25 2007 from mac.example.com
/bin/bash: No such file or directory
Connection to srv1.example.com closed.
これはchroot環境の設定に不具合があることを意味しており、この場合の原因としてはbinフォルダが見つからないか、フォルダ内にbashコマンドが存在していないことが疑われる。
SSHjailと同等の機能は、map-chrootというPAMモジュールあるいはchrootsshという別のパッチを用いることでも実装できる。そうした中で私が特にSSHjailを推す理由だが、それは同パッチの作成者であるGonçalo Silva氏が多大な努力を払って他の実行サービスへの透明性を確保し、OpenSSHの設定ファイルを変更することなくSSHjailを使えるようにしている点を評価してのことである。