B○G IPとか買うお金がなく、NIC追加したりするためのサーバ停止する機会すらなく、30分でロードバランサを構築したい場合、poundでリバースプロキシを構築すると便利です。
■■ やりたいこと
1台のリバースプロキシを、httpやhttpsアクセスの矢面に立たせる
バックエンドには、2台のhttpサーバがあり、それぞれhttpd.confベタ書きかIPベースのバーチャルホストを構築する
このコンテンツのために構築したサーバは以下の通りです。
リバースプロキシ:www.example.com 192.168.0.4 (CentOS4.6)
httpサーバ1:be1.example.com 192.168.0.120 (CentOS5.1)
httpサーバ2:be2.example.com 192.168.0.121 (CentOS5.1)
なお、www.example.comでapacheが動いている場合、192.168.0.4でhttpとhttpsをlistenしないようにします。
httpd.confで
Listen 80
となっているところを
Listen 192.168.0.3:80
のように、192.168.0.4以外のIPアドレスでlistenするようにします。
ssl.confでも、
Listen 443
となっているところを
Listen 192.168.0.3:443
とします。
■■ poundのインストール
※ ソースRPMをダウンロードして自分でビルドしてRPMパッケージを作るので、あらかじめrpm-buildをインストールし、ホームディレクトリ以下に.rpmmacrosファイルとrpm/{BUILD,RPMS,SOURCES,SPECS,SRPMS}ディレクトリを作成しておいてください。
poundの公式サイトから、パッケージをダウンロードしてきます。
ブラウザをちょっとだけスクロールすると、
・ RPMs for RedHat are available at http://www.invoca.ch/pub/packages/pound/
という文字列が見えるので、右クリックしてリンク先のURLをコピーします。
ターミナルから
$ wget http://www.invoca.ch/pub/packages/pound/pound-2.4.2-1.src.rpm
で、SRPMパッケージをダウンロードしてきます。なお、これは執筆時点での最新バージョンです。
次に、ダウンロードしてきたSRPMファイルを展開します。
$ rpm -ivh pound-2.4.2-1.src.rpm
SPECファイルを確認します。
$ cd rpm/SPECS/
$ less pound.spec
(中略)
BuildRequires: openssl-devel, pkgconfig, pcre-devel, google-perftools-devel
BuildRequires: sed, perl
と書いてあるので、openssl-devel、pkgconfig、pcre-devel、google-perftools-devel、sed、perlがインストールされているか確認します。
sedとperlは、恐らくほとんどの環境ではインストールされていると思います。
openssl-devel、pkgconfig、pcre-develはbaseリポジトリにあるので、何のオプションもなしにyumコマンドでインストールできるはずです。
google-perftools-devel は、RPM Searchから探して持って来ました。なお、google-perftools-develをインストールするには、google-perftoolsも必要になります。
$ wget ftp://ftp.pbone.net/mirror/download.fedora.redhat.com/pub/fedora/epel/4/i386/google-perftools-devel-0.92-1.el4.2.i386.rpm
(↑2行に見えますが実際は1行です)
$ wget ftp://ftp.pbone.net/mirror/download.fedora.redhat.com/pub/fedora/epel/4/i386/google-perftools-0.92-1.el4.2.i386.rpm
(↑2行に見えますが実際は1行です)
$ rpm --test -ivh google-perftools-0.92-1.el4.2.i386.rpm google-perftools-devel-0.92-1.el4.2.i386.rpm
$ su -
# rpm -ivh google-perftools-0.92-1.el4.2.i386.rpm google-perftools-devel-0.92-1.el4.2.i386.rpm
# exit
続いて、一般ユーザ「oresama」に戻ってからpoundのRPMをビルドします。
$ cd ~/rpm/SPECS/
$ rpmbuild -ba pound.spec
ビルドが終わったら、poundの依存関係を確認します。
$ cd ../RPMS/i386/
$ rpm --test -ivh pound-2.4.2-1.i386.rpm
何も問題なければ、インストールを行います。
$ su -
# cd /home/oresama/rpm/RPMS/i386/
# rpm -ivh pound-2.4.2-1.i386.rpm
■■ pound.cfgを編集する
# cd /etc/pound
# cp -p pound.cfg pound.cfg.orig
# vi pound.cfg
User "nobody"
Group "nobody"
RootJail "/usr/share/pound"
Control "/var/run/pound/ctl_socket"
# Main listening ports
ListenHTTP
#Address 0.0.0.0
#poundで待ち受けるIPアドレスを指定する。
Address 192.168.0.4
Port 80
xHTTP 1
End
ListenHTTPS
#Address 0.0.0.0
#poundで待ち受けるIPアドレスを指定する。
Address 192.168.0.4
Port 443
#秘密鍵と証明書がひとまとめになったファイルを指定する。
Cert "/usr/share/ssl/certs/pound.pem"
Ciphers "ALL:!ADH:!EXPORT56:RC4+RSA:+HIGH:+MEDIUM:+LOW:+SSLv2:+EXP:+eNULL"
xHTTP 1
End
# Catch-all server(s)
Service
BackEnd
#バックエンドで動くサーバのIPアドレスを指定する。
Address 192.168.0.120
Port 80
#優先度を1から9で指定する。数字が大きいほど優先度が高くなる。
Priority 1
End
BackEnd
Address 192.168.0.121
Port 80
Priority 1
End
Session
#セッションの保持時間を秒単位で指定する。
#ベーシック認証のほか、クッキーなども指定できるようだ。
Type BASIC
TTL 300
End
End
設定ファイルはここまで。
■■ 証明書作成
# cd /usr/share/ssl/certs/
まずはpound.pemのバックアップを取ります。
# cp -p pound.pem pound.pem.orig
# echo -n "" > pound.pem
■ 秘密鍵の生成
# openssl genrsa -des3 -out server-key.pem 1024
■ CSRの生成
# openssl req -new -key server-key.pem -out server-csr.pem
■ 秘密鍵からパスフレーズを取り除く
# cp -p server-key.pem server-key.pem.orig
# openssl req -text -noout -in server-csr.pem
■ 証明書作成
# openssl x509 -in server-csr.pem -out server-crt.pem -req -signkey server-key.pem
■ 秘密鍵と証明書をひとつのファイルにまとめる
# cat server-key.pem > pound.pem
# cat server-crt.pem >> pound.pem
■■ 起動前の確認
poundを起動する前に、poundコマンドの引数に-cをつけて、設定の確認をします。
# pound -c
starting...
Config file /etc/pound/pound.cfg is OK
このように表示されたら、設定ファイルの書式はあっています。
設定ファイルの書式が間違っていると
# pound -c
starting...
line 7: unknown directive "ListenHTTTP " - aborted
というように、設定ファイルの行番号つきで「ここ間違ってるぞ」と教えてくれます。
また、Certファイルが壊れていても
# pound -c
starting...
line 17: SSL_CTX_use_certificate_chain_file "/usr/share/ssl/certs/pound.pem" failed - aborted
error:0906D064:PEM routines:PEM_read_bio:bad base64 decode
このようにエラーが出ます。
■■ pound起動
# /etc/init.d/pound start
Starting pound: [ OK ]
■■ pound自動起動設定
# chkconfig pound --list
pound 0:off 1:off 2:off 3:off 4:off 5:off 6:off
# chkconfig pound on
# chkconfig pound --list
pound 0:off 1:off 2:on 3:on 4:on 5:on 6:off
■■ テスト
2台あるバックエンドサーバのドキュメントルートに、ちょっとずつ内容の違うhtmlファイルを、同じファイル名(ここではindex.htmlとしましょう)でアップロードします。
http://192.168.0.4/
https://192.168.0.4/
にそれぞれアクセスし、何度かリロードして、違う表示が交互に出てきたら、正しく振り分けられています。勿論、規則正しく振り分けてくれるわけではありません。
■■ 運用
poundのログは、/var/log/messagesに出力されます。ここに、アクセスログが記録されます。
バックエンドにあるapacheのアクセスログのフォーマットはデフォルトで
LogFormat "%h %l %u %t "%r" %>s %b "%{Referer}i" "%{User-Agent}i"" combined
と設定されていますが、この状態だと、poundが動いているサーバのIPアドレスが記録されてしまいます。なので、httpd.confの修正を行う必要があります。
ここを
LogFormat "%h %l %u %t "%r" %>s %b "%{Referer}i" "%{User-Agent}i"" combined
こうする
LogFormat "%{X-Forwarded-For}i %l %u %t "%r" %>s %b "%{Referer}i" "%{User-Agent}i"" combined
#LogFormat "%h %l %u %t "%r" %>s %b "%{Referer}i" "%{User-Agent}i"" combined
以上で、ごくごく簡単なロードバランサができました。
ね、簡単でしょ?