Pound + Nginx ( + Rails ) 環境で SSL 通信
勤めている会社のテストサーバ群は、
このような構成にしています。んでこの環境下だと必ず Pound を通るため、http は複数列挙して名前解決すればいいけど、「証明書が必要な SSL 通信をする場合どうすんの?」となります。
ワイルドカード SSL 証明書を用意する
Pound の下にぶら下げるサーバが一台ならドメインと一致した単一の証明書で問題ないのですが、今回は複数ホストの場合です。Pound は自身にぶら下げたサーバへの誘導に、当然ですがドメインを利用します。SSL もドメインの正当性を証明します。なので、複数のサーバをぶら下げた環境下で SSL を利用しようとすれば、複数のドメインに対応した証明書が必要ですね。という訳で前置きが長かったですが、ワイルドカード証明書です。これは簡単に言っちゃうと、所属するサブドメインを全て認める SSL 証明書、となります。
例えば、*.example.com というワイルドカード SSL 証明書を取得した場合、
- e4514.example.com
- oltusoudana,example.com
- jyaken.example.com
- etcetc…
このように、サブドメイン部に相違があっても、example.com ドメインであれば汎用的に利用することが可能です。
※気をつけなければ行けないのは、例えば stg.example.com と stg.local.example.com はサブドメインの階層が違うため、*.example.com というワイルドカード証明書一枚で対応出来ない、ということです。これのお陰で僕は数万円勉強代を払いました(半ギレ)。
という訳でワイルドカード SSL 証明書を素直に用意しましょう。僕はよく、Rapid-SSL で購入しています(ドメインの公開連絡窓口に紐付いたメールアドレスが受信可能なら、購入から発行まで 5 〜 10 分位で取得できる)が、別にこれはどこのでもいいです。中間証明書 ( CA ) がどこにあるのかちゃんと教えてくれる業者で買うことぐらいが注意点でしょう!
Pound に SSL 設定を記述する
たぶんこんなん。
User "pound" Group "pound" LogLevel 1 Alive 10 Daemon 1 LogFacility local1 ListenHTTPS Address 0.0.0.0 Port 443 xHTTP 2 #Err414 "/var/www/pound/err414.html" #Err500 "/var/www/pound/err500.html" #Err501 "/var/www/pound/err501.html" #Err503 "/var/www/pound/err503.html" Cert "/usr/local/etc/ssl_certificate/YYYY/wairudoka-do_syoumeisyo.pem" AddHeader "X-Forwarded-Proto: https" HeadRemove "X-Forwarded-Proto" ### SSL ( dev.example.com ) ### Service HeadRequire "Host: dev.example.com" BackEnd Address 192.168.10.1 Port 80 TimeOut 60 End End ### SSL ( stg.example.com ) ### Service HeadRequire "Host: stg.example.com" BackEnd Address 192.168.10.10 Port 80 TimeOut 60 End End ### SSL ( vip.example.com ) ### Service HeadRequire "Host: vip.example.com" BackEnd Address 192.168.10.100 Port 80 TimeOut 60 End End End
http 側の設定も一杯書いてあるけど、今回の記事には関係ないので省きます。修正すべきところは、
- ListenHTTPS
- Cert "/usr/local/etc/ssl_certificate/YYYY/wairudoka-do_syoumeisyo.pem"
- Service
- HeadRequire "Host: vip.example.com"
- Address 192.168.10.100
このあたりす。
ListenHTTPS の Cert が参照するファイルの中には、
- crt ( 発行された SSL 証明書の中身。安いやつは大体メールでくる )
- key ( csr 作る時に使った鍵ファイル。パスワードを含ませてパスフレーズ入力なしで使えるようにしたもの )
- ca ( 中間証明書。有名な所だったらブラウザがなんとかしてくれるけど慢心せず設定、しよう! )
これらを順に書き込みます。起動失敗した時は、多分中身を書く順番が間違ってるので、入れ替えてやれば動くはず。
Service の HeadRequire には、対象のサブドメインを含めたドメイン名を(ちゃんと DNS に登録するか、自分の hosts に書いて確認できるようにしとけよしとけー)、Address には、Pound から参照出来るそのサーバのアドレスを( Pound のサーバから lynx・wget・w3m・curl なんかで、http アクセスできるアドレスならおk)それぞれ記述します。
Pound を起動する
[root@localhost ~]# cd Pound のバイナリがあるとこ [root@localhost ~]# pound -vc starting... Config file /path/to/config/pound.cfg is OK [root@localhost ~]# pound
さらっと -vc でチェックしてるし、なんで root でうごかしてんねん、みたいなツッコミはやめろ、やめろォ!
アクセスする
バックエンドのサーバと通信できてれば、https:// から始まるアドレスでドメインアクセスできるはずです、やったね。
んで、この構成というかリバースプロキシの設定というか、実際にアクセスするときの https プロトコルの通信は Pound までです。Pound が自身にぶら下げてるサーバとの通信は http を利用します。なので、本番は Nginx 単体で SSL 通信を用い、テスト用のサーバ群では Pound が SSL 通信をする、などという場合は、アプリケーションによっては、というか大体は設定が変わると思います。純粋な意味でのテストをしたい場合は、このような環境を用いるべきではないですね!とはいえこの環境だと、機能のテスト程度では十分なはずなのです!
例として Rails アプリケーションと通信する場合
Nginx に https 対応の server 句 ( listen 443 ) を書いて、SSL 証明書のファイルとか設置して、なおかつ rails アプリケーションの config/enviroments/production.rb あたりに「config.force_ssl = true」をかく必要があります。
逆に Pound に https 通信をさせる場合はこのへんはいりません、http で動作させるのと同じ Nginx の server 句 ( listen 80 ) を書いて、逆に config/enviroments/production.rb あたりに「config.force_ssl = false」もしくは「そもそも記述しない(デフォルト値が false だったはず)」とします。