Chrootの設定
戻る
Chrootとは
chrootというのはUnixシステムコールの一つで、ファイルシステムのルートディレクトリの位置を変更するというものです。一度あるディレクトリへchrootすると、そのプロセスと全ての子プロセスはchrootしたディレクトリ階層より上のファイルを開くことができなくなります。esehttpdには、起動時に設定ファイルを読み込んでログファイルを開いた後にchrootする機能があります。このような機能には次のような利点があります。
- CGIのセキュリティホールを防止
- CGIスクリプトのバグによって任意のコマンドが実行されてしまうようなセキュリティホールがあった場合でも、chroot後の環境に/bin/shが無い場合には多くのケースで問題を回避できます。
- 被害がchroot後の環境に限定される
- たとえCGIにchrootによっても回避できないセキュリティホールが有ったとしても、それによる被害はchrootしたディレクトリの外には及びませんので、OS全体を乗っ取られる危険性は大幅に減少します。
- 設定ファイルが保護される
- 通常、esehttpdの設定ファイルやBasic認証のパスワードファイル、ログファイル等はchroot環境の外に置きますので、セキュリティホールによって読まれたり書き換えられたりする危険性がさらに減少します(もっともこれらはroot権限を落すことによっても保護されていますので、root以外でアクセスできないようにしておけばchrootしなくても安全です)。
- シンボリックリンクに対して安全になる
- chrootしてしまうとシンボリックリンクによってchroot環境外へアクセスすることができなくなりますので、誤って重要なファイルを読まれてしまう危険性が減ります。esehttpdにはシンボリックリンクを抑制する機能(apacheのFollowSymLinks等)がありませんので、シンボリックリンクが心配な場合はchrootする必要があります。
設定
esehttpdが起動時にchrootするようにするには、esehttpdの設定ファイルに次のような内容を書いてください。
ChangeRoot /usr/local/lib/esehttpd/www
DocumentRoot /html/
<Directory /html/>
....
</Directory>
これでとりあえず動作するはずです。chrootすることによって/usr/local/lib/esehttpd/wwwが新しいルートディレクトリになるので、DocumentRoot
には新しいルートディレクトリから見たパスを書く必要があります。同様の理由で<Directory>
に指定するパスも新しいルートディレクトリを基準に書かなくてはなりません。
CGIスクリプト
CGIプログラムをchrootした環境で動かすには、chroot後もそれが実行可能でなくてはなりません。C言語で書かれた実行形式であればライブラリを全てスタティックリンクするか、あるいは必要とするシェアードライブラリをchroot後の環境の中にコピーする必要があります。スクリプト言語で書かれたCGIならば、インタプリタとそれが必要とするシェアードライブラリをchroot後の環境の中にコピーします。例として、シェルスクリプトで書かれたshowenvというスクリプトを実行する環境を設定する方法を下に示します。
bash# cd /usr/local/lib/esehttpd/www/
bash# ls
cgi-bin html
bash# cat cgi-bin/showenv
#!/bin/bash
echo "Content-Type: text/plain"
echo
printenv
bash# mkdir bin lib
bash# cp /bin/bash bin/
bash# cp /usr/bin/printenv bin/
bash# ldd bin/bash bin/printenv
bin/bash:
libtermcap.so.2 => /lib/libtermcap.so.2 (0x40023000)
libc.so.6 => /lib/libc.so.6 (0x40027000)
/lib/ld-linux.so.2 => /lib/ld-linux.so.2 (0x40000000)
bin/printenv:
libc.so.6 => /lib/libc.so.6 (0x40023000)
/lib/ld-linux.so.2 => /lib/ld-linux.so.2 (0x40000000)
bash# cp /lib/libtermcap.so.2 lib/
bash# cp /lib/libc.so.6 lib/
bash# cp /lib/ld-linux.so.2 lib/
bash# chroot /usr/local/lib/esehttpd/www/ /cgi-bin/showenv
Content-Type: text/plain
HISTSIZE=1000
HOSTNAME=localhost
LOGNAME=root
....(以下省略)
この例では最後にchrootコマンドを使ってshowenvスクリプトが実際に/usr/local/lib/esehttpd/wwwへchroot後でも実行できることを確認しています。なお、この作業でコピーしてくるインタプリタやライブラリやディレクトリなどは、CGIスクリプトを実行するユーザの権限(デフォルトではnobody)では書きかえられないようにしておくことが重要ですので、rootで作業するのがいいでしょう。また、この例ではシェルスクリプトで書かれたCGIスクリプトを実行する環境を作っていますが、セキュリティの面から言えばCGIスクリプトはシェルスクリプトで書くのはできるだけ避けるべきで、chroot後の環境には/bin/shを置くのもできるだけ避けるべきです。
Rubyで書かれたCGIスクリプト
CGIスクリプトがRubyで書かれている場合、cgi-rubyモジュールを使って実行するようにすれば、chroot後の環境にインタプリタやシェアードライブラリを置く必要はありません。よってセキュリティの面からもRubyスクリプトはcgi-rubyモジュールを使って実行するほうが安全です。ただし、cgi-rubyモジュールは/tmp/ディレクトリの下に一時ファイルを作りますので、chroot後の環境にも、
bash# cd /usr/local/lib/esehttpd/www/
bash# mkdir -m 1777 ./tmp
のようにして/tmpディレクトリを作成してください。
戻る
Akira Higuchi