コンテナ提供のフィルター

目次

はじめに

Tomcatは、$CATALINA_BASE/conf/web.xml を使用してすべてのWebアプリケーションで利用できるように設定できる、あるいはアプリケーションの WEB-INF/web.xml で個々のWebアプリケーション向けに設定できる多数のフィルターを提供しています。各フィルターについては以下で説明します。

この説明では、ほとんどの相対パスが解決されるベースディレクトリを参照するために変数名 `$CATALINA_BASE` を使用しています。CATALINA_BASEディレクトリを設定してTomcatを複数インスタンス向けに構成していない場合、$CATALINA_BASEはTomcatをインストールしたディレクトリである `$CATALINA_HOME` の値に設定されます。

デフォルト文字セットフィルターの追加

はじめに

HTTP仕様では、「text」メディアタイプのサブタイプに文字セットが指定されていない場合、ISO-8859-1文字セットを使用しなければならないと明確に定められています。しかし、ブラウザは文字セットを自動検出しようとする場合があります。これは攻撃者によってXSS攻撃を実行するために悪用される可能性があります。Internet Explorerやその他のブラウザには、この動作を有効にするオプションがあります。

このフィルターは、文字セットを明示的に設定することで攻撃を防ぎます。ユーザーによって提供された文字セットが明示的に上書きされない限り、ブラウザは明示的に設定された文字セットに従い、XSS攻撃を防ぎます。

フィルタークラス名

デフォルト文字セット追加フィルターのフィルタークラス名は、org.apache.catalina.filters.AddDefaultCharsetFilter です。

初期化パラメータ

デフォルト文字セット追加フィルターは、以下の初期化パラメータをサポートしています

属性説明
encoding

Servletによって明示的に他の文字セットが設定されていない場合に設定されるべき文字セットの名前。このパラメータには、defaultsystem の2つの特殊な値があります。system の値は、通常ロケールによって設定されるJVM全体にわたるデフォルト文字セットを使用します。default の値はISO-8859-1を使用します。

CORSフィルター

はじめに

このフィルターは、オリジン間リクエストを可能にするメカニズムであるW3CのCORS (Cross-Origin Resource Sharing) 仕様の実装です。

このフィルターは、必要な Access-Control-* ヘッダーを HttpServletResponse オブジェクトに追加することで機能します。また、HTTPレスポンス分割も防止します。リクエストが無効であるか許可されていない場合、リクエストはHTTPステータスコード403 (Forbidden) で拒否されます。このフィルターによるリクエスト処理を示すフローチャートが利用可能です。

このフィルターを使用するために必要な最小限の設定は以下の通りです。

<filter>
  <filter-name>CorsFilter</filter-name>
  <filter-class>org.apache.catalina.filters.CorsFilter</filter-class>
</filter>
<filter-mapping>
  <filter-name>CorsFilter</filter-name>
  <url-pattern>/*</url-pattern>
</filter-mapping>

上記の設定はフィルターを有効にしますが、クロスオリジンポリシーを緩和しません。最低限、クロスオリジンリクエストを有効にするには、以下に説明するように cors.allowed.origins 初期化パラメータを追加する必要があります。要件によっては、追加の設定が必要になる場合があります。

このフィルターのインスタンスは、1つのポリシーしか実装できません。Webアプリケーション内で異なるURLまたはURLのセットに異なるポリシー(例えば、異なる許可されたオリジン)を適用したい場合は、設定したい各ポリシーごとにこのフィルターの別個のインスタンスを構成する必要があります。

フィルタークラス名

CORSフィルターのフィルタークラス名は、org.apache.catalina.filters.CorsFilter です。

初期化パラメータ

CORSフィルターは以下の初期化パラメータをサポートしています

属性説明
cors.allowed.origins

リソースへのアクセスが許可されるオリジンのリスト。* を指定すると、任意のオリジンからのリソースアクセスが可能になります。それ以外の場合は、カンマ区切りの許可オリジンリストを指定できます。例: https://www.w3.org, https://apache.dokyumento.jpデフォルト:空の文字列。(リソースへのアクセスが許可されるオリジンはありません)。

cors.allowed.methods

クロスオリジンリクエストを使用してリソースにアクセスできるHTTPメソッドのカンマ区切りリスト。これらは、プリフライト応答の Access-Control-Allow-Methods ヘッダーの一部としても含まれるメソッドです。例: GET, POSTデフォルト: GET, POST, HEAD, OPTIONS

cors.allowed.headers

実際のリクエストを行う際に使用できるリクエストヘッダーのカンマ区切りリスト。これらのヘッダーは、プリフライト応答の Access-Control-Allow-Headers ヘッダーの一部としても返されます。例: Origin,Acceptデフォルト: Origin, Accept, X-Requested-With, Content-Type, Access-Control-Request-Method, Access-Control-Request-Headers

cors.exposed.headers

ブラウザがアクセスを許可されている、シンプルなレスポンスヘッダー以外のヘッダーのカンマ区切りリスト。これらは、プリフライト応答の Access-Control-Expose-Headers ヘッダーの一部としても含まれるヘッダーです。例: X-CUSTOM-HEADER-PING,X-CUSTOM-HEADER-PONGデフォルト: なし。非シンプルなヘッダーはデフォルトでは公開されません。

cors.preflight.maxage

ブラウザがプリフライトリクエストの結果をキャッシュできる秒数。これは、プリフライト応答の Access-Control-Max-Age ヘッダーの一部として含まれます。負の値を指定すると、CORSフィルターはこの応答ヘッダーをプリフライト応答に追加しなくなります。デフォルト: 1800

cors.support.credentials

リソースがユーザー認証情報をサポートするかどうかを示すフラグ。このフラグは、プリフライト応答の Access-Control-Allow-Credentials ヘッダーの一部として公開されます。これは、ブラウザが認証情報を使用して実際のリクエストを実行できるかどうかを判断するのに役立ちます。デフォルト: false

cors.request.decorate

CORS固有の属性をHttpServletRequestオブジェクトに追加するかどうかを制御するフラグ。デフォルト: true

以下に、デフォルトを上書きする、より高度な設定例を示します

<filter>
  <filter-name>CorsFilter</filter-name>
  <filter-class>org.apache.catalina.filters.CorsFilter</filter-class>
  <init-param>
    <param-name>cors.allowed.origins</param-name>
    <param-value>https://apache.dokyumento.jp</param-value>
  </init-param>
  <init-param>
    <param-name>cors.allowed.methods</param-name>
    <param-value>GET,POST,HEAD,OPTIONS,PUT</param-value>
  </init-param>
  <init-param>
    <param-name>cors.allowed.headers</param-name>
    <param-value>Content-Type,X-Requested-With,accept,Origin,Access-Control-Request-Method,Access-Control-Request-Headers</param-value>
  </init-param>
  <init-param>
    <param-name>cors.exposed.headers</param-name>
    <param-value>Access-Control-Allow-Origin,Access-Control-Allow-Credentials</param-value>
  </init-param>
  <init-param>
    <param-name>cors.support.credentials</param-name>
    <param-value>true</param-value>
  </init-param>
  <init-param>
    <param-name>cors.preflight.maxage</param-name>
    <param-value>10</param-value>
  </init-param>
</filter>
<filter-mapping>
  <filter-name>CorsFilter</filter-name>
  <url-pattern>/*</url-pattern>
</filter-mapping>

CORSフィルターとHttpServletRequest属性

CORSフィルターは、ダウンストリームでの消費のために、リクエストに関する情報をHttpServletRequestオブジェクトに追加します。cors.request.decorate 初期化パラメータが true の場合、以下の属性が設定されます

  • cors.isCorsRequest: リクエストがCORSリクエストであるかどうかを判断するフラグ。
  • cors.request.origin: オリジンURL、つまりリクエストが生成されたページのURL。
  • cors.request.type: CORSリクエストのタイプ。取りうる値は以下の通り
    • SIMPLE: プリフライトリクエストに先行されないリクエスト。
    • ACTUAL: プリフライトリクエストに先行されるリクエスト。
    • PRE_FLIGHT: プリフライトリクエスト。
    • NOT_CORS: 通常の同一オリジンリクエスト。
    • INVALID_CORS: 無効なクロスオリジンリクエスト。
  • cors.request.headers: プリフライトリクエストのために、Access-Control-Request-Headers ヘッダーとして送信されるリクエストヘッダー。

CSRF防止フィルター

はじめに

このフィルターは、Webアプリケーションに基本的なCSRF保護を提供します。このフィルターは /* にマッピングされており、クライアントに返されるすべてのURLが HttpServletResponse#encodeRedirectURL(String) または HttpServletResponse#encodeURL(String) の呼び出しを介してエンコードされていることを前提としています。

このフィルターは、ノンスを生成してセッションに保存することでCSRFを防止します。URLも同じノンスでエンコードされます。次のリクエストが受信されると、リクエスト内のノンスがセッション内のノンスと比較され、それらが同じである場合にのみリクエストの続行が許可されます。

フィルタークラス名

CSRF防止フィルターのフィルタークラス名は、org.apache.catalina.filters.CsrfPreventionFilter です。

初期化パラメータ

CSRF防止フィルターは以下の初期化パラメータをサポートしています

属性説明
denyStatus

拒否されたリクエストを拒否する際に使用されるHTTP応答ステータスコード。デフォルト値は403です。

enforce

強制を有効または無効にするフラグ。強制が無効の場合、CsrfPreventionFilter はすべてのリクエストを許可し、CSRFの失敗をDEBUGメッセージとしてログに記録します。デフォルトはtrueで、CSRF保護の強制が有効になっています。

entryPoints

有効なノンスの有無がテストされないURLのカンマ区切りリスト。これらは、保護されたアプリケーションから離れた後に、そこへ戻る方法を提供するために使用されます。エントリーポイントはHTTP GETリクエストに限定され、セキュリティ上の機密性の高いアクションをトリガーするべきではありません。

nonceCacheSize

並行リクエスト、ブラウザでの更新や戻る機能の制限された使用、および現在のノンスではなく以前のノンスが送信される可能性のある同様の動作をサポートするために、LRUベースでキャッシュされる以前に発行されたノンスの数。設定されていない場合、デフォルト値の5が使用されます。

nonceRequestParameterName

ノンスに使用されるリクエストパラメータの名前。設定されていない場合、デフォルト値のorg.apache.catalina.filters.CSRF_NONCEが使用されます。

randomClass

ノンスの生成に使用するクラスの名前。このクラスは java.util.Random のインスタンスでなければなりません。設定されていない場合、デフォルト値の java.security.SecureRandom が使用されます。

noNonceURLPatterns

CSRFノンスが追加されないURLパターンのリスト。リソースキャッシングなどを無効にする可能性のある一意のURLの作成を避けるために、特定のURLにノンスを追加したくない場合があります。

サポートされるパターンにはいくつかの種類があります

  • * で終わるパターンを使用したプレフィックス一致。例: /images/*
  • * で始まるパターンを使用したサフィックス一致。例: *.css
  • mime: で始まり、URLファイル名のMIMEタイプに対してチェックされる上記の一致のいずれかを指定するMIMEタイプの一致。例: mime:image/*。MIMEタイプは ServletContext.getMimeType を使用して決定されることに注意してください。
  • / (スラッシュ) 記号で始まり、終わる単一の完全な正規表現パターン。例: //images/.*|/scripts/.*/。先頭と末尾の / 文字は、コンパイル前にパターンから削除されます。パターンは1つだけですが、そのパターンは正規表現の | (OR) 演算子を使用することで、望むだけ多くの選択肢を持つことができます。正規表現はURL全体に対して一致(つまり、マッチであって検索ではない意味論)し、正規表現の方言はJava (java.util.regex.Pattern) です。

デフォルトは *.css, *.js, *.gif, *.png, *.jpg, *.svg, *.ico, *.jpeg, *.mjs です。

REST API用CSRF防止フィルター

はじめに

このフィルターはREST APIに基本的なCSRF保護を提供します。CSRF保護は、保護されたリソースに対する変更HTTPリクエスト(GET、HEAD、OPTIONSとは異なる)にのみ適用されます。これは、有効なノンスを提供するカスタムヘッダー X-CSRF-Token に基づいています。

REST APIのCSRF保護メカニズムは、以下のステップで構成されます

  • クライアントは有効なノンスを要求します。これは、保護されたリソースへの変更を行わない「Fetch」リクエストによって実行されます。
  • サーバーは現在のユーザーセッションにマッピングされた有効なノンスで応答します。
  • クライアントは、同じユーザーセッションの枠内で、後続の変更リクエストにこのノンスを提供します。
  • サーバーは、有効なノンスを含まない保護されたリソースへのすべての変更リクエストを拒否します。

基本設定例

サーバー側では

  • すべてのCSRF保護されたREST APIは、認証メカニズムによって保護されるべきです。
  • 変更するREST APIをこのフィルターで保護します。
  • 少なくとも1つの変更を行わない操作を提供します。
<filter>
  <filter-name>RestCSRF</filter-name>
  <filter-class>org.apache.catalina.filters.RestCsrfPreventionFilter</filter-class>
</filter>
<filter-mapping>
  <filter-name>RestCSRF</filter-name>
  <!-- Modifying operations -->
  <url-pattern>/resources/removeResource</url-pattern>
  <url-pattern>/resources/addResource</url-pattern>
  <!-- Non-modifying operations -->
  <url-pattern>/resources/listResources</url-pattern>
</filter-mapping>

クライアント側では

  • 有効なノンスを取得するために、変更を行わない「Fetch」リクエストを行います。これは、追加ヘッダー X-CSRF-Token: Fetch を送信することで可能です。
  • 保護されたリソースへの後続の変更リクエストで提供するために、返されたセッションIDとノンスをキャッシュします。
  • 変更リクエストは拒否される可能性があり、ノンスが無効または欠落している場合、セッションの期限が切れている場合、またはサーバーによってセッションIDが変更された場合には、ヘッダー X-CSRF-Token: Required が返されます。
Client Request:
GET /rest/resources/listResources HTTP/1.1
X-CSRF-Token: Fetch
Authorization: Basic ...
Host: localhost:8080
...

Server Response:
HTTP/1.1 200 OK
Set-Cookie: JSESSIONID=...; Path=/rest; HttpOnly
X-CSRF-Token: ...
...

Client Request:
POST /rest/resources/addResource HTTP/1.1
Cookie: JSESSIONID=...
X-CSRF-Token: ...
Authorization: Basic ...
Host: localhost:8080
...

Server Response:
HTTP/1.1 200 OK
...

RestCsrfPreventionFilterとHttpServletRequestパラメータ

クライアントがREST APIへの呼び出しにカスタムヘッダーを挿入できない場合、有効なノンスがリクエストパラメータとして受け入れられるURLを構成する追加機能があります。

注意: X-CSRF-Token ヘッダーが存在する場合、リクエスト内の同じ名前のどのパラメータよりも優先されます。リクエストパラメータは新しいノンスを取得するために使用できず、ヘッダーのみが新しいノンスを要求するために使用できます。

<filter>
  <filter-name>RestCSRF</filter-name>
  <filter-class>org.apache.catalina.filters.RestCsrfPreventionFilter</filter-class>
  <init-param>
    <param-name>pathsAcceptingParams</param-name>
    <param-value>/resources/removeResource,/resources/addResource</param-value>
  </init-param>
</filter>
<filter-mapping>
  <filter-name>RestCSRF</filter-name>
  <url-pattern>/resources/*</url-pattern>
</filter-mapping>

フィルタークラス名

REST API用CSRF防止フィルターのフィルタークラス名は、org.apache.catalina.filters.RestCsrfPreventionFilter です。

初期化パラメータ

REST API用CSRF防止フィルターは以下の初期化パラメータをサポートしています

属性説明
denyStatus

拒否されたリクエストを拒否する際に使用されるHTTP応答ステータスコード。デフォルト値は403です。

pathsAcceptingParams

リクエストパラメータ X-CSRF-Token を介してノンスを受け入れることができるURLのカンマ区切りリスト。ヘッダー経由でノンス情報を提供できないユースケースでは、リクエストパラメータ経由で提供することができます。X-CSRF-Token ヘッダーが存在する場合、リクエスト内の同じ名前のどのパラメータよりも優先されます。リクエストパラメータは新しいノンスを取得するために使用できず、ヘッダーのみが新しいノンスを要求するために使用できます。

randomClass

ノンスの生成に使用するクラスの名前。このクラスは java.util.Random のインスタンスでなければなりません。設定されていない場合、デフォルト値の java.security.SecureRandom が使用されます。

Expiresフィルター

はじめに

ExpiresFilterは、Apache mod_expiresのJava Servlet API移植版です。このフィルターは、サーバー応答におけるExpires HTTPヘッダーとCache-Control HTTPヘッダーのmax-ageディレクティブの設定を制御します。有効期限は、ソースファイルの最終変更時刻、またはクライアントのアクセス時刻のいずれかに対して相対的に設定できます。

これらのHTTPヘッダーは、ドキュメントの有効性と永続性に関するクライアントへの指示です。キャッシュされている場合、この時間が経過するまでは、ドキュメントはソースからではなくキャッシュから取得されることがあります。その後、キャッシュされたコピーは「期限切れ」と見なされ無効となり、ソースから新しいコピーを取得する必要があります。

max-age以外のCache-Controlディレクティブ(RFC 2616 セクション 14.9を参照)を変更するには、他のサーブレットフィルターまたはApache Httpd mod_headersモジュールを使用できます。

基本設定例

画像、CSS、JavaScriptに「Expires」および「Cache-Control: max-age=」ヘッダーを追加するための基本設定。

<filter>
 <filter-name>ExpiresFilter</filter-name>
 <filter-class>org.apache.catalina.filters.ExpiresFilter</filter-class>
 <init-param>
    <param-name>ExpiresByType image</param-name>
    <param-value>access plus 10 minutes</param-value>
 </init-param>
 <init-param>
    <param-name>ExpiresByType text/css</param-name>
    <param-value>access plus 10 minutes</param-value>
 </init-param>
 <init-param>
    <param-name>ExpiresByType text/javascript</param-name>
    <param-value>access plus 10 minutes</param-value>
 </init-param>
</filter>
...
<filter-mapping>
 <filter-name>ExpiresFilter</filter-name>
 <url-pattern>/*</url-pattern>
 <dispatcher>REQUEST</dispatcher>
</filter-mapping>

代替構文

ExpiresDefault および ExpiresByType ディレクティブは、より読みやすい形式の構文でも定義できます

<init-param>
 <param-name>ExpiresDefault</param-name>
 <param-value><base> [plus] {<num> <type>}*</param-value>
</init-param>

<init-param>
 <param-name>ExpiresByType type</param-name>
 <param-value><base> [plus] {<num> <type>}*</param-value>
</init-param>

<init-param>
 <param-name>ExpiresByType type;encoding</param-name>
 <param-value><base> [plus] {<num> <type>}*</param-value>
</init-param>

ここで <base> は以下のいずれかです

  • access
  • now (access と同等)
  • modification

plus キーワードはオプションです。<num> は整数値(Integer.parseInt()で許容される)であるべきであり、<type> は以下のいずれかです

  • year, years
  • month, months
  • week, weeks
  • day, days
  • hour, hours
  • minute, minutes
  • second, seconds

例えば、以下のいずれかのディレクティブを使用すると、ドキュメントはデフォルトでアクセスされてから1ヶ月後に期限切れになります。

<init-param>
 <param-name>ExpiresDefault</param-name>
 <param-value>access plus 1 month</param-value>
</init-param>

<init-param>
 <param-name>ExpiresDefault</param-name>
 <param-value>access plus 4 weeks</param-value>
</init-param>

<init-param>
 <param-name>ExpiresDefault</param-name>
 <param-value>access plus 30 days</param-value>
</init-param>

有効期限は、複数の「<num> <type>」句を追加することで細かく調整できます。

<init-param>
 <param-name>ExpiresByType text/html</param-name>
 <param-value>access plus 1 month 15 days 2 hours</param-value>
</init-param>

<init-param>
 <param-name>ExpiresByType image/gif</param-name>
 <param-value>modification plus 5 hours 3 minutes</param-value>
</init-param>

変更日ベースの設定を使用する場合、ディスク上のファイルから来ないコンテンツにはExpiresヘッダーが追加されないことに注意してください。これは、そのようなコンテンツには変更時刻がないためです。

有効期限ヘッダー生成の適格性

応答が ExpiresFilter によってエンリッチされる資格があるのは、以下の条件を満たす場合です。

  1. 有効期限ヘッダー(Expires ヘッダーまたは Cache-Control ヘッダーの max-age ディレクティブ)が定義されていない場合、
  2. 応答ステータスコードが ExpiresExcludedResponseStatusCodes ディレクティブによって除外されていない場合、
  3. 応答の Content-TypeExpiresByType ディレクティブで定義されたタイプのいずれかに一致するか、または ExpiresDefault ディレクティブが定義されている場合。

注: Cache-Control ヘッダーに max-age 以外のディレクティブが含まれている場合、それらは ExpiresFilter によって追加される max-age ディレクティブと連結されます。

有効期限設定の選択

有効期限設定は以下のアルゴリズムに従って選択されます

  1. HttpServletResponse.getContentType() によって返される正確なコンテンツタイプに一致する ExpiresByType (charsetを含む場合もある、例: 'text/xml;charset=UTF-8'),
  2. HttpServletResponse.getContentType() がcharsetを含む場合、charsetなしのコンテンツタイプに一致する ExpiresByType (例: 'text/xml;charset=UTF-8' -> 'text/xml'),
  3. HttpServletResponse.getContentType() の主要なタイプ(例: '/' の前の部分文字列)に一致する ExpiresByType (例: 'text/xml;charset=UTF-8' -> 'text'),
  4. ExpiresDefault

フィルタークラス名

Expiresフィルターのフィルタークラス名は、org.apache.catalina.filters.ExpiresFilter です。

初期化パラメータ

Expiresフィルターは以下の初期化パラメータをサポートしています

属性説明
ExpiresExcludedResponseStatusCodes

このディレクティブは、ExpiresFilter が有効期限ヘッダーを生成しないHTTP応答ステータスコードを定義します。デフォルトでは、304 ステータスコード(「Not modified」)はスキップされます。値はHTTPステータスコードのカンマ区切りリストです。

このディレクティブは、ExpiresDefault ディレクティブの使用を容易にするのに役立ちます。実際、304 Not modified (Content-Type ヘッダーを指定します) の動作と、Expires および Cache-Control:max-age= ヘッダーを組み合わせると、不必要に理解が難しくなることがあります。

テーブルの下のサンプルを参照

ExpiresByType <content-type>

このディレクティブは、指定されたタイプ(例:text/html)のドキュメント用に生成されるExpiresヘッダーの値とCache-Controlヘッダーのmax-ageディレクティブを定義します。2番目の引数は、基準時間に加算されて有効期限日を構築する秒数を設定します。Cache-Control: max-ageは、有効期限日からリクエスト時間を減算し、その結果を秒数で表現することによって計算されます。

基準時間は、ファイルの最終変更時刻、またはクライアントがドキュメントにアクセスした時刻のいずれかです。どちらを使用するかは <code> フィールドで指定されます。M はファイルの最終変更時刻を基準時刻として使用することを意味し、A はクライアントのアクセス時刻を使用することを意味します。期間は秒単位で表されます。A2592000 は、代替構文で access plus 30 days を意味します。

効果の違いは微妙です。M(代替構文ではmodification)を使用すると、すべてのキャッシュ内のドキュメントの現在のコピーが同時に期限切れになります。これは、常に同じURLで見つかる週次通知のようなものに適しています。A(代替構文ではaccessまたはnow)を使用すると、有効期限はクライアントごとに異なります。これは、あまり頻繁に変わらない画像ファイル、特に同じ画像をすべて参照する関連ドキュメントのセット(つまり、画像は比較的短い時間内に繰り返しアクセスされます)に適しています。

注:コンテンツタイプにcharsetが含まれる場合(例:'ExpiresByType text/xml;charset=utf-8')、Tomcatは「;」と「charset」キーワードの間の空白文字を削除します。このため、charsetを含む有効期限の設定には、そのような空白文字を含めてはなりません

テーブルの下のサンプルを参照

これは、指定されたMIMEタイプのみについて、ExpiresDefault ディレクティブによって設定された有効期限を上書きします。

有効期限の計算は、このドキュメントの冒頭で説明されている代替構文を使用しても指定できます。

ExpiresDefault

このディレクティブは、対象となるレルム内のすべてのドキュメントの有効期限を計算するためのデフォルトアルゴリズムを設定します。これは、ExpiresByType ディレクティブによってタイプごとに上書きできます。引数の構文の詳細については、そのディレクティブの説明と、「代替構文」の説明も参照してください。

例: 応答ステータスコード 302, 500, 503 を除外

<init-param>
 <param-name>ExpiresExcludedResponseStatusCodes</param-name>
 <param-value>302, 500, 503</param-value>
</init-param>

ExpiresByType 初期化パラメータの例

<init-param>
   <param-name>ExpiresByType text/html</param-name>
   <param-value>access plus 1 month 15   days 2 hours</param-value>
</init-param>

<init-param>
   <!-- 2592000 seconds = 30 days -->
   <param-name>ExpiresByType image/gif</param-name>
   <param-value>A2592000</param-value>
</init-param>

トラブルシューティング

トラブルシューティングのために、org.apache.catalina.filters.ExpiresFilter でロギングを有効にしてください。

logging.properties の抜粋

org.apache.catalina.filters.ExpiresFilter.level = FINE    

初期化ログメッセージの例

Mar 26, 2010 2:01:41 PM org.apache.catalina.filters.ExpiresFilter init
FINE: Filter initialized with configuration ExpiresFilter[
 excludedResponseStatusCode=[304],
 default=null,
 byType={
    image=ExpiresConfiguration[startingPoint=ACCESS_TIME, duration=[10 MINUTE]],
    text/css=ExpiresConfiguration[startingPoint=ACCESS_TIME, duration=[10 MINUTE]],
    text/javascript=ExpiresConfiguration[startingPoint=ACCESS_TIME, duration=[10 MINUTE]]}]

ExpiresFilter が有効期限を追加するリクエストごとのログメッセージの例を以下に示します。メッセージは1行ですが、読みやすさのためにここで折り返されています。

Mar 26, 2010 2:09:47 PM org.apache.catalina.filters.ExpiresFilter onBeforeWriteResponseBody
FINE: Request "/tomcat.gif" with response status "200"
 content-type "image/gif", set expiration date 3/26/10 2:19 PM

ExpiresFilter が有効期限を追加しないリクエストごとのログメッセージの例

Mar 26, 2010 2:10:27 PM org.apache.catalina.filters.ExpiresFilter onBeforeWriteResponseBody
FINE: Request "/docs/config/manager.html" with response status "200"
 content-type "text/html", no expiration configured

HTTPヘッダーセキュリティフィルター

はじめに

接続のセキュリティを向上させるために、応答に追加できるHTTPヘッダーがいくつかあります。このフィルターは、それらのヘッダーを追加するメカニズムを提供します。CORSのような、より複雑な要件を持つセキュリティ関連のヘッダーは、別のフィルターとして実装されていることに注意してください。

フィルタークラス名

HTTPヘッダーセキュリティフィルターのフィルタークラス名は、org.apache.catalina.filters.HttpHeaderSecurityFilter です。

初期化パラメータ

HTTPヘッダーセキュリティフィルターは以下の初期化パラメータをサポートしています

属性説明
hstsEnabled

セキュアなリクエストに対する応答に、HTTP Strict Transport Security (HSTS) ヘッダー (Strict-Transport-Security) が設定されますか。既に存在するHSTSヘッダーは置き換えられます。HSTSの詳細についてはRFC 6797を参照してください。指定されていない場合、デフォルト値のtrueが使用されます。

hstsMaxAgeSeconds

HSTSヘッダーで使用されるべき最大有効期間(max age)の値。負の値はゼロとして扱われます。指定されていない場合、デフォルト値の0が使用されます。

hstsIncludeSubDomains

includeSubDomainsパラメータはHSTSヘッダーに含まれるべきですか。指定されていない場合、デフォルト値のfalseが使用されます。

hstsPreload

preloadパラメータはHSTSヘッダーに含まれるべきですか。指定されていない場合、デフォルト値のfalseが使用されます。このパラメータに関する重要な情報については、https://hstspreload.org を参照してください。

antiClickJackingEnabled

クリックジャッキング防止ヘッダー (X-Frame-Options) が応答に設定されるべきですか。既に存在するクリックジャッキング防止ヘッダーは置き換えられます。指定されていない場合、デフォルト値のtrueが使用されます。

antiClickJackingOption

クリックジャッキング防止ヘッダーにどのような値を使用すべきですか?DENYSAMEORIGINALLOW-FROM (大文字小文字を区別しない)のいずれかである必要があります。指定されていない場合、デフォルト値のDENYが使用されます。

antiClickJackingUri

antiClickJackingOption に ALLOW-FROM が使用される場合、どのURIが許可されるべきですか?指定されていない場合、デフォルト値の空文字列が使用されます。

blockContentTypeSniffingEnabled

コンテンツタイプスニッフィングをブロックするヘッダー (X-Content-Type-Options) は、すべての応答に設定されるべきですか。既に存在する場合、ヘッダーは置き換えられます。指定されていない場合、デフォルト値のtrueが使用されます。

レート制限フィルター

はじめに

レート制限フィルターは、単一のIPアドレスからのリクエスト数を時間枠(タイムバケットとも呼ばれる)内で制限することで、サービス妨害(DoS)攻撃やブルートフォース攻撃を軽減するのに役立ちます。例えば、60秒あたり300リクエストなどです。

このフィルターは、各IPアドレスのタイムバケット内のカウンターを増加させることで機能します。カウンターが許容される制限を超えると、そのIPからの後続のリクエストは、バケット時間が終了して新しいバケットが開始されるまで、「429 Too many requests」応答とともに破棄されます。

RateLimiterの実装は、rateLimitClassName 初期化パラメータを介して設定できます。デフォルトの実装である org.apache.catalina.util.FastRateLimiter は、効率と低オーバーヘッドのために最適化されており、一部の設定値をより効率的な値に変換します。たとえば、60秒のタイムバケットの設定は65.536秒に変換されます。これにより、ビットシフト演算を使用して非常に高速なバケット計算が可能になります。ユーザーの意図に忠実であるために、設定されたリクエスト数は同じ比率で乗算されるため、60秒あたり100リクエストの設定は、実際の値として65秒あたり109リクエストとなります。代替の実装である org.apache.catalina.util.ExactRateLimiter は、効率は劣るものの、より正確な制御を提供することを意図しており、秒単位での有効期間と許可されるリクエスト数は設定値と一致します。org.apache.catalina.util.RateLimiter インターフェースを実装している限り、異なるクラスを指定できます。

異なるURIに対して異なる制限を設定することは一般的です。例えば、ログインページや認証スクリプトは通常、アプリケーションの他の部分よりもはるかに少ないリクエストしか受け取らないと予想されるため、15秒あたり5リクエストのみを許可するフィルター定義を追加し、それらのURIをそこにマッピングすることができます。

許可された制限を超えるリクエストの終了を無効にするには、enforcefalse に設定できます。その後、アプリケーションコードはリクエスト属性 org.apache.catalina.filters.RateLimitFilter.Count を検査し、役割など、持っている他の情報に基づいてリクエストを処理する方法を決定できます。例えば、特定のユーザーに対して役割に基づいてより多くのリクエストを許可するなどです。

exposeHeaders は、HTTPのRateLimitヘッダーフィールド (ドラフト) に従って、レートリミッターの設定と状態をHTTP応答ヘッダーを介して出力することを可能にします。

警告: Tomcatがリバースプロキシの背後にある場合、レート制限フィルターがクライアントIPアドレスを認識するようにする必要があります。例えば、リモートIPフィルターを使用している場合、レート制限フィルターのフィルターマッピングはリモートIPフィルターのマッピングのに来る必要があります。これにより、各リクエストがレート制限フィルターが適用される前にIPアドレスが解決されることが保証されます。そうしないと、異なるIPからのリクエストが同じバケットでカウントされ、自己誘発型のDoS攻撃につながる可能性があります。

フィルタークラス名

レート制限フィルターのフィルタークラス名は、org.apache.catalina.filters.RateLimitFilter です。

初期化パラメータ

レート制限フィルターは以下の初期化パラメータをサポートしています

属性説明
bucketDuration

タイムバケットの秒数。デフォルトは60です。

bucketRequests

タイムバケットで許可されるリクエスト数。デフォルトは300です。

enforce

タイムウィンドウあたりの最大許容数を超過してもリクエストを通過させるには、falseに設定します。アプリケーションコードは、リクエスト属性 org.apache.catalina.filters.RateLimitFilter.Count を検査して、そのIPからタイムウィンドウ内に行われたリクエストの数を取得することができます。デフォルトはtrueです。

exposeHeaders

レートリミッターの設定と状態を、HTTPのRateLimitヘッダーフィールド (ドラフト) に従ってHTTP応答ヘッダーを介して公開するには、trueに設定します。デフォルトはfalseです。

rateLimitClassName

RateLimiterインターフェースの実装の完全なクラス名。デフォルトは「org.apache.catalina.util.FastRateLimiter」で、効率のために最適化されています。厳密なレート制限が必要で、わずかな効率の低下を受け入れられる場合は、代わりに「org.apache.catalina.util.ExactRateLimiter」を使用できます。

statusCode

リクエストが破棄されたときに返すステータスコード。デフォルトは429です。

statusMessage

リクエストが破棄されたときに返すステータスメッセージ。デフォルトは「Too many requests」です。

サイトのレート制限を1分あたり300リクエスト(デフォルト)に設定する

    <filter>
        <filter-name>RateLimitFilter Global</filter-name>
        <filter-class>org.apache.catalina.filters.RateLimitFilter</filter-class>
    </filter>

    <filter-mapping>
        <filter-name>RateLimitFilter Global</filter-name>
        <url-pattern>*</url-pattern>
    </filter-mapping>

/auth/* スクリプトのレート制限を1分あたり20リクエストに設定する

    <filter>
        <filter-name>RateLimitFilter Login</filter-name>
        <filter-class>org.apache.catalina.filters.RateLimitFilter</filter-class>
        <init-param>
            <param-name>bucketRequests</param-name>
            <param-value>20</param-value>
        </init-param>
    </filter>

    <filter-mapping>
        <filter-name>RateLimitFilter Login</filter-name>
        <url-pattern>/auth/*</url-pattern>
    </filter-mapping>

リモートアドレスフィルター

はじめに

リモートアドレスフィルターは、このリクエストを送信したクライアントのIPアドレスを1つ以上の正規表現と比較し、リクエストの続行を許可するか、このクライアントからのリクエストの処理を拒否するかを決定できます。

正規表現の構文は、「標準」のワイルドカードマッチングとは異なります。Tomcatはjava.util.regexパッケージを使用しています。サポートされている表現の詳細については、Javaドキュメントを参照してください。

注: このフィルターをIPv6アドレスで使用する場合、注意点があります。このバルブが処理するIPアドレスの形式は、それを取得するために使用されたAPIに依存します。アドレスがInet6Addressクラスを使用してJavaソケットから取得された場合、その形式は x:x:x:x:x:x:x:x になります。つまり、localhostのIPアドレスは、より一般的に使用される ::1 ではなく、0:0:0:0:0:0:0:1 になります。実際の値についてはアクセスログを参照してください。

参照: リモートホストフィルター

フィルタークラス名

リモートアドレスフィルターのフィルタークラス名は、org.apache.catalina.filters.RemoteAddrFilter です。

初期化パラメータ

リモートアドレスフィルターは以下の初期化パラメータをサポートしています

属性説明
allow

リモートクライアントのIPアドレスと比較される正規表現(java.util.regexを使用)。この属性が指定されている場合、このリクエストが受け入れられるためにはリモートアドレスが一致しなければなりません。この属性が指定されていない場合、リモートアドレスがdenyパターンに一致しない限り、すべてのリクエストが受け入れられます。

deny

リモートクライアントのIPアドレスと比較される正規表現(java.util.regexを使用)。この属性が指定されている場合、このリクエストが受け入れられるためにはリモートアドレスが一致してはなりません。この属性が指定されていない場合、リクエストの受け入れはaccept属性のみによって決定されます。

denyStatus

拒否されたリクエストを拒否する際に使用されるHTTP応答ステータスコード。デフォルト値は403です。例えば、404に設定することもできます。

localhostから接続するクライアントのみにアクセスを許可するには

    <filter>
      <filter-name>Remote Address Filter</filter-name>
      <filter-class>org.apache.catalina.filters.RemoteAddrFilter</filter-class>
      <init-param>
        <param-name>allow</param-name>
        <param-value>127\.\d+\.\d+\.\d+|::1|0:0:0:0:0:0:0:1</param-value>
      </init-param>
    </filter>
    <filter-mapping>
      <filter-name>Remote Address Filter</filter-name>
      <url-pattern>/*</url-pattern>
    </filter-mapping>

リモートホストフィルター

はじめに

リモートホストフィルターは、このリクエストを送信したクライアントのホスト名を1つ以上の正規表現と比較し、リクエストの続行を許可するか、このクライアントからのリクエストの処理を拒否するかを決定できます。

正規表現の構文は、「標準」のワイルドカードマッチングとは異なります。Tomcatはjava.util.regexパッケージを使用しています。サポートされている表現の詳細については、Javaドキュメントを参照してください。

注: このフィルターは、メソッド ServletRequest.getRemoteHost() によって返される値を処理します。このメソッドが適切なホスト名を返すようにするには、コネクターで「DNSルックアップ」機能を有効にする必要があります。

参照: リモートアドレスフィルターHTTPコネクターの設定。

フィルタークラス名

リモートホストフィルターのフィルタークラス名は、org.apache.catalina.filters.RemoteHostFilter です。

初期化パラメータ

リモートホストフィルターは以下の初期化パラメータをサポートしています

属性説明
allow

リモートクライアントのホスト名と比較される正規表現(java.util.regexを使用)。この属性が指定されている場合、このリクエストが受け入れられるためにはリモートホスト名が一致しなければなりません。この属性が指定されていない場合、リモートホスト名がdenyパターンに一致しない限り、すべてのリクエストが受け入れられます。

deny

リモートクライアントのホスト名と比較される正規表現(java.util.regexを使用)。この属性が指定されている場合、このリクエストが受け入れられるためにはリモートホスト名が一致してはなりません。この属性が指定されていない場合、リクエストの受け入れはaccept属性のみによって決定されます。

denyStatus

拒否されたリクエストを拒否する際に使用されるHTTP応答ステータスコード。デフォルト値は403です。例えば、404に設定することもできます。

リモートCIDRフィルター

はじめに

リモートCIDRフィルターは、このリクエストを送信したクライアントのIPアドレスをCIDR表記に従う1つ以上のネットマスクと比較し、リクエストの続行を許可するか、このクライアントからのリクエストの処理を拒否するかを決定できます。IPv4とIPv6の両方が完全にサポートされています。

このフィルターはApache httpdの OrderAllow fromDeny from ディレクティブを模倣していますが、以下の制限があります

  • Order は常に allow, deny となります。
  • ネットマスクのドットクワッド表記はサポートされていません(つまり、192.168.1.0/255.255.255.0 とは書けず、192.168.1.0/24 と書く必要があります)。
  • 10.10. のようなショートカット(10.10.0.0/16 と同等)はサポートされていません。
  • フィルター名が示すとおり、これはCIDR専用フィルターであるため、.mydomain.com のようなサブドメイン表記もサポートされていません。

このフィルターのその他の機能は以下の通りです

  • CIDRプレフィックスを省略すると、このフィルターは単一IPフィルターになります。
  • リモートホストフィルターとは異なり、IPv6アドレスを短縮形式(::1, fe80::/71など)で処理できます。

フィルタークラス名

リモートCIDRフィルターのフィルタークラス名は、org.apache.catalina.filters.RemoteCIDRFilter です。

初期化パラメータ

リモートCIDRフィルターは以下の初期化パラメータをサポートしています

属性説明
allow

リモートクライアントのIPアドレスと比較されるIPv4またはIPv6のネットマスクまたはアドレスのカンマ区切りリスト。この属性が指定されている場合、このリクエストが受け入れられるためにはリモートアドレスが一致しなければなりません。この属性が指定されていない場合、リモートIPがdeny属性内のネットマスクに一致しない限り、すべてのリクエストが受け入れられます。

deny

リモートクライアントのIPアドレスと比較されるIPv4またはIPv6のネットマスクまたはアドレスのカンマ区切りリスト。この属性が指定されている場合、このリクエストが受け入れられるためにはリモートアドレスが一致してはなりません。この属性が指定されていない場合、リクエストの受け入れはaccept属性のみによって決定されます。

localhostおよびローカルネットワーク 192.68.0.* から接続するクライアントのみにアクセスを許可するには

      <filter>
        <filter-name>Remote CIDR Filter</filter-name>
        <filter-class>org.apache.catalina.filters.RemoteCIDRFilter</filter-class>
        <init-param>
          <param-name>allow</param-name>
          <param-value>127.0.0.1, ::1, 192.68.0.0/24</param-value>
        </init-param>
      </filter>

      <filter-mapping>
        <filter-name>Remote CIDR Filter</filter-name>
        <url-pattern>/*</url-pattern>
      </filter-mapping>

リモートIPフィルター

はじめに

mod_remoteipのTomcat移植版であるこのフィルターは、リクエストの見かけ上のクライアントリモートIPアドレスとホスト名を、プロキシまたはロードバランサーがリクエストヘッダー(例:「X-Forwarded-For」)を介して提示するIPアドレスリストに置き換えます。

このフィルターのもう1つの機能は、見かけ上のスキーム(http/https)、サーバーポート、および request.secure を、プロキシまたはロードバランサーがリクエストヘッダー(例:「X-Forwarded-Proto」)を介して提示するスキームに置き換えることです。

リモートアドレス/ホストフィルターと組み合わせて使用する場合、このフィルターは、正しいクライアントIPアドレスがリモートアドレス/ホストフィルターに提示されるように、最初に定義されるべきです。

注: デフォルトでは、このフィルターはアクセスログに書き込まれる値に影響を与えません。元の値は、リクエスト処理がフィルターを離れるときに復元され、これは常にアクセスロギングよりも早く発生します。このフィルターによって設定されたリモートアドレス、リモートホスト、サーバーポート、プロトコルの値をアクセスログに渡すには、それらはリクエスト属性に格納されます。これらの値の公開はデフォルトで有効になっていますが、AccessLogValve はそれらを使用するように明示的に設定する必要があります。AccessLogValverequestAttributesEnabled 属性のドキュメントを参照してください。

このフィルターによって設定され、アクセスロギングによって使用できるリクエスト属性の名前は以下の通りです

  • org.apache.catalina.AccessLog.RemoteAddr
  • org.apache.catalina.AccessLog.RemoteHost
  • org.apache.catalina.AccessLog.Protocol
  • org.apache.catalina.AccessLog.ServerPort
  • org.apache.tomcat.remoteAddr

フィルタークラス名

リモートIPフィルターのフィルタークラス名は、org.apache.catalina.filters.RemoteIpFilter です。

'x-forwarded-for' を処理するための基本設定

このフィルターはx-forwarded-forHTTPヘッダーを処理します。

      <filter>
        <filter-name>RemoteIpFilter</filter-name>
        <filter-class>org.apache.catalina.filters.RemoteIpFilter</filter-class>
      </filter>

      <filter-mapping>
        <filter-name>RemoteIpFilter</filter-name>
        <url-pattern>/*</url-pattern>
        <dispatcher>REQUEST</dispatcher>
      </filter-mapping>

'x-forwarded-for' と 'x-forwarded-proto' を処理するための基本設定

このフィルターはx-forwarded-forおよびx-forwarded-protoHTTPヘッダーを処理します。SSL接続の場合のx-forwarded-protoヘッダーの期待値はhttps(大文字小文字を区別しない)です。

      <filter>
        <filter-name>RemoteIpFilter</filter-name>
        <filter-class>org.apache.catalina.filters.RemoteIpFilter</filter-class>
        <init-param>
          <param-name>protocolHeader</param-name>
          <param-value>x-forwarded-proto</param-value>
        </init-param>
      </filter>

      <filter-mapping>
        <filter-name>RemoteIpFilter</filter-name>
        <url-pattern>/*</url-pattern>
        <dispatcher>REQUEST</dispatcher>
      </filter-mapping>

内部プロキシを使用する高度な設定

RemoteIpFilter の設定

     <filter>
       <filter-name>RemoteIpFilter</filter-name>
       <filter-class>org.apache.catalina.filters.RemoteIpFilter</filter-class>
       <init-param>
         <param-name>internalProxies</param-name>
         <param-value>192\.168\.0\.10|192\.168\.0\.11</param-value>
       </init-param>
       <init-param>
         <param-name>remoteIpHeader</param-name>
         <param-value>x-forwarded-for</param-value>
       </init-param>
       <init-param>
         <param-name>remoteIpProxiesHeader</param-name>
         <param-value>x-forwarded-by</param-value>
       </init-param>
       <init-param>
         <param-name>protocolHeader</param-name>
         <param-value>x-forwarded-proto</param-value>
       </init-param>
     </filter>

     <filter-mapping>
       <filter-name>RemoteIpFilter</filter-name>
       <url-pattern>/*</url-pattern>
       <dispatcher>REQUEST</dispatcher>
     </filter-mapping>

リクエスト値

プロパティ RemoteIpFilter 適用前の値 RemoteIpFilter 適用後の値
request.remoteAddr 192.168.0.10 140.211.11.130
request.header['x-forwarded-for'] 140.211.11.130, 192.168.0.10 null
request.header['x-forwarded-by'] null null
request.header['x-forwarded-proto'] https https
request.scheme http https
request.secure false true
request.serverPort 80 443

注 : x-forwarded-by ヘッダーは null です。これは、リクエストが内部プロキシのみを経由したためです。x-forwarded-fornull です。これは、すべてのプロキシが信頼されているか内部プロキシであるためです。

信頼されたプロキシを使用する高度な設定

RemoteIpFilter の設定

     <filter>
       <filter-name>RemoteIpFilter</filter-name>
       <filter-class>org.apache.catalina.filters.RemoteIpFilter</filter-class>
       <init-param>
         <param-name>internalProxies</param-name>
         <param-value>192\.168\.0\.10|192\.168\.0\.11</param-value>
       </init-param>
       <init-param>
         <param-name>remoteIpHeader</param-name>
         <param-value>x-forwarded-for</param-value>
       </init-param>
       <init-param>
         <param-name>remoteIpProxiesHeader</param-name>
         <param-value>x-forwarded-by</param-value>
       </init-param>
       <init-param>
         <param-name>trustedProxies</param-name>
         <param-value>proxy1|proxy2</param-value>
       </init-param>
     </filter>

     <filter-mapping>
       <filter-name>RemoteIpFilter</filter-name>
       <url-pattern>/*</url-pattern>
       <dispatcher>REQUEST</dispatcher>
     </filter-mapping>

リクエスト値

プロパティ RemoteIpFilter 適用前の値 RemoteIpFilter 適用後の値
request.remoteAddr 192.168.0.10 140.211.11.130
request.header['x-forwarded-for'] 140.211.11.130, proxy1, proxy2 null
request.header['x-forwarded-by'] null proxy1, proxy2

注: proxy1proxy2 はどちらも x-forwarded-for ヘッダーで提供される信頼されたプロキシであり、両方とも x-forwarded-by ヘッダーに移行されます。x-forwarded-fornull です。これは、すべてのプロキシが信頼されているか内部プロキシであるためです。

内部および信頼されたプロキシを使用する高度な設定

RemoteIpFilter の設定

     <filter>
       <filter-name>RemoteIpFilter</filter-name>
       <filter-class>org.apache.catalina.filters.RemoteIpFilter</filter-class>
       <init-param>
         <param-name>internalProxies</param-name>
         <param-value>192\.168\.0\.10|192\.168\.0\.11</param-value>
       </init-param>
       <init-param>
         <param-name>remoteIpHeader</param-name>
         <param-value>x-forwarded-for</param-value>
       </init-param>
       <init-param>
         <param-name>remoteIpProxiesHeader</param-name>
         <param-value>x-forwarded-by</param-value>
       </init-param>
       <init-param>
         <param-name>trustedProxies</param-name>
         <param-value>proxy1|proxy2</param-value>
       </init-param>
     </filter>

     <filter-mapping>
       <filter-name>RemoteIpFilter</filter-name>
       <url-pattern>/*</url-pattern>
       <dispatcher>REQUEST</dispatcher>
     </filter-mapping>

リクエスト値

プロパティ RemoteIpFilter 適用前の値 RemoteIpFilter 適用後の値
request.remoteAddr 192.168.0.10 140.211.11.130
request.header['x-forwarded-for'] 140.211.11.130, proxy1, proxy2, 192.168.0.10 null
request.header['x-forwarded-by'] null proxy1, proxy2

注: proxy1proxy2 はどちらも x-forwarded-for ヘッダーで提供される信頼されたプロキシであり、両方とも x-forwarded-by ヘッダーに移行されます。192.168.0.10 は内部プロキシであるため、x-forwarded-by には表示されません。x-forwarded-fornull です。これは、すべてのプロキシが信頼されているか内部プロキシであるためです。

信頼されていないプロキシを使用する高度な設定

RemoteIpFilter の設定

     <filter>
       <filter-name>RemoteIpFilter</filter-name>
       <filter-class>org.apache.catalina.filters.RemoteIpFilter</filter-class>
       <init-param>
         <param-name>internalProxies</param-name>
         <param-value>192\.168\.0\.10|192\.168\.0\.11</param-value>
       </init-param>
       <init-param>
         <param-name>remoteIpHeader</param-name>
         <param-value>x-forwarded-for</param-value>
       </init-param>
       <init-param>
         <param-name>remoteIpProxiesHeader</param-name>
         <param-value>x-forwarded-by</param-value>
       </init-param>
       <init-param>
         <param-name>trustedProxies</param-name>
         <param-value>proxy1|proxy2</param-value>
       </init-param>
     </filter>

     <filter-mapping>
       <filter-name>RemoteIpFilter</filter-name>
       <url-pattern>/*</url-pattern>
       <dispatcher>REQUEST</dispatcher>
     </filter-mapping>

リクエスト値

プロパティ RemoteIpFilter 適用前の値 RemoteIpFilter 適用後の値
request.remoteAddr 192.168.0.10 untrusted-proxy
request.header['x-forwarded-for'] 140.211.11.130, untrusted-proxy, proxy1 140.211.11.130
request.header['x-forwarded-by'] null proxy1

注: x-forwarded-by には信頼されたプロキシ proxy1 が保持されます。x-forwarded-by140.211.11.130 が保持されるのは、untrusted-proxy が信頼されていないため、untrusted-proxy が実際のリモートIPであると信頼できないからです。request.remoteAddrproxy1 によって検証されたIPである untrusted-proxy です。

初期化パラメータ

リモートIPフィルターは以下の初期化パラメータをサポートしています

属性説明
enableLookups

ServletRequest#getRemoteHost() を呼び出す際に、ホスト名を提供するためにDNSルックアップを実行すべきですか。指定されていない場合、デフォルトのfalseが使用されます。

remoteIpHeader

このバルブが読み取るHTTPヘッダーの名前で、リクエスト元のクライアントからたどられたIPアドレスのリストを保持します。指定されていない場合、デフォルトのx-forwarded-forが使用されます。

internalProxies

プロキシのIPアドレスが内部プロキシと見なされるために一致しなければならない正規表現(java.util.regexを使用)。remoteIpHeader に表示される内部プロキシは信頼され、proxiesHeader の値には表示されません。指定されていない場合、デフォルト値の 10\.\d{1,3}\.\d{1,3}\.\d{1,3}|192\.168\.\d{1,3}\.\d{1,3}|169\.254\.\d{1,3}\.\d{1,3}|127\.\d{1,3}\.\d{1,3}\.\d{1,3}|100\.6[4-9]{1}\.\d{1,3}\.\d{1,3}|100\.[7-9]{1}\d{1}\.\d{1,3}\.\d{1,3}|100\.1[0-1]{1}\d{1}\.\d{1,3}\.\d{1,3}|100\.12[0-7]{1}\.\d{1,3}\.\d{1,3}|172\.1[6-9]{1}\.\d{1,3}\.\d{1,3}|172\.2[0-9]{1}\.\d{1,3}\.\d{1,3}|172\.3[0-1]{1}\.\d{1,3}\.\d{1,3}|0:0:0:0:0:0:0:1|::1|fe[89ab]\p{XDigit}:.*|"f[cd]\p{XDigit}{2}+:.* が使用されます。

proxiesHeader

このバルブによって作成されるHTTPヘッダーの名前で、受信するremoteIpHeaderで処理されたプロキシのリストを保持します。指定されていない場合、デフォルトのx-forwarded-byが使用されます。

requestAttributesEnabled

リモートアドレス、リモートホスト、サーバーポート、およびプロトコルについてリクエストによって返される値を上書きするためにAccessLog実装が使用するリクエスト属性を設定するには、true に設定します。リクエスト属性は、転送されたリモートアドレスをManager Webアプリケーションのステータスページに表示できるようにするためにも使用されます。設定されていない場合、デフォルト値のtrueが使用されます。

trustedProxies

プロキシのIPアドレスが信頼されたプロキシと見なされるために一致しなければならない正規表現(java.util.regexを使用)。remoteIpHeader に表示される信頼されたプロキシは信頼され、proxiesHeader の値に表示されます。指定されていない場合、どのプロキシも信頼されません。

protocolHeader

このバルブが読み取るHTTPヘッダーの名前で、クライアントがプロキシに接続するために使用したプロトコルを保持します。指定されていない場合、デフォルトのX-Forwarded-Protoが使用されます。

hostHeader

このバルブが読み取るHTTPヘッダーの名前で、クライアントがプロキシに接続するために使用したホストを保持します。指定されていない場合、デフォルトのnullが使用されます。

portHeader

このバルブが読み取るHTTPヘッダーの名前で、クライアントがプロキシに接続するために使用したポートを保持します。指定されていない場合、デフォルトのnullが使用されます。

protocolHeaderHttpsValue

HTTPSリクエストであることを示すprotocolHeaderの値。指定されていない場合、デフォルトのhttpsが使用されます。

httpServerPort

protocolHeaderhttp プロトコルを示し、かつ portHeader が存在しない場合に ServletRequest.getServerPort() によって返される値。指定されていない場合、デフォルトの80が使用されます。

httpsServerPort

protocolHeaderhttps プロトコルを示し、かつ portHeader が存在しない場合に ServletRequest.getServerPort() によって返される値。指定されていない場合、デフォルトの443が使用されます。

changeLocalName

trueの場合、ServletRequest.getLocalName()ServletRequest.getServerName() によって返される値がこのフィルターによって変更されます。指定されていない場合、デフォルトのfalseが使用されます。

changeLocalPort

trueの場合、ServletRequest.getLocalPort()ServletRequest.getServerPort() によって返される値がこのフィルターによって変更されます。指定されていない場合、デフォルトのfalseが使用されます。

リクエストダンプフィルター

はじめに

リクエストダンプフィルターは、リクエストオブジェクトとレスポンスオブジェクトから情報をログに記録し、デバッグ目的で使用することを意図しています。このフィルターを使用する際は、org.apache.catalina.filter.RequestDumperFilter ロガーを専用ファイルに振り向け、org.apache.juli.VerbatimFormatter を使用することを推奨します。

警告: このフィルターの使用には副作用があります。 このフィルターからの出力には、リクエストに含まれるすべてのパラメータが含まれます。これらのパラメータは、デフォルトのプラットフォームエンコーディングを使用してデコードされます。Webアプリケーション内でその後に request.setCharacterEncoding() を呼び出しても、効果はありません。

フィルタークラス名

リクエストダンプフィルターのフィルタークラス名は、org.apache.catalina.filters.RequestDumperFilter です。

初期化パラメータ

リクエストダンプフィルターは初期化パラメータをサポートしていません。

設定例

Webアプリケーションのweb.xmlにおける以下のエントリは、そのWebアプリケーションのすべてのリクエストに対してリクエストダンプフィルターを有効にします。もしエントリが CATALINA_BASE/conf/web.xml に追加された場合、リクエストダンプフィルターはすべてのWebアプリケーションに対して有効になります。

<filter>
    <filter-name>requestdumper</filter-name>
    <filter-class>
        org.apache.catalina.filters.RequestDumperFilter
    </filter-class>
</filter>
<filter-mapping>
    <filter-name>requestdumper</filter-name>
    <url-pattern>*</url-pattern>
</filter-mapping>

CATALINA_BASE/conf/logging.properties の以下のエントリは、リクエストダンプフィルターの出力用に別のログファイルを作成します。

# To this configuration below, 1request-dumper.org.apache.juli.FileHandler
# also needs to be added to the handlers property near the top of the file
1request-dumper.org.apache.juli.FileHandler.level = INFO
1request-dumper.org.apache.juli.FileHandler.directory = ${catalina.base}/logs
1request-dumper.org.apache.juli.FileHandler.prefix = request-dumper.
1request-dumper.org.apache.juli.FileHandler.encoding = UTF-8
1request-dumper.org.apache.juli.FileHandler.formatter = org.apache.juli.VerbatimFormatter
org.apache.catalina.filters.RequestDumperFilter.level = INFO
org.apache.catalina.filters.RequestDumperFilter.handlers = \
  1request-dumper.org.apache.juli.FileHandler

セッション初期化フィルター

はじめに

セッション初期化フィルターは、リクエストが処理される前に jakarta.servlet.http.HttpSession を初期化します。これは、ハンドシェイクフェーズ中に HttpSession が必要な場合、JSR-356準拠のWebSocket実装に必要です。

WebSocketのJava APIは、リクエスト時に HttpSession が初期化されることを義務付けていないため、事前に HttpSession が初期化されていない場合、jakarta.servlet.http.HttpServletRequestgetSession()null を返します。

このフィルターは、その url-pattern に一致する任意の HttpServletRequest に対してHttpSessionを初期化することで、その問題を解決します。

フィルタークラス名

セッション初期化フィルターのフィルタークラス名は、org.apache.catalina.filters.SessionInitializerFilter です。

初期化パラメータ

セッション初期化フィルターは初期化パラメータをサポートしていません。

設定例

Webアプリケーションのデプロイメントディスクリプタ、web.xmlにおける以下のエントリは、指定されたURLパターン(この例では「/ws/*」)に一致するリクエストに対してセッション初期化フィルターを有効にします。

<filter>
    <filter-name>SessionInitializer</filter-name>
    <filter-class>org.apache.catalina.filters.SessionInitializerFilter</filter-class>
</filter>
<filter-mapping>
    <filter-name>SessionInitializer</filter-name>
    <url-pattern>/ws/*</url-pattern>
</filter-mapping>

文字エンコーディング設定フィルター

はじめに

ユーザーエージェントは、リクエストに文字エンコーディング情報を含めない場合があります。リクエストの処理方法によっては、通常、ISO-8859-1 のデフォルトエンコーディングが使用されます。これは常に望ましいわけではありません。このフィルターは、そのエンコーディングを設定するか、特定の値に強制するためのオプションを提供します。本質的に、このフィルターは ServletRequest.setCharacterEncoding() メソッドを呼び出します。

このフィルターによって設定された値は、パラメータの解析がこのフィルターよりも後に行われる場合、POSTリクエストのパラメータを解析する際に実際に使用されます。したがって、フィルターマッピングの順序は重要です。GETリクエストのエンコーディングはここで設定されるのではなく、コネクターで設定されることに注意してください。詳細については、FAQの文字エンコーディングのページを参照してください。

フィルタークラス名

文字エンコーディング設定フィルターのフィルタークラス名は、org.apache.catalina.filters.SetCharacterEncodingFilter です。

初期化パラメータ

文字エンコーディング設定フィルターは以下の初期化パラメータをサポートしています

属性説明
encoding

設定されるべき文字エンコーディングの名前。

ignore

ユーザーエージェントによって指定された文字エンコーディングが無視されるかどうかを決定します。この属性がtrueの場合、ユーザーエージェントによって提供されるすべての値は無視されます。falseの場合、エンコーディングはユーザーエージェントがエンコーディングを指定しなかった場合にのみ設定されます。デフォルト値はfalseです。