結論
以下のように設定すると、secretを使ってApache HTTP Server(Apache)とTomcatを通信させることができます。
- Apacheの設定
ProxyPass / ajp://tomcat:8009/ secret=YOUR_PASSWORD
ProxyPassReverse / ajp://tomcat:8009/ secret=YOUR_PASSWORD
httpd.conf
内で読み込んでいる、他のconfファイルに記述しても問題ありません。
- Tomcatの設定
<Connector protocol="AJP/1.3"
address="0.0.0.0"
port="8009"
redirectPort="8443"
secret="YOUR_PASSWORD" />
address
はTomcatへのリクエストを許可する接続元IPです。デフォルトでは同一マシンからのアクセスのみ許可されています。0.0.0.0
はすべてのホストからのアクセスを許可するという意味です。
はじめに
CVE-2020-1938の発覚により、Tomcat9では9.0.31以降からAJPでの通信をするためにはTomcat側で初期設定が必要となりました。
一般にHTTPよりもAJPで通信するほうが高速である(参考:Tomcatハンドブック)ため、AJPを使い続けたいという考えはあると思います。信頼できないAJP通信を防ぐことができれば良いので、AJPを安全に使い続ける手段はいくつか考えられます。
- AJPコネクタへの接続元IPを限定する
- アクセス制限はファイアウォール等の別ソフトに任せる
- AJPコネクタにsecretを設定する(Apache 2.4.42以降のみ)
接続元IPを限定するのは、やや面倒です。基本的に固定値で設定することになるため、リバースプロキシのIPアドレスが変わると設定し直すことになります。リバースプロキシとTomcatが常に同一マシン上にあるならば127.0.0.1
を設定すればよいのですが、サービス同士の結合を疎にするために別ホストで動かしたい場合もあるでしょう。
ファイアウォール等を利用するという手段も、ApacheとTomcatで完結しなくなってしまうので面倒です。
そこで本記事では、接続元IPは制限せずTomcatのAJPコネクタにsecretを設定することで、AJPを安全に使用する方法を紹介します。
環境
- CentOS Linux release 7.8.2003
- Apache HTTP Server 2.4.43
- Apache Tomcat 9.0.34
設定
1.Apacheのmod_proxy
モジュールとmod_ajp
モジュールを使えるようにする
/etc/httpd/conf.modules.d/00-proxy.conf
の以下2モジュールが有効であることを確認します。
デフォルトで外れていると思いますが、もし先頭に#がついていたら外してください。
LoadModule proxy_module modules/mod_proxy.so
LoadModule proxy_ajp_module modules/mod_proxy_ajp.so
2. ApacheのProxyPass
、ProxyPassReverse
ディレクティブにsecretを設定する
httpd.conf
を直接編集してもよいですが、基本的に独自設定はconf.d/
以下にconfファイルを作成して配置するのが安全です。(conf/httpd.conf
にconf.d/*.conf
を読み込むという設定があります。)
proxy.conf
というファイルを作り、受け取ったリクエストをすべてTomcatに流すようにします。
# cd /etc/httpd/conf.d
# vi proxy.conf
ProxyPass / ajp://tomcat:8009/ secret=password
ProxyPassReverse / ajp://tomcat:8009/ secret=password
3. Tomcatのsever.xmlにsecret属性を設定する
同じsecretをTomcatのconf/server.xml
に設定します。また、AJPコネクタの設定はデフォルトでコメントアウトされているため、解除して有効にします。
<Connector protocol="AJP/1.3"
address="0.0.0.0"
port="8009"
redirectPort="8443"
secret="password" />
address属性を0.0.0.0
とすると、すべてのホストからのリクエストを受け付けるという意味になります。しかし、secretが設定されているためsecretのないリクエストはパーミッションエラーとなります。
以上で、secretを使ったTomcatのAJP通信設定は完了です。
Apacheの80番ポートに接続して、以下のようにTomcatのトップページが表示されれば成功です。
補足
セキュリティなんて必要ない場合は、以下のようにすると手っ取り早くAJPを使えます。
当然ながら非推奨ですが、検証時には便利だと思います。
- Apacheの設定
ProxyPass / ajp://tomcat:8009/
ProxyPassReverse / ajp://tomcat:8009/
- Tomcatの設定
<Connector protocol="AJP/1.3"
address="0.0.0.0"
port="8009"
redirectPort="8443"
secretRequired="false" />