Proxy Balancerの使い方

Apache 2.2 から実装されたプロキシバランサを、左図のような構図で使うことを想定する。リバースプロキシはユーザ(インターネット) からの全ての http リクエスト と https リクエストをロードバランスして実サーバ 1, 2 へ振り分ける。 https の場合は、リバースプロキシがリクエスト内容の暗号化をほどいてから実サーバ (バックエンドサーバ) に HTTPリクエストを送る。つまり SSLキーはリバースプロキシにだけ置いておけばいい。

このやりかたでは、実サーバのドキュメント空間をリバースプロキシのローカルドキュメント空間に割り付ける (概念的には alias に近い) イメージになるので、帰りのトラフィックもリバースプロキシを通る。 SSL通信の場合、実サーバからリバースプロキシへは平文でレスポンスが返され、リバースプロキシがそれを暗号化してからリクエストユーザへ返す。その点から、SSLを使う場合のプロキシサーバの仕事量は比較的重く、どちらかといえば実サーバよりもリバースプロキシのほうに立派なハードウェアを与えてやりたい。

2台の実サーバとも、各々の Apache上の ServerName には、インターネットユーザが解決可能な同一のサーバ名を設定する。もちろん、マシンとしてのホスト名は内部ネットワーク内で解決できるものでさえあればよく、例では real1.hoge.local, real2.hoge.local としている。

設定方法は、設定例のかたちで示すことにしよう。

Apacheプロキシバランサか Squid か

動的なコンテンツ (CGIなど) があるかどうかによって、どちらが適しているかは違ってくる。静的なコンテンツばかりなら、コンテンツキャッシュができるという点で Squid に優位性があるだろう。かたや、動的コンテンツがある場合には、リクエストURI に含まれるパラメータによってセッションを加味した振り分けができる Apache のプロキシバランサが優位だ。あるいは Pound という選択肢もあるようだが、Pound については筆者は未研究。

Apacheプロキシバランサと Pound はコンテンツキャッシュはできない。(もう少し正確に言うと、 Apache をプロキシバランサとして使った場合、プロキシバランサマシン自体の所持しているコンテンツはキャッシュすることも可能だが、実サーバから取ってくるコンテンツはプロキシバランサでキャッシュすることができない)。また、どうせキャッシュができないのならと割り切った上で、発想をリバースプロキシから Linuxルータに転換し、Ultra Monkey でロードバランスを行うという選択肢もある。ただし、筆者の実験では、Ultra Monkey L7 を使うとレスポンスが Apache mod_proxy_balancer より10倍以上遅かったことを申し添えておく。


プロキシマシンのhttpd.conf
# 前略
 
# Dynamic Shared Object (DSO) Support
# このサーバはリバースプロキシ専用なので、ほとんどのモジュールは要らない。
# 以下はプロキシバランサとして必須のものだけで、これ以外にも基本モジュールが要る。
#
LoadModule include_module /usr/lib/httpd/modules/mod_include.so
LoadModule headers_module /usr/lib/httpd/modules/mod_headers.so
LoadModule proxy_module /usr/lib/httpd/modules/mod_proxy.so
LoadModule proxy_http_module /usr/lib/httpd/modules/mod_proxy_http.so
LoadModule proxy_balancer_module /usr/lib/httpd/modules/mod_proxy_balancer.so
LoadModule status_module /usr/lib/httpd/modules/mod_status.so
# ロードしておいた方がよさそう
LoadModule dir_module /usr/lib/httpd/modules/mod_dir.so
 
# ここでSSL設定ファイル以外を読み込む。conf.d/ssl.confconf-ssl にリネームしておく
Include conf.d/*.conf
 
## 中略
#
# 通常のサーバ設定類がここに入る。
#
##
 
# ここからがロードバランサ設定の核心
<IfModule mod_proxy.c>
    # `ProxyVia On' や `AllowCONNECT 443' をやってはいけない。
    # ProxyRequests は必ず off に。
    ProxyRequests Off
 
    # バランサマネージャインターフェイスを使えるようにする
    <Location /balancer-manager>
        SetHandler balancer-manager
        Order allow,deny
        Allow From 127.0.0.1
    </Location>
 
    # 実サーバへ転送しないURI
    ProxyPass /manual/ !
    ProxyPass /server-status !
    ProxyPass /server-info !
    ProxyPass /balancer-manager !
 
    # 振り分けせずに常に決まった実サーバへ回したいロケーションがあれば、先に書いておく
    #ProxyPass /chome http://real1.hoge.local/chme
 
    # `/' つまり全てのリクエストURIをバランサ仮想ワーカーにアサインする。
    # stickysession パラメータを指定すれば `...hoge.php?mysessid=xxx'
    # といったリクエストの xxx を加味して振り分け先実サーバが決定されるので、
    # 一続きのCGIセッションが別の実サーバに振り分けられてしまうことがない。
    ProxyPass / balancer://clusterflat/
    ProxySet balancer://clusterflat/ \
        timeout=5 stickysession=mysessid
 
    # リバースプロキシとしての基本設定。Apache Doc の `mod_proxy' 参照
    ProxyPassReverse / http://real1.hoge.local/
    ProxyPassReverse / http://real2.hoge.local/
 
    # 負荷分散実サーバの指定。timeout はこちらでも設定した方がよい。
    <Proxy balancer://clusterflat>
        # 実サーバ 1
        BalancerMember http://real1.hoge.local \
            loadfactor=50 timeout=5 keepalive=on route=14
        # 実サーバ 2
        BalancerMember http://real2.hoge.local \
            loadfactor=50 timeout=5 keepalive=on route=15
    </Proxy>
 
    # おまけだが、実サーバのCGI処理でSSLか非SSLか判定したい場合のディレクティブ。
    # X-SSL-REQ ヘッダ (ヘッダ名は自由) には、リクエストスキームが https://
    # だった場合には `1'、そうでない場合には `0' がセットされて実サーバへ
    # 転送される。
    RequestHeader set X-SSL-REQ %{HTTPS}s
 
</IfModule>
 
# ここで SSL設定ファイルをインクルードする
Include conf.d/conf-ssl
 
### Section 3: Virtual Hosts
#
#NameVirtualHost *:80
 
<VirtualHost _default_:80>
    ServerName www.hoge.com:80
    LogLevel warn
 
    # ユーザからのリクエストヘッダにあるHOSTヘッダは実サーバへそのまま伝える。
    # ネームベースのバーチャルホストを使っている場合には必須。
    ProxyPreserveHost On
 
    ## このプロキシサーバと実サーバとの通信もSSL化したい場合(通常はそうする必要なし)
    ## には、以下をアンコメントする。同時に、SSL設定ファイル内の同様の部分もアンコメ
    ## ントし、メインブロックの `<IfModule mod_proxy.c>..</IfModule>' 内の同様の部分
    ## はコメントアウトする。
    #ProxyPass / balancer://clusterflat/
    #ProxySet balancer://clusterflat/ \
    #    timeout=5 stickysession=mysessid
    #
    #ProxyPassReverse / http://real1.hoge.local/
    #ProxyPassReverse / http://real2.hoge.local/
    #
    #<Proxy balancer://clusterflat>
    #    BalancerMember http://real1.hoge.local \
    #        loadfactor=50 timeout=5 keepalive=on route=14
    #    BalancerMember http://real2.hoge.local \
    #        loadfactor=50 timeout=5 keepalive=on route=15
    #</Proxy>
 
</VirtualHost>
プロキシマシンのconf.d/conf-ssl
LoadModule ssl_module /usr/lib/httpd/modules/mod_ssl.so
 
## 中略
#
# 通常のSSL設定類がここに入る
#
##
 
#NameVirtualHost *:443
  
<VirtualHost *:443>
    ServerName www.hoge.com:443
    LogLevel warn
 
    ## 中略
    #
    # 通常の設定類がここに入る
    #
    ##
 
    # ユーザからのリクエストヘッダにあるHOSTヘッダは実サーバへそのまま伝える。
    # ネームベースのバーチャルホストを使っている場合には必須。
    ProxyPreserveHost On
 
    ## このプロキシサーバと実サーバとの通信もSSL化したい場合(通常はそうする必要はない)
    ## には、以下をアンコメントする。同時に、メイン設定ファイル内の同様の部分もアンコ
    ## メントし、メインブロックの `<IfModule mod_proxy.c>..</IfModule>' 内の同様の部分
    ## はコメントアウトする。詳しい解説はメイン設定ファイルの方を参照のこと。
    #ProxyPass / balancer://clusterssl/
    #ProxySet balancer://clusterssl/ \
    #    timeout=5 stickysession=mysessid
    #
    #ProxyPassReverse / https://real1.hoge.local/
    #ProxyPassReverse / https://real2.hoge.local/
    #
    #<Proxy balancer://clusterssl>
    #    # 実サーバ 1
    #    BalancerMember https://real1.hoge.local:443 \
    #        loadfactor=50 timeout=5 keepalive=on route=14
    #    # 実サーバ 2
    #    BalancerMember https://real2.hoge.local:443 \
    #        loadfactor=50 timeout=5 keepalive=on route=15
    #</Proxy>
 
</VirtualHost>

ProxySet は、ProxyPass に渡すオプションを別途指定するディレクティブ。
`ProxyPass / balancer://clusterflat/ timeout=5 ...'
といった具合に直接 ProxyPass の引数でセットしてもいいのだが、各所でオプションを上書きする場合にはオプションは ProxySet でセットする方が妥当な気がする。あくまでも主観だが。stickysession= の引数は大文字小文字を区別する。もし、リクエストの Cookieヘッダの時は大文字、GETメソッド等でURIのクエリに直接指定する時は小文字という風に異なるなら、stickysession=MYSESSID|mysessid と書けば、バーティカルバーの前がクッキー時、後が直接指定時という解釈になる。

また、Apache 2.2.12 からは、ProxyPassReverse ディレクティブが、バランサメンバを認識するようになった。つまり、ProxyPassReverse をバックエンドサーバの数だけ書く必要がなくなった。よって、その部分は下記のように書くこともできる。少なくとも BalancerMemberhttp://... である場合は問題なく動いた。ただしバックエンドのプロトコルが ajp://... だったりすると動かないという報告もある。

ProxyPass / balancer://clusterflat/
ProxySet balancer://clusterflat/ \
  timeout=5 stickysession=mysessid
 
ProxyPassReverse / http://real1.hoge.local/
ProxyPassReverse / http://real2.hoge.local/
 
<Proxy balancer://clusterflat>
    BalancerMember http://real1.hoge.local \
      loadfactor=50 timeout=5 keepalive=on route=14
    BalancerMember http://real2.hoge.local \
      loadfactor=50 timeout=5 keepalive=on route=15
</Proxy>
 
ProxyPassReverse / balancer://clusterflat/

BalancerMemberroute=xxx は、ロードバランスを機能させるためには事実上必須。というより、Proxy Balancer にとって、ドットより前のセッションID自体はどうでもよく、ドット以降こそが重要なのだ。例のように route=14 とした場合、mod_proxy_balancer は、(StickySession=mysessid だとすると) Webアプリケーションが mysessid=abcdabcdabcd.14 というようなクッキーをクライアントへ発行すること要求する。あらかじめ、Webアプリケーション(例えばPHPやPerl CGI) の方で、それに合わせた実装をしておかなければならない。言うまでもないが、もう一方のバックエンドアプリが発行すべきクッキーは cdefcdefcdef.15 といった具合。ただし、そこがままならない場合もある - Javaアプリケーションサーバがその典型だ。苦肉の策で mod_headers で補完する手 (コラム参照) もある。

複数のドメインを VirtualHost でホスティングしていて、それぞれにバランサの設定 (振り分け割合や stickysession などのパラメータ) を変えたい場合は、バランサを直接仕切るディレクティブと (入れるのであれば) 関連の RewriteRule は各 <VirtualHost> セクション内に書き、グローバルセクションからは削除する。その際には、conf-ssl<VirtualHost> セクション内にも書かなければならない。balancer定義名は VirtualHost 毎に変えた方が気持ちがいい - 例えば非SSLの VirtualHost ひとつ目で clusterflat にしたなら、2つ目の非SSL VirtualHost では clusterflatdeux にするといった具合だ。

cache_module などをロードしてコンテンツキャッシュを効かせる設定も試みたが、無駄だった。プロキシサーバ自体にあるコンテンツは確かにキャッシュされたが、実サーバから得たコンテンツはキャッシュされなかった。

記述としては些細でありながら重大な落とし穴となるのが、パスの最後のスラッシュの有無だ。基本的に、マッピング先とマッピング元は、スラッシュの有無をそろえないといけない。例えば、

悪い例:

# 前略
... 
# Dynamic Shared Object (DSO) Support
#
...
LoadModule rewrite_module /usr/lib/httpd/modules/mod_rewrite.so
 
## 中略
...
<IfModule mod_proxy.c>
    ProxyRequests Off
 
    RewriteEngine On
 
    ## 中略
    ... 
    <Proxy balancer://clusterflat/>
        # 実サーバ 1
        BalancerMember http://real1.hoge.local \
            loadfactor=50 timeout=5 keepalive=on route=14
        # 実サーバ 2
        BalancerMember http://real2.hoge.local \
            loadfactor=50 timeout=5 keepalive=on route=15
    </Proxy>
 
    RewriteRule ^/(.*)$ balancer://clusterflat/$1 [P]
</IfModule>

このように <Proxy> ブロックのロケーションと BalancerMember の URI とでスラッシュの有無が食い違っていると、クライアントからのリクエストURI の最後に "/" が付いていた場合に実サーバからコンテンツが取ってこれない。RewriteRule による補正でなんとか動作が成り立つが、正しく書けばこんな小細工は不要なのだった。

route判定用クッキーをApache側でくっつける

Oracle Fusion系のJavaアプリケーションサーバをバックエンドにしようとした時、クッキーのフォーマットが自由に設定できなくて困った。JSESSIONID はこんなフォーマットだ。

nzrZ3pm42MWToGb7GZ4vcPWU26O-n7B3dxXYIuNKXTa_1b114EVw!-828310230

"!"の後ろに続く文字列が、その時実行されている java インスタンスのIDであることが分かった。しかし、Apache 2.2.x では、セッションID と route 要素との区切りがドットであることはハードコードされていて変更できない。Apacheでレスポンスヘッダをいじれば何とかなるかなぁ、といろいろ調べていたら、そのものズバリの解決策があった。Bugzilla 42513 から辿った Load balancing with appservers who set a bad sticky cookie という記事だ。上で想定している環境を土台にすると、こうなる。

...前略
LoadModule headers_module modules/mod_headers.so
...中略
 
<IfModule mod_proxy.c>
...中略

    ProxyPass / balancer://clusterflat/
    ProxySet balancer://clusterflat/ \
        timeout=5 stickysession=SESSROUTE scolonpathdelim=On
 
    <Proxy balancer://clusterflat>
        BalancerMember http://real1.hoge.local:7003 \
            loadfactor=50 timeout=5 keepalive=on route=14
        BalancerMember http://real2.hoge.local:7003 \
            loadfactor=50 timeout=5 keepalive=on route=15
    </Proxy>
 
    ProxyPassReverse / balancer://clusterflat/
 
    Header add Set-Cookie "SESSROUTE=session.%{BALANCER_WORKER_ROUTE}e; path=/" env=BALANCER_ROUTE_CHANGED
</IfModule>

stickysession には本来のクッキーである JSESSIONID でなく、新たな別のクッキー名(名前は任意)を勝手に書く。上に挙げた元記事を真似して書くとシナリオは以下のようになる;

  1. 最初のアクセスではまだクライアントブラウザが何のクッキーも持っていないので、mod_proxy_balancer はHTTPリクエストから SESSROUTE クッキーが読み取れない。よって、Apache上では環境変数 BALANCER_ROUTE_CHANGED が設定される。この環境変数は、mod_proxy_balancerのマニュアルに書いてあるように、その時 balancer の選択したバックエンドの route値 (これは環境変数 BALANCER_WORKER_ROUTE へ設定される) と、SESSROUTE の値 (=null) が食い違っている時 "1" に設定される。
  2. Apacheがバックエンドからレスポンスを読み取ってユーザへ返す直前で、mod_headers が、env=BALANCER_ROUTE_CHANGED が正なのでレスポンスヘッダに SESSROUTE クッキーを加える。クライアントブラウザにクッキーがセットされる。
  3. そのクライアントからの次のリクエストヘッダには (本来のJSESSIONIDクッキーとともに) このクッキーが載っている。今度は SESSROUTE クッキーと BALANCER_WORKER_ROUTE が合致しているので BALANCER_ROUTE_CHANGED は非定義となる。よって、バックエンドが何らかの理由でフェイルオーバーしない限り SESSROUTE クッキーは再発行されず、後続のリクエストは同じバックエンドへ固定される。

上の例では SESSROUTE は例えば "session.14; path=/" という値になるが、実際のところ"session"のところは"sess"でも"sticky"でも何でも構わない、どころか、何もなしにいきなりドットで始めても問題ない。ちなみに scolonpathdelim=On は、クッキーの path情報をクッキーの値の後にセミコロンで区切って記載してくるというJavaアプリケーションサーバ (Tomcatもそうらしい) の仕様を mod_proxy_balancer に伝えるためのものだ。ソースの mod_proxy_balancer.c を覗くと、通常は "&?" となっている区切り文字が、scolonpathdelim=On にすると ";&?" に変わるようだ。

ここに辿り着くまでには、SetEnvIfRewriteRule を使って本来の JSESSIONID クッキーからインスタンスIDを切り出して SESSROUTE クッキーを設定するということをやった。後から述べる理由で実用には堪えないが、何か別の時に応用できるかもしれないので載せておく。

...前略
LoadModule headers_module modules/mod_headers.so
LoadModule rewrite_module modules/mod_rewrite.so
...中略
 
# リクエストのCookieヘッダから"!"以降の数字部だけを取り出して(ヒットすれば)環境変数SESS_ROUTEに投入する
SetEnvIf Cookie "JSESSIONID=[^!;[:blank:]]+!-?([0-9]+)" SESS_ROUTE=$1
 
<IfModule mod_rewrite.c>
# セッションIDを"http://url?jsessionid=...."のようにリクエストボディ自体に載せてきた場合への対処。クッキーもある時はこちらを勝たせる。
    RewriteEngine On
    #RewriteLog logs/rewrite_log
    #RewriteLogLevel 9
    # QUERY_STRINGはSetEnvIfでは読み取れないためmod_rewriteのENV設定アクションを利用
    RewriteCond %{QUERY_STRING} jsessionid=[^!;[:blank:]]+!-?([0-9]+) [NC]
    RewriteRule .* - [E=SESS_ROUTE:%1]
</IfModule>
 
<IfModule mod_proxy.c>
...中略

    ProxyPass / balancer://clusterflat/
    ProxySet balancer://clusterflat/ \
        timeout=5 stickysession=SESSROUTE scolonpathdelim=On
 
    <Proxy balancer://clusterflat>
        BalancerMember http://real1.hoge.local:7003 \
            loadfactor=50 timeout=5 keepalive=on route=828310230
        BalancerMember http://real2.hoge.local:7003 \
            loadfactor=50 timeout=5 keepalive=on route=1152481115
    </Proxy>
 
    ProxyPassReverse / balancer://clusterflat/
 
    Header add Set-Cookie "SESSROUTE=session.%{SESS_ROUTE}e; path=/" env=BALANCER_ROUTE_CHANGED
</IfModule>

このやり方は、Apacheがレスポンスから環境変数や別クッキーを作れないという機能的制約のために、クライアントのクッキーとrouteが一致するまで 3サイクルかかる。

WebLogicの場合、ご丁寧にも、インスタンスIDが"-"で始まる時がある。やってみたところ、route=-123456 と指定するとバランサが機能しなかった。正規表現で頭のダッシュを除外して取り込んでいるのはそのためだ。route値に使えない文字があることを確かどこかで読んだような記憶があるのだが二度と見つけられない。

実際にこの手を使うとすれば、JSESSIONID のインスタンスID部はJVMを再起動する度に変化してしまうので、例えば WebLogic Server なら JVMの起動オプションに -Dweblogic.servlet.useExtendedSessionFormat=true を加えて JSESSIONIDホストIDという固定の値が追加されるようにしておく必要がある。それに合わせて、最初の SetEnvIf の正規表現フィルタも、このホストID部がバックリファレンス "$1" に入るように少し調整しなければならない。

%{BALANCER_WORKER_ROUTE}e を使う場合にしろ SetEnvIf を使う場合にしろ、これらクッキー追加方式のもうひとつの問題点は、たとえアプリケーションサーバ側で JSESSIONID に期限 (Expires属性やMax-Age属性) を設けたとしても、それを無視してバックエンドが固定され続けてしまうことだろう。さらに言えば、前者を使うと、バックエンドが JSESSIONIDクッキーを発行しようがしまいが SESSROUTE クッキーが設定され、ラウンドロビンすべき時も振り分け先が固定されてしまう。

奥の手 - ResponseSetEnvIfPlus

で、奥の手を発見した。SetEnvIf をレスポンスに対しても使えるように拡張する。正確には setenvif モジュールを置き換えるわけでなく、mod_setenvifplus というモジュールを追加インストールするのだ。ついでに、SetEnvIf でリクエストのクエリストリングも扱えるようになり願ったり適ったりである。コンパイルするには apxs が必要。RHEL/CentOSの場合、apxs (/usr/sbin/apxs) は httpd-devel パッケージに含まれる。mod_setenvifplus-x.x.src.tar.gz をダウンロードしたら、

# tar xzvf mod_setenvifplus-x.x.src.tar.gz
# cd mod_setenvifplus-x.x/apache2
# vim Makefile.in
<"SH_LDFLAGS += -lcrypto"という行のコメントマークを外す>
# apxs -c -i -a mod_setenvifplus.c

httpd.conf はこのようになる。注意だが、

  1. mod_setenvifplus は内部で mod_ssl を必要とするようなので、先に mod_ssl をロードしないとエラーとなり httpd が立ち上がらない。
  2. ResponseSetEnvIfPlus<Directory(Match)><Location(Match)> ブロックの中でしか機能しない。そうでないとやはり起動を拒否する。レスポンスに関する処理は Apache の処理の流れの中ではかなり後の方で行われるが、setenvifplus はコードの単純化のためかこれによって処理ステージを調整しているのだろう。
...前略
LoadModule headers_module modules/mod_headers.so
LoadModule ssl_module modules/mod_ssl.so
LoadModule setenvifplus_module modules/mod_setenvifplus.so
...中略
 
# レスポンスのSet-Cookieヘッダから"!"以降の数字部だけを取り出して(ヒットすれば)環境変数SESS_ROUTEに投入する
<Location />
    ResponseSetEnvIfPlus Set-Cookie "JSESSIONID=[^!;[:blank:]]+!-?([0-9]+)" SESS_ROUTE=$1
</Location>
 
<IfModule mod_proxy.c>
...中略

    ProxyPass / balancer://clusterflat/
    ProxySet balancer://clusterflat/ \
        timeout=5 stickysession=SESSROUTE scolonpathdelim=On
 
    <Proxy balancer://clusterflat>
        BalancerMember http://real1.hoge.local:7003 \
            loadfactor=50 timeout=5 keepalive=on route=828310230
        BalancerMember http://real2.hoge.local:7003 \
            loadfactor=50 timeout=5 keepalive=on route=1152481115
    </Proxy>
 
    ProxyPassReverse / balancer://clusterflat/
 
    Header add Set-Cookie "SESSROUTE=session.%{SESS_ROUTE}e; path=/" env=BALANCER_ROUTE_CHANGED
</IfModule>

これで、レスポンスに "Set-Cookie: JSESSIONID" ヘッダがあり、且つ振り分け先が切り替わった時 (あるいは初回アクセス時) だけ、しかも JSESSIONID クッキーと同じタイミングで SESSROUTE クッキーが追加される。メデタシメデタシ。バックエンドからレスポンスを採った後に処理が差し挟まれるため処理速度に影響が出る可能性は否定できないが、測ってはいないので分からない。

なお、同じJavaアプリケーションサーバでも Tomcat では、server.xmljvmRouteパラメータで route値を指定すれば、ドット区切りで JSESSIONID に付加されるらしいので、こんな手管は不要。また、Apache 2.4.4 以降の mod_proxy では、route のデリミタをドット以外のものに変更できる stickysessionsep パラメータが使えるようになっている。


ファイル/ディレクトリのパーミション設定

以下で指すユーザディレクトリは、 UserDir ディレクティブによる開放の場合だけでなく、 alias ディレクティブなどで開放する DocumentRoot 外のディレクトリも同様。Apache が当該のディレクトリにアクセスできるようにするには、ルートフォルダ / から当該のディレクトリに至る途中のディレクトリも、少なくとも実行ビットが立っていなくてはならない。パーミションそのものに関する考察はこちら。 Apache はユーザ apache、グループ apache で動かしているものとする。

必要なモジュール、要らないモジュール

不要なモジュールをロードから外すための参考となるよう、各モジュールの役割を一覧にした。通常最低限必要と思われるモジュールはセルをブルーにした。デフォルトの httpd.conf でいかにたくさんの無用なモジュールがロードされているかが分かる。もちろんサーバの運用方法によって事情は全く異なるので、設定ファイル内で実際に使っているディレクティブを確認しながら慎重に絞り込まなければならない。必要なものまで削ってしまうと、かえってセキュリティや安定性を落とすおそれもある。

Apache 2.2系

`auth' 系のモジュールは、2.0系とは違って auth_*, authn_*, authz_* の 3種類に別れた。authn_* の n は Authentication (「認証」と訳される) であり「アクセス者の身元を確認するため」のモジュール、authz_* の z は Authorization (「承認」) であり「誰がどこへアクセスできるかを決定するため」のモジュール。auth_* はそれら n や z を利用して実際のアクションを行うフロントエンドとなっている。

水色のセルは、最低限必要と思われるモジュール。
Apache 2.0系のモジュール一覧は別ファイルへ引退させた。

mod_ A B C D E F G H I J K L M N O P Q R S T U V W X Y Z

モジュール 機能概要
関連ディレクティブ
mod_actions リクエストされたファイルタイプやメソッドに応じて特定の CGI を実行する。
Action, Script
mod_alias alias 機能によるリクエストのリダイレクト。
Alias, AliasMatch, Redirect, RedirectMatch, RedirectPermanent, RedirectTemp, ScriptAlias, ScriptAliasMatch
mod_asis Apache による HTTP ヘッダのパースを抑止し、ヘッダを含むドキュメントをそのまま送信する。
send-as-isハンドラ
mod_auth_basic HTTPベーシック認証の基本フロントエンド。
AuthName, AuthType, Require, Satisfy
mod_auth_digest HTTPダイジェスト認証の基本フロントエンド。
AuthDigestAlgorithm, AuthDigestDomain, AuthDigestNcCheck, AuthDigestNonceFormat, AuthDigestNonceLifetime, AuthDigestProvider, AuthDigestQop, AuthDigestShmemSize
mod_authn_alias 認証設定を組み合わせたプリセットグループ作成しておき、それを別名で簡便に使えるようにする。
<AuthnProviderAlias>
mod_authn_anon 匿名FTPのようなアノニマス認証を提供するプロバイダ。
Anonymous, Anonymous_LogEmail, Anonymous_MustGiveEmail, Anonymous_NoUserID, Anonymous_VerifyEmail
mod_authn_dbm DBMファイルを使用した認証を提供するプロバイダ。
AuthDBMType, AuthDBMUserFile
mod_authn_default mod_auth_basic など他の認証モジュールが設定されていない場合に全ての認証を拒否する。
AuthDefaultAuthoritative
mod_authn_file プレインテキストファイル(htpasswdで作成)を使用した認証を提供するプロバイダ。
AuthUserFile
mod_authnz_ldap HTTPベーシック認証でLDAPを使用できるようにする。
AuthLDAPBindAuthoritative, AuthLDAPBindDN, AuthLDAPBindPassword, AuthLDAPUrl, AuthzLDAPAuthoritative ...etc.
mod_authz_dbm DBMファイルに基づいたグループベースでのアクセス制御。
AuthDBMGroupFile, AuthzDBMAuthoritative, AuthzDBMType
mod_authz_default mod_authz_user など他のアクセス制御モジュールが設定されていない場合に全ての承認を拒否する。
AuthzDefaultAuthoritative
mod_authz_groupfile プレインテキストファイルに基づいたグループベースのアクセス制御を提供。
AuthGroupFile, AuthzGroupFileAuthoritative
mod_authz_host ホスト名やIPアドレスに基づいたアクセス制御。2.0系での mod_access にあたる。
Allow, Deny, Order
mod_authz_owner HTTP上でのユーザ名と、アクセス先ファイルのOS上での所有ユーザや所有グループが一致するかどうかによりアクセスを制御。明示的に使われることは少ないが、デフォルトが不許可となるようロードすべき
`require file-owner', `require file-group', AuthzOwnerAuthoritative
mod_authz_user ユーザ名に基づくアクセス制御。
`Require user', AuthzUserAuthoritative
mod_autoindex ディレクトリの内容の一覧を生成して表示。
`Options indexes', AddAlt, AddAltByEncoding, AddAltByType, AddDescription, AddIcon, AddIconByEncoding, AddIconByType, DefaultIcon, HeaderName, IndexIgnore, IndexOptions, IndexOrderDefault, IndexStyleSheet, ReadmeName
mod_cache URI に基づいたコンテンツキャッシング。 mod_disk_cachemod_mem_cache が必要。
CacheDefaultExpire, CacheDisable, CacheEnable, CacheIgnoreCacheControl, CacheIgnoreHeaders, CacheIgnoreNoLastMod, CacheLastModifiedFactor, CacheMaxExpire ...etc.
mod_cern_meta 標準で出力するヘッダに、外部ファイルに書かれたメタ要素を追加する。
MetaDir, MetaFiles, MetaSuffix
mod_cgi CGI 実行のための土台となる環境を提供。
application/x-httpd-cgiタイプ, cgi-scriptハンドラ, `Options ExecCGI', ScriptLog, ScriptLogBuffer, ScriptLogLength
mod_cgid 外部CGIデーモンを使ったCGIスクリプトの実行。UNIXで、httpdのMPMがマルチスレッド(つまりprefork以外)の場合は、mod_cgi の代わりにこちらを使うべし。
ScriptSock ...あとは mod_cgi と同じ
mod_charset_lite コンテナ (<Directory><Files> などで囲ったブロック) 毎に、どんなキャラクターコードで書かれているかやどんなキャラクターコードに変換して送り出したいかを Apache に伝え、レスポンスボディを変換してから送信する。
CharsetDefault, CharsetOptions, CharsetSourceEnc
mod_dav WEB DAV。 mod_dav_fs も必要。
Dav, DavDepthInfinity, DavMinTimeout
mod_dav_fs WEB DAV。 mod_dav も必要。
DavLockDB
mod_deflate サーバからの出力を圧縮してから送り出す。また、圧縮されて送られてきた要求を解凍する。
DEFLATEフィルタ, DeflateBufferSize, DeflateCompressionLevel, DeflateFilterNote, DeflateMemLevel, DeflateWindowSize
mod_dir リクエストされたURLがディレクトリだが末尾に / がなかった場合に自動的に / を加える。また、ディレクトリのインデックスファイルを扱う機能を提供。
DirectoryIndex, DirectorySlash, FallbackResource
mod_disk_cache キャッシュファイルを用いたコンテンツキャッシング機能。mod_cache と併せて使用。
CacheDirLength, CacheDirLevels, CacheMaxFileSize, CacheMinFileSize, CacheRoot
mod_dumpio [デバグ用] Apache の受信/送信した内容全てをログファイルへ出力する。
DumpIOInput, DumpIOOutput, DumpIOLogLevel
mod_echo [実験的] Telnet で接続して文字列を送信するとエコーを返す。
ProtocolEcho
mod_env 任意の環境変数を設定できるようにする。 これらの変数は CGI と SSI で利用可能。
PassEnv, SetEnv, UnsetEnv
mod_example [実験的] Apache モジュール API のデモンストレーション用。
example-handlerハンドラ, Example
mod_expires ドキュメントの更新日時またはクライアントのアクセス時刻に基づいて相対的に、 HTTP 応答ヘッダの Expires, Cache-Control ヘッダがパースできる。
ExpiresActive, ExpiresByType, ExpiresDefault
mod_ext_filter 応答のアウトプットフィルタとして任意の外部プログラムが指定できる。
ExtFilterDefine, ExtFilterOptions
mod_file_cache [実験的] 静的なドキュメントファイルをあらかじめメモリ上にロードしておくことによりレスポンスを加速。mod_cache系とは別物。
CacheFile, MMapFile
mod_headers 要求/応答の際の HTTP ヘッダをカスタマイズする。
Header, RequestHeader
mod_imagemap サーバーサイドイメージマップ (imagemap) 機能。Apache2.0系での mod_imap から改名。
application/x-http-imapタイプ, imap-fileハンドラ, ImapBase, ImapDefault, ImapMenu
mod_include サーバーサイドインクルード機能。デフォルトのエラー応答ページで使用されている。
`Options Includes', INCLUDESフィルタ, SSIEnableAccess, SSIEndTag, SSIErrorMsg, SSIETag, SSILastModified, SSIStartTag, SSITimeFormat, SSIUndefinedEcho, XBitHack
mod_info サーバの稼働環境を一覧にしたページをパースする。
/server-infoロケーション, server-infoハンドラ, AddModuleInfo
mod_isapi [Windowsサーバ用]
ISAPIAppendLogToErrors, ISAPIAppendLogToQuery, ISAPICacheFile, ISAPIFakeAsync, ISAPILogNotSupported, ISAPIReadAheadBuffer
mod_ldap [実験的] 外部Ldapサーバを使った、コネクションとリザルトのキャッシング。
LDAPCacheEntries, LDAPConnectionTimeout, LDAPOpCacheEntries, LDAPSharedCacheFile, LDAPSharedCacheSize, LDAPTrustedClientCert, LDAPTrustedGlobalCert ...etc.
mod_log_config ログフォーマットのカスタマイズ。
BufferedLogs, CookieLog, CustomLog, LogFormat, TransferLog
mod_log_forensic リクエストロギングを拡張。 mod_unique_id も必要。
ForensicLog, CustomLog/LogFormat%{forensic-id}n パラメータ
mod_logio リクエストの入出力バイト数のロギングを可能にする。 mod_log_config も必要。
なし (CustomLog, LogFormat)
mod_mem_cache 動的コンテンツも含め、コンテンツをメモリ上にキャッシュ。 mod_cache も必要。
MCacheMaxObjectCount, MCacheMaxObjectSize, MCacheMaxStreamingBuffer, MCacheMinObjectSize, MCacheRemovalAlgorithm, MCacheSize
mod_mime 拡張子に対する、ハンドラとフィルタ、MIME タイプ、言語、文字セット、エンコーディングを関連付け。
AddCharset, AddEncoding, AddHandler, AddInputFilter, AddLanguage, AddOutputFilter, AddType, DefaultLanguage, ModMimeUsePathInfo, MultiviewsMatch, RemoveCharset, RemoveEncoding, RemoveHandler, RemoveInputFilter, RemoveLanguage, RemoveOutputFilter, RemoveType, TypesConfig
mod_mime_magic mod_mime が拡張子から MIME タイプを判断できなかった場合に、ファイルの内容から判断する。
MimeMagicFile
mod_negotiation コンテントネゴシエーション。
type-mapハンドラ, MultiViewsオプション, CacheNegotiatedDocs, ForceLanguagePriority, LanguagePriority
mod_nw_ssl [NetWare]
NWSSLTrustedCerts, NWSSLUpgradeable, SecureListen
mod_proxy HTTP 1.1 プロキシ/ゲートウェイサーバ。
AllowCONNECT, BalancerMember, NoProxy, <Proxy>, ProxyBadHeader, ProxyBlock, ProxyDomain, ProxyErrorOverride, ProxyFtpDirCharset, ProxyIOBufferSize, <ProxyMatch>, ProxyMaxForwards, ProxyPass, ProxyPassInterpolateEnv, ProxyPassMatch, ProxyPassReverse, ProxyPassReverseCookieDomain, ProxyPassReverseCookiePath, ProxyPreserveHost, ProxyReceiveBufferSize, ProxyRemote, ProxyRemoteMatch, ProxyRequests, ProxySet, ProxyStatus, ProxyTimeout, ProxyVia
mod_proxy_ajp mod_proxy でAJP (Aapache JServ Protocol) を使用できるように拡張する。 mod_proxy も必要。
なし
mod_proxy_balancer mod_proxy を利用したロードバランサ。mod_proxy も必要。
前項「Proxy Balancerの使い方」参照
mod_proxy_connect CONNECT リクエストに対するプロキシ機能。mod_proxy も必要。
AllowCONNECT
mod_proxy_ftp FTP リクエストに対するプロキシ機能。mod_proxy も必要。
なし
mod_proxy_http HTTP リクエストに対するプロキシ機能。mod_proxy も必要。
なし
mod_rewrite リクエストされた URL 文字列をルールに従って書き換える。
RewriteBase, RewriteCond, RewriteEngine, RewriteLock, RewriteLog, RewriteLogLevel, RewriteMap, RewriteOptions, RewriteRule
mod_setenvif リクエストの特徴に応じて環境変数を設定。
BrowserMatch, BrowserMatchNoCase, SetEnvIf, SetEnvIfNoCase
mod_so 動的共有モジュール (DSO) のロード。
LoadFile, LoadModule
mod_speling リクエストされた URL の綴り間違いを自動修正 (ただし大文字小文字の違い及び 1 文字の間違いまで)
CheckSpelling
mod_ssl SSL/TSL コネクション機能。
SSLEngine, SSLMutex, SSLOptions など `SSL' で始まるディレクティブ
mod_status サーバのステータスを一覧にしたページをパースする。
/server-statusロケーション, server-statusハンドラ, ExtendedStatus
mod_suexec CGI を、指定したユーザとグループの権限で実行する。
SuexecUserGroup
mod_unique_id 各リクエストに対して、環境変数 UNIQUE_ID に一意な識別名を設定する。mod_log_forensic に必要。
なし (ForensicLog)
mod_userdir ユーザのホームディレクトリにある WEB フォルダを ~/ ロケーションにマッピングする。
UserDir
mod_usertrack ユーザの使用したクッキーに関する情報のロギングを可能にする。昔は mod_cookies と呼ばれていた。
CookieDomain, CookieExpires, CookieName, CookieStyle, CookieTracking, CustomLog/LogFormat%{cookie}n パラメータ
mod_version 複数のバージョンの httpd サーバを稼働させている場合にバージョンによって挙動を変える。
<IfVersion>
mod_vhost_alias 通常のバーチャルホスト動作には不要。リクエストヘッダの IP アドレスや Host: ヘッダを利用し、% 変数を使った動的バーチャルホスト定義を可能にする。
VirtualDocumentRoot, VirtualDocumentRootIP, VirtualScriptAlias, VirtualScriptAliasIP