Apacheでリバースプロキシ(mod_proxy)を活用する(1) - インストール編に続いて、今回は実際にリバースプロキシサーバを構築してみたいと思います。
まずはバックエンドのサーバを準備
リバースプロキシを構築する前に、リバースプロキシサーバからリクエストが転送されるバックエンドのアプリケーションサーバを用意しておきます。今回はUbuntuでaptからインストールできるApacheを使用します。apache2パッケージがインストールされていない場合は、まずはこれをインストールしておきましょう。
$ sudo apt-get install apache2
インストールが完了したら下記のようなアプリケーションサーバ(といってもただCGIスクリプトを動かすだけのサーバ)の設定ファイルを /etc/apache2/httpd_backend_8080.conf として用意します。
#
# /etc/apache2/httpd_backend_8080.conf
#
User www-data
Group www-data
# modules
LoadModule authn_default_module /usr/lib/apache2/modules/mod_authn_default.so
LoadModule authz_default_module /usr/lib/apache2/modules/mod_authz_default.so
LoadModule authz_host_module /usr/lib/apache2/modules/mod_authz_host.so
LoadModule cgi_module /usr/lib/apache2/modules/mod_cgi.so
LoadModule dir_module /usr/lib/apache2/modules/mod_dir.so
LoadModule mime_module /usr/lib/apache2/modules/mod_mime.so
ServerRoot "/etc/apache2"
Listen 8080
ServerName localhost:8080
PidFile /tmp/httpd_backend_8080.pid
ServerAdmin example_at_example.com
DocumentRoot "/var/www/html"
TypesConfig /etc/mime.types
LogFormat "%h %l %u %t "%r" %>s %b "%{Referer}i" "%{User-Agent}i"" combined
ErrorLog /tmp/error_8080.log
CustomLog /tmp/access_8080.log combined
UseCanonicalName Off
AddHandler cgi-script .pl
StartServers 1
MinSpareServers 1
MaxSpareServers 5
MaxClients 20
MaxRequestsPerChild 50
Options ExecCGI FollowSymLinks
AllowOverride None
設定ファイルを用意したら以下のコマンドでDocumentRootで指定したディレクトリを作成し、その下にCGIスクリプトである index.pl を用意します。
$ sudo mkdir -p /var/www/html
$ sudo chmod 755 /var/www/html
$ sudo vi /var/www/html/index.pl
#!/usr/bin/perl
use strict;
use CGI;
my $q = CGI->new;
print $q->header(
-type => 'text/html',
);
print <<"EOS";
Hello world!!
EOS
index.pl を作成したら実行権限を付与します。そしてサンプルのための画像を Apache のサイトからダウンロードして /var/www/html/httpd_logo_wide.gif として保存します。
$ sudo chmod +x /var/www/html/index.pl
$ cd /var/www/html
$ sudo wget http://httpd.apache.org/images/httpd_logo_wide.gif
これで準備が整いました。アプリケーションサーバの Apache を起動しましょう。
$ sudo /usr/sbin/apache2ctl -f /etc/apache2/httpd_backend_8080.conf -k start
起動したら http://example:8080/index.pl にアクセスして Hello world!! なページが表示されることを確認します。example のホスト名は例なので、お手持ちのマシン名に置き換えてください。これでバックエンドのサーバの設定は完了です。もし起動しない場合はエラーログが /tmp/error.log にあるので、これを確認してみてください。
リバースプロキシの準備
次は肝心のリバースプロキシの設定です。前回 /usr/local/httpd_proxy_2.2.11 にインストールしたので、/usr/local/httpd_proxy_2.2.11/conf/httpd.conf を以下のように修正します。
リバースプロキシの設定については ProxyPassReverse を使うやり方と mod_rewrite の [P] を使う2種類のやり方があると思いますが、今回は mod_rewrite でやりたいと思います。
--- httpd.conf.orig 2009-02-01 13:06:48.000000000 +0900
+++ httpd.conf 2009-02-04 22:40:14.000000000 +0900
@@ -106,7 +106,7 @@
# documents. By default, all requests are taken from this directory, but
# symbolic links and aliases may be used to point to other locations.
#
-DocumentRoot "/usr/local/httpd_proxy_2.2.11/htdocs"
+DocumentRoot "/var/www/html"
#
# Each directory to which Apache has access can be configured with respect
@@ -412,3 +412,15 @@
SSLRandomSeed startup builtin
SSLRandomSeed connect builtin
+
+
+ Options Indexes FollowSymLinks MultiViews
+ AllowOverride Indexes Limit
+ Order allow,deny
+ Allow from all
+
+
+RewriteEngine on
+RewriteRule ^/(.+).pl$ http://localhost:8080/index.pl [L,P,QSA]
+RewriteRule ^/(.+).(gif)$ /var/www/html/$1.$2 [L,QSA]
修正内容を順番に大雑把に解説すると
- DocumentRootの変更
- /var/www/htmlディレクトリの設定
- mod_rewriteによるリバースプロキシの設定
となります。詳しく見ておきたいのは3.の部分で
RewriteEngine on
というディレクティブで mod_rewrite によるURLの書き換えを有効にし
RewriteRule ^/(.+).pl$ http://localhost:8080/index.pl [L,P,QSA]
で 拡張子が .pl のファイルを先ほど設定したバックエンドのサーバに転送し
RewriteRule ^/(.+).(gif)$ /var/www/html/$1.$2 [L,QSA]
拡張子が .pl 以外の .gif ファイルはこのリバースプロキシサーバ自体が処理する、という設定になっています。つまり、index.pl 内で使用しているスタティックな画像ファイル httpd_logo_wide.gif はプロキシサーバによって処理されますが、index.pl のファイルは動的にコンテンツを生成するCGIスクリプトなので、バックエンドのアプリケーションサーバにリクエストが転送されます。
ちなみに RewriteRule で使っている L, P, QSA のようなオプションの意味ですが
- L - このルールが適用されたらそれ以降のルールは実行されない
- P - プロキシとしてURLの書き換えを行う
- QSA - URLの?以降のQUERY_STRINGを転送先のURLに常につける
という意味になります。詳しくはmod_rewrite - Apache HTTP Serverに書いてあるので参照してみてください。
動作確認
これで全ての準備が整ったので mod_proxy サーバを起動します。
$ sudo /usr/local/httpd_proxy_2.2.11/bin/apachectl -k start
そしてブラウザから http://example/index.pl にアクセスしてみましょう。Hello world!! のあとにApache のロゴが表示されているでしょうか。表示されていればリバースプロキシサーバの構築は完了ですが、念のため本当にリバースプロキシで動いているのか、アクセスログを見て確認してみましょう。リバースプロキシのログは /usr/local/httpd_proxy_2.2.11/logs/access_log にあります。
192.168.1.54 - - [05/Feb/2009:02:12:43 +0900] "GET /index.pl HTTP/1.1" 200 129
192.168.1.54 - - [05/Feb/2009:02:12:44 +0900] "GET /httpd_logo_wide.gif HTTP/1.1" 200 -
このログには上のような2つのログが出ているはずです。次にバックエンドのサーバのログを見てみます。これは /tmp/access.log にあります。
127.0.0.1 - - [05/Feb/2009:02:12:43 +0900] "GET /index.pl HTTP/1.1" 200 129 "-" "Mozilla/5.0 (Macintosh; U; Intel Mac OS X 10.5; ja-JP-mac; rv:1.9.0.5) Gecko/2008120121 Firefox/3.0.5"
こちらのログには index.plのアクセスのみで httpd_logo_wide.gif へのアクセスはないはずです。これが確認できれば mod_proxy によるリバースプロキシサーバ構築に成功ということになります。ここまで設定できれば、あとは応用で「バックエンドのサーバを2台にして運用する」ということも可能になります。次回はそういう負荷分散も視野にいれたエントリを書きたいと思います。
なお、今回記載した Apache の設定は、簡潔なサンプルであるためセキュリティ的にはよろしくありません。なので、インターネットにつながっているサーバではこの記事の内容を試す場合、動作確認後すみやかに Apache のプロセスを落としておいた方が良いかと思います。
2009/04/06: 後世のためにバックエンドの設定ファイルの名前を /etc/apache2/httpd_backend.conf から /etc/apache2/httpd_backend_8080.conf に変更しました。