システム設計・構成管理

ApacheとTomcatをmod_proxyでつなぐ方法(AJP/HTTP対応)

ApacheでSSL通信を終端し、Tomcatへリクエストを中継する構成は、Javaアプリケーションの公開環境では一般的なパターンです。本記事では、Apacheのmod_proxy機能を使ってTomcatと連携する方法を、AJP方式とHTTP方式の両面から解説します。

単にファイルを配置して起動するだけでは連携できず、VirtualHostやserver.xmlの記述方法、ポートバインディング、モジュールの有効化、セキュリティ面の考慮が必要です。特に、Let's EncryptでHTTPS化したApacheとTomcatを安全かつ確実に接続するには、いくつかの注意点があります。

このページでは、ApacheとTomcatを分離構成で運用する際に必要な設定の全体像と、実際に使われているリバースプロキシ構成の実装方法を詳しく紹介します。初めてmod_proxy連携を扱う方でも迷わないよう、具体的なVirtualHostの記述例やトラブル対処までを網羅します。

ApacheとTomcatの接続構成パターン

ApacheとTomcatを連携させる際に、最初に悩むのは「どんな構成で組むべきか」という点です。

開発環境や商用環境によって構成は大きく変わりますが、いずれの構成でもApacheがリバースプロキシとして動作し、Tomcatと役割を分担するのが基本です。

以下に、代表的な接続構成パターンをまとめました。まずはご自身の環境がどれに該当するかを確認してから、接続方式や設定方法を選ぶのが確実です。

No.構成パターン内容想定用途
単一ノード構成Web / AP / DB を1台に集約検証環境、小規模サービス
DB分離構成Web/APは同一筐体、DBは別筐体データ保護・負荷分散目的
3層分離構成Web・AP・DBがすべて別筐体セキュリティ・可用性重視構成
Web冗長(宛先固定)Web1→AP1、Web2→AP2 と固定接続シンプルな冗長性確保
Web冗長(負荷分散)ロードバランサでWebを分散スケーラビリティと冗長性重視
AP冗長構成Apacheから複数Tomcatへ振り分けmod_proxy_balancer活用

これらの構成はすべて、ApacheがリバースプロキシとしてTomcatと接続する仕組みを前提としています。このあと解説する接続方式や設定手順は、これらの構成を支える具体的な手段となります。

代表的な接続構成パターン

本記事では「ApacheとTomcatの連携構成」に焦点を当てて解説するため、データベース(DB)サーバーの構成や冗長化については扱いません。DBの接続方式やフェイルオーバー構成などは別記事にて取り上げる予定です。ここではWeb層とAP層の接続パターンに限定して整理しています。

単一ノード構成

単一ノード構成は、Apache・Tomcat・PostgreSQLなどすべてのコンポーネントを1台のサーバー上に集約した構成です。

検証環境や学習目的の最小構成として最も手軽に始められますが、障害時にはすべての機能が同時停止するため、冗長性や可用性には課題があります。本番環境には向きませんが、小規模なイントラ用ツールには採用されるケースもあります。

DB分離構成

DB分離構成は、Webサーバー(Apache)とアプリケーションサーバー(Tomcat)を1台にまとめ、データベースのみ別の筐体に分離するパターンです。

アプリケーション層とデータ層を分離することで、I/O負荷の分散やデータ保護の対策が取りやすくなります。ネットワーク経由のDBアクセスが発生するため、ファイアウォールやポート制御を含めたセキュリティ設計が求められます。

3層分離構成

3層分離構成は、Web・AP・DBの各層をすべて物理的に分離した典型的な業務システム構成です。

セキュリティ・スケーラビリティ・可用性を重視する場合に最適で、特に商用システムや社内基幹システムではこの形が一般的です。負荷分散装置やリバースプロキシ、セッション制御、接続プールなどを組み合わせることで、柔軟かつ強固な設計が可能になります。

Web冗長(宛先固定)

Web冗長(宛先固定)構成は、複数のWebサーバーを用意しておき、それぞれが特定のTomcatインスタンスに固定的に接続する構成です。

ロードバランサを使わずとも、クライアントの接続先を分散させることで障害時の回避が可能です。ただし、個別のWebとAPが密結合となるため、セッション管理や構成変更の柔軟性には課題が残ります。冗長化を安価に実現したい場合に向いています。

Web冗長(負荷分散)

Web冗長(負荷分散)構成は、ロードバランサを介して複数のWebサーバーにリクエストを分散させる構成です。

どのWebサーバーにも同じ構成を導入し、ユーザーセッションをどのノードでも処理できるようにします。この場合、セッション共有の設計やStickySession設定、SSL終端位置の明確化など、分散環境特有の設計ポイントを意識する必要があります。高可用性を実現する主流の構成です。

AP冗長構成

AP冗長構成は、Apacheから複数のTomcatインスタンスへリクエストを分散する構成です。

mod_proxy_balancerやStickySessionを用いて負荷を分散しつつ、セッション整合性を確保するのが一般的です。この構成により、アプリケーション層の障害に強く、性能劣化を抑えながら横方向のスケーリングが可能になります。Web1台にAPを複数並列接続する形で構築されることが多く、シンプルな分散構成として非常に有効です。

ApacheとTomcatの役割の違い

ApacheとTomcatはどちらもWebシステムの構築において頻繁に登場する重要なソフトウェアですが、それぞれの役割には明確な違いがあります。適切に機能分担させることで、高速でセキュアなWebサービスを実現することができます。

Webサーバーとアプリケーションサーバーの基本

Webブラウザからのリクエストは、まずWebサーバー(Apache)に届きます。Apacheは静的ファイルの配信を行い、動的な処理が必要なリクエストはTomcatに転送されます。このとき両者は直接つながっているのではなく、図のように明確にレイヤーとして分離され、役割が異なるサーバーに配置されることが多くあります。

Webサーバーとアプリケーションサーバーは、Webシステム内でそれぞれ異なる責務を担います。混同されがちですが、実際の役割は明確に分かれています。

Webサーバーとは?

Webサーバーは、主にHTMLやCSS、JavaScript、画像などの静的コンテンツをクライアントに配信する役割を持っています。Apache HTTP Server(httpd)はその代表例であり、安定性と高速処理で知られています。

アプリケーションサーバーとは?

一方、アプリケーションサーバーは、JavaやPHPなどの動的な処理を担当します。ユーザーからのリクエストを受け取り、処理して動的なレスポンスを生成します。TomcatはJava ServletやJSPを実行するためのアプリケーションサーバーであり、Webアプリケーションの中核となります。

役割の分業

この2つを連携させることで、Apacheがリクエストの受付と静的ファイルの配信を行い、Tomcatがアプリケーションの処理を担当するという分業体制が実現します。これにより、リソースの効率的な活用と、セキュリティ上のメリットも生まれます。

例えば、Apacheをインターネットに直接公開し、Tomcatは内部ネットワーク上に限定することで、アプリケーション層を外部からの攻撃から守る構成が可能です。

実際の現場では、以下のような分業構成が一般的です。

レイヤー使用ソフトウェア主な役割
WebサーバーApacheHTTPリクエストの受付と静的コンテンツの配信
アプリケーションサーバーTomcat動的処理(Servlet/JSP)の実行

このような役割の分離により、スケーラビリティや障害時の切り分けがしやすくなるという運用上の利点も得られます。

たとえば、以下のような構成では、Apacheが受け取ったリクエストを条件によってTomcatへ転送することができます。

ProxyPass /app http://localhost:8080/app
ProxyPassReverse /app http://localhost:8080/app

この設定により、クライアントから見ればApacheだけが見える一方、内部ではTomcatがアプリケーション処理を行っているという構成になります。

また、AJP(Apache JServ Protocol)を用いた接続を選択することで、HTTPよりも軽量な通信が可能となります。ただし、AJPはセキュリティリスクの高いプロトコルでもあるため、利用には十分な注意が必要です。

このように、ApacheとTomcatは単体で使うよりも、組み合わせて使用することで初めて本来のパフォーマンスと柔軟性を発揮します。特に業務系システムやエンタープライズ領域では、この分業構成が定番となっています。

今後は、具体的なApacheとTomcatの連携方法や、AJPとHTTPの違い、設定ファイルの記述方法なども詳しく解説していきます。目的に応じて最適な接続方式を選択し、セキュアで安定したWebシステムを構築してください。

ApacheとTomcatの連携方式

ApacheとTomcatを連携させる方法には、主にAJP(Apache JServ Protocol)とHTTPの2種類の連携方式があります。それぞれに特徴があり、利用シーンやセキュリティ要件によって適切な方式を選択することが重要です。

Apache-Tomcat間の連携方式

  • AJP接続方式
  • HTTP接続方式

AJP接続の特徴

AJP接続は、ApacheとTomcat間の通信を効率化するために設計された独自プロトコルです。HTTPと比較してヘッダー情報がバイナリ化されており、ネットワーク転送時のオーバーヘッドが軽減されるというメリットがあります。

この方式は、以下のような特徴を持っています。

項目AJP接続の特性
プロトコル形式バイナリ
転送速度高速(オーバーヘッドが少ない)
ポート番号8009(デフォルト)
Tomcat設定ファイルserver.xml に AJP Connectorを追加
注意点外部公開禁止(セキュリティリスク高)

TomcatのAJP接続を有効にするには、以下のようにserver.xmlに記述します。

<Connector port="8009" protocol="AJP/1.3" redirectPort="8443" />

また、Apache側ではmod_proxy_ajpモジュールを使用し、VirtualHost内で次のように記述します。

ProxyPass /app ajp://localhost:8009/app
ProxyPassReverse /app ajp://localhost:8009/app

AJPは内部ネットワーク上での高速通信に最適ですが、外部からのアクセスを許可するとセキュリティリスクが非常に高いため、ファイアウォールやListen制限などを必ず設けてください。

HTTP接続の特徴

HTTP接続は、ApacheとTomcatが共通で使用する標準的なプロトコルを使った連携方式です。AJPに比べて処理効率は若干劣りますが、構成のシンプルさや透明性の高さから、最近ではHTTP接続を選択するケースが増えています。

以下は、HTTP接続の主な特徴です。

項目HTTP接続の特性
プロトコル形式テキスト(プレーンHTTP)
転送速度中速(標準的)
ポート番号8080(デフォルト)
Tomcat設定ファイルserver.xml の HTTP Connector
セキュリティ対策ApacheによるSSL終端・IP制限など

Tomcat側ではHTTPポートは標準で有効化されています。特別な設定変更は不要ですが、明示的にserver.xml内でポートを確認しておくと安心です。

<Connector port="8080" protocol="HTTP/1.1" connectionTimeout="20000" redirectPort="8443" />

Apache側の設定例は以下の通りです。

ProxyPass /app http://localhost:8080/app
ProxyPassReverse /app http://localhost:8080/app

HTTP接続の利点は、AJPに比べて構成がわかりやすく、トラブル時の切り分けもしやすい点です。また、リバースプロキシやSSL終端をApache側に集約することで、アプリケーションサーバーの保守性を高めることができます。

どちらの方式にも一長一短がありますが、セキュリティと管理性を重視するのであれば、近年はHTTP接続を選択するのが主流になりつつあります。運用ポリシーやアプリケーションの要件に応じて、最適な構成を選定してください。

Apache側の設定手順

ApacheとTomcatを連携させる際、Apache側にはいくつかの設定が必要です。使用するモジュールの確認から、実際のProxyPassの記述、VirtualHostの定義まで、順を追って設定を進めていくことで、スムーズな通信を実現できます。

必要なモジュールの確認と有効化

ApacheでTomcatと連携するには、プロキシ関連のモジュールが有効である必要があります。特に、mod_proxy、mod_proxy_http、mod_proxy_ajpなどが必須となります

項番Webコネクタ説明
1mod_proxyApache HTTPに標準で含まれているプロキシ用モジュールです。
2mod_proxy_httpHTTPプロトコル専用のプロキシ転送モジュールです。mod_proxyと組み合わせて使用します。
3mod_proxy_ajpajp/1.3 プロキシ/ゲートウェイサーバです。
4mod_proxy_balancerApacheによる負荷分散機能を提供するモジュールで、mod_proxyと連携して使用します。

以下のコマンドでモジュールの有効化状況を確認できます。

httpd -M | grep proxy

出力結果にproxy_module、proxy_http_module、proxy_ajp_moduleなどが含まれていれば、有効化されています。もし無効であれば、/etc/httpd/conf.modules.d/配下の設定ファイルを編集するか、コメントを外して再起動してください。

モジュールを明示的に読み込むには、以下のように記述します。

LoadModule proxy_module modules/mod_proxy.so
LoadModule proxy_http_module modules/mod_proxy_http.so
LoadModule proxy_ajp_module modules/mod_proxy_ajp.so

設定変更後はApacheを再起動してください。

systemctl restart httpd

ProxyPassの基本構文(HTTP/AJP両対応)

ApacheからTomcatにリクエストを転送するには、ProxyPassとProxyPassReverseディレクティブを使用します。これはApacheの設定ファイル(httpd.conf または VirtualHost設定)内に記述します。

HTTPで接続する場合は以下のように記述します。

ProxyPass /app http://localhost:8080/app
ProxyPassReverse /app http://localhost:8080/app

AJPで接続する場合は、以下のように記述します。

ProxyPass /app ajp://localhost:8009/app
ProxyPassReverse /app ajp://localhost:8009/app

それぞれの接続方法に対応するTomcatのConnectorが有効化されていることを確認しておく必要があります。接続方式によって内部のプロトコルやパフォーマンスが異なるため、要件に応じて使い分けてください。

また、プロキシ対象が複数ある場合や、サブアプリケーションごとに転送先を分けたい場合も、同様の形式で複数のProxyPassを設定できます。

VirtualHost設定の例

Apacheでは、VirtualHostを使って複数ドメインや複数アプリケーションの設定を分離することができます。Tomcat連携においても、VirtualHost構成を活用することで柔軟な管理が可能になります。

以下は、HTTPS環境でHTTPをリダイレクトしつつ、TomcatのアプリケーションにAJPで転送する構成例です。

このような設定により、ユーザーがHTTPでアクセスした場合も自動的にHTTPSへリダイレクトされ、Tomcatが処理するアプリケーションへ安全に転送される仕組みが構築されます。

<VirtualHost *:80>
    ServerName app1.example.com
    RewriteEngine On
    RewriteCond %{HTTPS} off
    RewriteRule ^(.*)$ https://%{HTTP_HOST}%{REQUEST_URI} [L,R=301]
</VirtualHost>

<VirtualHost *:443>
    ServerName app1.example.com
    SSLEngine on
    SSLCertificateFile /etc/letsencrypt/live/app1.example.com/fullchain.pem
    SSLCertificateKeyFile /etc/letsencrypt/live/app1.example.com/privkey.pem
    <Location /app1>
        ProxyPass ajp://localhost:8009/app1/
        ProxyPassReverse ajp://localhost:8009/app1/
    </Location>
</VirtualHost>

<VirtualHost *:443>
    ServerName app2.example.com
    SSLEngine on
    SSLCertificateFile /etc/letsencrypt/live/app2.example.com/fullchain.pem
    SSLCertificateKeyFile /etc/letsencrypt/live/app2.example.com/privkey.pem
    <Location /app2>
        ProxyPass ajp://localhost:8010/app2/
        ProxyPassReverse ajp://localhost:8010/app2/
    </Location>
</VirtualHost>

実際にこの設定を反映させるためには、Let's Encryptなどで取得した証明書の配置と、firewalldのポート開放(80番と443番)が必要になります。

firewall-cmd --permanent --add-port=80/tcp
firewall-cmd --permanent --add-port=443/tcp
firewall-cmd --reload

また、mod_sslパッケージのインストールも忘れずに実行してください。

dnf install -y mod_ssl

VirtualHostを活用することで、ドメインごとの制御や複数アプリの切り分けが容易になり、Tomcatの複雑な構成管理をApache側に集約できます。これは運用上の保守性や拡張性を高めるうえでも非常に有効な手段です。今後の構成変更を見越して、最初からVirtualHostによる分離設計を検討することをおすすめします。

VirtualHostの設定は、通常はhttpd.confまたはそれにインクルードされた別ファイル(例:vhost.confなど)に記述します。

mod_proxyによる接続設定例(HTTP/AJP対応)

ApacheとTomcatを接続する際は、mod_proxy系モジュールを使用して、リバースプロキシとしてTomcatへ転送する構成が一般的です。ここでは、HTTP接続とAJP接続のそれぞれのVirtualHost設定例を紹介します。どちらも必要なモジュールを有効化したうえで、正しく構成する必要があります。

mod_proxy_httpによる接続設定

mod_proxy_httpを使用する場合は、ApacheからTomcatのHTTPポート(通常8080番)へ転送します。シンプルで設定が直感的なため、セキュリティ対策を施せる環境であればこちらを推奨します。

<VirtualHost *:80>
    ServerName www.example.com
    ProxyPass /app http://localhost:8080/app
    ProxyPassReverse /app http://localhost:8080/app
</VirtualHost>

mod_proxy_ajpによる接続設定

mod_proxy_ajpを使うと、ApacheからTomcatのAJPコネクタ(デフォルト8009番)を通じて通信できます。AJPはバイナリプロトコルで軽量ですが、近年のセキュリティリスクから使用には十分なネットワーク制御が求められます。

<VirtualHost *:80>
    ServerName www.example.com
    ProxyPass /app ajp://localhost:8009/app
    ProxyPassReverse /app ajp://localhost:8009/app
</VirtualHost>

AJP接続を有効にするには、Tomcatのserver.xmlに以下のようなコネクタ定義が存在している必要があります。

<Connector port="8009" protocol="AJP/1.3" redirectPort="8443" />

mod_proxy_balancerの設定例と解説

mod_proxy_balancerを使用すると、Apache上で複数台のTomcatに対してロードバランシングを構成できます。セッションの維持(スティッキーセッション)や異常系のフェイルオーバー対応が可能なため、本番環境で広く採用されています。

バランサー設定の基本構造

ApacheでTomcatを複数台構成で運用する場合、mod_proxy_balancerを利用することで簡単に負荷分散設定を実現できます。ここでは、app1を2台、app2を3台構成したバランサ設定のVirtualHost構成例を示します。それぞれ異なるServerNameを用いて、HTTPS経由でTomcatクラスタにリバースプロキシを行う構成です。

<Proxy "balancer://app1cluster">
    BalancerMember http://192.168.1.101:8080
    BalancerMember http://192.168.1.102:8080
</Proxy>

<Proxy "balancer://app2cluster">
    BalancerMember http://192.168.1.201:8080
    BalancerMember http://192.168.1.202:8080
    BalancerMember http://192.168.1.203:8080
</Proxy>

<VirtualHost *:443>
    ServerName app1.example.com
    SSLEngine on
    SSLCertificateFile /etc/letsencrypt/live/app1.example.com/fullchain.pem
    SSLCertificateKeyFile /etc/letsencrypt/live/app1.example.com/privkey.pem
    <Location /app1>
        ProxyPass balancer://app1cluster/app1/
        ProxyPassReverse balancer://app1cluster/app1/
    </Location>
</VirtualHost>

<VirtualHost *:443>
    ServerName app2.example.com
    SSLEngine on
    SSLCertificateFile /etc/letsencrypt/live/app2.example.com/fullchain.pem
    SSLCertificateKeyFile /etc/letsencrypt/live/app2.example.com/privkey.pem
    <Location /app2>
        ProxyPass balancer://app2cluster/app2/
        ProxyPassReverse balancer://app2cluster/app2/
    </Location>
</VirtualHost>

設定の各項目の意味

以下の表は設定内容とその役割をまとめたものです。

ディレクティブ意味
BalancerMember各Tomcatノードを定義します。routeオプションはTomcat側のjvmRoute属性と一致させます。
ProxySet stickysessionJSESSIONIDの末尾に付加されるルート値をもとに同一サーバーへ転送し続けます。
ProxyPass /app balancer://...ApacheのURLパス「/app」をTomcatクラスタの同一パスへ転送します。
ProxyPassReverseTomcatからのレスポンスを元のURLに書き換えます。

Tomcat側のjvmRoute設定も必要

Apacheから転送されたリクエストをセッション維持しながら処理するには、Tomcat側でもrouteと一致するよう設定する必要があります。 以下はTomcatのserver.xmlの一部抜粋です。

<Engine name="Catalina" defaultHost="localhost" jvmRoute="tomcat1">

もう一方のTomcatは jvmRoute="tomcat2" と設定してください。

設定後はApacheの再起動が必要です。なお、mod_proxy_balancerを使用するには以下のモジュールが有効になっている必要があります。 

sudo a2enmod proxy
sudo a2enmod proxy_http
sudo a2enmod proxy_balancer
sudo a2enmod lbmethod_byrequests

Tomcat側の設定手順

ApacheとTomcatを連携させるには、Tomcat側でもいくつかの基本設定が必要です。とくに重要なのが、HTTPおよびAJPポートの有効化、適切なポート番号の確認、そしてserver.xmlの編集です。ここではTomcat側の最小構成として必要な手順を丁寧に解説します。

HTTPポートとAJPポートの確認方法

Tomcatが使用するポートは、デフォルトでHTTPが8080番、AJPが8009番に設定されています。これらはTomcatのインストールディレクトリ配下にあるconf/server.xmlファイルに定義されています。

まず、Tomcatがどのポートでリスンしているかを確認するには、以下のコマンドを使用します。

ss -ltnp | grep java

または、Tomcatのプロセスを含めて確認したい場合は以下でも構いません。

netstat -plnt | grep java

これにより、8080や8009がLISTEN状態になっていれば、TomcatのHTTPおよびAJPコネクタが起動していることが確認できます。

初期状態では以下のようなポートが使用されていることが多くなっています。

用途デフォルトポート説明
HTTP8080Webブラウザからのアクセス用ポート
AJP8009Apache mod_proxy_ajp連携用ポート
管理者コンソール(同上)managerアプリにHTTP経由でアクセス

運用上の理由でこれらのポートを変更することも可能ですが、Apache側と整合を取ることが大前提となります。

Tomcatのserver.xml編集ポイント

TomcatとApacheを連携させるには、Tomcat側で通信ポートや接続方式を正しく設定する必要があります。これらの設定は、Tomcatのインストールディレクトリ配下にある server.xml で行います。パスの例は以下の通りです。

vi /opt/tomcat/conf/server.xml

HTTPコネクタの役割と設定例

TomcatのHTTPコネクタは、Apacheのmod_proxy_httpや、単体アクセス時に使用される標準的な通信手段です。以下の設定により、8080番ポートでHTTPリクエストを受け付けるようになります。

<Connector port="8080" protocol="HTTP/1.1"
    connectionTimeout="20000"
    redirectPort="8443" />

この設定は、Apacheからmod_proxy_httpでTomcatに接続する際に必要となる基本的なHTTPコネクタの定義です。

AJPコネクタの役割と設定例

AJP(Apache JServ Protocol)は、ApacheとTomcatの高速なバイナリ通信を可能にするプロトコルです。mod_proxy_ajpを使用する場合、Tomcat側でAJPコネクタを有効にする必要があります。

<Connector port="8009" protocol="AJP/1.3" redirectPort="8443" />

この設定がコメントアウトされている場合は、mod_proxy_ajp経由での接続ができません。設定変更後は、Tomcatを再起動することで反映されます。

systemctl restart tomcat

AJP接続のセキュリティ強化と制限設定

AJPは外部ネットワーク経由の攻撃を受けやすいため、必ずローカルホストに限定して使用することが重要です。以下のように secretRequired と address 属性を明示することで、安全に制限できます。

<Connector port="8009" protocol="AJP/1.3" redirectPort="8443"
    secretRequired="false" address="127.0.0.1" />

この設定により、AJP接続は127.0.0.1からの要求のみに制限され、外部からの不正アクセスを防止できます。

firewalldによるAJPポート制御の具体例

追加でファイアウォールによる制御を行う場合は、以下のようにfirewalldでルールを追加します。

firewall-cmd --permanent --add-rich-rule='rule family="ipv4" source address="127.0.0.1" port protocol="tcp" port="8009" accept'
firewall-cmd --permanent --add-port=8009/tcp --remove-port=8009/tcp
firewall-cmd --reload

これにより、8009ポートはローカルホスト以外からのアクセスが完全に遮断されます。

設定ミスに備えるためのバックアップ習慣

server.xmlの編集は、Tomcat全体の挙動に影響を与えるため、事前にバックアップを取ることが重要です。以下のようにバックアップを作成してから編集に入ることをおすすめします。

cp /opt/tomcat/conf/server.xml /opt/tomcat/conf/server.xml.bak

ApacheとTomcatの連携に関する注意点

ApacheとTomcatを連携させる構成は一般的ですが、運用上のトラブルを避けるためには、いくつかの注意点を事前に把握しておく必要があります。単純なProxyPassの設定だけでは意図した動作とならないケースが多く、特にセッション管理やヘッダー処理、URL設計においては意識的な対応が求められます。

セッション引き継ぎの設定確認

ApacheからTomcatにリクエストを転送した場合でも、セッション管理はTomcat側で行われます。しかし、環境によってはセッションIDが維持されず、ログイン状態が失われるなどの現象が発生することがあります。

この問題は、クッキーのパス設定やセッションIDのURL付加(URLリライティング)が適切に処理されていないことが原因で発生します。特に、ProxyPassでルート以外のパスをマッピングしている場合、Tomcat側の設定でクッキーのパス属性が想定と異なる動作になることがあります。

以下のような構成で /app に転送する場合、セッションCookieが正しく働かないことがあります。

ProxyPass /app http://localhost:8080/app
ProxyPassReverse /app http://localhost:8080/app

その場合、web.xmlで以下のようにセッションCookieのパス属性を明示的に定義する方法があります。

<session-config>
    <cookie-config>
        <path>/app</path>
    </cookie-config>
</session-config>

この設定により、クライアントは /app 配下のみにセッションCookieを送信するようになり、セッションの切断が回避できます。

プロキシ越しのX-Forwardedヘッダー対応

ApacheからTomcatにプロキシ経由でリクエストが届いた場合、Tomcat側から見ると送信元IPアドレスがすべて127.0.0.1などのApache自身に見えてしまいます。これではアクセスログや制限処理に支障が出るため、X-Forwardedヘッダーを有効活用する必要があります。

Apache側では以下の設定を追加して、クライアントIPなどを明示的にTomcatに引き渡します。

RemoteIPHeader X-Forwarded-For
RemoteIPInternalProxy 127.0.0.1

また、Tomcat側ではRemoteIpValveを有効にすることで、受け取ったヘッダーを正しく解釈させます。server.xmlに以下を追記してください。

<Valve className="org.apache.catalina.valves.RemoteIpValve"
    remoteIpHeader="x-forwarded-for"
    proxiesHeader="x-forwarded-by"
    protocolHeader="x-forwarded-proto" />

この構成により、Tomcatが実際のクライアントIPやプロトコル(HTTP/HTTPS)を正確に認識できるようになります。

同一ドメイン配下でのURL設計の注意

Apacheで複数のアプリケーションを同一ドメインの異なるパスでホスティングする場合、URL設計に細心の注意が必要です。例えば以下のような構成で複数のアプリを展開するケースがあります。

アプリケーション名URL転送先(Tomcat)
App1https://example.com/app1http://localhost:8080/app1
App2https://example.com/app2http://localhost:8080/app2

この構成では、以下のProxyPass設定を用います。

ProxyPass /app1 http://localhost:8080/app1
ProxyPassReverse /app1 http://localhost:8080/app1

ProxyPass /app2 http://localhost:8080/app2
ProxyPassReverse /app2 http://localhost:8080/app2

このとき重要なのが、各アプリケーションの内部URLやJavaScript、CSS、画像の相対パスが/app1や/app2を前提に書かれていることです。そうでない場合、リソースが読み込まれず、表示崩れやJavaScriptエラーの原因になります。

開発時にはのようにベースパスをHTMLヘッダーで明示したり、ServletContextのルートパスに応じた相対パス指定を徹底することが重要です。

また、ApacheのリダイレクトやRewrite設定によっては、意図しないURLリダイレクトが発生し、ログイン画面がループするなどの障害が発生することもあります。設定を複雑化させすぎないよう、VirtualHostごとにアプリを分離する方針も有効です。

このように、ApacheとTomcatの連携は一見シンプルですが、セッション管理やヘッダー、URL設計に対する注意が不十分なままだと、運用開始後に致命的な不具合を引き起こす可能性があります。構築時点でこれらの設計を明確にしておくことが、後々のトラブルを未然に防ぐ最良の手段となります。

よくある質問(FAQ)

ApacheとTomcatの連携については、初心者から中級者まで多くの疑問を抱く場面があります。ここでは、特に多く寄せられる2つの質問に対して、現場での実用性を前提に解説します。どちらも運用設計やセキュリティ設計に直結する重要な論点です。

HTTPとAJPのどちらを使うべきか?

ApacheとTomcatを接続する際、もっとも悩まれるのが「HTTPでつなぐべきか、AJPでつなぐべきか」という点です。この選択は、単なる好みではなくシステム要件やセキュリティポリシーに大きく依存します。

結論からいえば、セキュリティを最優先する現代の構成ではHTTP接続が推奨されます。その理由は以下の通りです。

項目HTTPAJP
接続方式テキストベース(HTTP/1.1)バイナリベース(AJP/1.3)
設定の簡易性Apache側だけで完結Tomcat側の設定が必要
パフォーマンス通常利用で十分な速度通信コストがやや軽い
セキュリティリスクApacheの設定で制御しやすい外部公開時に深刻な脆弱性が存在
主な用途社内・公開システム全般閉域構成・内部限定用途

AJPはたしかに軽量で効率的なプロトコルですが、設定が少しでも誤ると外部からの攻撃を直接受ける入口となりかねません。特に有名なのが、2020年に公開された「Ghostcat」脆弱性(CVE-2020-1938)です。この脆弱性では、AJPポートが外部に開放された状態でTomcatにアクセスされ、任意ファイルを読み取られるという深刻な被害が報告されました。

一方、HTTP接続はSSL終端、アクセス制御、IP制限、ヘッダー書き換えなどApache側の防御機構をそのまま利用できるという利点があります。内部通信であっても、将来的な公開に備える構成としてHTTP接続を選択しておくほうが安全です。

また、HTTP接続はAJPと比べて明示的なTomcat側設定が不要で、server.xmlを触らずに構築できるため、運用負荷の点でも優位です。

それでもAJPを使う場合は、次のような制限を厳密に守る必要があります。

  • Tomcat側のAJPポートを127.0.0.1やUNIXドメインソケットで限定する
  • ファイアウォールで8009ポートを外部から完全に遮断する
  • TomcatのAJP Connectorに address, secretRequired などを設定する

<Connector port="8009" protocol="AJP/1.3"
    address="127.0.0.1"
    secretRequired="false" />

このように、AJPは適切な知識と構成があって初めて安全に運用できる選択肢となります。初心者や公開サーバーを扱う場合は、まずHTTP接続から始めることを強く推奨します。

mod_jkとの違いは?

ApacheとTomcatの連携を調べていると、「mod_jk」という古いモジュールに遭遇することがあります。現在ではあまり使われていませんが、以前はAJPを使用する際の定番構成として広く利用されていました。

mod_jkはApacheとTomcatを連携させる専用のネイティブモジュールで、以下のような特徴があります。

比較項目mod_jkmod_proxy_ajp
開発元Tomcatチーム(Jakarta Project)Apache HTTPDに標準搭載
設定ファイルworkers.properties が必要httpd.conf のみで完結
ロードバランシング独自のfailover機能ありmod_proxy_balancerに依存
保守性構成が複雑構成がシンプル
今後の推奨非推奨(レガシー)推奨(活発に保守されている)

mod_jkは一時期、信頼性と柔軟性の高さから多くの企業で採用されていましたが、Apache本体にmod_proxy_ajpが取り込まれて以降は、その必要性が薄れました。特に、workers.propertiesファイルの構文が複雑で、複数サーバー連携時の設定ミスが頻発しやすい点が課題でした。

現在では、Apacheが標準で提供しているmod_proxyやmod_proxy_ajpを使用する方が、構築・保守ともに合理的で安全です。また、将来的にHTTPへ切り替える場合も、mod_proxyを使っていれば構成変更が最小限で済むという利点があります。

過去にmod_jkを使っていたプロジェクトからの移行を検討している場合は、まずmod_proxy_ajpベースでの接続構成に変更し、必要に応じてHTTP接続に切り替えることで、安全かつ段階的な移行が可能になります。

以上のことから、現代のApacheとTomcat連携ではmod_jkをあえて使う理由はほとんどなく、推奨される構成ではありません。すでにmod_proxy系列のモジュールで十分な機能が揃っており、セキュリティや将来性も含めて、mod_jkからの脱却は早期に検討すべきです。

本サイトにて記載のすべてのスクリプト利用により発生した利用者の損害全てに対し、いかなる責任をも負わないものとし、損害賠償をする一切の義務はないものとします。また、この記事は、実際の案件対応を通じて得た知見をもとに筆者が作成したものであり、全コードと解説は著者本人による設計・検証結果に基づいています。

よく読まれている記事

1

「シェル」と「シェルスクリプト」という言葉を聞いたことがありますか?どちらもLinuxやMacのターミナルで使われるものですが、それぞれの役割や使い方には違いがあります。 本記事では、「シェル」と「シ ...

2

「私たちが日々利用しているスマートフォンやインターネット、そしてスーパーコンピュータやクラウドサービス――これらの多くがLinuxの力で動いていることをご存じですか? 無料で使えるだけでなく、高い柔軟 ...

3

この記事は、Linuxについて勉強している初心者の方向けに「Shellスクリプト」について解説します。最後まで読んで頂けましたら、Shellスクリプトはどのような役割を担っているのか?を理解出来るよう ...

-システム設計・構成管理