1. はじめに
こんにちは。Cloud Armor の事前構成済み WAF ルール Codelab へようこそ。
Google Cloud Armor は、DDoS 対策、WAF ルールの適用、適応型管理機能を大規模に提供する Google のエンタープライズ エッジ ネットワーク セキュリティ ソリューションです。
OWASP トップ 10 のウェブ アプリケーション セキュリティの脆弱性を軽減するために、Cloud Armor は事前構成済みの WAF ルールセットを拡張しました。このルールセットは、OWASP Modsecurity コアルールセット バージョン 3.0.2 に基づいており、ローカル ファイル インクルード(lfi)、リモート ファイル インクルード(rfi)、リモートコード実行(rce)など、最も一般的なウェブ アプリケーションのセキュリティ リスクから保護します。
この Codelab では、Google Cloud Armor WAF ルールを使用して一般的な脆弱性を軽減する方法を学びます。
学習内容
- サービスをサポートするインスタンス グループとグローバル ロードバランサを設定する方法
- lfi、rce、スキャナ、プロトコル攻撃、セッション修正から保護するために、事前構成された WAF ルールを使用して Cloud Armor セキュリティ ポリシーを構成する方法
- ログを監視することで、Cloud Armor が攻撃を軽減したことを検証する方法。
必要なもの
- Google Compute Engine に関する基本的な知識(Codelab)
- ネットワークと TCP/IP に関する基本的な知識
- Unix / Linux コマンドラインに関する基本的な知識
- Networking in the Google Cloud で GCP のネットワーキングの概要を学習しておくと役に立ちます。
- (省略可)Cloudnet20 Cloud Armor ラボを完了し、SQL インジェクション、IP ベース、地域ベースのルールを使用してワークロードを保護する方法について学びます。
Codelab のトポロジとユースケース
図 1 - Cloud Armor WAF ルール Codelab のトポロジ
OWASP Juice Shop アプリケーションは、OWASP トップ 10 のセキュリティ脆弱性のそれぞれが設計上から挙げられているため、セキュリティのトレーニングや認知向上に役立ちます。攻撃者がそれをテスト目的で悪用する可能性があります。この Codelab では、これを使用してアプリケーション攻撃をいくつか実演し、その後、Cloud Armor WAF ルールでアプリケーションを保護します。このアプリケーションの前面には Google Cloud ロードバランサがあり、このロードバランサに Cloud Armor のセキュリティ ポリシーとルールが適用されます。公共のインターネット上でサービスが提供されるため、ほぼどこからでもアクセス可能で、Cloud Armor と VPC ファイアウォール ルールを使用して保護されます。
2. 設定と要件
セルフペース型の環境設定
- Cloud コンソールにログインして、新しいプロジェクトを作成するか、既存のプロジェクトを再利用しますGmail アカウントも Google Workspace アカウントもまだお持ちでない場合は、アカウントを作成してください。
プロジェクト ID を忘れないようにしてください。プロジェクト ID はすべての Google Cloud プロジェクトを通じて一意の名前にする必要があります(上記の名前はすでに使用されているので使用できません)。以降、このコードラボでは PROJECT_ID
と呼びます。
- 次に、Google Cloud リソースを使用するために、Cloud Console で課金を有効にする必要があります。
このコードラボを実行しても、費用はほとんどかからないはずです。このチュートリアル以外で請求が発生しないように、リソースのシャットダウン方法を説明する「クリーンアップ」セクションの手順に従うようにしてください。Google Cloud の新規ユーザーは、$300 USD 分の無料トライアル プログラムをご利用いただけます。
Cloud Shell の起動
Google Cloud はノートパソコンからリモートで操作できますが、この Codelab では、Google Cloud Shell(Cloud 上で動作するコマンドライン環境)を使用します。
GCP Console で右上のツールバーにある Cloud Shell アイコンをクリックします。
プロビジョニングと環境への接続にはそれほど時間はかかりません。完了すると、次のように表示されます。
この仮想マシンには、必要な開発ツールがすべて用意されています。永続的なホーム ディレクトリが 5 GB 用意されており、Google Cloud で稼働します。そのため、ネットワークのパフォーマンスと認証機能が大幅に向上しています。このラボでの作業はすべて、ブラウザから実行できます。
始める前に
Cloud Shell 内で、プロジェクト ID が設定されていることを確認します。
gcloud config list project gcloud config set project [YOUR-PROJECT-NAME] PROJECT_ID=[YOUR-PROJECT-NAME] echo $PROJECT_ID
API を有効にする
必要なサービスをすべて有効にする
gcloud services enable compute.googleapis.com gcloud services enable logging.googleapis.com gcloud services enable monitoring.googleapis.com
3. VPC ネットワークを作成する
VPC ネットワークを作成する
Cloud Shell から
gcloud compute networks create ca-lab-vpc --subnet-mode custom
出力
Created NAME SUBNET_MODE BGP_ROUTING_MODE IPV4_RANGE GATEWAY_IPV4 ca-lab-vpc CUSTOM REGIONAL
サブネットを作成する
Cloud Shell から
gcloud compute networks subnets create ca-lab-subnet \ --network ca-lab-vpc --range 10.0.0.0/24 --region us-central1
出力
Created NAME REGION NETWORK RANGE ca-lab-subnet us-central1 ca-lab-vpc 10.0.0.0/24
VPC ファイアウォール ルールを作成する
VPC とサブネットを作成したら、ファイアウォール ルールをいくつか設定します。1 つ目のファイアウォール ルールは、すべての IP からテスト アプリケーションのウェブサイトの外部 IP にポート 3000 でアクセスできるようにするためのものです。2 つ目のファイアウォール ルールは、ロードバランサの送信元 IP からのヘルスチェックを許可するために使用します。
Cloud Shell から
gcloud compute firewall-rules create allow-js-site --allow tcp:3000 --network ca-lab-vpc
出力
Creating firewall...done. NAME NETWORK DIRECTION PRIORITY ALLOW DENY DISABLED allow-js-site ca-lab-vpc INGRESS 1000 tcp:3000 False
Google ヘルスチェック範囲からのヘルスチェックを許可する FW ルールを作成します。
Cloud Shell から
gcloud compute firewall-rules create allow-health-check \ --network=ca-lab-vpc \ --action=allow \ --direction=ingress \ --source-ranges=130.211.0.0/22,35.191.0.0/16 \ --target-tags=allow-healthcheck \ --rules=tcp
出力
Creating firewall...done. NAME NETWORK DIRECTION PRIORITY ALLOW DENY DISABLED allow-health-check ca-lab-vpc INGRESS 1000 tcp False
4. テスト アプリケーションを設定する
次のステップでは、テスト アプリケーションを作成します。この場合は、OWASP Juice Shop ウェブサーバーです。
Compute インスタンスを作成する際には、サーバーに適切なサービスを提供するためにコンテナ イメージを使用します。このサーバーは us-central1-c にデプロイされ、ヘルスチェックを可能にするネットワーク タグが設定されます。
OWASP Juice Shop アプリケーションを作成する
オープンソースのよく知られている OWASP Juice Shop アプリケーションを使用して、脆弱なアプリケーションとして機能する。また、このアプリケーションを使用して、同社のウェブサイトで OWASP セキュリティ チャレンジを実施することもできます。
Cloud Shell から
gcloud compute instances create-with-container owasp-juice-shop-app --container-image bkimminich/juice-shop \ --network ca-lab-vpc \ --subnet ca-lab-subnet \ --private-network-ip=10.0.0.3 \ --machine-type n1-standard-2 \ --zone us-central1-c \ --tags allow-healthcheck
出力
NAME ZONE MACHINE_TYPE PREEMPTIBLE owasp-juice-shop-app us-central1-c n1-standard-2 INTERNAL_IP EXTERNAL_IP STATUS 10.0.0.3 <public IP> RUNNING
Cloud ロードバランサ コンポーネントを設定する: インスタンス グループ
非マネージド インスタンス グループを作成します。
Cloud Shell から
gcloud compute instance-groups unmanaged create juice-shop-group \ --zone=us-central1-c
出力
NAME LOCATION SCOPE NETWORK MANAGED INSTANCES juice-shop-group us-central1-c zone 0
Juice Shop GCE インスタンスを非マネージド インスタンス グループに追加する。
Cloud Shell から
gcloud compute instance-groups unmanaged add-instances juice-shop-group \ --zone=us-central1-c \ --instances=owasp-juice-shop-app
出力
Updated [https://www.googleapis.com/compute/v1/projects/<project name>/zones/us-central1-c/instanceGroups/juice-shop-group].
名前付きポートを Juice Shop アプリケーションのポートに設定します。
Cloud Shell から
gcloud compute instance-groups unmanaged set-named-ports \ juice-shop-group \ --named-ports=http:3000 \ --zone=us-central1-c
出力
Updated [https://www.googleapis.com/compute/v1/projects/<project name>/zones/us-central1-c/instanceGroups/juice-shop-group].
非マネージド インスタンス グループを作成したら、次のステップではヘルスチェック、バックエンド サービス、URL マップ、ターゲット プロキシ、転送ルールを作成します。
Cloud ロードバランサ コンポーネントを設定する: ヘルスチェック
Juice Shop サービスポートのヘルスチェックを作成します。
Cloud Shell から
gcloud compute health-checks create tcp tcp-port-3000 \ --port 3000
出力
Created NAME PROTOCOL tcp-port-3000 TCP
Cloud ロードバランサ コンポーネントを設定する: バックエンド サービス
バックエンド サービス パラメータを作成します。
Cloud Shell から
gcloud compute backend-services create juice-shop-backend \ --protocol HTTP \ --port-name http \ --health-checks tcp-port-3000 \ --enable-logging \ --global
出力
NAME BACKENDS PROTOCOL juice-shop-backend HTTP
Juice Shop インスタンス グループをバックエンド サービスに追加します。
Cloud Shell から
gcloud compute backend-services add-backend juice-shop-backend \ --instance-group=juice-shop-group \ --instance-group-zone=us-central1-c \ --global
出力
Updated [https://www.googleapis.com/compute/v1/projects/cythom-host1/global/backendServices/juice-shop-backend].
クラスタ ロードバランサ コンポーネントを設定する: URL マップ
バックエンドに送信する URL マップを作成します。
Cloud Shell から
gcloud compute url-maps create juice-shop-loadbalancer \ --default-service juice-shop-backend
出力
NAME DEFAULT_SERVICE juice-shop-loadbalancer backendServices/juice-shop-backend
クラスタ ロードバランサ コンポーネント: ターゲット プロキシを設定する
URL マップの前にターゲット プロキシを作成します。
Cloud Shell から
gcloud compute target-http-proxies create juice-shop-proxy \ --url-map juice-shop-loadbalancer
出力
NAME URL_MAP juice-shop-proxy juice-shop-loadbalancer
Cloud ロードバランサ コンポーネントを設定する: 転送ルール
ロードバランサの転送ルールを作成します。
Cloud Shell から
gcloud compute forwarding-rules create juice-shop-rule \ --global \ --target-http-proxy=juice-shop-proxy \ --ports=80
出力
Created [https://www.googleapis.com/compute/v1/projects/cythom-host1/global/forwardingRules/juice-shop-rule].
Juice Shop サービスがオンラインであることを確認する
Cloud Shell から
PUBLIC_SVC_IP="$(gcloud compute forwarding-rules describe juice-shop-rule --global --format="value(IPAddress)")"
Cloud Shell から
echo $PUBLIC_SVC_IP
出力
<public VIP of service>
数分待ってから、続行してください。そうしないと、HTTP/1.1 404 Not Found レスポンスが返される可能性があります。
Cloud Shell から
curl -Ii http://$PUBLIC_SVC_IP
出力
HTTP/1.1 200 OK <...>
ブラウザで Juice Shop を表示することもできます。
これで、Juice Shop の脆弱性と、Cloud Armor WAF ルールセットを使用してそれらを保護する方法を調べる準備が整いました。
5. 既知の脆弱性を実証
時間を節約するため、Cloud Armor WAF ルールが伝播される前後の状態を簡単に説明します。
LFI の脆弱性を観察する: パス トラバーサル
ローカル ファイル インクルードとは、リクエストに含まれる入力検証の欠如を利用して、サーバー上にあるファイルを監視し、機密データを潜在的に漏洩させるプロセスです。以下は、パス トラバーサルが可能なことを簡単に示したものです。ブラウザまたは curl を使用して、アプリケーションによって提供される既存のパスを確認します。
Cloud Shell から
curl -Ii http://$PUBLIC_SVC_IP/ftp
出力
HTTP/1.1 200 OK <...>
また、パス トラバーサルも機能することを確認します。
Cloud Shell から
curl -Ii http://$PUBLIC_SVC_IP/ftp/../
出力
HTTP/1.1 200 OK <...>
RCE の脆弱性を観察する
リモートコード実行には、さまざまな UNIX および Windows コマンドインジェクションシナリオが含まれており、攻撃者は通常、特権ユーザーに限定された OS コマンドを実行できます。渡された単純な ls コマンドの実行を次に示します。
Cloud Shell から
curl -Ii http://$PUBLIC_SVC_IP/ftp?doc=/bin/ls
出力
HTTP/1.1 200 OK <...>
出力全体を確認するには、curl フラグを削除します。
よく知られたスキャナによるアクセスを確認する
商用とオープンソースの両方で、脆弱性のスキャンなど、さまざまな目的でアプリケーションをスキャンします。これらのツールは、よく知られたユーザーエージェントやその他のヘッダーを使用します。curl が既知のユーザー エージェント ヘッダーで機能していることを確認します。
Cloud Shell から
curl -Ii http://$PUBLIC_SVC_IP -H "User-Agent: blackwidow"
出力
HTTP/1.1 200 OK <...>
プロトコル攻撃を観察する: HTTP 分割
一部のウェブ アプリケーションでは、ユーザーからの入力を使用してレスポンスのヘッダーを生成します。アプリケーションが入力を適切にフィルタリングしていない場合、攻撃者は入力パラメータをシーケンス %0d%0a(異なる行を区切るために使用される CRLF シーケンス)で汚染する可能性があります。このレスポンスは、中間プロキシ サーバーのようなたまたま解析されたものによって 2 つのレスポンスとして解釈される可能性があります。その場合、後続のリクエストで偽のコンテンツが提供される可能性があります。入力パラメータにシーケンス「%0d%0a」を挿入すると、誤解を招くページが表示される可能性があります。
Cloud Shell から
curl -Ii "http://$PUBLIC_SVC_IP/index.html?foo=advanced%0d%0aContent-Length:%200%0d%0a%0d%0aHTTP/1.1%20200%20OK%0d%0aContent-Type:%20text/html%0d%0aContent-Length:%2035%0d%0a%0d%0a<html>Sorry,%20System%20Down</html>"
出力
HTTP/1.1 200 OK <...>
セッションの修正を観察する
Cloud Shell から
curl -Ii http://$PUBLIC_SVC_IP -H session_id=X
出力
HTTP/1.1 200 OK <...>
6. Cloud Armor WAF ルールを定義する
事前構成 WAF ルールを一覧表示します。
Cloud Shell から
gcloud compute security-policies list-preconfigured-expression-sets
出力
EXPRESSION_SET Sqli-canary RULE_ID owasp-crs-v030001-id942110-sqli owasp-crs-v030001-id942120-sqli <...>
Cloud Armor セキュリティ ポリシーを作成する
Cloud Shell から次の操作を行います。
gcloud compute security-policies create block-with-modsec-crs \ --description "Block with OWASP ModSecurity CRS"
セキュリティ ポリシーのデフォルト ルールを更新する
デフォルトのルールの優先度の数値は 2147483647 です
Cloud Shell から次の操作を行います。
gcloud compute security-policies rules update 2147483647 \ --security-policy block-with-modsec-crs \ --action "deny-403"
デフォルトのルールではアクション拒否が構成されているため、IP からのアクセスを許可する必要があります。パブリック IP を確認してください(curl、ipmonkey、whatismyip など)。
Cloud Shell から次の操作を行います。
MY_IP=$(curl ifconfig.me)
IP からのアクセスを許可する 1 つ目のルールを追加する(以下に IP を挿入)
Cloud Shell から次の操作を行います。
gcloud compute security-policies rules create 10000 \ --security-policy block-with-modsec-crs \ --description "allow traffic from my IP" \ --src-ip-ranges "$MY_IP/32" \ --action "allow"
セキュリティ ポリシーを更新して LFI 攻撃をブロックする
ローカル ファイル インクルードでパス トラバーサルを防ぐ OWASP ModSecurity Core Rule Set を適用します。
Cloud Shell から次の操作を行います。
gcloud compute security-policies rules create 9000 \ --security-policy block-with-modsec-crs \ --description "block local file inclusion" \ --expression "evaluatePreconfiguredExpr('lfi-stable')" \ --action deny-403
セキュリティ ポリシーを更新してリモートコード実行(rce)をブロックする
OWASP ModSecurity Core Rule Set に従って、コマンド インジェクションなど、rce を検索するルールを適用します。一般的な OS コマンドが検出され、ブロックされる。
Cloud Shell から次の操作を行います。
gcloud compute security-policies rules create 9001 \ --security-policy block-with-modsec-crs \ --description "block rce attacks" \ --expression "evaluatePreconfiguredExpr('rce-stable')" \ --action deny-403
セキュリティ スキャナをブロックするようにセキュリティ ポリシーを更新する
OWASP ModSecurity Core Rule Set を適用して、よく知られたセキュリティ スキャナ、HTTP クライアント、ウェブ クローラーをブロックする。
Cloud Shell から次の操作を行います。
gcloud compute security-policies rules create 9002 \ --security-policy block-with-modsec-crs \ --description "block scanners" \ --expression "evaluatePreconfiguredExpr('scannerdetection-stable')" \ --action deny-403
セキュリティ ポリシーを更新してプロトコル攻撃をブロックする
OWASP ModSecurity Core Rule Set に従って、改行(CR)%0d およびラインフィード(LF)%0a 文字と、HTTP リクエスト スマグリングなどの他のタイプのプロトコル攻撃を検索するルールを適用します。
Cloud Shell から次の操作を行います。
gcloud compute security-policies rules create 9003 \ --security-policy block-with-modsec-crs \ --description "block protocol attacks" \ --expression "evaluatePreconfiguredExpr('protocolattack-stable')" \ --action deny-403
セキュリティ ポリシーを更新してセッションの修正をブロックする
OWASP ModSecurity Core Rule Set に従って、次のルールを適用します。
Cloud Shell から次の操作を行います。
gcloud compute security-policies rules create 9004 \ --security-policy block-with-modsec-crs \ --description "block session fixation attacks" \ --expression "evaluatePreconfiguredExpr('sessionfixation-stable')" \ --action deny-403
セキュリティ ポリシーをバックエンド サービスに接続する
Cloud Shell から次の操作を行います。
gcloud compute backend-services update juice-shop-backend \ --security-policy block-with-modsec-crs \ --global
ルールが反映されるまでに時間がかかることがあります(10 分以内)。十分な時間が経過したことを確認したら、これまでに確認した脆弱性をテストして、次のステップで Cloud Armor WAF ルールの適用を確認します。
7. OWASP ModSecurity Core Rule Set で Cloud Armor の保護を確認する
LFI の脆弱性が軽減されていることを確認する
Cloud Shell から
curl -Ii http://$PUBLIC_SVC_IP/?a=../
出力
HTTP/1.1 403 Forbidden <...>
RCE 攻撃が軽減されていることを確認する
Cloud Shell から
curl -Ii http://$PUBLIC_SVC_IP/ftp?doc=/bin/ls
出力
HTTP/1.1 403 Forbidden <..>
既知のスキャナ検出を確認する
Cloud Shell から
curl -Ii http://$PUBLIC_SVC_IP -H "User-Agent: blackwidow"
出力
HTTP/1.1 403 Forbidden <..>
プロトコル攻撃が軽減されていることを確認する
OWASP ModSecurity Core Rule Set ver.3.0.2 では、
Cloud Shell から
curl -Ii "http://$PUBLIC_SVC_IP/index.html?foo=advanced%0d%0aContent-Length:%200%0d%0a%0d%0aHTTP/1.1%20200%20OK%0d%0aContent-Type:%20text/html%0d%0aContent-Length:%2035%0d%0a%0d%0a<html>Sorry,%20System%20Down</html>"
出力
HTTP/1.1 403 Forbidden <..>
セッション修正の試行がブロックされることを確認する
Cloud Shell から
curl -Ii http://$PUBLIC_SVC_IP/?session_id=a
出力
HTTP/1.1 403 Forbidden <..>
8. Cloud Armor セキュリティ ルールを確認する
セキュリティ ポリシーを作成できたので、どのようなルールが構成されているかを詳しく見てみましょう。
ルールは優先度によって評価されます。値が小さいほど最初に評価され、トリガーされると、優先度の値が高いルールの処理は続行されません。
- 優先度 9000 - LFI のブロック(ローカル ファイル インクルード)
- 優先度 9001 - RCE のブロック(リモートコード実行/コマンド インジェクション)
- 優先度 9002 - ブロック スキャナの検出
- 優先度 9003 - HTTP 分割や HTTP スマグリングなどのプロトコル攻撃のブロック
- 優先度 9004 - セッション修正攻撃のブロック
- 優先度 10000 - 使用する IP にウェブサイトへのアクセスを許可する
- 優先度のデフォルト - 拒否。
*[ IP アドレスを許可] というサイトへのアクセスを許可する一方、攻撃はすべてブロックされます。
9. Cloud Armor セキュリティ ポリシーのログを確認する
Cloud Armor コンソール ページで、セキュリティ ポリシーの詳細を確認できます。[Logs
] タブをクリックしてから View policy logs
リンクをクリックすると、Cloud Logging ページに移動します。関心のあるセキュリティ ポリシー(resource.type:(http_load_balancer) AND jsonPayload.enforcedSecurityPolicy.name:(block-with-modsec-crs)
。403 エラー レスポンス コードを確認し、ログの詳細を開いて、適用されているセキュリティ ポリシーの名前、一致したフィールド値、さらに下位の事前構成された式 ID(または署名 ID)を確認します。次のスクリーンショットは、この Codelab で構成した適用済みのセキュリティ ポリシーのログの例を示しています。
LFI ログ
RCE ログ
スキャナ検出ログ
プロトコル攻撃ログ
セッション修正ログ
10. ラボのクリーンアップ
ラボが完了したので、リソースをクリーンアップします。
次のコマンドを実行して、Cloud Armor セキュリティ ポリシー、ロードバランサ、インスタンス、ファイアウォール ルール、VPC ネットワークを削除します。
バックエンド サービスから Cloud Armor セキュリティ ポリシーを削除する
gcloud -q compute backend-services update juice-shop-backend --security-policy "" --global
Cloud Armor セキュリティ ポリシーを削除する
セキュリティ ポリシーを削除すると、関連するルールが自動的に削除されます。
gcloud -q compute security-policies delete block-with-modsec-crs
ロードバランサのリソースを削除する
削除されるロードバランサのリソースには、転送ルール、target-http-proxies、URL マップ、バックエンド、ヘルスチェック、インスタンス グループが含まれます。
gcloud -q compute forwarding-rules delete juice-shop-rule --global gcloud -q compute target-http-proxies delete juice-shop-proxy gcloud -q compute url-maps delete juice-shop-loadbalancer gcloud -q compute backend-services delete juice-shop-backend \ --global gcloud -q compute health-checks delete tcp-port-3000 gcloud -q compute instance-groups unmanaged delete juice-shop-group --zone=us-central1-c
インスタンスを削除する
gcloud -q compute instances delete owasp-juice-shop-app --zone us-central1-c
ファイアウォール ルール、サブネット、VPC を削除する
gcloud -q compute firewall-rules delete allow-health-check gcloud -q compute firewall-rules delete allow-js-site gcloud -q compute networks subnets delete ca-lab-subnet --region us-central1 gcloud -q compute networks delete ca-lab-vpc
11. 完了
以上で、Cloud Armor の事前構成済み WAF ルールの Codelab は終了です。
学習した内容
- インスタンス グループとグローバル Cloud ロードバランサを設定する方法
- lfi、rce、スキャナ、プロトコル攻撃、セッション修正から保護するために、事前構成された WAF ルールを使用して Cloud Armor セキュリティ ポリシーを構成する方法
- OWASP トップ 10 の攻撃の一部が Cloud Armor によってログから軽減されたことを確認する方法
次のステップ
- Cloud Armor の事前構成 WAF ルールを使用して、OWASP トップ 10 の脆弱性からアプリケーションを保護する
- 機密性レベルに基づいてルールを微調整する
- より具体的なセキュリティ適用については、カスタムルールの言語リファレンスをご覧ください。