Hosts Default と Virtual Hosts セクションで使えるディレクティブ (続き)

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 でロードバランスを行うという選択肢もある。

プロキシマシンのhttpd.conf
# 前略
 
# Dynamic Shared Object (DSO) Support
# このサーバはリバースプロキシ専用なので、ほとんどのモジュールは要らない。
# 以下はプロキシバランサとして必須のものだけで、これ以外にも基本モジュールが要る。
#
# キャッシュは本当は働かないので実際は不要
LoadModule cache_module /usr/lib/httpd/modules/mod_cache.so
# キャッシュは本当は働かないので実際は不要
LoadModule mem_cache_module /usr/lib/httpd/modules/mod_mem_cache.so
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
LoadModule rewrite_module /usr/lib/httpd/modules/mod_rewrite.so
 
# ここでSSL設定ファイル以外を読み込む。conf.d/ssl.confconf-ssl にリネームしておく
Include conf.d/*.conf
 
## 中略
#
# 通常のサーバ設定類がここに入る。
#
##
 
# ここからがロードバランサ設定の核心
<IfModule mod_proxy.c>
    # `ProxyVia On' や `AllowCONNECT 443' をやってはいけない。
    # ProxyRequests は必ず off に。
    ProxyRequests off
 
    RewriteEngine On
 
    # バランサマネージャインターフェイスを使えるようにする
    <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 !
 
    # `/' つまり全てのリクエストURIをバランサ仮想ワーカーにアサインする。
    # stickysession パラメータを指定すれば `...hoge.php?mysessid=xxx'
    # といったリクエストの xxx を加味して振り分け先実サーバが決定されるので、
    # 一続きのCGIセッションが別の実サーバに振り分けられてしまうことがない。
    ProxyPass / balancer://clusterflat/ \
        timeout=5 stickysession=mysessid nofailover=On
 
    # リバースプロキシとしての基本設定。Apache Doc の `mod_proxy' 参照
    ProxyPassReverse / http://real1.hoge.local/
    ProxyPassReverse / http://real2.hoge.local/
 
    # 負荷分散実サーバの指定。timeout はこちらでも設定した方がよい。
    # route パラメータで指定した文字列(ここでは実サーバのIPの第4オクテット)
    # は、stackysession で指定したURIパラメータに付加されてから実サーバへ
    # 転送される。下記 `実サーバ 1' で言えば `...hoge.php?mysessid=xxx.14'
    # というURIに合成されてから実サーバへ送られる。
    <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 mod_mem_cache.c>
        CacheEnable mem /
        CacheIgnoreHeaders Set-Cookie
        MCacheSize    40960
    </IfModule>
 
    # プロキシが実サーバへコンテンツを取りに行く時、問題になるのが、ユーザからの
    # リクエストURIの最後にあるスラッシュ。プロキシから実サーバへの要求を確実に
    # 整形するには、下記の RewriteRule を使うのが最も有効だった。
    RewriteRule ^/(.*)$ balancer://clusterflat/$1 [P]
</IfModule>
 
# ここで SSL設定ファイルをインクルードする
Include conf.d/conf-ssl
 
### Section 3: Virtual Hosts
#
<VirtualHost _default_:80>
    ServerName www.hoge.com:80
    LogLevel warn
 
    # ユーザからのリクエストヘッダにあるHOSTヘッダは実サーバへそのまま伝える。
    # ネームベースのバーチャルホストを使っている場合には必須。
    ProxyPreserveHost On
 
    ## このプロキシサーバと実サーバとの通信もSSL化したい場合(通常はそうする必要なし)
    ## には、以下をアンコメントする。同時に、SSL設定ファイル内の同様の部分もアンコメ
    ## ントし、メインブロックの `<IfModule mod_proxy.c>..</IfModule>' 内の同様の部分
    ## はコメントアウトする。
    #ProxyPass / balancer://clusterflat/ \
    #    timeout=5 stickysession=mysessid nofailover=On
    #
    #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>
    #
    #RewriteRule ^/(.*)$ balancer://clusterflat/$1 [P]
</VirtualHost>
プロキシマシンのconf.d/conf-ssl
LoadModule ssl_module /usr/lib/httpd/modules/mod_ssl.so
 
## 中略
#
# 通常のSSL設定類がここに入る
#
##
 
<VirtualHost *:443>
    ServerName www.hoge.com:443
    LogLevel warn
 
    ## 中略
    #
    # 通常の設定類がここに入る
    #
    ##
 
    # ユーザからのリクエストヘッダにあるHOSTヘッダは実サーバへそのまま伝える。
    # ネームベースのバーチャルホストを使っている場合には必須。
    ProxyPreserveHost On
 
    ## このプロキシサーバと実サーバとの通信もSSL化したい場合(通常はそうする必要はない)
    ## には、以下をアンコメントする。同時に、メイン設定ファイル内の同様の部分もアンコ
    ## メントし、メインブロックの `<IfModule mod_proxy.c>..</IfModule>' 内の同様の部分
    ## はコメントアウトする。詳しい解説はメイン設定ファイルの方を参照のこと。
    #ProxyPass / balancer://clusterssl/ \
    #    timeout=5 stickysession=mysessid nofailover=On
    #
    #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>
    #
    #RewriteRule ^/(.*)$ balancer://clusterssl/$1 [P]
</VirtualHost>

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

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

モジュール一覧

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_access クライアントの IP アドレスなどに基づいたアクセス制限。
Allow, Deny, Order
mod_actions リクエストされたファイルのタイプとメソッドに応じて特定の CGI を実行する。
Action, Script
mod_alias alias 機能によるリクエストのリダイレクト。
Alias, AliasMatch, Redirect, RedirectMatch, RedirectPermanent, RedirectTemp, ScriptAlias, ScriptAliasMatch
mod_asis Apache による HTTP ヘッダのパースを抑止し、ドキュメント自体の中に記述することを可能にする。
Set-as-isハンドラ
mod_auth プレーンテキストベースのベーシック認証。
AuthAuthoritative, AuthGroupFile, AuthUserFile
mod_auth_anon 匿名FTPのような anonymous アクセスを可能にする。
Anonymous, Anonymous_Authoritative, Anonymous_LogEmail, Anonymous_MustGiveEmail, Anonymous_NoUserID, Anonymous_VerifyEmail
mod_auth_dbm DBM データベースファイルベースのベーシック認証。
AuthDBMAuthoritative, AuthDBMGroupFile, AuthDBMType, AuthDBMUserFile
mod_auth_digest ダイジェスト認証を可能にする。
AuthDigestAlgorithm, AuthDigestDomain, AuthDigestFile, AuthDigestGroupFile, AuthDigestNcCheck, AuthDigestNonceFormat, AuthDigestNonceLifetime, AuthDigestQop, AuthDigestShmemSize
mod_auth_ldap [実験的] Ldap サーバを利用したベーシック認証。
AuthLDAPAuthoritative, AuthLDAPBindDN, AuthLDAPBindPassword, AuthLDAPCharsetConfig, AuthLDAPCompareDNOnServer, AuthLDAPDereferenceAliases, AuthLDAPEnabled, AuthLDAPFrontPageHack, AuthLDAPGroupAttribute, AuthLDAPGroupAttributeIsDN, AuthLDAPRemoteUserIsDN, AuthLDAPUrl
mod_autoindex ディレクトリの内容の一覧を生成して表示。
AddAlt, AddAltByEncoding, AddAltByType, AddDescription, AddIcon, AddIconByEncoding, AddIconByType, DefaultIcon, HeaderName, IndexIgnore, IndexOptions, IndexOrderDefault, ReadmeName
mod_cache [実験的] URI に基づいたコンテンツキャッシング。 mod_disk_cachemod_mem_cache が必要。
CacheDefaultExpire, CacheDisable, CacheEnable, CacheForceCompletion, CacheIgnoreCacheControl, CacheIgnoreHeaders, CacheIgnoreNoLastMod, CacheLastModifiedFactor, CacheMaxExpire
mod_cern_meta 標準で出力するヘッダに、外部ファイルに書かれたメタ要素を追加する。
MetaDir, MetaFiles, MetaSuffix
mod_cgi CGI 実行のための土台となる環境を提供。
application/x-httpd-cgiタイプ, MetaDir, MetaFiles, MetaSuffix
mod_cgid UNIX マルチスレッド MPM 環境用の mod_cgi
ScriptLog, ScriptLogBuffer, ScriptLogLength, ScriptSock
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 リクエストの「最後のスラッシュ」のリダイレクトと、ディレクトリのインデックスファイルを扱う機能を提供。
DirectoryIndex, DirectorySlash
mod_disk_cache [実験的] キャッシュファイルを用いたコンテンツキャッシング機能。
CacheDirLength, CacheDirLevels, CacheExpiryCheck, CacheGcClean, CacheGcDaily, CacheGcInterval, CacheGcMemUsage, CacheGcUnused, CacheMaxFileSize, CacheMinFileSize, CacheRoot, CacheSize, CacheTimeMargin
mod_dumpio [実験的] Apache の受信/送信した内容全てをログファイルへダンプ (ログ) する。
DumpIOInput, DumpIOOutput
mod_echo [実験的] Telnet で接続して文字列を送信するとエコーを返す。
ProtocolEcho
mod_env 任意の環境変数を設定できるようにする。 これらの変数は CGI と SSI で利用可能。
PassEnv, SetEnv, UnsetEnv
mod_example Apache モジュール API のデモンストレーション用。
Example
mod_expires ドキュメントの更新日時またはクライアントのアクセス時刻に基づいて相対的に、 HTTP 応答ヘッダの Expires, Cache-Control ヘッダがパースできる。
ExpiresActive, ExpiresByType, ExpiresDefault
mod_ext_filter 応答のアウトプットフィルタとして任意の外部プログラムが指定できる。
ExtFilterDefine, ExtFilterOptions
mod_file_cache [実験的] 静的な (CGI やハンドラによってパースされるのではない) ドキュメントをメモリ上にキャッシュする機能。
CacheFile, MMapFile
mod_headers 要求/応答の際の HTTP ヘッダをカスタマイズする。
Header, RequestHeader
mod_imap サーバーサイドイメージマップ (imagemap) 機能。
example-handlerハンドラ, application/x-http-imapタイプ, imap-fileハンドラ, ImapBase, ImapDefault, ImapMenu
mod_include サーバーサイドインクルード機能。
INCLUDESフィルタ, SSIEndTag, SSIErrorMsg, SSIStartTag, SSITimeFormat, SSIUndefinedEcho, XBitHack
mod_info サーバの稼働環境を一覧にしたページをパースする。
/server-infoロケーション, server-infoハンドラ, AddModuleInfo
mod_isapi [Windowsサーバ用]
ISAPIAppendLogToErrors, ISAPIAppendLogToQuery, ISAPICacheFile, ISAPIFakeAsync, ISAPILogNotSupported, ISAPIReadAheadBuffer
mod_ldap [実験的] 外部Ldapサーバを使った、コネクションとリザルトのキャッシング。
LDAPCacheEntries, LDAPCacheTTL, LDAPConnectionTimeout, LDAPOpCacheEntries, LDAPOpCacheTTL, LDAPSharedCacheFile, LDAPSharedCacheSize, LDAPTrustedCA, LDAPTrustedCAType
mod_log_config ログフォーマットのカスタマイズ。
CookieLog, CustomLog, LogFormat, TransferLog
mod_log_forensic リクエストロギングを拡張。 mod_unique_id も必要。
ForensicLog
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, NoProxy, <Proxy>, ProxyBadHeader, ProxyBlock, ProxyDomain, ProxyErrorOverride, ProxyIOBufferSize, <ProxyMatch>, ProxyMaxForwards, ProxyPass, ProxyPassReverse, ProxyPreserveHost, ProxyReceiveBufferSize, ProxyRemote, ProxyRemoteMatch, ProxyRequests, ProxyTimeout, ProxyVia
mod_proxy_connect CONNECT リクエストに対するプロキシ機能。mod_proxy も必要。
なし
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 ユーザの使用したクッキーに関する情報のロギングを可能にする。
CookieDomain, CookieExpires, CookieName, CookieStyle, CookieTracking, CustomLog/LogFormat%{cookie}n パラメータ
mod_vhost_alias 通常のバーチャルホスト動作には不要。リクエストヘッダの IP アドレスや Host: ヘッダを利用し、% 変数を使った動的バーチャルホスト定義を可能にする。
VirtualDocumentRoot, VirtualDocumentRootIP, VirtualScriptAlias, VirtualScriptAliasIP

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

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