정책 기반 경로 (PBR) Codelab

1. 소개

정책 기반 경로

정책 기반 경로를 사용하면 패킷의 대상 IP 주소 이상을 기준으로 다음 홉을 선택할 수 있습니다. 프로토콜 및 소스 IP 주소별로 트래픽을 일치시킬 수도 있습니다. 일치하는 트래픽은 내부 네트워크 부하 분산기로 리디렉션됩니다. 이렇게 하면 방화벽과 같은 어플라이언스를 네트워크 트래픽의 경로에 삽입할 수 있습니다.

정책 기반 경로를 만들 때는 경로에서 트래픽을 처리할 수 있는 리소스를 선택합니다. 경로는 다음에 적용할 수 있습니다.

  • 전체 네트워크: 모든 가상 머신 (VM) 인스턴스, VPN 게이트웨이, 상호 연결
  • 네트워크 태그 사용: VPC에서 VM 인스턴스 선택
  • Interconnect 리전: 리전의 VLAN 연결을 통해 VPC 네트워크에 들어오는 모든 트래픽

정책 기반 경로의 다음 홉은 정책 기반 경로와 동일한 VPC 네트워크에 있는 유효한 내부 네트워크 부하 분산기여야 합니다.

내부 네트워크 부하 분산기는 기본적으로 대칭 해싱을 사용하므로, 소스 NAT를 구성하지 않고도 트래픽이 발신 및 반환 경로에서 동일한 어플라이언스에 도달할 수 있습니다.

정책 기반 경로는 특수 반환 경로를 제외하고 다른 경로 유형보다 우선순위가 높습니다.

두 정책 기반 경로의 우선순위가 동일한 경우 Google Cloud는 확정적인 내부 알고리즘을 사용하여 단일 정책 기반 경로를 선택하고 우선순위가 같은 다른 경로는 무시합니다. 정책 기반 경로는 가장 긴 프리픽스 일치를 사용하지 않고 우선순위가 가장 높은 경로만 선택합니다.

단방향 트래픽에 대한 단일 규칙을 만들거나 양방향 트래픽을 처리하는 여러 규칙을 만들 수 있습니다.

Cloud Interconnect에서 정책 기반 경로를 사용하려면 전체 리전의 모든 Cloud Interconnect 연결에 해당 경로를 적용해야 합니다. 정책 기반 경로는 개별 Cloud Interconnect 연결에만 적용할 수 없습니다.

정책 기반 경로에서 트래픽을 수신하는 VM 인스턴스에는 IP 전달이 사용 설정되어 있어야 합니다.

PBR 관련 고려사항

다음과 같은 방식으로 정책 기반 경로를 사용하려면 특별한 구성이 필요합니다.

예를 들어 GKE, PSC 또는 PGA/PSA와 함께 PBR을 사용합니다.

GKE를 사용한 PBR에 대한 자세한 내용은 여기에서, 일반적인 PBR 제한사항 섹션은 여기에서 확인할 수 있습니다.

학습할 내용

  • 정책 기반 경로를 구성하는 방법

필요한 항목

  • 인스턴스 배포 및 네트워킹 구성요소 구성에 관한 지식
  • VPC 방화벽 구성 지식

2. 테스트 환경

이 Codelab에서는 단일 VPC를 활용합니다. 이 환경에는 패킷을 다른 서버 리소스로 전송하는 두 개의 컴퓨팅 리소스인 clienta와 clientb가 있습니다. PBR 및 필터를 사용하면 클라이언트 트래픽이 서버로 직접 전달되는 동안 방화벽 적용을 위해 다른 컴퓨팅 리소스를 통해 클라이언트로부터 발생하는 트래픽을 강제 적용합니다. 아래 다이어그램은 이 경로를 보여줍니다.

bff32b01ada8e9ad.png

위의 다이어그램에는 PBR 경로용 ILB (네트워크 내부 부하 분산기)가 있어야 합니다. 다이어그램의 단순성을 위해 생략했습니다.

3. 시작하기 전에

Codelab에는 단일 프로젝트가 필요합니다.

cloudshell에서:

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를 아직 사용 설정하지 않았다면 사용 설정하세요.

cloudshell에서:

gcloud services enable compute.googleapis.com
gcloud services enable networkconnectivity.googleapis.com

5. VPC 네트워크 및 서브넷 만들기

VPC 네트워크

Codelab-pbr-vpc VPC 만들기:

cloudshell에서:

gcloud compute networks create $prefix-vpc --subnet-mode=custom 

서브넷

선택한 리전에 각 서브넷을 만듭니다.

cloudshell에서:

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 주소가 포함됩니다.

cloudshell에서:

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'인 리소스에 적용
  • 모든 소스에서의 인그레스 허용

cloudshell에서:

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 소스에서의 인그레스 허용

cloudshell에서:

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'인 리소스에 적용
  • 상태 점검 범위에서 인그레스 허용

cloudshell에서:

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 만들기

cloudshell에서:

gcloud compute routers create ${prefix}-cr \
--region=${region} \
--network=${prefix}-vpc

Cloud NAT 게이트웨이 만들기

cloudshell에서:

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. Compute 인스턴스 만들기

다음과 같이 컴퓨팅 인스턴스 ClientA, ClientB, FW, Server를 만듭니다.

cloudshell에서:

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'

cloudshell에서:

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'

cloudshell에서:

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'

cloudshell에서:

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 탭을 엽니다.

3722d8574c3812b1.png

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의 비관리형 인스턴스 그룹을 만듭니다.

cloudshell에서:

gcloud compute instance-groups unmanaged create pbr-uig --zone=$zone

비관리형 인스턴스 그룹에 fw 인스턴스를 추가합니다.

cloudshell에서:

gcloud compute instance-groups unmanaged add-instances pbr-uig --instances=fw --zone=$zone

11. 상태 점검 만들기

백엔드 서비스의 상태 점검을 만듭니다. 간단한 TCP 포트 80 상태 점검을 수행해 보겠습니다.

cloudshell에서:

gcloud compute health-checks create tcp $prefix-hc-tcp-80 --region=$region --port 80

12. 백엔드 서비스 만들기

전달 규칙에 연결할 백엔드 서비스를 만듭니다.

cloudshell에서:

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

이제 백엔드 서비스에 인스턴스 그룹을 추가합니다.

cloudshell에서:

gcloud compute backend-services add-backend be-pbr --region=$region --instance-group=pbr-uig --instance-group-zone=$zone

13. 전달 규칙 만들기

cloudshell에서:

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는 clientb가 아닌 PBR과 일치합니다.

cloudshell에서:

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로 라우팅합니다.

cloudshell에서:

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이 작동하면 clienta에서 이전에 작동했던 요청이 이제 실패하는 반면 clientb는 여전히 성공적입니다.

SSH를 통해 클라이언트 컴퓨팅 VM에 연결하고 동일한 테스트를 실행합니다.

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 인스턴스로 활발하게 라우팅되고 있음을 확인할 수 있습니다.

SSH를 통해 clientb에 연결하고 동일한 연결 테스트를 실행합니다.

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에서 서버로의 요청은 성공합니다. 이는 요청이 소스 IP의 PBR 규칙과 일치하지 않기 때문입니다.

16. [선택사항] 방화벽에서 캡처로 유효성 검사

이 선택사항 섹션에서는 방화벽 VM에서 패킷 캡처를 수행하여 PBR의 유효성을 검사할 수 있습니다.

cloudshell1과 cloudshell2의

+를 클릭하여 추가 Cloud Shell 탭을 엽니다.

5eb3a9956f7e41a2.png

cloudshell3에서 다음과 같이 변수를 설정합니다.

export project_id=`gcloud config list --format="value(core.project)"`
export region=us-central1
export zone=us-central1-a
export prefix=codelab-pbr

SSH로 fw에 연결:

gcloud compute ssh fw --zone=$zone --tunnel-through-iap

fw (cloudshell3)에서 다음 명령어를 실행합니다.

sudo tcpdump -i any icmp -nn

clienta (cloudshell1)에서 핑 테스트를 실행합니다.

ping 10.10.10.200 -c 5

clientb (cloudshell2)에서 핑 테스트를 실행합니다.

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에 패킷이 표시되지 않습니다.

리소스 삭제를 위해 cloudshell로 돌아갑니다.

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을 완료했습니다.

학습한 내용

  • 정책 기반 경로