delete from hateblo.jp where 1=1;

タイトルに意味はありません。

Apache2におけるマルチユーザー環境(apache2-mpm-itkで権限分離編)

対象

  • Debian lenny
  • Apache2
  • シングルホストで複数ドメインを複数人で運営する

Debianのシステムは標準設定で十分使いやすくなっているので、さほど設定する必要はない。

動作イメージ

各ユーザーはそれぞれのLinuxユーザー権限でスクリプトを実行できるようにする。

クライアント | root権限    | 利用者権限
Request     -> Apache -> itk -> mod_php  -> *.php
Request     -> Apache -> itk -> mod_perl -> *.pl,*.cgi 
検討時のメモ
  • いい所
    • ユーザー権限で動作させることができる(webdavも!)
    • キャッシュなどの既存のモジュールを生かすことが出来る(php-apcなど)
  • 動作的問題
    • ユーザーが増えるとメモリを消費する
    • preforkの動作となる(workerではない)
      • しかしながら、1千万ヒット/日(秒間115hits?)以下なら十分に対応できる/実績があるそうだ(本家より)
    • requestがパースされるまでroot権限で動作する

基本

各種インストール(注意:パッケージが異なります)
sudo aptitude install apache2-mpm-itk
/etc/apache2/apache2.conf
KeepAliveTimeout 2

標準では15秒。2秒にする理由はアクセス数が多い場合、すぐにMaxKeepAliveRequestsに達してしまうから。
また、たくさんのコネクションを維持されると、すぐに上限になってしまうため。

/etc/apache2/conf.d/security
ServerTokens Prod
ServerSignature Off
TraceEnable Off

サーバー情報は極力隠すようにする。



ユーザー権限動作のための設定

各種インストール
sudo aptitude install libapache2-mod-perl2
sudo aptitude install libapache2-mod-php5
sudo aptitude install libapache2-mod-vhost-hash-alias
#念のため無効化 
sudo a2dismod suexec
sudo a2dismod fcgid
sudo a2dismod proxy
sudo a2dismod proxy_connect
sudo a2enmod php5
sudo a2enmod rewrite
sudo a2enmod include
sudo a2enmod vhost_alias
/etc/php5/cgi/php.ini

標準では128MBまで消費してもいいことになっているが、サーバーメモリが512しかないので、我慢の限界を念のため低くしておく。

memory_limit = 64M      ; Maximum amount of memory a script may consume (64MB)

セキュリティ的パラメータを調整

allow_call_time_pass_reference = Off
expose_php = Off
error_reporting  =  E_ALL | E_STRICT
display_errors = Off
register_long_arrays = Off
register_argc_argv = Off
magic_quotes_gpc = Off
file_uploads = Off
session.gc_divisor     = 1000
session.bug_compat_42 = 0
session.hash_function = 1

セキュリティのためのパラメータの調整を行ったとき、エラーログが何処にも表示されないため、ログに吐いてあげるようにする。

log_errors = On
error_log = php_error_logs

ユーザーの作成

ここまで煩雑な設定等は無い。
VirtualHostのためのLinuxのユーザーとグループを作る

グループを追加する
sudo addgroup --gid 500 webusers

100よりも大きくなるようにgidを設定する(100以下だとデーモン関連の権限を持つことが多いため避ける)

ユーザーを追加する
sudo adduser web1 --gid 500 --disabled-login

作ったgidを指定する

公開ディレクトリを作成する
sudo -u web1 mkdir /home/web1/public_html

VirtualHostの設定を行う

/etc/apache2/sites-available/web1

AssignUserID の設定が重要。他にMaxClientsVHostやNiceValueディレクティブがある。

<VirtualHost *:80>
       ServerName example.com
       ServerAlias *.example.com
       ServerAdmin webmaster@example.com
       #SuexecUserGroup web1 webusers
       AssignUserID web1 webusers
       VirtualDocumentRoot /home/web1/public_html/%0.0
       DocumentRoot /home/web1/public_html
       <Directory /home/web1/public_html>
               Options +ExecCGI -Indexes FollowSymLinks -MultiViews
               AllowOverride All
       </Directory>
       
       
       # Possible values include: debug, info, notice, warn, error, crit, alert, emerg.
       LogLevel warn
       ErrorLog /var/log/apache2/error.log
       CustomLog /var/log/apache2/access.log vhost_combined
</VirtualHost>

サイトを有効にし、反映する

sudo a2ensite web1
sudo /etc/init.d/apache2 reload

正しく動作しているかを確認する。

sudo /etc/init.d/apache2 status

ドメインが追加された場合は、以下のように追記する

ServerAlias example2.com
ServerAlias *.example2.com

他のユーザーが勝手にvhostを名乗ってしまうのはまずいために、暫定的にそのようにしている。
本来なら、mod-mysql-vhostとかしてあげるのがいいのだが...パッケージがないため断念。

(今のところ、10ヒット/秒ぐらいなら問題なく動作している)
oops! mod_encodingで不具合があるらしい(#519503 - [apache2-mpm-itk] EncodingEngine (mod_encoding) does not work with ITK - Debian Bug report logs)

結果

組み込みモジュール(ビルトイン)について

最終的にこんな感じになる(はず)

$ sudo apache2 -l
Compiled in modules:
  core.c
  mod_log_config.c
  mod_logio.c
  itk.c
  http_core.c
  mod_so.c
$ sudo su
# export APACHE_RUN_USER=www-data
# export APACHE_RUN_GROUP=www-data
# apache2 -M
Loaded Modules:
 core_module (static)
 log_config_module (static)
 logio_module (static)
 mpm_itk_module (static)
 http_module (static)
 so_module (static)
 alias_module (shared)
 auth_basic_module (shared)
 authn_file_module (shared)
 authz_default_module (shared)
 authz_groupfile_module (shared)
 authz_host_module (shared)
 authz_user_module (shared)
 autoindex_module (shared)
 cgi_module (shared)
 deflate_module (shared)
 dir_module (shared)
 env_module (shared)
 expires_module (shared)
 mime_module (shared)
 negotiation_module (shared)
 perl_module (shared)
 php5_module (shared)
 rewrite_module (shared)
 setenvif_module (shared)
 status_module (shared)
 vhost_alias_module (shared)
Syntax OK

参考文献