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ディレクトリを作成してください。また、実行するスクリプトが他のrubyライブラリをrequireしている場合はchroot環境の中にもそれらをコピーしてやる必要があります。
戻る
Akira Higuchi