Google Cloud Armor の各セキュリティ ポリシー ルールには、優先度、一致条件、アクションがあります。実行されるのは、リクエストに一致する最も優先度の高いルールのアクションです。その他のルールは、同じ一致条件が設定されていても優先度が低ければ評価されません。
各セキュリティ ポリシー ルールでは 2 種類の一致条件を指定できます。
- 基本一致条件。IP アドレスまたは IP アドレス範囲のリストで構成されます。基本一致条件は、Google Cloud CLI を使用してルールを作成するときに
--src-ip-rangesフラグを使用して定義します。 - 高度な一致条件。受信リクエストのさまざまな属性と照合できる最大 5 つのサブ式を含む式で構成されます。高度な一致条件は、Google Cloud CLI を使用してルールを作成するときに
--expressionフラグを使用して定義します。
このページでは、セキュリティ ポリシー ルールを作成して表示する方法について説明します。また、高度な一致条件で式を記述するために使用する Cloud Armor のカスタムルール言語のリファレンスについても説明します。Cloud Armor のカスタムルール言語は Common Expression Language(CEL)のサブセットです。
Cloud Armor のカスタムルール言語で記述する式には、次の 2 つのコンポーネントが必要です。
- 属性: 検査するデータ
- 演算: データの使用方法
たとえば、次の式では、演算 inIpRange で属性 origin.ip と 198.51.100.0/24 が使用されています。この式は、origin.ip が 198.51.100.0/24 の IP アドレス範囲に含まれている場合、true を返します。
inIpRange(origin.ip, '198.51.100.0/24')
上の式で照合されるのはクライアント IP アドレスだけですが、この式を使用する Cloud Armor セキュリティ ポリシー ルールは、割り当ての観点からは高度な一致条件を使用するルールとみなされます。詳細については、Cloud Armor の割り当てと上限をご覧ください。
セキュリティ ポリシー ルールを作成する
このセクションの手順に沿って、Cloud Armor セキュリティ ポリシーにルールを追加します。
コンソール
Google Cloud コンソールで、[Cloud Armor ポリシー] ページに移動します。
セキュリティ ポリシーの名前をクリックして [ポリシーの詳細] ページを開き、[ルール] タブをクリックします。
[ルールを追加] をクリックします。
(省略可)ルールの説明を入力します。
モードを選択します。
- 基本モード: IP アドレスまたは範囲に基づいてトラフィックを許可または拒否します。
- 詳細モード: ルール式に基づいてトラフィックを許可または拒否します。
[一致] フィールドで、ルールが適用される条件を指定します。
基本モード: ルールに一致する IP アドレス範囲を 1 ~ 10 の間で入力します。追加できる IP アドレス範囲は 10 個までです。上限については、Cloud Armor の割り当てと上限をご覧ください。
詳細モード:
- 条件作成ツール(プレビュー): ビジュアル ビルダーを使用して、未加工の CEL コードを記述せずに式を作成します。条件を組み合わせてグループ化し、文字列変換を適用します。一致条件作成ツールを使用するをご覧ください。
- 一致条件エディタ: 受信リクエストと照らして評価する式を入力します。詳細については、オペレーションと属性をご覧ください。
[アクション] リストで、[許可] または [拒否] を選択します。
拒否ルールを構成する場合は、[レスポンス コード] リストでレスポンス コードを選択します。
ルールのプレビュー モードを有効にするには、[有効にする] を選択します。
[優先度] フィールドに、0 ~ 2,147,483,646 の整数を入力します。Cloud Armor は、0(最高)から 2,147,483,647(最低)の優先順位でルールを評価します。デフォルト ルールの優先度は 2,147,483,647 です。
[追加] をクリックします。
gcloud
gcloud compute security-policies rules create
PRIORITY コマンドを使用します。PRIORITY は、ポリシー内のルールの優先度に置き換えます。
gcloud compute security-policies rules create PRIORITY \
--security-policy POLICY_NAME \
--description DESCRIPTION \
--src-ip-ranges IP_RANGES | --expression EXPRESSION \
--action=[ allow | deny-403 | deny-404 | deny-502 ] \
--preview
たとえば、次のコマンドは、IP アドレス範囲 192.0.2.0/24 と 198.51.100.0/24 からのトラフィックをブロックする優先度 1000 のルールを追加します。
gcloud compute security-policies rules create 1000 \
--security-policy my-policy \
--description "block traffic from 192.0.2.0/24 and 198.51.100.0/24" \
--src-ip-ranges "192.0.2.0/24","198.51.100.0/24" \
--action "deny-403"
条件を指定するには、--expression フラグを使用します。次のコマンドは、User-Agent ヘッダーに文字列 example を含む IP アドレス 1.2.3.4 からのトラフィックを許可するルールを追加します。
gcloud compute security-policies rules create 1000 \
--security-policy my-policy \
--expression "inIpRange(origin.ip, '1.2.3.4/32') && has(request.headers['user-agent']) && request.headers['user-agent'].contains('example')" \
--action allow \
--description "Block User-Agent 'example'"
次のコマンドは、リクエストの Cookie に特定の値が含まれている場合に、リクエストをブロックするルールを追加します。
gcloud compute security-policies rules create 1000 \
--security-policy my-policy \
--expression "has(request.headers['cookie']) && request.headers['cookie'].contains('80=SomeValue')" \
--action deny-403 \
--description "Cookie Block"
次のコマンドは、リージョン AU からのリクエストをブロックするルールを追加します。
gcloud compute security-policies rules create 1000 \
--security-policy my-policy \
--expression "origin.region_code == 'AU'" \
--action deny-403 \
--description "AU block"
次のコマンドは、指定した IP 範囲にないリージョン AU からのリクエストをブロックするルールを追加します。
gcloud compute security-policies rules create 1000 \
--security-policy my-policy \
--expression "origin.region_code == \"AU\" && !inIpRange(origin.ip, '1.2.3.0/24')" \
--action deny-403 \
--description "country and IP block"
次のコマンドは、正規表現に一致する URI を含むリクエストをブロックするルールを追加します。
gcloud compute security-policies rules create 1000 \
--security-policy my-policy \
--expression "request.path.matches('/example_path/')" \
--action deny-502 \
--description "regex block"
次のコマンドは、Base64 デコードされた user-id ヘッダーの値に特定の値が含まれている場合に、リクエストをブロックするルールを追加します。
gcloud compute security-policies rules create 1000 \
--security-policy my-policy \
--expression "has(request.headers['user-id']) && request.headers['user-id'].base64Decode().contains('myValue')" \
--action deny-403 \
--description "country and IP block"
次のコマンドは、OWASP Core Rule Set(CRS)4.22 の事前構成された式セットを使用して SQL インジェクション(SQLi)攻撃を軽減するルールを追加します。
gcloud compute security-policies rules create 1000 \
--security-policy my-policy \
--expression "evaluatePreconfiguredWaf('sqli-v422-stable')" \
--action deny-403
一致条件作成ツールを使用する
一致条件作成ツールは、 Google Cloud コンソールのビジュアル インターフェースです。Common Expression Language(CEL)コードを記述せずに、複雑な Cloud Armor ルール式を作成できます。コードを記述する代わりに、ビルダーの構造化 UI を使用して条件とグループ ロジックを組み合わせることができます。これにより、構文エラーを回避し、ルール構造をより適切に可視化できます。ビルダーは、フラットリストと最大 5 レベルの式のネストされたロジックをサポートしています。このツールは、マルチクラウド バックエンドまたはハイブリッド デプロイを保護するルールを構成するときに使用します。この場合、トラフィックをルーティングする前に特定のリクエスト属性を検査する必要があります。
一致条件作成ツールの機能
一致条件作成ツールには次の機能があります。
- ロジックとネスト:
AND演算子とOR演算子を使用して複数の条件を組み合わせます。ビルダーは、最大 5 つの式のグループ化とネストをサポートしています。 - 文字列変換: 文字列ベースの属性(
request.pathやrequest.headersなど)の場合、評価前に変換を適用してデータを正規化します。サポートされている変換は次のとおりです。- 小文字と大文字
- Base64 デコード
- URL デコードと URL デコード(Unicode)
- UTF-8 から Unicode への変換
- 双方向解析: 視覚的な一致条件ビルダーと未加工テキストの一致条件エディタを切り替えます。UI は、未加工の CEL コードを自動的に解析してビジュアル ブロックに変換します。
- 関数のサポート: ビルダーには、事前構成 WAF ルール、アドレス グループ、脅威インテリジェンスなどの関数ベースの式用の UI コントロールが用意されています。
制限事項
一致条件作成ツールは、高度なルールを作成するためのデフォルトのインターフェースです。式にサポートされていないロジック(不明なマクロなど)が含まれている場合、ビルダーは無効になります。このような場合は、一致条件エディタの未加工テキストを使用してルールを編集します。
また、ビルダーで特定の式を使用できるかどうかは、プロジェクトの Google Cloud Armor Enterprise ティアとセキュリティ ポリシーの種類によって異なります。
式のサンプル
以下にサンプルの式を示します。サポートされているオペレーションと属性の詳細については、オペレーションと属性をご覧ください。
ルールまたは式で ISO 3166-1 alpha-2 の国コードまたは地域コードを使用する場合、Cloud Armor は各コードを個別に処理します。Cloud Armor のルールと式では、これらのコードを使用してリクエストを許可または拒否します。
次の式は、IP アドレス
1.2.3.4からのリクエストのうち、User-Agentヘッダーに文字列exampleが含まれるリクエストと一致します。inIpRange(origin.ip, '1.2.3.4/32') && has(request.headers['user-agent']) && request.headers['user-agent'].contains('example')origin.user_ip属性を使用すると、カスタムのクライアント IP アドレス ヘッダーの IP アドレス範囲と一致する式を作成できます。inIpRange(origin.user_ip, '1.2.3.4/32') && has(request.headers['user-agent']) && request.headers['user-agent'].contains('example')次の式は、特定の値を含む Cookie を持つリクエストと一致します。
has(request.headers['cookie']) && request.headers['cookie'].contains('cookie_name=cookie_value')次の式は、リージョン
AUからのリクエストと一致します。origin.region_code == 'AU'
次の式は、指定された IP 範囲に存在しないリージョン
AUからのリクエストを照合します。origin.region_code == "AU" && !inIpRange(origin.ip, '1.2.3.0/24')
次の式は、URI が正規表現に一致する場合、特定のファイルへの番号付き変数パスを含むリクエストを照合します。
request.path.matches('/path/[0-9]+/target_file.html')次の式は、Base64 でデコードされた
user-idヘッダーの値に特定の値が含まれている場合に、リクエストを照合します。has(request.headers['user-id']) && request.headers['user-id'].base64Decode().contains('myValue')次の式は、OWASP CRS 4.22 ルールセットの事前構成された式セットを使用して、SQLi 攻撃を照合します。
evaluatePreconfiguredWaf('sqli-v422-stable')
パス トラバーサルと正規化
パスベースのルールでコンテンツを正規化して、パス トラバーサルとエンコード ルールを管理し、大文字と小文字の区別やコンテンツ固有のエンコードを回避する汎用ルールを作成します。
startsWith、endsWith、contains を使用して request.path を照合するルールを作成する場合は、照合前に lower と urlDecode を使用してパスを正規化します。これにより、URL エンコードや大文字と小文字のバリエーションを使用するバイパスを防ぐことが可能です。
たとえば、/admin ディレクトリへのアクセスをブロックするには、次の式を使用します。
request.path.lower().urlDecode().startsWith('/admin')
このルールは、/admin、/Admin、/a%64min、その他のバリエーションに対するリクエストをブロックします。
matches を使用して request.path を照合するルールを作成する場合は、正規表現でバックスラッシュ文字(\)を考慮します。
たとえば、/admin ディレクトリへのアクセスをブロックするには、次の式を使用して、バックスラッシュ文字(\)を使用するバイパスをブロックします。
request.path.matches(r'^/\\*admin')
urlDecode と組み合わせて、URL エンコードとバックスラッシュ文字(\)バイパスの両方を処理します。
request.path.urlDecode().matches(r'^/\\*admin')
セキュリティ ポリシー ルールを表示する
以降のセクションでは、セキュリティ ポリシーで構成されているルールを一覧表示し、使用可能な事前構成 WAF ルールを表示する方法について説明します。
セキュリティ ポリシーのルールを一覧表示する
このセクションの手順に沿って、Cloud Armor セキュリティ ポリシーのルールを一覧表示します。
コンソール
Google Cloud コンソールで、[Cloud Armor ポリシー] ページに移動します。
特定のセキュリティ ポリシーの名前をクリックします。[ポリシーの詳細] ページの [ルール] タブにポリシールールが表示されます。
gcloud
次の gcloud コマンドを使用して、セキュリティ ポリシー内のすべてのルールを一覧表示します。
gcloud compute security-policies describe NAME
次の gcloud コマンドを使用して、指定されたリージョンの 1 つのセキュリティ ポリシー内のすべてのルールを、ポリシーの説明とともに一覧表示します。
gcloud compute security-policies describe NAME \ --region REGION
次の gcloud コマンドを使用して、ルールの説明を取得します。
gcloud compute security-policies rules describe PRIORITY \
--security-policy POLICY_NAME
たとえば、次のコマンドは、セキュリティ ポリシー my-policy で優先度が 1000 のルールを記述します。
gcloud compute security-policies rules describe 1000 \
--security-policy my-policy
出力:
action: deny(403) description: block traffic from 192.0.2.0/24 and 198.51.100.0/24 kind: compute#securityPolicyRule match: srcIpRanges: - '192.0.2.0/24' - '198.51.100.0/24' preview: false priority: 1000
詳細については、gcloud compute security-policies
describe をご覧ください。
使用可能な事前構成ルールを一覧表示する
Cloud Armor には、自分で構成するルールのほかに、セキュリティ ポリシーで使用できる事前構成済みのルールが用意されています。事前構成済みのルールを一覧表示すると、Cloud Armor で提供されている事前定義済みのアプリケーション保護ルールとシグネチャ(OWASP Core Rule Set(CRS)など)を確認できます。これらのルールには、Cloud Armor が受信リクエストに対して評価する組み込みシグネチャが含まれています。カスタムルール言語を使用して、事前構成済みのルールを新規または既存のルールに追加します。可能な限り、最新の CRS ルール バージョンを使用することをおすすめします。
gcloud
gcloud compute security-policies list-preconfigured-expression-setsコマンドを実行します。gcloud compute security-policies list-preconfigured-expression-sets
次の例は、コマンドの出力形式を示しています。
EXPRESSION_SET expression-set-1 RULE_ID SENSITIVITY expression-set-1-id-1 sensitivity-value-1 expression-set-1-id-2 sensitivity-value-2 expression-set-2 alias-1 RULE_ID SENSITIVITY expression-set-2-id-1 sensitivity-value-1 expression-set-2-id-2 sensitivity-value-2
次の例には、コマンドの実際の出力のサンプルが含まれています。ただし、実際の出力には Cloud Armor WAF ルールの調整にリストされているすべてのルールが含まれます。
gcloud compute security-policies list-preconfigured-expression-sets
EXPRESSION_SET sqli-canary RULE_ID SENSITIVITY owasp-crs-v042200-id942120-sqli 2 … xss-canary RULE_ID SENSITIVITY owasp-crs-v042200-id941110-xss 1 owasp-crs-v042200-id941120-xss 2 … sourceiplist-fastly sourceiplist-cloudflare sourceiplist-imperva
運用
次の表では、ルールの式を定義するために属性(x、y、k で表現)と一緒に使用できる演算子について説明します。
| 演算 | 式 | 説明 |
|---|---|---|
| 平等 | x == y |
x が y と等しい場合、true を返します。 |
| 等しい(文字列リテラル) | x == "foo" |
x が指定した定数文字列リテラルと等しい場合に true を返します。 |
| 等しい(生文字列リテラル) | x == R"fo'o" |
x がエスケープ シーケンスを解釈しない指定された元の文字列リテラルと等しい場合、true を返します。生文字列リテラルは、式の文字列でエスケープ シーケンス文字を使用する必要がある場合に便利です。 |
| 論理 NOT | !x |
ブール値 x が false の場合は true を返し、ブール値 x が true の場合は false を返します。 |
| 等しくない | x != y |
x が y と等しくない場合、true を返します。 |
| 連結 | x + y |
連結された文字列 xy を返します。 |
| 論理 AND | x && y |
x と y の両方が true の場合、true を返します。 |
| 論理 OR | x || y |
x、y、または両方が true の場合、true を返します。 |
| 部分文字列を含む | x.contains(y) |
文字列 x に部分文字列 y が含まれている場合に true を返します。 |
| 部分文字列で始まる | x.startsWith(y) |
文字列 x が部分文字列 y で始まる場合に true を返します。 |
| 部分文字列で終わる | x.endsWith(y) |
文字列 x が部分文字列 y で終わる場合、true を返します。 |
| 正規表現一致 | x.matches(y) |
文字列 x が指定の RE2 パターン y と部分的に一致する場合、true を返します。RE2 パターンは、Unicode 機能を無効にする RE2::Latin1 オプションを使用してコンパイルされます。 |
| 範囲内の IP アドレス | inIpRange(x, y) |
IP アドレス x が IP 範囲 y に含まれている場合に true を返します。 |
| 小文字で表記 | x.lower() |
文字列 x を小文字で表記した値を返します。 |
| 大文字で表記 | x.upper() |
文字列 x を大文字で表記した値を返します。 |
| Base64 でデコードされた値 | x.base64Decode() |
x を Base64 でデコードした値を返します。アンダースコア(_)とハイフン(-)は、最初にスラッシュ(/)とプラス記号(+)にそれぞれ置き換えられます。xx が有効な Base64 値でない場合は ""(空の文字列)を返します。x |
| キーマップ値 | m['k'] |
文字列間マップ m でキー k が使用可能な場合に k の値を返します。k が使用可能でない場合はエラーを返します。k が使用可能かどうかを "has(m['k'])==true" によって最初に確認することをおすすめします。 |
| マップでキーの可用性を確認する | has(m['k']) |
マップ m でキー k が使用可能な場合に true を返します。 |
| 整数に変換 | int(x) |
文字列の結果である x を int 型に変換します。変換後は、> や <= などの標準の算術演算子を使用して整数の比較が行えます。これは、整数とみなせる文字列の場合にのみ機能します。 |
| 長さ | size(x) |
文字列 x の長さを返します。 |
| URL デコード | x.urlDecode() |
x を URL デコードした値を返します。%## 形式の文字シーケンスは ASCII でない同等の文字に置き換えられ、+ はスペースに置き換えられます。無効なエンコードはそのまま返されます。 |
| URL デコード(Unicode) | x.urlDecodeUni() |
x を URL デコードした値を返します。urlDecode() に加えて、%u### 形式の Unicode 文字シーケンスも処理します。無効なエンコードはそのまま返されます。 |
| UTF-8 を Unicode に変換 | x.utf8ToUnicode() |
UTF-8 でエンコードされた x を小文字で表記した Unicode 表現を返します。 |
| 存在する | m.exists(k, expr) |
マップ m の少なくとも 1 つのエントリが expr を満たす場合、true を返します。ここで、k は各マップエントリのキーを表します。 |
| 1 つ存在する | m.exists_one(k, expr) |
マップ m のエントリが expr を満たす場合に true を返します。ここで、k は各マップエントリのキーを表します。 |
| すべて | m.all(k, expr) |
マップ m のすべてのエントリが expr を満たす場合、true を返します。ここで、k は各マップエントリのキーを表します。 |
| フィルタ | m.filter(k, expr) |
エントリが expr を満たすマップ m のエントリのみを含むマップを返します。ここで、k は各マップエントリのキーを表します。 |
| 地図 | m.map(k, expr) |
マップ m の各キーに対して expr を評価した結果を含むリストを返します。ここで、k は各マップエントリのキーを表します。 |
属性
属性は、クライアント IP アドレスやリクエストされた URL パスなど、受信リクエストからの情報を表します。
| フィールド | タイプ | フィールドの説明 |
|---|---|---|
origin.ip |
文字列 | リクエストを開始したクライアントの IP アドレス。 |
origin.user_ip |
文字列 | 送信元クライアントの IP アドレス。アップストリーム プロキシによって HTTP-HEADER に含められます。この属性を使用する前に、セキュリティ ポリシーの advancedOptionsConfig フィールドで userIpRequestHeaders[] オプションを構成して、True-Client-IP、X-Forwarded-For、X-Real-IP などの送信元に一致させる必要があります。詳細については、ユーザーの IP アドレスの概要をご覧ください。
|
origin.tls_ja4_fingerprint |
文字列 | JA4 TLS / SSL フィンガープリント(クライアントが HTTPS、HTTP/2、HTTP/3 を使用して接続している場合)。使用できない場合は空の文字列が返されます。 |
origin.tls_ja3_fingerprint |
文字列 | JA3 TLS / SSL フィンガープリント(クライアントが HTTPS、HTTP/2、HTTP/3 を使用して接続している場合)。使用できない場合は空の文字列が返されます。 |
request.headers |
マップ | HTTP リクエスト ヘッダーの文字列間マップヘッダーに複数の値がある場合、このマップの対応する値は、すべての値をカンマで区切って含む単一の文字列になります。このマップのキーはすべて小文字です。外部アプリケーション ロードバランサは、受け入れられたすべてのヘッダーを検査します。同じヘッダー制限が適用されます。
マップを反復処理して、キーと値の両方を確認できます。
ただし、 |
request.body |
文字列 | リクエスト本文を未加工の文字列として表します。任意の Content-Type のデータを表すことができます。コンテンツは、自動解析なしで文字列として保存されます。 |
request.params |
地図 | URL に追加されるか、リクエストの本文に含まれる Key-Value ペアのマップ。 URI リクエスト: name1=value1&name2=value2Content-Type: application/json を含む JSON リクエスト本文:{ "username": "johndoe", "email": "johndoe@example.com" }Content-Type: application/graphql を含む GraphQL POST リクエスト本文:{ Username: "exampleUser", query: "/* other fields */" }Content-Type: application/x-www-form-urlencoded を含むフォーム POST リクエスト本文:"username=exampleUser&email=johndoe%40example.com"
|
request.method |
文字列 | HTTP リクエスト メソッド。 |
request.path |
文字列 | リクエストした HTTP URL パス。request.path に一致するルールを作成する場合は、URL エンコード、大文字と小文字の区別、バックスラッシュがある場合に構文を一致させやすくするために、パスを正規化することをおすすめします。詳細と例については、パス トラバーサルと正規化をご覧ください。 |
request.scheme |
文字列 | http、https などの HTTP URL スキーム。この属性の値はすべて小文字です。 |
request.query |
文字列 | HTTP リクエストの第 1 行に現れるような、name1=value&name2=value2 形式の HTTP URL クエリ。デコードは行われません。 |
origin.region_code |
文字列 | クライアント IP に関連付けられた Unicode の国コード(US など)。ISO 3166-1 alpha 2 の国コードや地域コードを使用するルールまたは式を構成した場合、Cloud Armor は各コードを個別に処理します。Cloud Armor のルールと式では、これらの地域コードを明示的に使用してリクエストを許可または拒否します。 |
origin.asn |
整数 | クライアント IP アドレスに関連付けられた自律システム番号(ASN)。グローバルに一意の ASN は、クライアント IP アドレスを含む IP アドレス接頭辞をサポートするネットワーク事業者に基づいて決定されます。 |
式の例
以降の各式は、その式が拒否ルールに含まれるか、許可ルールに含まれるかによってアクションが変わります。
IPv4 または IPv6 の IP アドレス範囲に基づいてアクセスを許可または拒否する
次の式は、
198.51.100.0/24IP アドレス範囲からのリクエストと一致します。inIpRange(origin.ip, '198.51.100.0/24')
次の式は、
2001:db8::/32IP アドレス範囲からのリクエストと一致します。inIpRange(origin.ip, '2001:db8::/32')
アップストリーム プロキシの背後にあるカスタム クライアント IP アドレス範囲に基づいて、アクセスを許可または拒否する
origin.user_ip 演算子をすでに構成している場合は、advancedOptionsConfig.userIpRequestHeaders[] フィールドで指定したヘッダーの値に基づいて照合できます。
次の式は、IP アドレス範囲
192.0.2.0/24から発信されたリクエストと一致します。inIpRange(origin.user_ip, '192.0.2.0/24')
次の式は、IP アドレス範囲
2001:db8::/32から発信されたリクエストと一致します。inIpRange(origin.user_ip, '2001:db8::/32')
特定の Cookie を持つトラフィックを許可または拒否する
次の式は、
80=BLAHを含む Cookie を持つリクエストと一致します。has(request.headers['cookie']) && request.headers['cookie'].contains('80=BLAH')
空でない referer ヘッダーを使用してトラフィックを許可または拒否する
次の式は、空ではない
refererヘッダーを持つリクエストと一致します。has(request.headers['referer']) && request.headers['referer'] != ""
ホストヘッダーに基づいてトラフィックを許可または拒否する
リクエストの Host ヘッダーの値に基づいてトラフィックを許可または拒否できます。
次の式は、
==を使用する特定の URL へのリクエストと一致します。request.headers['host'].lower() == 'test.example.com'
次の式は、
endsWithを使用する特定の URL へのリクエストと一致します。request.headers['host'].lower().endsWith('.example.com')次の式は、
containsを使用する特定の URL へのリクエストと一致します。request.headers['host'].lower().contains('test.example.com')
次の式は、
containsを使用する複数のドメインへのリクエストと一致します。request.headers['host'].lower().contains('test.example.com') || request.headers['host'].lower().contains('test22.example.com')次の式は、
matchesを使用するドメインとそのサブドメインのリクエストと一致します。request.headers['host'].matches('(?i:(?:sub\.)?test\.example\.com)')
特定のリージョンからのトラフィックを許可またはブロックする
AU リージョンでウェブ アプリケーションが利用できない場合は、そのリージョンからのリクエストをすべてブロックする必要があります。
拒否ルールで次の式を使用します。これは、
AUリージョンからのリクエストを照合します。origin.region_code == 'AU'
ウェブ アプリケーションが AU リージョンでのみ利用可能である場合、他のリージョンからのリクエストもブロックする必要があります。
拒否ルールで次の式を使用します。これは、
AUリージョン以外のすべてのリージョンからのリクエストと一致します。origin.region_code != 'AU'
リージョン コードは、ISO 3166-1 alpha 2 コードに基づいています。1 つのリージョンが 1 つの国に対応する場合が複数ありますが、そうでない場合もあります。たとえば、US コードには米国のすべての州、1 つの特別区、6 つの海外領土が含まれます。
特定の ASN からのトラフィックを許可またはブロックする
特定のネットワーク事業者によるサービスを受けるユーザーに対してウェブ アプリケーションをブロックする必要がある場合は、ネットワーク事業者の ASN 番号を使用するとブロックできます。
拒否ルールで次の式を使用します。これは、特定の ASN からのリクエストに一致します。
origin.asn == 123
また、ウェブ アプリケーションを、特定のネットワーク事業者のユーザーのみが使用できるようにするには、他のすべてのネットワーク事業者からのリクエストをブロックする必要があります。
拒否ルールで次の式を使用します。これは、許可するネットワーク事業者以外のすべてのネットワーク事業者に一致します。
origin.asn != 123
複数の式
1 つのルールに複数の条件を含めるには、複数のサブ式を組み合わせます。
次の例では、
AUリージョンの1.2.3.0/24(アルファ テスターなど)からのリクエストが次の式と一致します。origin.region_code == "AU" && inIpRange(origin.ip, '1.2.3.0/24')
次の式は、ユーザー エージェントに文字列
WordPressが含まれている1.2.3.4からのリクエストに一致します。inIpRange(origin.ip, '1.2.3.4/32') && has(request.headers['user-agent']) && request.headers['user-agent'].contains('WordPress')
正規表現と一致するリクエスト URI のトラフィックを許可または拒否する
次の式は、URI に文字列
/example_path/を含むリクエストと一致します。request.path.matches('/example_path/')次の式は、
User-Agentヘッダー フィールドにChromeが含まれるリクエストと一致します。request.headers['user-agent'].matches('Chrome')次の式は、
wordpressを含むUser-Agentヘッダーで大文字と小文字を区別しない一致を示します。これは、User-Agent:WordPress/605.1.15、User-Agent:wordPress、その他のwordpressのパターンと一致します。request.headers['user-agent'].matches('(?i:wordpress)')
特定の Base64 デコード値を含むトラフィックを許可または拒否する
次の式は、
user-idヘッダー用の Base64 でデコードされたmyValueの値を含むリクエストと一致します。has(request.headers['user-id']) && request.headers['user-id'].base64Decode().contains('myValue')
特定の長さの文字列値を含むトラフィックを許可または拒否する
次の式は、URL の長さが 10 文字を超えるリクエストと一致します。
size(request.path) > 10
次の式は、ヘッダー
x-dataの長さが 1,024 文字以上のリクエストと一致します。size(request.headers['x-data']) >= 1024
HTTP 本文で content-length がゼロのトラフィックを許可または拒否する
次の式は、HTTP 本文で
content-lengthがゼロのリクエストに一致します。int(request.headers["content-length"]) == 0
特定の URL エンコード値を含むトラフィックを許可または拒否する
次の式は、
%3cを含む Cookie 値を持つリクエストと一致します。has(request.headers['cookie']) && request.headers['cookie'].urlDecode().contains('<')
Unicode 文字列の特定の URL エンコード値を含むトラフィックを許可または拒否する
次の式は、Cookie 値が
Match%2BValueまたはMatch%u002BValueと等しいリクエストと一致します。has(request.headers['cookie']) && request.headers['cookie'].urlDecodeUni() == 'Match+Value'
UTF-8 テキストの特定の Unicode 文字列を含むトラフィックを許可または拒否する
次の式は、Cookie 値が
¬と等しいリクエストと一致します。has(request.headers['cookie']) && request.headers['cookie'].utf8ToUnicode() == '%u00ac'
既知の JA4 フィンガープリントに基づいてトラフィックを許可または拒否する
次の式は、JA4 フィンガープリントが
t13d1516h2_8daaf6152771_b186095e22b6と等しいリクエストと一致します。origin.tls_ja4_fingerprint == 't13d1516h2_8daaf6152771_b186095e22b6'
JA4 フィンガープリントのリストに基づいてトラフィックを許可または拒否する
次の式は、次の JA4 フィンガープリントのいずれかと等しい JA4 フィンガープリントがあるリクエストと一致します。
t00d0000h0_000000000000_000000000000t13d1516h2_8daaf6152771_b186095e22b6
origin.tls_ja4_fingerprint == 't00d0000h0_000000000000_000000000000' || origin.tls_ja4_fingerprint == 't13d1516h2_8daaf6152771_b186095e22b6'
リクエスト本文のコンテンツに基づいてトラフィックを許可または拒否する
次の式は、リクエスト本文に
malicious-valueを含む POST リクエストに一致します。request.method == 'POST' && request.body.contains('malicious-value')次の式は、
<!DOCTYPE html>で始まるリクエストと一致します。request.body.startsWith('<!DOCTYPE html>')次の式は、本文が正規表現
\w+@\w+.comに一致するリクエストに一致します。request.body.matches('\w+@\w+.com')
リクエスト パラメータに基づいてトラフィックを許可または拒否する
次の式は、
categoryという名前のパラメータを含まないリクエストに一致します。!has(request.params.category)
次の式は、
categoryパラメータがelectronicsであるリクエストに一致します。request.params.category == 'electronics'
次の式は、すべてのパラメータ値が空ではないリクエストと一致します。
request.params.all(k, request.params[k] != '')
次の式は、いずれかのパラメータに文字列
adminが含まれているリクエストと一致します。request.params.exists(k, request.params[k].contains('admin'))次の式は、1 つのパラメータ名に
adminが含まれているリクエストと一致します。request.params.exists_one(k, k.contains('admin'))次の式は、少なくとも 1 つのパラメータ名に
idが含まれるリクエストに一致します。size(request.params.filter(k, k.contains('id'))) > 0次の式は、パラメータ値に文字列
adminが含まれるリクエストと一致します。request.params.map(k, request.params[k]).contains('admin')
リクエスト本文の構造化データに基づいてトラフィックを許可または拒否する
次の式は、JSON リクエスト本文の
passwordフィールドに123が含まれているリクエストに一致します。has(request.params.password) && request.params.password.contains('123')次の式は、フォームデータの
cityフィールドがNewYorkであるリクエストに一致します。has(request.params.city) && request.params.city == 'NewYork'
次の式は、ネストされた
newsletterフィールドがtrueであるリクエストに一致します。has(request.params.preferences) && has(request.params.preferences.newsletter) && request.params.preferences.newsletter == true
次の式は、
friends配列の最初の要素のnameフィールドがjohndoeであるリクエストに一致します。request.params['friends'][0]['name'] == 'johndoe'
事前構成 WAF ルール
事前構成 WAF ルールでは、事前構成された静的シグネチャ、正規表現、またはその両方を使用して、HTTP POST 本文、HTTP リクエスト ヘッダー、クエリ パラメータが照合されます。使用可能な事前構成 WAF ルールは、OWASP Core Rule Set 4.22 に基づいています。Cloud Armor には、事前構成 WAF ルールがいくつか用意されています。事前構成 WAF ルールの全一覧については、Cloud Armor の事前構成 WAF ルールの概要をご覧ください。
使用可能なすべての事前構成 WAF ルールを一覧表示するには、使用可能な事前構成 WAF ルールを一覧表示するをご覧ください。
事前構成 WAF ルールの詳細については、使用例: 事前構成 WAF ルールを使用してアプリケーション レイヤ攻撃を軽減するをご覧ください。
事前構成 WAF ルールの名前
事前構成 WAF ルール名の形式は <attack category>-<OWASP CRS version>-<version field> です。attack category には、xss(クロスサイト スクリプティング)や sqli(SQL インジェクション)など、防御対象となる攻撃タイプを指定します。
サポートされているバージョン フィールドは stable と canary です。ルールへの追加と変更は、最初に canary バージョンでリリースされます。追加と変更が安全で安定しているとみなされると、stable バージョンに昇格します。
事前構成 WAF ルールのメンバー ID
事前構成 WAF ルールには、それぞれシグネチャを持つ複数の式が含まれています。たとえば、事前構成 WAF ルール xss-v422-stable には、owasp-crs-v042200-id941100-xss という式が含まれています。これは、バージョン 4.22 のルール ID id941100 に対応します。シグネチャを使用して、特定の式が使用されないように除外できます。これは、特定の式が一貫して誤検出をトリガーする場合に便利です。詳しくは、誤検出のトラブルシューティング情報をご覧ください。
Core Rule Set とさまざまな感度レベルでのチューニングの詳細については、Cloud Armor WAF ルールのチューニングをご覧ください。
事前構成 WAF ルールのオペレーター
| 式 | 説明 |
|---|---|
evaluatePreconfiguredWaf(string, MAP<string, dyn>) |
指定された WAF ルールセット内の WAF シグネチャのいずれかが true を返す場合、true を返します。最初の引数は、WAF ルールセットの名前(xss-v422-stable など)です。2 番目の引数(省略可)は、キーと値のマッピングです。キーは文字列です。値は、キーに応じて動的に設定されます。この引数は、評価する WAF シグネチャを微調整することを目的としています。使用できるキーは次のとおりです。
キー |
evaluatePreconfiguredWaf(string, LIST) |
指定された事前構成 WAF ルール内の式のいずれかが 最初の引数は、事前構成 WAF ルールの名前です( |
事前構成 WAF ルールの例
次の式は、
xss-v422-stable事前構成 WAF ルールを使用して XSS 攻撃を軽減します。evaluatePreconfiguredWaf('xss-v422-stable')次の式は、メンバー ID
941100と941110を除いて、xss-v422-stable事前構成 WAF ルールのすべての式を使用します。evaluatePreconfiguredWaf('xss-v422-stable', {'opt_out_rule_ids': ['owasp-crs-v042200-id941100-xss', 'owasp-crs-v042200-id941110-xss']})次の式は、事前構成 WAF ルールを使用して
198.51.100.0/24IP アドレス範囲からの SQLi 攻撃を軽減します。inIpRange(origin.ip, '198.51.100.0/24') && evaluatePreconfiguredWaf('sqli-v422-stable')次の式は、事前構成 WAF ルールの
xss-v422-stableを使用して、example.comへのリクエストに対する XSS 攻撃を緩和します。ただし、/login/api/で始まるパスは除外されます。request.headers['host'].lower() == 'example.com' && !request.path.startswith('/login/api/') && evaluatePreconfiguredWaf('xss-v422-stable')
その他の演算子
| 式 | 説明 |
|---|---|
evaluateThreatIntelligence(string)evaluateThreatIntelligence(string, LIST)evaluateThreatIntelligence(string, string, LIST)
|
除外リストで明示的に除外されていない限り、クライアント IP アドレスが指定された IP リストのいずれかの IP 範囲と一致する場合に 最初の引数は、Google Threat Intelligence フィード名です( |
evaluateAddressGroup(string, string)evaluateAddressGroup(string, string, LIST)evaluateOrganizationAddressGroup(string, string)evaluateOrganizationAddressGroup(string, string, LIST)
|
除外リストで明示的に除外されていない限り、クライアント IP アドレスが指定されたアドレス グループの IP 範囲のいずれかと一致する場合に 最初の引数はアドレス グループ名です。2 番目の引数は、IP アドレスの抽出元を決定します。 |
evaluateAdaptiveProtection(string) |
リクエストが Google Cloud Armor の適応型保護によって生成された攻撃シグネチャと一致する場合は 引数は、攻撃の検出時に Adaptive Protection によって生成された特定のアラートの ID です。 |
evaluateAdaptiveProtectionAutoDeploy() |
リクエストが、Adaptive Protection によって検出された進行中の攻撃の攻撃シグネチャと一致するヘビーヒッター IP アドレスからのものである場合、 |
例
次の式は、既知の悪意のある IP のリストから保護するために、Google Threat Intelligence
iplist-known-malicious-ipsフィードに対して受信リクエストを照合します。evaluateThreatIntelligence('iplist-known-malicious-ips')次の式は、既知の悪意のある IP のリストから保護するために、
203.0.113.0/24の IP を除く、Google Threat Intelligenceiplist-known-malicious-ipsフィードに対して受信リクエストを照合します。evaluateThreatIntelligence('iplist-known-malicious-ips', ['203.0.113.0/24'])次の式は、ユーザー IP のカスタム リクエスト ヘッダーを
my-own-list-of-bad-ipsという名前のアドレス グループと照合します。evaluateAddressGroup('my-own-list-of-bad-ips', origin.user_ip)