1. はじめに
ポリシーベースのルート
ポリシーベースのルートを使用すると、パケットの宛先 IP アドレス以外の要素に基づいてネクストホップを選択できます。プロトコルと送信元 IP アドレスでトラフィックを照合することもできます。一致するトラフィックは、内部ロードバランサにリダイレクトされます。これは、ファイアウォールなどのアプライアンスをネットワークトラフィックのパスに挿入するのに役立ちます。
ポリシーベースのルートを作成するときに、ルートでトラフィックを処理できるリソースを選択します。このルートは次のものに適用できます。
- ネットワーク全体: すべての仮想マシン(VM)インスタンス、VPN ゲートウェイ、相互接続
- ネットワーク タグの使用: VPC 内の VM インスタンスの選択
- 相互接続リージョン: リージョンの VLAN アタッチメント経由で VPC ネットワークに到達するすべてのトラフィック
ポリシーベースのルートのネクストホップは、ポリシーベースのルートと同じ VPC ネットワークにある有効な内部ネットワーク ロードバランサである必要があります。
内部ロードバランサはデフォルトで対称ハッシュを使用するため、送信元 NAT を構成することなく、トラフィックが送信パスとリターンパスで同じアプライアンスに到達できます。
ポリシーベースのルートは、特別なリターンパスを除き、他のルートタイプよりも優先度が高くなります。
2 つのポリシーベースのルートの優先度が同じ場合、Google Cloud は決定論的な内部アルゴリズムを使用して 1 つのポリシーベースのルートを選択し、同じ優先度の他のルートを無視します。ポリシーベースのルートは最長プレフィックス マッチングを使用せず、優先度が最も高いルートのみを選択します。
一方向のトラフィックを処理するルールを 1 つ作成することも、双方向のトラフィックを処理する複数のルールを作成することもできます。
Cloud Interconnect でポリシーベースのルートを使用するには、リージョン内のすべての Cloud Interconnect 接続にルートを適用する必要があります。ポリシーベースのルートは、個々の Cloud Interconnect 接続にのみ適用することはできません。
ポリシーベースのルートからトラフィックを受信する VM インスタンスで、IP 転送を有効にする必要があります。
PBR に関する考慮事項
次の方法でポリシーベースのルートを使用するには、特別な構成が必要です。
たとえば、GKE、PSC、または PGA/PSA で PBR を使用します。
GKE を使用した PBR の詳細についてはこちらを、一般的な PBR の制限事項についてはこちらをご覧ください。
学習内容
- ポリシーベースのルートの構成方法
必要なもの
- インスタンスのデプロイとネットワーキング コンポーネントの構成に関する知識
- VPC ファイアウォール構成に関する知識
2. テスト環境
この Codelab では単一の VPC を使用します。この環境には、別のサーバー リソースにパケットを送信する、clienta と clientb の 2 つのコンピューティング リソースがあります。PBR とフィルタを使用して、clientb のトラフィックはサーバーに直接送信され、clientb のトラフィックは別のコンピューティング リソースを経由してファイアウォールが適用されます。次の図にパスを示します。
上の図では、技術的には PBR パス用の ILB(ネットワーク内部ロードバランサ)が必要です。図をわかりやすくするため、ここでは省略しています。
3. 始める前に
Codelab に必要なプロジェクトは 1 つです。
Cloud Shell から:
export project_id=`gcloud config list --format="value(core.project)"` export region=us-central1 export zone=us-central1-a export prefix=codelab-pbr
4. API を有効にする
まだ行っていない場合は、API を有効にしてプロダクトを使用できるようにします。
Cloud Shell から:
gcloud services enable compute.googleapis.com gcloud services enable networkconnectivity.googleapis.com
5. VPC ネットワークとサブネットを作成する
VPC ネットワーク
Codelab-pbr-vpc VPC を作成します。
Cloud Shell から:
gcloud compute networks create $prefix-vpc --subnet-mode=custom
サブネット
選択したリージョンにそれぞれのサブネットを作成します。
Cloud Shell から:
gcloud compute networks subnets create $prefix-vpc-subnet \ --range=10.10.10.0/24 --network=$prefix-vpc --region=${region}
6. ファイアウォール ルールを作成する
IAP に VM インスタンスへの接続を許可するには、次のファイアウォール ルールを作成します。
- IAP を使用してアクセスできるようにするすべての VM インスタンスに適用します。
- IP 範囲 35.235.240.0/20 からの上り(内向き)トラフィックを許可する。この範囲には、IAP が TCP 転送に使用するすべての IP アドレスが含まれています。
Cloud Shell から:
gcloud compute firewall-rules create $prefix-allow-iap-proxy \ --direction=INGRESS \ --priority=1000 \ --network=$prefix-vpc \ --action=ALLOW \ --rules=tcp:22 \ --source-ranges=35.235.240.0/20
サーバーへの標準 HTTP ポート(TCP 80)と ICMP プロトコルを許可するには:
- ネットワーク タグ「server」を持つリソースに適用されます。
- すべての送信元からの上り(内向き)を許可
Cloud Shell から:
gcloud compute firewall-rules create $prefix-allow-http-icmp \ --direction=INGRESS \ --priority=1000 \ --network=$prefix-vpc \ --action=ALLOW \ --rules=tcp:80,icmp \ --source-ranges=0.0.0.0/0 \ --target-tags=server
FW がパケットを受信できるようにするには、すべてのプロトコルとポートで上り(内向き)を許可します。
- ネットワーク タグ「fw」を持つリソースに適用されます。
- 10.10.10.0/24 の送信元からの上り(内向き)を許可
Cloud Shell から:
gcloud compute firewall-rules create $prefix-fw-allow-ingress \ --direction=INGRESS \ --priority=1000 \ --network=$prefix-vpc \ --action=ALLOW \ --rules=all \ --source-ranges=10.10.10.0/24 \ --target-tags=fw
ヘルスチェック プローブを許可する
- ネットワーク タグ「fw」を持つリソースに適用されます。
- ヘルスチェック範囲からの上り(内向き)を許可する
Cloud Shell から:
gcloud compute firewall-rules create $prefix-allow-hc-ingress \ --direction=INGRESS \ --priority=1000 \ --network=$prefix-vpc \ --action=ALLOW \ --rules=tcp:80 \ --source-ranges=130.211.0.0/22,35.191.0.0/16 \ --target-tags=fw
7. Cloud Router を作成し、Cloud NAT
このセクションの目的は、プライベート仮想マシンがインターネットから適切なソフトウェア パッケージをダウンロードできるようにすることです。
Cloud Router を作成
Cloud Shell から:
gcloud compute routers create ${prefix}-cr \ --region=${region} \ --network=${prefix}-vpc
Cloud NAT ゲートウェイを作成
Cloud Shell から:
gcloud compute routers nats create ${prefix}-nat-gw-${region} \ --router=${prefix}-cr \ --router-region=${region} \ --auto-allocate-nat-external-ips \ --nat-all-subnet-ip-ranges
8. コンピューティング インスタンスを作成する
コンピューティング インスタンス ClientA、ClientB、FW、Server を作成します。
Cloud Shell から:
gcloud compute instances create clienta \ --subnet=$prefix-vpc-subnet \ --no-address \ --private-network-ip=10.10.10.10 \ --zone $zone \ --tags client \ --metadata startup-script='#! /bin/bash apt-get update'
Cloud Shell から:
gcloud compute instances create clientb \ --subnet=$prefix-vpc-subnet \ --no-address \ --private-network-ip=10.10.10.11 \ --zone $zone \ --tags client \ --metadata startup-script='#! /bin/bash apt-get update'
Cloud Shell から:
gcloud compute instances create server \ --subnet=$prefix-vpc-subnet \ --no-address \ --private-network-ip=10.10.10.200 \ --zone $zone \ --tags server \ --metadata startup-script='#! /bin/bash sudo su apt-get update apt-get -y install tcpdump apt-get -y install nginx cat > /var/www/html/index.html << EOF <html><body><p>Server</p></body></html> EOF'
Cloud Shell から:
gcloud compute instances create fw \ --subnet=$prefix-vpc-subnet \ --can-ip-forward \ --no-address \ --private-network-ip=10.10.10.75 \ --zone $zone \ --tags fw \ --metadata startup-script='#! /bin/bash apt-get update sudo apt-get -y install tcpdump sudo apt-get -y install nginx sudo sysctl -w net.ipv4.ip_forward=1 sudo iptables -I FORWARD -d 10.10.10.200 -j REJECT'
9. PBR なしで接続をテストする
先ほど作成したクライアント コンピューティング VM に SSH で接続し、両方のクライアントからサーバーへの接続を確認します。
cloudshell1 から clienta にログインします。
gcloud compute ssh clienta --zone=$zone --tunnel-through-iap
次のコマンドを実行します。
ping 10.10.10.200 -c 5
curl 10.10.10.200/index.html
ping と curl のリクエストは成功するはずです。
出力:
root@clienta:~$ ping 10.10.10.200 -c 5 PING 10.10.10.200 (10.10.10.200) 56(84) bytes of data. 64 bytes from 10.10.10.200: icmp_seq=1 ttl=64 time=1.346 ms 64 bytes from 10.10.10.200: icmp_seq=2 ttl=64 time=0.249 ms 64 bytes from 10.10.10.200: icmp_seq=3 ttl=64 time=0.305 ms 64 bytes from 10.10.10.200: icmp_seq=4 ttl=64 time=0.329 ms 64 bytes from 10.10.10.200: icmp_seq=5 ttl=64 time=0.240 ms
root@clienta:~$ curl 10.10.10.200/index.html <html><body><p>Server</p></body></html>
[+] をクリックして追加の Cloud Shell タブを開きます。
cloudshell2 から、使用する変数を設定します。
export project_id=`gcloud config list --format="value(core.project)"` export region=us-central1 export zone=us-central1-a export prefix=codelab-pbr
cloudshell2 SSH から clientb に接続します。
gcloud compute ssh clientb --zone=$zone --tunnel-through-iap
次のコマンドを実行します。
ping 10.10.10.200 -c 5
curl 10.10.10.200/index.html
ping と curl のリクエストは成功するはずです。
出力:
root@clientb:~$ ping 10.10.10.200 -c 5 PING 10.10.10.200 (10.10.10.200) 56(84) bytes of data. 64 bytes from 10.10.10.200: icmp_seq=1 ttl=64 time=1.346 ms 64 bytes from 10.10.10.200: icmp_seq=2 ttl=64 time=0.249 ms 64 bytes from 10.10.10.200: icmp_seq=3 ttl=64 time=0.305 ms 64 bytes from 10.10.10.200: icmp_seq=4 ttl=64 time=0.329 ms 64 bytes from 10.10.10.200: icmp_seq=5 ttl=64 time=0.240 ms
root@clientb:~$ curl 10.10.10.200/index.html <html><body><p>Server</p></body></html>
VM ターミナルを終了し、Cloud Shell に戻ります。
10. インスタンス グループを作成する
fw VM に非マネージド インスタンス グループを作成します。
Cloud Shell から:
gcloud compute instance-groups unmanaged create pbr-uig --zone=$zone
fw インスタンスを非マネージド インスタンス グループに追加します。
Cloud Shell から:
gcloud compute instance-groups unmanaged add-instances pbr-uig --instances=fw --zone=$zone
11. ヘルスチェックを作成する
バックエンド サービスのヘルスチェックを作成します。簡単な TCP ポート 80 のヘルスチェックを行います。
Cloud Shell から:
gcloud compute health-checks create tcp $prefix-hc-tcp-80 --region=$region --port 80
12. バックエンド サービスを作成する
転送ルールに接続するバックエンド サービスを作成します。
Cloud Shell から:
gcloud compute backend-services create be-pbr --load-balancing-scheme=internal --protocol=tcp --region=$region --health-checks=$prefix-hc-tcp-80 --health-checks-region=$region
次に、インスタンス グループをバックエンド サービスに追加します。
Cloud Shell から:
gcloud compute backend-services add-backend be-pbr --region=$region --instance-group=pbr-uig --instance-group-zone=$zone
13. 転送ルールを作成する
Cloud Shell から:
gcloud compute forwarding-rules create fr-pbr --region=$region --load-balancing-scheme=internal --network=$prefix-vpc --subnet=$prefix-vpc-subnet --ip-protocol=TCP --ports=ALL --backend-service=be-pbr --backend-service-region=$region --address=10.10.10.25 --network-tier=PREMIUM
14. PBR ルールを作成
この PBR ルールはクライアントに適用されます。送信元 IP が 10.10.10.10/32(クライアントのアドレス)、宛先 IP が 10.10.10.0/24 の場合、すべての IPv4 トラフィックが転送ルール 10.10.10.25 にルーティングされます。
つまり、clienta は PBR と一致し、clientb は一致しません。
Cloud Shell から:
gcloud network-connectivity policy-based-routes create pbr-client \ --network=projects/$project_id/global/networks/$prefix-vpc \ --next-hop-ilb-ip=10.10.10.25 \ --source-range=10.10.10.10/32 \ --destination-range=10.10.10.0/24 \ --protocol-version=IPv4 \ --priority=1000 \ --tags=client
この PBR ルールはサーバーに適用されます。送信元 IP が 10.10.10.200/32 で、宛先 IP が 10.10.10.10/32 の場合、すべての IPv4 トラフィックが転送ルール 10.10.10.25 にルーティングされます。
Cloud Shell から:
gcloud network-connectivity policy-based-routes create pbr-server \ --network=projects/$project_id/global/networks/$prefix-vpc \ --next-hop-ilb-ip=10.10.10.25 \ --source-range=10.10.10.200/32 \ --destination-range=10.10.10.10/32 \ --protocol-version=IPv4 \ --priority=2000 \ --tags=server
15. PBR で接続をテストする
次に、PBR 機能を検証します。「fw」インスタンスが、サーバーを宛先とするリクエストを拒否する iptables を使用して構成されているPBR が機能している場合、clientb は引き続き成功しますが、clienta で以前動作していたリクエストは失敗します。
クライアント Compute VM に SSH で接続し、同じテストを実行します。
cloudshell1 から:
gcloud compute ssh clienta --zone=$zone --tunnel-through-iap
次のコマンドを実行します。
ping 10.10.10.200 -c 5
curl 10.10.10.200/index.html
出力:
root@clienta:~$ ping 10.10.10.200 -c 5 PING 10.10.10.200 (10.10.10.200) 56(84) bytes of data. From 10.10.10.75 icmp_seq=1 Destination Port Unreachable From 10.10.10.75 icmp_seq=2 Destination Port Unreachable From 10.10.10.75 icmp_seq=3 Destination Port Unreachable From 10.10.10.75 icmp_seq=4 Destination Port Unreachable From 10.10.10.75 icmp_seq=5 Destination Port Unreachable
root@clienta:~$ curl 10.10.10.200/index.html curl: (7) Failed to connect to 10.10.10.200 port 80: Connection refused
リクエストに失敗したため、PBR がこのトラフィックをブロックするように構成された fw インスタンスに clienta のトラフィックをアクティブにルーティングしていることがわかります。
clientb に SSH で接続し、同じ接続テストを実行します。
cloudshell2 から:
gcloud compute ssh clientb --zone=$zone --tunnel-through-iap
次のコマンドを実行します。
ping 10.10.10.200 -c 5
curl 10.10.10.200/index.html
出力:
root@clientb:~$ ping 10.10.10.200 -c 5 PING 10.10.10.200 (10.10.10.200) 56(84) bytes of data. 64 bytes from 10.10.10.200: icmp_seq=1 ttl=63 time=0.361 ms 64 bytes from 10.10.10.200: icmp_seq=2 ttl=63 time=0.475 ms 64 bytes from 10.10.10.200: icmp_seq=3 ttl=63 time=0.379 ms
root@clientb:~$ curl 10.10.10.200 <html><body><p>Server</p></body></html>
ご覧のとおり、clientb から server へのリクエストは成功しています。これは、リクエストが送信元 IP の PBR ルールと一致しないためです。
16. [省略可] ファイアウォールでのキャプチャによる検証
このオプションのセクションでは、ファイアウォール VM でパケット キャプチャを行って PBR を検証できます。
cloudshell1 と cloudshell2 で clienta と clientb に SSH で接続しているはずです。
[+] をクリックして追加の Cloud Shell タブを開きます。
cloudshell3 から、変数を設定します。
export project_id=`gcloud config list --format="value(core.project)"` export region=us-central1 export zone=us-central1-a export prefix=codelab-pbr
fw に SSH 接続します。
gcloud compute ssh fw --zone=$zone --tunnel-through-iap
fw(cloudshell3)で次のコマンドを実行します。
sudo tcpdump -i any icmp -nn
clienta(cloudshell1)から ping テストを実行します。
ping 10.10.10.200 -c 5
clientb(cloudshell2)から ping テストを実行します。
ping 10.10.10.200 -c 5
fw での出力(cloudshell 3):
root@fw:~$ sudo tcpdump -i any icmp -nn tcpdump: data link type LINUX_SLL2 tcpdump: verbose output suppressed, use -v[v]... for full protocol decode listening on any, link-type LINUX_SLL2 (Linux cooked v2), snapshot length 262144 bytes 17:07:42.215297 ens4 In IP 10.10.10.10 > 10.10.10.200: ICMP echo request, id 25362, seq 1, length 64 17:07:42.215338 ens4 Out IP 10.10.10.75 > 10.10.10.10: ICMP 10.10.10.200 protocol 1 port 51064 unreachable, length 92 17:07:43.216122 ens4 In IP 10.10.10.10 > 10.10.10.200: ICMP echo request, id 25362, seq 2, length 64 17:07:43.216158 ens4 Out IP 10.10.10.75 > 10.10.10.10: ICMP 10.10.10.200 protocol 1 port 30835 unreachable, length 92 17:07:44.219064 ens4 In IP 10.10.10.10 > 10.10.10.200: ICMP echo request, id 25362, seq 3, length 64 17:07:44.219101 ens4 Out IP 10.10.10.75 > 10.10.10.10: ICMP 10.10.10.200 protocol 1 port 2407 unreachable, length 92
PBR は適用されないため、clientb(10.10.10.11)からの tcpdump にパケットは表示されません。
Cloud Shell に戻り、リソースをクリーンアップします。
17. クリーンアップ手順
Cloud Shell で、PBR ルール、転送ルール、バックエンド サービス、ヘルスチェック、インスタンス グループ、コンピューティング インスタンス、NAT、Cloud Router、ファイアウォール ルールを削除します。
gcloud -q network-connectivity policy-based-routes delete pbr-client gcloud -q network-connectivity policy-based-routes delete pbr-server gcloud -q compute forwarding-rules delete fr-pbr --region=$region gcloud -q compute backend-services delete be-pbr --region=$region gcloud -q compute health-checks delete $prefix-hc-tcp-80 --region=$region gcloud -q compute instance-groups unmanaged delete pbr-uig --zone=$zone gcloud -q compute instances delete clienta --zone=$zone gcloud -q compute instances delete clientb --zone=$zone gcloud -q compute instances delete server --zone=$zone gcloud -q compute instances delete fw --zone=$zone gcloud -q compute routers nats delete ${prefix}-nat-gw-${region} \ --router=$prefix-cr --router-region=$region gcloud -q compute routers delete $prefix-cr --region=$region gcloud -q compute firewall-rules delete $prefix-allow-iap-proxy gcloud -q compute firewall-rules delete $prefix-allow-http-icmp gcloud -q compute firewall-rules delete $prefix-fw-allow-ingress gcloud -q compute firewall-rules delete $prefix-allow-hc-ingress
サブネットと VPC を削除します。
gcloud -q compute networks subnets delete $prefix-vpc-subnet \ --region $region gcloud -q compute networks delete $prefix-vpc
18. 完了
以上で、この Codelab は完了です。
学習した内容
- ポリシーベースのルート