suEXEC環境への移行
おやじのサーバは、家族以外に開放しているわけでもないのですが、家族が勝手に CGI を置くことと、万が一のことを考え suEXEC
環境に移行することにしました。他人にサーバを貸す場合は、ユーザの利便性を保ちつつセキュリティや事故を防止する方法として WWW サーバを suEXEC
環境で動作させるのは非常に有効です。但し、いくつか制約が出てくるので、現用サーバを移行する場合は、十分テストしてから移行することを薦めます。設定ミスだけではなく、プログラムによっては、切り替えた途端に動作しなくなる場合もありますので注意が必要です。
■suEXEC 機能の概要
通常、CGI や SSI を実行する場合、WWW サーバと同じユーザ ( apache や nobody 等 )で実行されます。 十分に試験された、あるいは広く流通している CGI ではあまり問題はないでしょうが、ユーザが作成した CGI や SSI を実行した場合、悪意はなくても WWW サーバのユーザ権限が及ぶファイル等が誤って消してしまう等の事故が考えられます。 当然、自分自身で作成する場合も同じようなことが発生しないとも限りません。このような危険を減らしてくれるのが、suEXEC 機能です。
suEXEC 機能を使用すると、Apache ユーザは WWW サーバを実行しているユーザ
ID とは 異なるユーザ ID で CGI や SSI を実行することができます。具体的には、ユーザディレクトリで
CGI を動作させる場合は、そのユーザ ID で動作するので、他人のファイルを壊すようなことはありません。また、このおかげといってはなんですが、通常モードでは
CGI が生成するファイル等は、WWWサーバのユーザ ID ( nobody等 ) になってしまい、一般ユーザ権限では削除や書き換えができないため、削除するとなると管理者が
root で代行して削除する等、管理が煩わしくなります。これに対し、suEXEC 環境では、これらのファイルはそのユーザの
ID になるので、例えば、FTP で削除したりできるようになり、ユーザにホームディレクトリの管理を任せることが可能になります。
■Apache の suEXEC 化
今回は、Apache2.0.48 を suEXEC 化しました。 Apache の suEXEC
化自体は対して難しい話ではありません。難しく、注意が必要なのは、むしろ環境設定や CGI そのものの作りです。Apache2.0.48 を
こちらからダウンロードします。
インストールは、任意の場所にソースを展開してコンパイルします。suEXECは、apacheをコンパイルする際に、オプションを指定することで有効となります。
今回は、suEXEC だけでなく、SSL や DAV を利用できるようにするとともに、PHP を DSO
モジュールとして組み込むためのオプションをつけてコンパイルしなおしました。
なお、RedHat9 の場合、の openssl が Kerberos サポートの状態でコンパイルされていて、kerberos のヘッダが何故か
/usr/kerberos/include にあるため make でエラーが発生します。下記の赤字のように、ヘッダの場所を明示してあげて下さい。
$ tar zxfv httpd-2.0.48.tar.gz $ cd
httpd-2.0.48 $ export
CPPFLAGS=-I/usr/kerberos/include $
./configure --enable-ssl \ --enable-dav \ --enable-so
\ --enable-suexec
\ --with-suexec-caller=apache \ --with-suexec-userdir=public_html
\ --with-suexec-docroot=/home
\ --with-suexec-logfile=/usr/local/apache2/logs/suexec_log
\ --with-suexec-uidmin=500
\ --with-suexec-gidmin=100 $ make
clean # 以前にmake作業した場合のみ $ make $
su # make install |
[suEXECコンパイルオプション]
- --enable-suexec
デフォルトでは、suEXEC
は有効にならないので、このオプションで有効にする。
- --with-suexec-caller
Apache
を通常動作させるユーザ名を指定する。 おやじは RedHat 標準の Apache 用に作成されていた apche ユーザとした。このユーザだけが
suexec の実行を許可されたユーザになる。
- --with-suexec-userdir
このオプションは、UserDir
ディレクティブを使用して、http://www.aconus.com/~oyaji/cgi/hoge.cgi
のようなアクセスで、各ユーザのホーム・ディレクトリにアクセスする時に使用される。
ここでは、suEXEC
がアクセスを許されるユーザホームディレクトリ配下の サブディレクトリを指定するが、おやじはデフォルトの "public_html" とした。
- --with-suexec-docroot
Apache
のドキュメントルートを設定する。UserDir の指定は別として、ここで指定したディレクトリが suEXEC
の動作で使用する唯一のディレクトリ階層になり、このディレクトリ以下でないと CGI や SSI
は動作しない。おやじは、IPベースのバーチャルホストを動かしているので、一部、ドキュメント構成の変更をせざるを得なかった。おやじは、 "/home"
とした。
- --with-suexec-logfile
suEXEC
の処理とエラーが記録されるファイル名を指定する。ログファイルは デフォルトで "suexec_log" という名前で、 標準のログファイルディレクトリ
(特に変更していなけれが、/usr/local/apache2/logs/)
に置かれるので、名前や場所を変更するのでなければ本オプションの指定は不要。
- --with-suexec-uidmin
suEXEC の対象ユーザとして許される
UID の最小値を指定する。 RedHat の場合は、一般ユーザは 500 から始まるので 500 とする。( デフォルト値は 100 )
- --with-suexec-gidmin
suEXEC の対象ユーザとして許される
GID の最小値を指定する。 RedHat の場合は、一般ユーザは 100 から始まるので 100 とする。( デフォルト値は 100
)
■Apache の suEXEC 化の確認
インストールが完了したら、Apache を起動して suEXEC 化がうまくなされているか確認します。新規の場合は、あらかじめおやじの
HP の他の Apache に関するページと下記を参考にして設定を済ませてください。なお、初めて
Apache を触られるなら、いきなり suEXEC 環境でスタートするといろいろな問題にぶつかって行き詰まってしまう恐れもあります。その場合は、suexec
を下記のような形で rename しておけば、通常モードで起動するので、こちらで
CGI を含めた動作確認をしてから suEXEC 化されると良いでしょう。
# cd /usr/local/apache2/bin # mv suexec
suexec.bak |
Apache がうまく suEXEC 環境で構築できていれば、起動時に Apache
のエラーログに下記のようなメッセージが出力されているはずですので確認します。下記で、wrapper 以降に示される suexec
のパスはデフォルトのままの場合で、コンパイル時にインストールパスを変更していれば、そのディレクトリになります。
suEXEC mechanism enabled (wrapper: /usr/local/apache2/bin/suexec)
|
コンパイル時のオプション設定は、下記でも確認できます。
# /usr/local/apache2/bin/suexec
-V -D AP_DOC_ROOT="/home/" -D
AP_GID_MIN=100 -D AP_HTTPD_USER="apache" -D
AP_LOG_EXEC="/usr/local/apache2/logs/suexec_log" -D
AP_SAFE_PATH="/usr/local/bin:/usr/bin:/bin" -D
AP_UID_MIN=500 -D
AP_USERDIR_SUFFIX="public_html" |
■suEXEC 環境への変更
suEXEC 環境で CG Iを動作させるためには、
こちらにあるセキュリティモデルの20項目の条件を満たさなければなりません。条件はいろいろありますが、その中で主に問題となるのは、ディレクトリの構成とCGI
関係のファイルやディレクトリの所有権やパーミッションに関することです。
◆バーチャルホスト環境下での suEXEC 化
おやじのサイトでは、2つのドメインを IP ベースのバーチャルホストで動かしています。一つは、今、ご覧になっているドメイン( ドメイン1:
www.aconus.com )で、UserDir を使用した複数ユーザでの運用( http://www.aconus.com/~oyaji/
等)がメインで、ルートディレクトリはどちらかと言えばおまけで、事実上使用していないに等しいものです。
もう一つは、全く関係ないサイトで、ここでは仮に example.com (ドメイン2 ) とします。このドメインは、逆に UserDir
は使用せず、ルートディレクトリでの運用がメインのサイトです。
バーチャルホスト環境下で suEXEC 化する場合、当然、それぞれのバーチャルホストで suEXEC に関する設定が必要になります。
まず最初に問題になるのが、ドキュメントルートの問題です。suEXEC 化した場合、CGI を実行できるのは、コンパイル時に
--with-suexec-docroot オプションで指定したドキュメントルート ( /home )
配下のみになります。また、そのプログラムで「/」で始まったり、「../」等でディレクトリ参照していると、プログラムを実行できません。今まで、おやじの環境では、複数ユーザが使用する
ドメイン1では、FTP や UserDir で扱いやすいよう /home をドキュメントルートにし、ドメイン2は単一ユーザ使用のため、/var/www
としていました。そのため、suEXEC 化するとドメイン2ではドキュメントルート配下で CGI が動作しなくなりましたので、ドキュメントを
/home/example 配下に移動するとともに、バーチャルホストの設定も変更して問題を解決しました。
しかし、ここで新たな問題が発生しました。 suEXEC では、UserDir を除き、CGI
の実行権限がコンパイル時に --with-suexec-caller オプションで指定したユーザになってしまい、二つのサイトともドキュメントルート配下では同じユーザ権限
( apache )になってしまうという問題です。UserDir 環境では suEXEC でセキィリティを確保したのにこれでは片手落ちです。
この問題に関しては、Apache2.0で採用された SuexecUserGroup ディレクティブで解決しました。但し、SuexecUserGroup
ディレクティブを使用すると、そのホスト配下の UserDir がここで指定したユーザ権限になってしまうという問題があり、結果として
SuexecUserGroup でユーザ/グループを指定すると個別ユーザで CGI
が動作しなくなってしまいます。(おやじは未確認ですが、1.3系ではこういうことはないそうです。) そこで、UserDir
を使用するドメイン1のドキュメントルートでは、SuexecUserGroup を使用せず、コンパイル時に指定したユーザ権限で動作させることにし、 UserDir
を使用しないドメイン2で SuexecUserGroup ディレクティブを使用してドメイン1と異なる example/users
で動作させることにしました。バーチャルホストを使用せず、一ホストで動かす場合は、ドメイン1と同様の対処とすればいいでしょう。
この条件での、httpd.conf の設定( おやじは管理面から、バーチャルホスト関係は vhost.conf として定義し、httpd.conf
から include している) を以下に示します。なお、おやじは ssl も使用しているので、ssl.conf
のバーチャルホストにも同様の設定をしてあります。ここでは、www.aconus.com用のプライベートアドレスを192.168.1.100、
www.example.com
用を192.168.1.101として説明します。それぞれの設定に関しては、おやじの他のApache関係のコンテンツを参照してください。 suEXEC
環境に移行したたために行った変更部分を赤字で示します。
<VirtualHost 192.168.1.100:80> ServerAdmin
oyaji@mail.aconus.com DocumentRoot "/home/acorn" ServerName www.aconus.com
<Directory "/home/acorn"> Options
FollowSymLinks Includes ExecCGI AllowOverride
None Order allow,deny Allow
from all </Directory>
UserDir /home/*/public_html <Directory
/home/*/public_html> AllowOverride FileInfo
AuthConfig Limit Options MultiViews
SymLinksIfOwnerMatch ExecCGI IncludesNoExec
<LimitExcept GET POST OPTIONS
PROPFIND> Order
deny,allow Deny from
all </LimitExcept>
</Directory>
ErrorLog logs/error_log SetEnvIf Remote_Addr
192.168. homelog nolog SetEnvIf Request_URI "~akirin"
akirinlog nolog SetEnvIf Request_URI "default.ida" wormlog
nolog SetEnvIf Request_URI "root.exe" wormlog nolog
SetEnvIf Request_URI "cmd.exe" wormlog nolog
SetEnvIf Request_URI "Admin.dll" wormlog nolog CustomLog
logs/home_log common env=homelog CustomLog logs/akirin_log
combined env=akirinlog CustomLog logs/worm_log common
env=wormlog CustomLog logs/access_log combined env=!nolog
</VirtualHost>
<VirtualHost 192.168.1.101:80> ServerAdmin
oyaji@mail.aconus.com DocumentRoot "/home/example" ServerName
www.example.com
SuexecUserGroup
example users
UserDir desable
<Directory "/home/example"> Options
FollowSymLinks Includes ExecCGI AllowOverride
None Order allow,deny Allow
from all </Directory>
ErrorLog logs/example.com-error_log SetEnvIf
Remote_Addr 192.168. homelog nolog SetEnvIf Request_URI
"default.ida" wormlog nolog SetEnvIf Request_URI "root.exe"
wormlog nolog SetEnvIf Request_URI "cmd.exe" wormlog nolog
SetEnvIf Request_URI "Admin.dll" wormlog nolog
CustomLog logs/example.com-home_log common env=homelog
CustomLog logs/example.com-worm_log common env=wormlog
CustomLog logs/example.com-access_log combined env=!nolog
</VirtualHost> |
◆所有権の設定
suEXEC 環境では、CGI や SSI は指定されたユーザ権限で動作します。従って、CGI や
SSI そのものだけでなく、CGI や SSI がアクセスするディレクトリ( ロックフォルダ)や作成されるログファイル等は、全てそのユーザの所有になっていなければなりません。新規の場合は問題にはならないはずですが、既存環境から移行する場合は、前述のようなフォルダやファイルの所有者が
apache や nobody になっているはずですので、全てを対象となるユーザに所有権を変更しなければ動作しません。
おやじのコンテンツの例を以下に示します。今までは、Apache のユーザ/グループは、nobody/nobody になっていましたので、これを
oyaji/users に変更します。当然ですが、ユーザ毎に変更が必要になります。
# cd /home/oyaji/public_html # find . -user
nobody -print | xargs chown
oyaji:users |
◆パーミッションの設定
suEXEC 環境では、CGI や SSI
のファイルや関連するディレクトリ及びファイルが他のユーザからは書き込める状態では動作しません。指定されたユーザ権限で動作します。従って、CGI や
SSI そのものだけでなく、CGI や SSI がアクセスするディレクトリ(
ロックフォルダ)や作成されるログファイル等は、全てそのユーザの所有になっていなければなりません。新規の場合は、以下のようにすればよい。なお、CGI
関係以外のファイル( HTML や GIF 等)の扱いは、従来どおり "644" 等としないと見えません。suEXEC はあくまで CGI や SSI
の実行に関してのみ機能するものだからです。
- CGI ファイル: 701
- ログファイル: 600
- フォルダ(ロックフォルダ等): 701
[参考]
ユーザディレクトリやpublic_htmlディレクトリは下記のようにしてください。
- ユーザディレクトリ: 755
- public_htmlディレクトリ:
711
既存環境から移行する場合は、前述のようなフォルダやファイルが所有者以外から書き込み可能になっていると
CGI や SSI
が実行できません。従って、下記により public_html 以下のパーミッションを変更します。
# find /home/*/public_html -perm +022 | xargs chmod go-w |
■その他
その他、変更が必要となるものを以下に示します。基本的な設定は、おやじのHPの他の Apache 関係のコンテンツを参考にしてください。
Top Pageへ