クライアントIPとX-Forwarded-For IPをTomcatアクセスログに記録する方法。
%{X-Forwarded-For} iを使用していますが、ロードバランサーを介してアクセスすると、実際のクライアントアドレスがログに記録されます。しかし、Tomcatインスタンスに直接アクセスした場合、実際のクライアントアドレスはログに記録されません。どちらの場合でも、実際のクライアントIPアドレスを表示する方法はありますか?
http://www.techstacks.com/howto/configure-access-logging-in-Tomcat.html から:
バージョン6.0.21以降のTomcatまたはTomcat 7を実行している場合は、新しいリモートIPバルブを利用できます。アクセスロギングの場合、このバルブの良い点は、IPアドレスがX-Forwarded-Forヘッダーで渡された場合に、クライアントIPをX-Forwarded-Forヘッダーで渡されたIPアドレスと自動的に入れ替えることです。読み込みはとても簡単です。 AccessLogValve宣言の前にorg.Apache.catalina.valves.RemoteIpValveをserver.xmlに追加するだけです。例えば:
<Host name="localhost" appBase="webapps" unpackWARs="true" autoDeploy="true" xmlValidation="false" xmlNamespaceAware="false">
<!-- Remote IP Valve -->
<Valve className="org.Apache.catalina.valves.RemoteIpValve" />
<!-- Access log processes all example.
Documentation at: /docs/config/Valve.html -->
<Valve className="org.Apache.catalina.valves.AccessLogValve" directory="logs"
prefix="localhost_access_log." suffix=".txt"
pattern="combined" resolveHosts="false"/>
-->
</Host>
6.0.21より古いバージョンのTomcat 6を使用していて、代わりにX-Forwarded-For IPアドレスを保存する場合は、AccessLogValveのパターンプロパティを変更できます。 「共通」または「結合」パターンを削除し、次のパターンのいずれかに置き換える必要があります。
Common Log Format: %{X-Forwarded-For}i %l %u %t "%r" %s %b
Combined Log Format: %{X-Forwarded-For}i %l %u %t %r %s %b %{User-Agent}i %{Referer}i
ここでの主な問題は、RemoteIPバルブが処理するものであり、ログでX-Forwarded-Forアドレスのみを取得することです。リクエストにX-Forwarded-Forヘッダーを挿入しているデバイスをバイパスして、アプリサーバーに直接アクセスした場合、IPアドレスがログに記録されません。あなたはまだリクエストを記録します-あなたはそれがどこから来たのか分かりません。
Tomcat/9.0.12で実行されているJavaアプリケーションの前でApacheリバースプロキシを使用してこの問題がありました。
これをTomcat conf/server.xmlに追加して修正しました。バルブを配置する場所は、エンジン/ホスト/コンテキストごとにこれを適用したい天候に依存します。この2つのバルブを追加しました
<Valve className="org.Apache.catalina.valves.RemoteIpValve" remoteIpHeader="x-forwarded-for" protocolHeader="x-forwarded-proto" />
<Valve className="org.Apache.catalina.valves.AccessLogValve" directory="logs" prefix="Tomcat_access_log" suffix=".log" pattern="%t %{X-AUSERNAME}o %{User-Agent}i %a %m %r %b %s %D %I %{x-forwarded-for}i" />
これらはデフォルト値なので、すべてのremoteIpHeaderおよびprotocolHeaderを定義する必要はありませんが、明確にするためにこれらを追加しました https://Tomcat.Apache.org/Tomcat-9.0-doc/api/org/ Apache/catalina/valves/RemoteIpValve.html
%aはプロキシip(またはロードバランサー)を表示し、%{x-forwarded-for} iはユーザーipを表示します
<Valve className="org.Apache.catalina.valves.RemoteIpValve"
remoteIpHeader="x-forwarded-for" />
<Valve className="org.Apache.catalina.valves.AccessLogValve"
requestAttributesEnabled="true"
pattern="Remote Ip is: %{org.Apache.Tomcat.remoteAddr}r" />
これら2つのバルブ定義をcontext.xmlに追加できます。したがって、どちらの場合でもリモートIPを確認できます。ロードバランサーまたは直接。
org.Apache.catalina.valves.RemoteIpValveが「x-forwarded-for」ヘッダーを検出します。ヘッダーに「x-forwarded-for」がある場合は、その値を「org.Apache.Tomcat.remoteAddr」リクエスト属性に入れます。ヘッダーに「x-forwarded-for」がない場合は、クライアントのIPアドレスを「org.Apache.Tomcat.remoteAddr」リクエスト属性に入れます。
AccessLogValve configは、正しいリモートIPを保持する "org.Apache.Tomcat.remoteAddr"リクエスト属性をログに記録するだけです。