1. 소개
이 Codelab에서는 리전 네트워크 방화벽 정책을 사용하여 내부 애플리케이션 부하 분산기 (ALB) 및 프록시 네트워크 부하 분산기 (NLB)용 Cloud Next Generation Firewall (NGFW) Essentials를 살펴봅니다.
Cloud NGFW는 Google Cloud 워크로드를 보호하는 고급 위협 보호 및 마이크로 세분화 기능을 갖춘 완전 분산형 방화벽 서비스입니다. 부하 분산기 수준에서 Cloud NGFW를 사용 설정하면 내부 프록시 기반 부하 분산기로 들어오는 모든 TCP 트래픽에 일관된 방화벽 정책 규칙이 적용됩니다. 모든 서비스에 대한 정책을 더 광범위하게 적용하여 조직 보안 상황 프로비저닝을 간소화합니다.
이 Codelab에서는 다음 Cloud NGFW 및 Cloud Load Balancing 제품과 기능을 다룹니다.
- 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의 세 가지 기능 등급이 있습니다. 각 단계별 등급은 추가 수준의 네트워크 트래픽 필터링 및 검사 기능을 제공합니다.
Cloud NGFW Essentials 필터링 기능 요약:
등급 | 기능 | 네트워크 계층 | 규칙 매개변수 예 |
Essentials | IP 주소 및 범위 필터링 | IP |
|
Essentials | 주소 그룹 | IP |
|
Essentials | 프로토콜 및 포트 필터링 | TCP |
|
Essentials | 보안 태그 | 메타데이터 |
|
Essentials | 네트워크 유형 필터링 | IP / 메타데이터 |
|
부하 분산기 전달 규칙은 대상 TCP 포트를 명시적으로 정의합니다. 방화벽 규칙 --layer4-configs= 매개변수는 tcp만 지정할 수 있습니다. 포트 값은 전달 규칙 자체에 의해 암시됩니다.
주소 그룹과 네트워크 유형은 방화벽 정책 규칙을 더 효율적으로 만드는 데 유용합니다. VPC_NETWORKS 및 INTRA_VPC 네트워크 유형은 부하 분산기의 방화벽 정책 규칙과 함께 지원됩니다.
참고: 부하 분산기의 방화벽 정책 규칙은 --direction=INGRESS만 지원합니다. 이러한 규칙은 부하 분산기에서 노출된 서비스에 대한 액세스를 제어하도록 설계되었습니다.
데이터 영역 필터링
Cloud NFGW Essentials 기능은 기본 Layer 3 (IP 주소) 및 Layer 4 (TCP 포트) 스테이트풀 방화벽 규칙을 다룹니다. 이러한 방화벽 정책 규칙 기능은 전체 패킷 검사 없이 부하 분산기 데이터 플레인에서 효율적으로 실행됩니다.
VM 인스턴스를 타겟팅하는 Cloud NGFW Essentials 정책 규칙은 핵심 Google Cloud 소프트웨어 정의 네트워크 (Andromeda)의 일부로 분산 VPC 네트워크 패브릭에서 적용됩니다. 패킷 필터링 및 방화벽 정책 규칙은 패킷이 VM 인스턴스 네트워크 인터페이스에 도달하기 전에 각 개별 VM 인스턴스의 하이퍼바이저 수준에서 적용됩니다.
부하 분산기를 타겟팅하는 Cloud NGFW Essentials 정책 규칙은 Google Cloud 부하 분산기의 기본 기술, 특히 Envoy 서비스 프록시 인프라를 사용하여 적용됩니다. 동일한 Cloud NFGW 리소스 모델과 규칙 구조를 사용하여 상태 저장 패킷 필터링이 프록시 기반 부하 분산기 데이터 플레인에서 직접 적용됩니다.
부하 분산기 타겟
부하 분산기를 타겟팅하는 Cloud NGFW 정책과 VM 인스턴스를 타겟팅하는 정책 간에는 몇 가지 주요 차이점이 있습니다.
방화벽 정책 규칙은 부하 분산기 전달 규칙 --target-forwarding-rules=FR_NAME에 대한 특정 참조와 함께 --target-type=INTERNAL_MANAGED_LB를 지정하여 단일 부하 분산기에 적용할 수 있습니다. VPC 네트워크 리전 (정책으로 범위가 지정된 리전)의 모든 부하 분산기 전달 규칙을 타겟팅하려면 특정 참조를 생략하고 --target-type=INTERNAL_MANAGED_LB 플래그만 필요합니다.
--target-type 매개변수가 규칙 구성에 설정되어 있지 않으면 규칙이 모든 VM 인스턴스에 자동으로 적용되고 부하 분산기에는 적용되지 않습니다.
Codelab 네트워크
이 Codelab에서는 VPC 네트워크 하나와 다음 리소스가 있는 단일 프로젝트를 사용합니다.
- 리전 서브넷 2개
- 리전 네트워크 방화벽 정책 1개
- 3개의 리전 내부 애플리케이션 부하 분산기
wwwVM 인스턴스 그룹 백엔드가 있는 HTTP 서비스apiVM 인스턴스 그룹 백엔드가 있는 HTTP 서비스gcsPSC NEG 백엔드를 사용하여 Google API에 연결되는 HTTPS 서비스
- 다양한 허용 및 거부 정책을 테스트할 VM 인스턴스 2개
그림 1. Codelab 네트워크
부하 분산기를 타겟팅하는 방화벽 정책 규칙은 부하 분산기 전달 규칙 리소스에 연결됩니다. 부하 분산기는 완전한 부하 분산 서비스를 제공하기 위해 함께 구성된 개별적으로 정의된 리소스로 구성됩니다. 전달 규칙 정의는 정의된 특정 대상 프록시 리소스를 직접 참조합니다.
그림 1. 부하 분산기 리소스용 Cloud NGFW
Cloud NGFW Essentials 필터는 부하 분산기 데이터 플레인에 프로그래밍되고 정책을 적용하기 위해 동일한 분산되고 일관된 방화벽 메커니즘을 사용하여 정의된 타겟 프록시 서비스 레이어(VM 인스턴스 인터페이스와 유사)에서 구현됩니다.
3. 프로젝트 설정
프로젝트에 액세스
이 Codelab에서는 단일 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
- 부하 분산기 인그레스의 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. 부하 분산기 서비스
이 섹션에서는 다음 세 가지 서비스의 부하 분산기 구성요소 (백엔드 서비스, 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 API 프런트엔드를 통해 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의 소스 네트워크 유형은 다른 소스 매개변수와 조합하여 사용할 때 부하 분산기를 타겟팅하는 방화벽 정책 규칙에서 지원됩니다. 평가 논리는 두 소스 매개변수 사이의 AND입니다. 여기에서는 트래픽이 허용되려면 INTRA_VPC 및 --src-ip-ranges=${VM_ALLOW_IP}/32 기준을 충족해야 합니다.
fr-foo-www을 타겟팅하는 vm-allow을 허용하는 규칙 만들기
# 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를 구성했습니다.
이 의견 양식을 사용하여 의견, 질문 또는 수정사항을 자유롭게 제공해 주세요.
감사합니다.