1. はじめに
この Codelab では、リージョン ネットワーク ファイアウォール ポリシーを使用して、内部アプリケーション ロードバランサ(ALB)とプロキシ ネットワーク ロードバランサ(NLB)の Cloud Next Generation Firewall(NGFW)Essentials について説明します。
Cloud NGFW は、Google Cloud ワークロードを保護するための高度な脅威対策機能とマイクロセグメンテーション機能を備えた、完全分散型のファイアウォール サービスです。ロードバランサ レベルで Cloud NGFW を有効にすると、内部プロキシベースのロードバランサに入ってくる TCP トラフィックに一貫したファイアウォール ポリシー ルールが適用されます。すべてのサービスに対してポリシーの適用範囲を拡大することで、組織のセキュリティ ポスチャーのプロビジョニングを簡素化します。
この Codelab では、次の Cloud NGFW と Cloud ロードバランサのプロダクトと機能について説明します。
- Cloud NGFW Essentials
- リージョン ネットワーク ファイアウォール ポリシー
- リージョン内部アプリケーション ロードバランサ
- バックエンド マネージド インスタンス グループ(MIG)と Private Service Connect(PSC)ネットワーク エンドポイント グループ(NEG)
注: ロードバランサのターゲットのファイアウォール ポリシー ルールでサポートされている最新の機能と制限事項については、Cloud NFGW のドキュメントをご覧ください。
学習内容
- ロードバランサをターゲットとする基本的な Cloud NGFW ファイアウォール ポリシー ルールを有効にする
- VM インスタンスと PSC バックエンドを使用して内部コンシューマー ロードバランサ サービスを保護する
- クライアント アクセスのテストとファイアウォール ログの検証
必要なもの
- Google Cloud プロジェクト
- Google Cloud のネットワーキングのコンセプトと Google Cloud CLI の使用に精通していること
- IAM 権限:
roles/compute.instanceAdmin.v1、roles/compute.networkAdmin、roles/compute.securityAdmin、roles/storage.admin
2. コンセプト
ファイアウォール機能の階層
Cloud NGFW には、Essentials、Standard、Enterprise の 3 つの機能階層があります。各プログレッシブ ティアでは、ネットワーク トラフィックのフィルタリングと検査機能のレベルが上がります。
Cloud NGFW Essentials のフィルタリング機能の概要は次のとおりです。
階層 | 能力 | ネットワーク レイヤ | ルールのパラメータの例 |
Essentials | IP アドレスと IP 範囲のフィルタリング | IP |
|
Essentials | アドレス グループ | IP |
|
Essentials | プロトコルとポートのフィルタリング | TCP |
|
Essentials | セキュア タグ | メタデータ |
|
Essentials | ネットワークの種類のフィルタリング | IP / メタデータ |
|
ロードバランサの転送ルールは、宛先 TCP ポートを明示的に定義します。ファイアウォール ルールの --layer4-configs= パラメータには tcp のみを指定できます。ポート値は転送ルール自体によって暗黙的に指定されます。
アドレス グループとネットワーク タイプは、ファイアウォール ポリシー ルールをより効率的にするために役立ちます。ネットワーク タイプ VPC_NETWORKS と INTRA_VPC は、ロードバランサのファイアウォール ポリシー ルールでサポートされています。
注: ロードバランサのファイアウォール ポリシー ルールでは、--direction=INGRESS のみがサポートされます。これらのルールは、ロードバランサによって公開されるサービスへのアクセスを制御するように設計されています。
データプレーンのフィルタリング
Cloud NFGW Essentials の機能は、基本的なレイヤ 3(IP アドレス)とレイヤ 4(TCP ポート)のステートフル ファイアウォール ルールを対象としています。これらのファイアウォール ポリシー ルールの機能はすべて、完全なパケット検査を必要とせずに、ロードバランサのデータプレーンで効率的に実行されます。
VM インスタンスを対象とする Cloud NGFW Essentials ポリシー ルールは、コア Google Cloud ソフトウェア定義ネットワーク(Andromeda)の一部として、分散 VPC ネットワーク ファブリックで適用されます。パケット フィルタリングとファイアウォール ポリシー ルールは、パケットが VM インスタンスのネットワーク インターフェースに到達する前に、個々の VM インスタンスのハイパーバイザ レベルで適用されます。
ロードバランサを対象とする Cloud NGFW Essentials ポリシールールは、Google Cloud ロードバランサの基盤となるテクノロジー(具体的には Envoy サービス プロキシ インフラストラクチャ)を使用して適用されます。同じ Cloud NFGW リソースモデルとルール構造を使用して、ステートフル パケット フィルタリングがプロキシベースのロードバランサ データプレーンで直接適用されます。
ロードバランサのターゲット
ロードバランサをターゲットとする Cloud NGFW ポリシーと、VM インスタンスをターゲットとするポリシーには、いくつかの重要な違いがあります。
ファイアウォール ポリシー ルールは、--target-type=INTERNAL_MANAGED_LB とロードバランサ転送ルール --target-forwarding-rules=FR_NAME への特定のリファレンスを指定することで、単一のロードバランサに適用できます。VPC ネットワーク リージョン(リージョンはポリシーによってスコープ設定される)内のすべてのロードバランサ転送ルールをターゲットにするには、特定の参照を省略し、--target-type=INTERNAL_MANAGED_LB フラグのみが必要です。
ルール構成で --target-type パラメータが設定されていない場合、ルールはデフォルトで、すべての VM インスタンスに自動的に適用され、ロードバランサには適用されません。
Codelab ネットワーク
この Codelab では、1 つの VPC ネットワークと次のリソースを含む単一のプロジェクトを使用します。
- 2 つのリージョン サブネット
- 1 つのリージョン ネットワーク ファイアウォール ポリシー
- 3 つのリージョン内部アプリケーション ロードバランサ
wwwVM インスタンス グループのバックエンドを持つ HTTP サービスapiVM インスタンス グループのバックエンドを持つ HTTP サービスgcsPSC NEG バックエンドを使用した Google API への HTTPS サービス
- さまざまな許可ポリシーと拒否ポリシーをテストするための 2 つの VM インスタンス
図 1. Codelab ネットワーク
ロードバランサをターゲットとするファイアウォール ポリシー ルールは、ロードバランサの転送ルール リソースにリンクされます。ロードバランサ自体は、個別に定義されたリソースで構成され、完全なロード バランシング サービスを提供するように構成されています。転送ルールの定義は、そのために定義された特定のターゲット プロキシ リソースを直接参照します。
図 1. ロードバランサ リソース用の Cloud NFGW
Cloud NGFW Essentials フィルタは、ロードバランサ データプレーンにプログラムされ、定義されたターゲット プロキシ サービスレイヤ(VM インスタンス インターフェースに類似)で実装されます。ポリシーを適用するために、同じ分散型の一貫したファイアウォール メカニズムが使用されます。
3. プロジェクトの設定
プロジェクトにアクセスする
この Codelab では、1 つの Google Cloud プロジェクトを使用します。構成手順では、gcloud cli CLI と Linux シェルコマンドを使用します。
まず、Google Cloud プロジェクトのコマンドラインにアクセスします。
shell.cloud.google.comの Cloud ShellgcloudCLI がインストールされているローカル ターミナル
プロジェクト ID を設定する
gcloud config set project YOUR_PROJECT_ID_HERE
API サービスを有効にする
gcloud services enable \
cloudresourcemanager.googleapis.com \
compute.googleapis.com \
dns.googleapis.com \
networksecurity.googleapis.com \
certificatemanager.googleapis.com
シェル環境変数を設定する
# set your region preference
export REGION_1="us-west1"
# set your zone preference
export ZONE_1="us-west1-c"
# fetch project info and verify vars set
export PROJECT_ID=$(gcloud config list --format="value(core.project)")
export PROJECT_NO=$(gcloud projects describe ${PROJECT_ID} --format="value(projectNumber)")
echo ${REGION_1}
echo ${ZONE_1}
echo ${PROJECT_ID}
echo ${PROJECT_NO}
4. ネットワーク基盤
このセクションでは、次のものを使用してネットワーク基盤をデプロイします。
- グローバル VPC ネットワークとリージョン サブネット
- VPC ネットワークを保護するリージョン ネットワーク ファイアウォール ポリシー
- サーバーがソフトウェア パッケージを取得するための Cloud Router と Cloud NAT
- ロードバランサの Ingress の IP アドレス予約と DNS レコード
ネットワーク リソースを作成する
# create vpc network
gcloud compute networks create vnet-foo --subnet-mode=custom
# create subnet for clients
gcloud compute networks subnets create subnet-foo-1 \
--network=vnet-foo \
--region=${REGION_1} \
--range=10.0.0.0/24 \
--enable-private-ip-google-access
# create subnet for backend servers
gcloud compute networks subnets create subnet-foo-2 \
--network=vnet-foo \
--region=${REGION_1} \
--range=172.16.0.0/24 \
--enable-private-ip-google-access
# create proxy subnet
gcloud compute networks subnets create subnet-foo-3 \
--purpose=REGIONAL_MANAGED_PROXY \
--role=ACTIVE \
--network=vnet-foo \
--region=${REGION_1} \
--range=172.16.128.0/23
ファイアウォール コンポーネントを作成する
ここで作成する基本的なリージョン ネットワーク ファイアウォール ポリシーは、後でロードバランサ固有のターゲットを追加するときに使用します。ポリシーは、ロードバランサと同じリージョンに存在する必要があります。
アドレス グループを作成
まず、ロードバランサ機能をサポートする送信元ヘルスチェックのプローブ IP 範囲を特定するアドレス グループを作成します。これらの範囲は、ロードバランサ バックエンドが正常と見なされるように許可する必要があります。また、ロードバランサをターゲットとするファイアウォール ポリシー ルールでも使用されます。
# create address group
gcloud network-security address-groups create uhc-probes \
--description="health check probes" \
--type=IPv4 \
--capacity=42 \
--location=${REGION_1}
# add ip ranges to address group
gcloud network-security address-groups add-items uhc-probes \
--items=35.191.0.0/16,130.211.0.0/22 \
--location=${REGION_1}
ファイアウォール ポリシーを作成
# create fw policy
gcloud compute network-firewall-policies create fw-policy-foo-${REGION_1} \
--description="foo fw ${REGION_1}" \
--region=${REGION_1}
# create fw policy rule to allow in iap
gcloud compute network-firewall-policies rules create 1001 \
--description="allow iap for ssh" \
--firewall-policy=fw-policy-foo-${REGION_1} \
--firewall-policy-region=${REGION_1} \
--action=allow \
--direction=INGRESS \
--layer4-configs=tcp:22 \
--src-ip-ranges=35.235.240.0/20
# create fw policy rule to allow in health checks
gcloud compute network-firewall-policies rules create 1002 \
--description="allow health checks to backends" \
--firewall-policy=fw-policy-foo-${REGION_1} \
--firewall-policy-region=${REGION_1} \
--action=allow \
--direction=INGRESS \
--layer4-configs=tcp \
--src-address-groups=projects/${PROJECT_ID}/locations/${REGION_1}/addressGroups/uhc-probes
# create fw policy rule to allow in lb proxies
gcloud compute network-firewall-policies rules create 1003 \
--description="allow lb proxy" \
--firewall-policy=fw-policy-foo-${REGION_1} \
--firewall-policy-region=${REGION_1} \
--action=allow \
--direction=INGRESS \
--layer4-configs=tcp:80,tcp:443,tcp:8080 \
--src-ip-ranges=172.16.128.0/23
# associate fw policy to vnet
gcloud compute network-firewall-policies associations create \
--name=fw-policy-association-foo-${REGION_1} \
--firewall-policy=fw-policy-foo-${REGION_1} \
--network=vnet-foo \
--firewall-policy-region=${REGION_1}
ネットワーク サービスの構成
Cloud Router と NAT ゲートウェイを作成する
# create router for nat
gcloud compute routers create cr-nat-foo \
--network=vnet-foo \
--asn=16550 \
--region=${REGION_1}
# create nat gateway
gcloud compute routers nats create natgw-foo \
--router=cr-nat-foo \
--region=${REGION_1} \
--auto-allocate-nat-external-ips \
--nat-all-subnet-ip-ranges
IP アドレスを予約する
# reserve vip for lb www service
gcloud compute addresses create vip-foo-www \
--region=${REGION_1} \
--subnet=subnet-foo-1 \
--addresses=10.0.0.101
# reserve vip for lb api service
gcloud compute addresses create vip-foo-api \
--region=${REGION_1} \
--subnet=subnet-foo-1 \
--addresses=10.0.0.102
# reserve vip for lb gcs service
gcloud compute addresses create vip-foo-gcs \
--region=${REGION_1} \
--subnet=subnet-foo-1 \
--addresses=10.0.0.103
DNS レコードを作成する
# create dns zone
gcloud dns managed-zones create zone-foo \
--description="private zone for foo" \
--dns-name=foo.com \
--networks=vnet-foo \
--visibility=private
# create dns record for www service
gcloud dns record-sets create www.foo.com \
--zone=zone-foo \
--type=A \
--ttl=300 \
--rrdatas="10.0.0.101"
# create dns record for api service
gcloud dns record-sets create api.foo.com \
--zone=zone-foo \
--type=A \
--ttl=300 \
--rrdatas="10.0.0.102"
# create dns record for gcs service
gcloud dns record-sets create gcs.foo.com \
--zone=zone-foo \
--type=A \
--ttl=300 \
--rrdatas="10.0.0.103"
これでネットワーク設定は完了です。次はロードバランサの構成に進みます。
5. ロードバランサ サービス
このセクションでは、次の 3 つのサービスに対してロードバランサ コンポーネント(バックエンド サービス、URL マップ、ターゲット プロキシ、転送ルール)をデプロイします。
- ポート
80のwwwサービス(ilb-foo-www) - ポート
8080のapiサービス(ilb-foo-api) - TLS 証明書を使用してポート
443でgcsサービス(ilb-foo-gcs)
サポートするバックエンド リソース:
- マネージド インスタンス グループで HTTP サーバーを実行している VM インスタンス
- Google API への Private Service Connect(PSC)ネットワーク エンドポイント グループ(NEG)
- Google Cloud Storage(GCS)バケット
バックエンド リソースを設定する
VM インスタンス グループ サーバーを作成する
www ロードバランサは、ポート 80 をリッスンしている Apache ウェブサーバーを実行する VM インスタンス グループのバックエンド サーバーを使用します。
api ロードバランサは、ポート 8080 をリッスンしている同じ VM インスタンス グループを使用します。
# create vm startup config with http server
cat > vm-server-startup.sh << 'OEOF'
#! /bin/bash
set -e
apt-get update
apt-get install apache2 -y
vm_hostname="$(curl -H "Metadata-Flavor:Google" \
http://169.254.169.254/computeMetadata/v1/instance/name)"
vm_zone="$(curl -H "Metadata-Flavor:Google" \
http://169.254.169.254/computeMetadata/v1/instance/zone | cut -d/ -f4)"
echo "www served from: $vm_hostname in zone $vm_zone on port 80" | \
tee /var/www/html/index.html
echo "Listen 8080" | tee -a /etc/apache2/ports.conf
mkdir -p /var/www/api
echo "api served from: $vm_hostname in zone $vm_zone on port 8080" | \
tee /var/www/api/index.html
tee /etc/apache2/sites-available/api.conf << EOF
<VirtualHost *:8080>
DocumentRoot /var/www/api
</VirtualHost>
EOF
a2ensite api.conf
systemctl restart apache2
OEOF
# create managed instance group template
gcloud compute instance-templates create mig-template-foo \
--machine-type=e2-micro \
--network=vnet-foo \
--region=${REGION_1} \
--subnet=subnet-foo-2 \
--no-address \
--shielded-secure-boot \
--metadata-from-file=startup-script=vm-server-startup.sh
# create regional managed instance group
gcloud compute instance-groups managed create mig-foo \
--region=${REGION_1} \
--size=2 \
--template=mig-template-foo \
--base-instance-name=service-foo
# create named ports for instance group
gcloud compute instance-groups managed set-named-ports mig-foo \
--named-ports=www-port:80,api-port:8080 \
--region=${REGION_1}
ストレージ バケットを作成
gcs ロードバランサは、PSC NEG バックエンドを使用して、Google APIs フロントエンド経由で Cloud Storage バケットに接続します。
# create random bucket name
export BUCKET=$(openssl rand -hex 12)
echo ${BUCKET}
注: シェル セッションを閉じると、環境変数は失われます。今後のセッションで完了する必要がある場合は、バケット名をメモします。
# create bucket
gcloud storage buckets create gs://${BUCKET} --location=${REGION_1}
# give compute sa object admin role on bucket
gcloud storage buckets add-iam-policy-binding gs://${BUCKET} \
--member=serviceAccount:${PROJECT_NO}-compute@developer.gserviceaccount.com \
--role=roles/storage.objectAdmin
証明書の作成
gcs ロードバランサは、ターゲット HTTPS プロキシにデプロイされた自己署名証明書を使用して、クライアントの HTTPS リクエストを終了します。
# create cert
openssl req -x509 -newkey rsa:2048 \
-nodes \
-days 365 \
-keyout foo-gcs-key.pem \
-out foo-gcs-cert.pem \
-subj "/CN=Foo, Inc." \
-addext "subjectAltName=DNS:gcs.foo.com"
# upload to certificate manager
gcloud certificate-manager certificates create cert-foo-gcs \
--private-key-file=foo-gcs-key.pem \
--certificate-file=foo-gcs-cert.pem \
--location=${REGION_1}
ロードバランサのコンポーネントの作成
次のスクリプトを使用して、ロードバランサ コンポーネントのデプロイを自動化します。これにより、関連するすべての構成要素の速度と精度が向上します。
ロードバランサ作成スクリプトをデプロイする
# create script file
cat > create_lbs.sh << EOF
#!/bin/bash
set -e
# --- Create load balancer for www service port 80 ---
echo "--- Creating Load Balancer for WWW Service (ilb-foo-www) on port 80 ---"
echo "ilb-foo-www: creating health check (hc-foo-www)"
gcloud compute health-checks create http hc-foo-www \
--use-serving-port \
--region=${REGION_1}
echo "ilb-foo-www: creating backend service (bes-foo-www)"
gcloud compute backend-services create bes-foo-www \
--load-balancing-scheme=INTERNAL_MANAGED \
--protocol=HTTP \
--port-name=www-port \
--health-checks=hc-foo-www \
--health-checks-region=${REGION_1} \
--region=${REGION_1}
echo "ilb-foo-www: adding managed instance group (mig-foo) to backend service (bes-foo-www)"
gcloud compute backend-services add-backend bes-foo-www \
--balancing-mode=UTILIZATION \
--instance-group=mig-foo \
--instance-group-region=${REGION_1} \
--region=${REGION_1}
echo "ilb-foo-www: creating url map (ilb-foo-www)"
gcloud compute url-maps create ilb-foo-www \
--default-service=bes-foo-www \
--region=${REGION_1}
echo "ilb-foo-www: creating target http proxy (proxy-foo-www)"
gcloud compute target-http-proxies create proxy-foo-www \
--url-map=ilb-foo-www \
--url-map-region=${REGION_1} \
--region=${REGION_1}
echo "ilb-foo-www: creating forwarding rule (fr-foo-www)"
gcloud compute forwarding-rules create fr-foo-www \
--load-balancing-scheme=INTERNAL_MANAGED \
--network=vnet-foo \
--subnet=subnet-foo-1 \
--subnet-region=${REGION_1} \
--address=vip-foo-www \
--ports=80 \
--target-http-proxy=proxy-foo-www \
--target-http-proxy-region=${REGION_1} \
--region=${REGION_1}
echo "--- Successfully created Load Balancer for WWW Service (ilb-foo-www) ---"
echo
# --- Create load balancer for api service port 8080 ---
echo "--- Creating Load Balancer for API Service (ilb-foo-api) on port 8080 ---"
echo "ilb-foo-api: creating health check (hc-foo-api)"
gcloud compute health-checks create http hc-foo-api \
--use-serving-port \
--region=${REGION_1}
echo "ilb-foo-api: creating backend service (bes-foo-api)"
gcloud compute backend-services create bes-foo-api \
--load-balancing-scheme=INTERNAL_MANAGED \
--protocol=HTTP \
--port-name=api-port \
--health-checks=hc-foo-api \
--health-checks-region=${REGION_1} \
--region=${REGION_1}
echo "ilb-foo-api: adding managed instance group (mig-foo) to backend service (bes-foo-api)"
gcloud compute backend-services add-backend bes-foo-api \
--balancing-mode=UTILIZATION \
--instance-group=mig-foo \
--instance-group-region=${REGION_1} \
--region=${REGION_1}
echo "ilb-foo-api: creating url map (ilb-foo-api)"
gcloud compute url-maps create ilb-foo-api \
--default-service=bes-foo-api \
--region=${REGION_1}
echo "ilb-foo-api: creating target http proxy (proxy-foo-api)"
gcloud compute target-http-proxies create proxy-foo-api \
--url-map=ilb-foo-api \
--url-map-region=${REGION_1} \
--region=${REGION_1}
echo "ilb-foo-api: creating forwarding rule (fr-foo-api)"
gcloud compute forwarding-rules create fr-foo-api \
--load-balancing-scheme=INTERNAL_MANAGED \
--network=vnet-foo \
--subnet=subnet-foo-1 \
--subnet-region=${REGION_1} \
--address=vip-foo-api \
--ports=8080 \
--target-http-proxy=proxy-foo-api \
--target-http-proxy-region=${REGION_1} \
--region=${REGION_1}
echo "--- Successfully created Load Balancer for API Service (ilb-foo-api) ---"
echo
# --- Create load balancer for gcs service port 443 ---
echo "--- Creating Load Balancer for GCS Service (ilb-foo-gcs) on port 443 ---"
echo "ilb-foo-gcs: creating network endpoint group (neg-psc-gcs)"
gcloud compute network-endpoint-groups create neg-psc-gcs \
--network-endpoint-type=private-service-connect \
--psc-target-service=storage.${REGION_1}.rep.googleapis.com \
--region=${REGION_1}
echo "ilb-foo-gcs: creating backend service (bes-foo-gcs)"
gcloud compute backend-services create bes-foo-gcs \
--load-balancing-scheme=INTERNAL_MANAGED \
--protocol=HTTPS \
--region=${REGION_1}
echo "ilb-foo-gcs: adding network endpoint group (neg-psc-gcs) to backend service (bes-foo-gcs)"
gcloud compute backend-services add-backend bes-foo-gcs \
--network-endpoint-group=neg-psc-gcs \
--network-endpoint-group-region=${REGION_1} \
--region=${REGION_1}
echo "ilb-foo-gcs: creating url map (ilb-foo-gcs)"
gcloud compute url-maps create ilb-foo-gcs \
--default-service=bes-foo-gcs \
--region=${REGION_1}
echo "ilb-foo-gcs: creating target https proxy (proxy-foo-gcs)"
gcloud compute target-https-proxies create proxy-foo-gcs \
--url-map=ilb-foo-gcs \
--url-map-region=${REGION_1} \
--certificate-manager-certificates=cert-foo-gcs \
--region=${REGION_1}
echo "ilb-foo-gcs: creating forwarding rule (fr-foo-gcs)"
gcloud compute forwarding-rules create fr-foo-gcs \
--load-balancing-scheme=INTERNAL_MANAGED \
--network=vnet-foo \
--subnet=subnet-foo-1 \
--subnet-region=${REGION_1} \
--address=vip-foo-gcs \
--ports=443 \
--target-https-proxy=proxy-foo-gcs \
--target-https-proxy-region=${REGION_1} \
--region=${REGION_1}
echo "--- Successfully created Load Balancer for GCS Service (ilb-foo-gcs) ---"
echo
echo "All load balancers created successfully."
EOF
# make script executable
chmod +x create_lbs.sh
# run script
./create_lbs.sh
注: このスクリプトが完了するまでに数分かかります。
ロードバランサの作成を確認する
転送ルールとバックエンド サービスがデプロイされていることを確認します。
# check forwarding rules
gcloud compute forwarding-rules list
# check backend services
gcloud compute backend-services list
これでロードバランサの設定は完了です。次はクライアント VM インスタンスの構成に進みます。
6. クライアント アクセス
VM クライアント リソースを作成する
このセクションでは、クライアントをデプロイし、エンドツーエンドの接続を確認します。
VM インスタンスを作成する
# set variables for client ip addresses
export VM_ALLOW_IP="10.0.0.11"
export VM_DENY_IP="10.0.0.12"
echo ${VM_ALLOW_IP}
echo ${VM_DENY_IP}
# create client 1 vm
gcloud compute instances create vm-allow \
--machine-type=e2-micro \
--zone=${ZONE_1} \
--subnet=subnet-foo-1 \
--no-address \
--private-network-ip=${VM_ALLOW_IP} \
--scopes=cloud-platform \
--shielded-secure-boot
# create client 2 vm
gcloud compute instances create vm-deny \
--machine-type=e2-micro \
--zone=${ZONE_1} \
--subnet=subnet-foo-1 \
--no-address \
--private-network-ip=${VM_DENY_IP} \
--scopes=cloud-platform \
--shielded-secure-boot
ベースライン サービスをテストする
クライアント vm-allow からテストする
注: instances create コマンドを発行すると、VM インスタンスはすぐにオンラインになり、IAP を使用して ssh 経由でアクセスできるようになります。最初のリクエストが失敗した場合は、しばらくお待ちいただく必要があります。
# send request to foo www service
gcloud compute ssh vm-allow --zone=${ZONE_1} --command="
curl -s www.foo.com"
# send request to foo api service
gcloud compute ssh vm-allow --zone=${ZONE_1} --command="
curl -s api.foo.com:8080"
ロードバランサを介して Google Cloud Storage にファイルをアップロードするテストを行います。
# send request to foo gcs service
gcloud compute ssh vm-allow --zone=${ZONE_1} --command="
echo 'test one on the way' > test-upload-1.txt
TOKEN=\$(gcloud auth print-access-token)
curl -s -k -X POST \"https://gcs.foo.com/upload/storage/v1/b/${BUCKET}/o?uploadType=media&name=test-upload-object-1.txt\" \
-H \"Authorization: Bearer \${TOKEN}\" \
-H \"Content-Type: text/plain\" \
--data-binary @test-upload-1.txt"
Cloud Storage API レスポンスにより、ネットワーク パスが正しく機能していることを確認します。
クライアント vm-deny からテストする
# send request to foo www service
gcloud compute ssh vm-deny --zone=${ZONE_1} --command="
curl -s www.foo.com"
# send request to foo api service
gcloud compute ssh vm-deny --zone=${ZONE_1} --command="
curl -s api.foo.com:8080"
# send request to foo gcs service
gcloud compute ssh vm-deny --zone=${ZONE_1} --command="
echo 'test two on the way' > test-upload-2.txt
TOKEN=\$(gcloud auth print-access-token)
curl -s -k -X POST \"https://gcs.foo.com/upload/storage/v1/b/${BUCKET}/o?uploadType=media&name=test-upload-object-2.txt\" \
-H \"Authorization: Bearer \${TOKEN}\" \
-H \"Content-Type: text/plain\" \
--data-binary @test-upload-2.txt"
注: ファイアウォール ルールがまだロードバランサをターゲットにしていないため、これらのテストも成功するはずです。
これで、主な設定はすべて完了しました。次は、ロードバランサのファイアウォール ルールを作成します。
7. ロードバランサのファイアウォール
このセクションでは、ロードバランサをターゲットとするファイアウォール ポリシー ルールをデプロイします。構成の順序は、vm-allow アクセスを許可し、すべてのサービスへの vm-deny トラフィックをブロックするセキュリティ ポスチャーを構築します。
fr-foo-www へのトラフィックを選択して許可する
既存のファイアウォール ポリシーに新しいファイアウォール ポリシールールを追加する fw-policy-foo-${REGION_1}
vm-allowを含み、vm-denyIP アドレスを除外する送信元 IP 範囲を許可する- ロードバランサをターゲットとするファイアウォール ポリシールールでネットワークの種類を使用するために、追加の送信元フィルタ
INTRA_VPCを追加する
INTRA_VPC と VPC_NETWORKS のソース ネットワークの種類は、別のソース パラメータと組み合わせて使用する場合、ロードバランサをターゲットとするファイアウォール ポリシールールでサポートされます。評価ロジックは、2 つのソース パラメータ間の AND です。ここでは、トラフィックが許可されるには、INTRA_VPC と --src-ip-ranges=${VM_ALLOW_IP}/32 の両方の条件を満たす必要があります。
vm-allow が fr-foo-www をターゲットにすることを許可するルールを作成する
# create fw policy rule
gcloud beta compute network-firewall-policies rules create 2001 \
--description="allow vm traffic to fr-www" \
--firewall-policy=fw-policy-foo-${REGION_1} \
--firewall-policy-region=${REGION_1} \
--enable-logging \
--action=allow \
--direction=INGRESS \
--layer4-configs=tcp \
--src-network-type=INTRA_VPC \
--src-ip-ranges=${VM_ALLOW_IP}/32 \
--target-type=INTERNAL_MANAGED_LB \
--target-forwarding-rules=projects/${PROJECT_ID}/regions/${REGION_1}/forwardingRules/fr-foo-www
クライアント vm-allow からテストする
# send request to foo www service
gcloud compute ssh vm-allow --zone=${ZONE_1} --command="
curl -s www.foo.com"
クライアント vm-deny からテストする
# send request to foo www service
gcloud compute ssh vm-deny --zone=${ZONE_1} --command="
curl -s www.foo.com"
注: ロードバランサの暗黙的なデフォルトのファイアウォール ポリシー ルールの動作は --action=allow であるため、これは成功します。この変更を行うには、デフォルト(キャッチオール)の拒否ルールが必要です。
fr-foo-www へのデフォルトのトラフィックを拒否する
優先度の低い(優先度の数値が高い)新しいファイアウォール ポリシールールを追加します。
- 任意の送信元 IP アドレスからのすべてのトラフィックを拒否する
- 拒否ルールにヒットする前に、
vm-allowからfr-foo-wwwへのトラフィックが許可されます。
fr-foo-www をターゲットとするトラフィックを拒否するルールを作成する
# create fw policy rule
gcloud beta compute network-firewall-policies rules create 2999 \
--description="allow vm traffic to fr-www" \
--firewall-policy=fw-policy-foo-${REGION_1} \
--firewall-policy-region=${REGION_1} \
--enable-logging \
--action=deny \
--direction=INGRESS \
--layer4-configs=tcp \
--src-ip-ranges=0.0.0.0/0 \
--target-type=INTERNAL_MANAGED_LB \
--target-forwarding-rules=projects/${PROJECT_ID}/regions/${REGION_1}/forwardingRules/fr-foo-www
ヘルスチェックに関する考慮事項
VM インスタンスをターゲットとするファイアウォール ポリシー ルールと同様に、デフォルトのキャッチオール(暗黙的)の上り(内向き)拒否ルールは、ヘルスチェック プローブの範囲からロードバランサのバックエンド宛てのトラフィックをブロックします。そのため、上り(内向き)ヘルスチェック プローブ範囲を許可するように明示的な許可ルールが構成されました(ルール 1002 を参照)。
重要: 同様に、ロードバランサ ターゲットのキャッチオール(明示的)上り(内向き)拒否ルールを作成する場合は、ヘルスチェック プローブ範囲からの上り(内向き)を許可する、優先度の高い(優先度番号が小さい)別のルールを作成する必要があります。このルールは、ロードバランサをターゲットにする必要があります。
# create fw policy rule
gcloud beta compute network-firewall-policies rules create 2002 \
--description="allow health checks to fr-www" \
--firewall-policy=fw-policy-foo-${REGION_1} \
--firewall-policy-region=${REGION_1} \
--action=allow \
--direction=INGRESS \
--layer4-configs=tcp \
--src-address-groups=projects/${PROJECT_ID}/locations/${REGION_1}/addressGroups/uhc-probes \
--target-type=INTERNAL_MANAGED_LB \
--target-forwarding-rules=projects/${PROJECT_ID}/regions/${REGION_1}/forwardingRules/fr-foo-www
クライアント vm-deny からテストする
# send request to foo www service
gcloud compute ssh vm-deny --zone=${ZONE_1} --command="
curl -s www.foo.com"
ファイアウォール ルール 2999 は VPC ネットワークから送信されるすべてのトラフィックを拒否するため、このコマンドは失敗します。優先度の高い(優先度の数値が小さい)ルール 2001 では、vm-allow を含む送信元範囲のみが許可されていました。
Ctrl+C を押して curl プロセスを停止します。
# send request to foo api service
gcloud compute ssh vm-deny --zone=${ZONE_1} --command="
curl -s api.foo.com:8080"
vm-deny は引き続き API サービスにアクセスできます。これは、ファイアウォール ルールが転送ルール fr-foo-www にのみ適用され、fr-foo-api を対象としていないためです。
すべてのロードバランサをターゲットにするようにルールを更新する
注: --target-forwarding-rules=FR_NAME を省略すると、ファイアウォール ポリシー ルールを VPC ネットワーク内のすべてのロードバランサに適用できます。
ファイアウォール ポリシー ルールを変更して、VPC ネットワーク内のすべてのロードバランサ転送ルール ターゲットに適用されるようにします。
- すべての転送ルールをターゲットにして VM トラフィック(
vm-allowIP 範囲)を許可する新しい上り(内向き)許可ルール2003を作成します。 - すべての転送ルールをターゲットにして、ヘルスチェック(
uhc-probesアドレス グループ)トラフィックを許可する新しい上り(内向き)許可ルール2004を作成します。 - 他のすべてのトラフィックを拒否するキャッチオールとして、すべての転送ルールをターゲットとする新しい上り(内向き)拒否ルール
2998を作成します。
すべてのロードバランサを対象とするようにファイアウォール ルールを変更する
# create fw policy rule
gcloud beta compute network-firewall-policies rules create 2003 \
--description="allow vm traffic to all vnet lb fr" \
--firewall-policy=fw-policy-foo-${REGION_1} \
--firewall-policy-region=${REGION_1} \
--enable-logging \
--action=allow \
--direction=INGRESS \
--layer4-configs=tcp \
--src-ip-ranges=${VM_ALLOW_IP}/32 \
--target-type=INTERNAL_MANAGED_LB
# create fw policy rule
gcloud beta compute network-firewall-policies rules create 2004 \
--description="allow health checks to all vnet lb fr" \
--firewall-policy=fw-policy-foo-${REGION_1} \
--firewall-policy-region=${REGION_1} \
--enable-logging \
--action=allow \
--direction=INGRESS \
--layer4-configs=tcp \
--src-address-groups=projects/${PROJECT_ID}/locations/${REGION_1}/addressGroups/uhc-probes \
--target-type=INTERNAL_MANAGED_LB
# create fw policy rule
gcloud beta compute network-firewall-policies rules create 2998 \
--description="deny all vnet traffic to all vnet lb fr" \
--firewall-policy=fw-policy-foo-${REGION_1} \
--firewall-policy-region=${REGION_1} \
--enable-logging \
--action=deny \
--direction=INGRESS \
--layer4-configs=tcp \
--src-ip-ranges=0.0.0.0/0 \
--target-type=INTERNAL_MANAGED_LB
明示的なロードバランサ転送ルールをターゲットとする以前のファイアウォール ポリシー ルールは、VPC ネットワーク内のすべての転送ルールをターゲットとするルールと重複しているため、削除できます。
# delete redundant fw policy rules
gcloud beta compute network-firewall-policies rules delete 2001 \
--firewall-policy=fw-policy-foo-${REGION_1} \
--firewall-policy-region=${REGION_1}
gcloud beta compute network-firewall-policies rules delete 2002 \
--firewall-policy=fw-policy-foo-${REGION_1} \
--firewall-policy-region=${REGION_1}
gcloud beta compute network-firewall-policies rules delete 2999 \
--firewall-policy=fw-policy-foo-${REGION_1} \
--firewall-policy-region=${REGION_1}
クライアント vm-deny からテストする
# send request to foo api service
gcloud compute ssh vm-deny --zone=${ZONE_1} --command="
curl -s api.foo.com:8080"
fr-foo-api は --target-type=INTERNAL_MANAGED_LB を含むすべてのファイアウォール ポリシールールのターゲットでもあるため、このコマンドは失敗します。
Ctrl+C を押して curl プロセスを停止します。
ロードバランサを介して Google Cloud Storage からファイルをダウンロードするテストを行います。
# send request to foo gcs service
gcloud compute ssh vm-deny --zone=${ZONE_1} --command="
TOKEN=\$(gcloud auth print-access-token)
curl -s -k \"https://gcs.foo.com/storage/v1/b/${BUCKET}/o/test-upload-object.txt?alt=media\" \
-H \"Authorization: Bearer \${TOKEN}\" \
-o test-download.txt"
Ctrl+C を押して curl プロセスを停止します。
クライアント vm-allow からテストする
# send request to foo www service
gcloud compute ssh vm-allow --zone=${ZONE_1} --command="
curl -s www.foo.com"
# send request to foo api service
gcloud compute ssh vm-allow --zone=${ZONE_1} --command="
curl -s api.foo.com:8080"
# send request to foo gcs service
gcloud compute ssh vm-allow --zone=${ZONE_1} --command="
TOKEN=\$(gcloud auth print-access-token)
curl -s -k \"https://gcs.foo.com/storage/v1/b/${BUCKET}/o/test-upload-object-1.txt?alt=media\" \
-H \"Authorization: Bearer \${TOKEN}\" \
-o test-download-1.txt"
ダウンロードしたコンテンツを確認する
# send request from vm
gcloud compute ssh vm-allow --zone=${ZONE_1} --command="
cat test-download-1.txt"
すべてのロードバランサ サービスが vm-allow で利用可能であり、vm-deny で正常にブロックされています。
テスト部分は以上です。次はロギングについて簡単に説明します。
8. ファイアウォール ルールのロギング
ファイアウォール ログ形式には、ロードバランサ(--target-type=INTERNAL_MANAGED_LB)をターゲットとするルールのフィールドとレコードがあります。
ログには、ファイアウォール ポリシー ルールのターゲットとなったロードバランサに関する詳細情報を含む load_balancer_details というラベルの追加フィールドが含まれます。これは、ファイアウォール ポリシールールで VM インスタンスがターゲットに設定されている場合の InstanceDetails フィールド形式に類似しています。
load_balancer_details.forwarding_rule_nameは、ファイアウォール ポリシー ルールのターゲット転送ルールを示します。load_balancer_details.typeは、ターゲットとなるプロキシベースのロードバランサのフレーバーを示します。- タイプがアプリケーション ロードバランサの場合、
load_balancer_details.url_map_nameは使用された URL マップ リソースをログに記録します
ログを表示
ファイアウォール ログをクエリして、ファイアウォール ポリシー ルールの結果を確認します。
gcloud logging read \
"logName=projects/${PROJECT_ID}/logs/compute.googleapis.com%2Ffirewall \
AND (jsonPayload.connection.src_ip=\"${VM_ALLOW_IP}\" OR jsonPayload.connection.src_ip=\"${VM_DENY_IP}\")" \
--project=${PROJECT_ID} \
--freshness=30m \
--limit=50 \
--format="table(
timestamp:label=TIMESTAMP,
jsonPayload.connection.src_ip:label=SRC_IP,
jsonPayload.connection.src_port:label=SRC_PORT,
jsonPayload.connection.dest_ip:label=DEST_IP,
jsonPayload.connection.dest_port:label=DEST_PORT,
jsonPayload.disposition:label=ACTION,
jsonPayload.rule_details.priority:label=PRIORITY,
jsonPayload.load_balancer_details.forwarding_rule_name:label=FWD_RULE
)"
ログ出力には、ポリシーによって適用される有効なルールが表示されます。
- すべてのロードバランサへのすべての
vm-allowトラフィックはルール2011で許可されます - ロードバランサ宛てのすべてのトラフィックは、ルール
2998によって拒否されます。
TIMESTAMP SRC_IP SRC_PORT DEST_IP DEST_PORT ACTION PRIORITY FWD_RULE
YYYY-MM-DDTHH:MM:SS.850967068Z 10.0.0.11 48480 10.0.0.103 443 ALLOWED 2003 fr-foo-gcs
YYYY-MM-DDTHH:MM:SS.418613380Z 10.0.0.11 37340 10.0.0.101 80 ALLOWED 2003 fr-foo-www
YYYY-MM-DDTHH:MM:SS.213234118Z 10.0.0.12 55950 10.0.0.103 443 DENIED 2998 fr-foo-gcs
YYYY-MM-DDTHH:MM:SS.981484412Z 10.0.0.11 41738 10.0.0.101 80 ALLOWED 2003 fr-foo-www
YYYY-MM-DDTHH:MM:SS.189358071Z 10.0.0.12 55950 10.0.0.103 443 DENIED 2998 fr-foo-gcs
YYYY-MM-DDTHH:MM:SS.061463883Z 10.0.0.12 55950 10.0.0.103 443 DENIED 2998 fr-foo-gcs
YYYY-MM-DDTHH:MM:SS.965498098Z 10.0.0.12 53284 10.0.0.102 8080 DENIED 2998 fr-foo-api
ログは、Google Cloud コンソールのログ エクスプローラでも表示できます。console.cloud.google.com/logs/query に移動し、標準の VPC ファイアウォール ログ compute.googleapis.com/firewall を使用します。
logName=projects/${PROJECT_ID}/logs/compute.googleapis.com%2Ffirewall
ロギングの説明は以上です。次はクリーンアップに進みます。
9. クリーンアップ
# delete client compute resources
gcloud -q compute instances delete vm-deny --zone=${ZONE_1}
gcloud -q compute instances delete vm-allow --zone=${ZONE_1}
# next
# delete load balancer resources for gcs
gcloud -q compute forwarding-rules delete fr-foo-gcs --region=${REGION_1}
gcloud -q compute target-https-proxies delete proxy-foo-gcs --region=${REGION_1}
gcloud -q compute url-maps delete ilb-foo-gcs --region=${REGION_1}
gcloud -q compute backend-services delete bes-foo-gcs --region=${REGION_1}
gcloud -q compute addresses delete vip-foo-gcs --region=${REGION_1}
# next
# delete load balancer resources for api
gcloud -q compute forwarding-rules delete fr-foo-api --region=${REGION_1}
gcloud -q compute target-http-proxies delete proxy-foo-api --region=${REGION_1}
gcloud -q compute url-maps delete ilb-foo-api --region=${REGION_1}
gcloud -q compute backend-services delete bes-foo-api --region=${REGION_1}
gcloud -q compute health-checks delete hc-foo-api --region=${REGION_1}
gcloud -q compute addresses delete vip-foo-api --region=${REGION_1}
# next
# delete load balancer resources for www
gcloud -q compute forwarding-rules delete fr-foo-www --region=${REGION_1}
gcloud -q compute target-http-proxies delete proxy-foo-www --region=${REGION_1}
gcloud -q compute url-maps delete ilb-foo-www --region=${REGION_1}
gcloud -q compute backend-services delete bes-foo-www --region=${REGION_1}
gcloud -q compute health-checks delete hc-foo-www --region=${REGION_1}
gcloud -q compute addresses delete vip-foo-www --region=${REGION_1}
# next
# delete service backend resources
gcloud -q storage rm --recursive gs://${BUCKET}
gcloud -q certificate-manager certificates delete cert-foo-gcs --location=${REGION_1}
gcloud -q compute network-endpoint-groups delete neg-psc-gcs --region=${REGION_1}
gcloud -q compute instance-groups managed delete mig-foo --region=${REGION_1}
gcloud -q compute instance-templates delete mig-template-foo --global
# next
# delete dns, nat, fw resources
gcloud -q dns record-sets delete gcs.foo.com --type=A --zone=zone-foo
gcloud -q dns record-sets delete api.foo.com --type=A --zone=zone-foo
gcloud -q dns record-sets delete www.foo.com --type=A --zone=zone-foo
gcloud -q dns managed-zones delete zone-foo
gcloud -q compute routers delete cr-nat-foo --region=${REGION_1}
gcloud -q compute network-firewall-policies associations delete \
--firewall-policy=fw-policy-foo-${REGION_1} \
--name=fw-policy-association-foo-${REGION_1} \
--firewall-policy-region=${REGION_1}
gcloud -q compute network-firewall-policies delete fw-policy-foo-${REGION_1} --region=${REGION_1}
gcloud -q network-security address-groups delete uhc-probes --location=${REGION_1}
# next
# delete network resources
gcloud -q compute networks subnets delete subnet-foo-3 --region=${REGION_1}
gcloud -q compute networks subnets delete subnet-foo-2 --region=${REGION_1}
gcloud -q compute networks subnets delete subnet-foo-1 --region=${REGION_1}
gcloud -q compute networks delete vnet-foo
# next
# delete shell variables and local files
unset PROJECT_ID REGION_1 ZONE_1 VM_ALLOW_IP VM_DENY_IP BUCKET
rm vm-server-startup.sh create_lbs.sh foo-gcs-key.pem foo-gcs-cert.pem
# end
10. まとめ
おめでとうございます!ロードバランサ用の Cloud NGFW Essentials の構成が完了しました。
コメント、質問、修正などがありましたら、こちらのフィードバック フォームからお気軽にお送りください。
ありがとうございました。