よくわかるSSLアクセラレータとapache/tomcatの連携設定

先日SSL環境下で広告の配信、計測を行おうとした際にSSLアクセラレータとapache、tomcatの連携で苦労しました。 今回はこの問題の解決方法を見つけるまでに調べたことを、順に説明します。

今回実現したいこと

SSL通信を受けた配信モジュール側(java)でSSL通信なのかどうかを判定して処理を行うようにする。

はじめに下調べ

SSLの仕組みは理解してはいましたが、まずはWeb上の情報を収集して調査してみます。 キーワード:「java SSL 判定」で検索したところ、どうやらHttpServletRequestの中のgetScheme()を呼び出せばhttpかhttpsが取得できるらしいです。

リクエスト方法の取得(getScheme)

が、しかし検証環境で実験してみたもののhttpしか取れません。ということで、現行の環境を再確認してみます。

環境の見直し

apacheは2.2、tomcatの連携にはmod_proxy_ajpを使用した一般的な構成。 そもそもSSL通信用の証明書とかのconfを見直そうとapacheの設定を漁っていたら何も設定が見つかりません。…何故でしょう?

ここで、BIG-IPの存在を思い出しました。 ロードバランサ側でSSLの処理をしているので、apacheではもう平文で送られてることがわかりました。

apache、tomcatでSSLか否かをどう判別するか

まずはapache側の設定を見直すことにしました。 Apache HTTP サーバ(バージョン 2.2)のドキュメントには以下のように書かれています。

リバースプロキシやロードバランサやSSL負荷軽減装置のような、 SSLを処理するマシンの後ろでサーバを動かす場合は、サーバが正しい自己参照 URLを確実に生成するように、 https:// スキームとクライアントが接続するポート番号を、 ServerName ディレクティブに指定してください。 Apache HTTP サーバ(バージョン 2.2)「ServerName ディレクティブ」

VirtualHostを作成し、ポートを分けることでSSLを判定します。 環境変数「HTTPS」はCGI側でSSL、non-SSLを判断したい場合の為に設定しました。


<VirtualHost *:80>
	ServerName www.hoge
	ProxyPass /hoge ajp://localhost:8009/hoge/
	SetEnv HTTPS OFF
</VirtualHost>

<VirtualHost *:443>
	ServerName https://www.hoge
	ProxyPass /hoge ajp://localhost:8443/hoge/
	SetEnv HTTPS ON
</VirtualHost>

次にtomcat側の設定です。 tomcat側にも2つのコネクタを用意します。schemeの設定により、getScheme()の値を変更できます。

Apache Tomcat Configuration Reference

server.xmlに以下のような設定を行いました。

<Connector port="8009"
	protocol="AJP/1.3"
	enableLookups="false"
	useBodyEncodingForURI="true" />

<Connector port="8443"
	protocol="AJP/1.3"
	proxyPort="443"
	redirectPort="443"
	scheme="https"
	secure="true" />

これで、完璧のはず…なのに、うまくいかず。 試しにport80の転送先を8443コネクタのほうに設定してみました。

<VirtualHost *:80>
	ServerName www.hoge
	ProxyPass /hoge ajp://localhost:8443/hoge/
	SetEnv HTTPS OFF
</VirtualHost>

これでhttpでアクセスしてみると、httpsが取得できました。 つまりapache、tomcatを分割して判定する発想は良いけれど、SSL通信時に443portでリクエストされていなかったのが原因のようでした。 BIG-IP側の設定を疑ってみると、やはり80番に送ってるみたいです。 あとはSSL通信で来た時は別portで転送してもらうよう設定すればOKです。

今回の問題を解決して

こんなわけで、なんとか問題解決はできそうな流れになりました。 ハードやミドルの環境は様々なので、思うように知りたい情報を探せずに苦労しました。 SSLアクセラレータ+apache+tomcatというパターンでの参考になれたらと思います。