Cloud NGFW Essentials para balanceadores de cargas

1. Introducción

En este codelab, se exploran los conceptos básicos de Cloud Next Generation Firewall (NGFW) para los balanceadores de cargas de aplicaciones (ALB) internos y los balanceadores de cargas de red (NLB) de proxy con políticas de firewall de red regionales.

Cloud NGFW es un servicio de firewall completamente distribuido con capacidades avanzadas de protección contra amenazas y microsegmentación para proteger las cargas de trabajo de Google Cloud. Habilitar Cloud NGFW a nivel del balanceador de cargas aplica reglas de política de firewall coherentes a cualquier tráfico TCP que ingrese a los balanceadores de cargas internos basados en proxy. Simplifica el aprovisionamiento de una postura de seguridad organizacional, ya que ofrece una aplicación más amplia de las políticas para todos los servicios.

En este codelab, se tratan los siguientes productos y funciones de Cloud NGFW y Cloud Load Balancing:

  • Cloud NGFW Essentials
  • Políticas de firewall de redes regionales
  • Balanceador de cargas de aplicaciones interno regional
  • Grupo de instancias administrado (MIG) de backend y grupo de extremos de red (NEG) de Private Service Connect (PSC)

NOTA: Consulta la documentación de Cloud NGFW para conocer las funciones y limitaciones más recientes admitidas de las reglas de políticas de firewall para los destinos del balanceador de cargas.

Qué aprenderá

  • Habilita reglas básicas de política de firewall de Cloud NGFW dirigidas a balanceadores de cargas
  • Protege un servicio de balanceador de cargas interno para consumidores con instancias de VM y backends de PSC
  • Prueba el acceso del cliente y verifica los registros del firewall

Requisitos

2. Conceptos

Niveles de funciones del firewall

Cloud NGFW tiene tres niveles de funciones: Essentials, Standard y Enterprise. Cada nivel progresivo ofrece niveles adicionales de filtrado de tráfico de red y capacidades de inspección.

A continuación, se muestra un resumen de las capacidades de filtrado de Cloud NGFW Essentials:

Nivel

Función

Capas de red

Ejemplo de parámetros de regla

Imprescindibles

Filtrado de rango y dirección IP

IP

--src-ip-ranges=1.1.1.0/24,2.2.2.2/32

Imprescindibles

Grupos de direcciones

IP

--src-address-groups=special-ranges

Imprescindibles

Filtrado de protocolos y puertos

TCP

--layer4-configs=tcp

Imprescindibles

Etiquetas seguras

Metadatos

--src-secure-tags=tagValues/987654321098

Imprescindibles

Filtrado por tipo de red

IP / metadatos

--src-network-type=INTRA_VPC

Las reglas de reenvío del balanceador de cargas definen de forma explícita el puerto TCP de destino. El parámetro --layer4-configs= de la regla de firewall solo puede especificar tcp. El valor del puerto está implícito en la regla de reenvío.

Los grupos de direcciones y los tipos de redes pueden ser útiles para que las reglas de políticas de firewall sean más eficientes. Los tipos de red VPC_NETWORKS y INTRA_VPC son compatibles con las reglas de políticas de firewall para los balanceadores de cargas.

NOTA: Las reglas de políticas de firewall para balanceadores de cargas solo admiten --direction=INGRESS. Estas reglas están diseñadas para controlar el acceso a los servicios expuestos por el balanceador de cargas.

Filtrado del plano de datos

Las funciones Essentials del NFGW de Cloud abarcan reglas de firewall con estado básicas de capa 3 (dirección IP) y capa 4 (puerto TCP). Todas estas funciones de reglas de políticas de firewall se realizan de manera eficiente en el plano de datos del balanceador de cargas sin necesidad de una inspección completa de paquetes.

Las reglas de política de Cloud NGFW Essentials que segmentan instancias de VM se aplican en la estructura de red de VPC distribuida como parte de la red definida por software (Andromeda) principal de Google Cloud. El filtrado de paquetes y las reglas de políticas de firewall se aplican a nivel del hipervisor de cada instancia de VM individual, antes de que el paquete llegue a la interfaz de red de la instancia de VM.

Las reglas de política de Cloud NGFW Essentials que se dirigen a los balanceadores de cargas se aplican con las tecnologías subyacentes de los balanceadores de cargas de Google Cloud, específicamente la infraestructura de proxy de servicio de Envoy. Con el mismo modelo de recursos y estructura de reglas de Cloud NFGW, el filtrado de paquetes con estado se aplica directamente en el plano de datos del balanceador de cargas basado en proxy.

Destinos del balanceador de cargas

Existen algunas diferencias clave entre las políticas de Cloud NGFW que segmentan balanceadores de cargas y las políticas que segmentan instancias de VM.

Las reglas de la política de firewall se pueden aplicar a un solo balanceador de cargas especificando --target-type=INTERNAL_MANAGED_LB junto con la referencia específica a la regla de reenvío del balanceador de cargas --target-forwarding-rules=FR_NAME. Para segmentar todas las reglas de reenvío del balanceador de cargas en la región de la red de VPC (en la que la política define el alcance de la región), se debe omitir la referencia específica y solo se necesita la marca --target-type=INTERNAL_MANAGED_LB.

Si el parámetro --target-type no se establece en la configuración de la regla, la regla se aplica de forma predeterminada a todas las instancias de VM y no a los balanceadores de cargas.

Red de Codelab

En este codelab, se usa un solo proyecto con una red de VPC y los siguientes recursos:

  • Dos subredes regionales
  • Una política de firewall de red regional
  • Tres balanceadores de cargas de aplicaciones internos regionales
    • Servicio HTTP www con backend de grupo de instancias de VM
    • Servicio HTTP api con backend de grupo de instancias de VM
    • gcs Servicio HTTPS con backend del NEG de PSC para las APIs de Google
  • Dos instancias de VM para probar varias políticas de permiso y denegación

figure1

Fig. 1: Red de Codelab

Las reglas de la política de firewall que segmentan los balanceadores de cargas se vinculan a los recursos de reglas de reenvío del balanceador de cargas. Los balanceadores de cargas se componen de recursos definidos individualmente que se configuran en conjunto para proporcionar un servicio completo de balanceo de cargas. La definición de la regla de reenvío hace referencia directamente a un recurso de proxy de destino específico definido para ella.

figure2

Fig. 1: Cloud NGFW para recursos de balanceadores de cargas

Los filtros Essentials de Cloud NGFW se programan en el plano de datos del balanceador de cargas y se implementan en la capa de servicio de proxy de destino definida (análoga a una interfaz de instancia de VM) con los mismos mecanismos de firewall distribuidos y coherentes para aplicar políticas.

3. Configura el proyecto

Accede a tu proyecto

En este codelab, se usa un solo proyecto de Google Cloud. En los pasos de configuración, se usan la CLI de gcloud cli y los comandos de shell de Linux.

Para comenzar, accede a la línea de comandos de tu proyecto de Google Cloud:

Establece tu ID del proyecto

gcloud config set project YOUR_PROJECT_ID_HERE

Habilita los servicios de la API

gcloud services enable \
  cloudresourcemanager.googleapis.com \
  compute.googleapis.com \
  dns.googleapis.com \
  networksecurity.googleapis.com \
  certificatemanager.googleapis.com

Establece variables de entorno de shell

# 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. Base de la red

En esta sección, implementarás una base de red con lo siguiente:

  • Red de VPC global y subredes regionales
  • Política de firewall de red regional para proteger la red de VPC
  • Cloud Router y Cloud NAT para que los servidores recuperen paquetes de software
  • Reservas de direcciones IP y registros DNS para la entrada del balanceador de cargas

Crea recursos de red

# 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

Crea componentes de firewall

La política de firewall de red regional básica que se creó aquí se usará más adelante cuando se agreguen destinos específicos del balanceador de cargas. La política debe estar en la misma región que el balanceador de cargas.

Crear grupo de direcciones

Comienza por crear un grupo de direcciones para identificar los rangos de IP de sondeo de la verificación de estado de origen que admiten la funcionalidad del balanceador de cargas. Estos rangos deben permitirse para que los backends del balanceador de cargas se consideren en buen estado. También se usará más adelante con las reglas de política de firewall que segmentan los balanceadores de cargas.

# 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}

Crear política de firewall

# 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}

Configurar servicios de red

Crea un Cloud Router y una puerta de enlace de 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

Reserva direcciones 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

Crea registros 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"

Con esto, se completa la parte de configuración de la red. A continuación, se configurarán los balanceadores de cargas.

5. Servicios de balanceador de cargas

En esta sección, implementarás componentes del balanceador de cargas (servicios de backend, mapas de URL, proxies de destino y reglas de reenvío) para tres servicios:

  1. Servicio www (ilb-foo-www) en el puerto 80
  2. Servicio api (ilb-foo-api) en el puerto 8080
  3. Servicio gcs (ilb-foo-gcs) en el puerto 443 con certificado TLS

Junto con los recursos de backend complementarios:

  1. Instancias de VM que ejecutan servidores HTTP en un grupo de instancias administrado
  2. Grupo de extremos de red (NEG) de Private Service Connect (PSC) para las APIs de Google
  3. Bucket de Google Cloud Storage (GCS)

Configura los recursos de backend

Crea servidores de grupos de instancias de VM

El balanceador de cargas www usará los servidores de backend del grupo de instancias de VM que ejecutan el servidor web Apache que escucha en el puerto 80.

El balanceador de cargas api usará el mismo grupo de instancias de VM que escucha en el puerto 8080.

# 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}

Crear bucket de almacenamiento

El balanceador de cargas gcs usará el backend del NEG de PSC para conectarse a través del frontend de las APIs de Google al bucket de Cloud Storage.

# create random bucket name
export BUCKET=$(openssl rand -hex 12)
echo ${BUCKET}

NOTA: Las variables de entorno se pierden una vez que se cierra la sesión de shell. Anota el nombre del bucket si es necesario para completarlo en una sesión futura.

# 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

Crear certificado

El balanceador de cargas gcs finalizará las solicitudes HTTPS del cliente con un certificado autofirmado implementado en el proxy HTTPS de destino.

# 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}

Crear componentes del balanceador de cargas

Usa la siguiente secuencia de comandos para automatizar la implementación de los componentes del balanceador de cargas. Esto ayudará a mejorar la velocidad y la precisión en todos los elementos de configuración involucrados.

Implementa el script de creación del balanceador de cargas

# 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

NOTA: Esta secuencia de comandos tarda varios minutos en completarse.

Verifica la creación del balanceador de cargas

Verifica que se hayan implementado las reglas de reenvío y los servicios de backend.

# check forwarding rules
gcloud compute forwarding-rules list
# check backend services
gcloud compute backend-services list

Con esto, se completa la parte de la configuración del balanceador de cargas. A continuación, se configurarán las instancias de VM del cliente.

6. Acceso del cliente

Crea recursos de cliente de VM

En esta sección, implementarás clientes y verificarás la conectividad de extremo a extremo.

Cree instancias de 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

Probar el servicio de referencia

Prueba desde el cliente vm-allow

NOTA: Las instancias de VM se conectarán y estarán disponibles a través de ssh con IAP poco después de que se emitan los comandos instances create. Es posible que debas esperar un momento si la solicitud falla en el primer intento.

# 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"

Prueba la carga de un archivo en Google Cloud Storage a través del balanceador de cargas.

# 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"

La respuesta de la API de Cloud Storage confirma que la ruta de red funciona correctamente.

Prueba desde el cliente 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"

NOTA: Estas pruebas también deberían completarse correctamente porque aún no se aplicó ninguna regla de firewall al balanceador de cargas.

Con esto, se completan todas las partes principales de la configuración. A continuación, se crearán las reglas de firewall del balanceador de cargas.

7. Firewall del balanceador de cargas

En esta sección, implementarás reglas de políticas de firewall dirigidas a los balanceadores de cargas. La secuencia de configuraciones se orientará hacia una postura de seguridad que permita el acceso a vm-allow y bloquee el tráfico de vm-deny a todos los servicios.

Permite el tráfico seleccionado a fr-foo-www

Agrega una regla de política de firewall nueva a la política de firewall existente.fw-policy-foo-${REGION_1}

  • Permite un rango de IP de origen que incluya vm-allow y excluya las direcciones IP vm-deny.
  • Agrega un filtro de fuente adicional INTRA_VPC para usar tipo de red en una regla de política de firewall que tenga como objetivo el balanceador de cargas.

El tipo de red de origen de INTRA_VPC y VPC_NETWORKS se admite en las reglas de políticas de firewall que segmentan los balanceadores de cargas cuando se usan en combinación con otro parámetro de origen. La lógica de evaluación es un AND entre los dos parámetros de origen. Aquí, el tráfico debe cumplir con los criterios de INTRA_VPC y --src-ip-ranges=${VM_ALLOW_IP}/32 para que se permita.

Crea una regla para permitir la segmentación de 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

Prueba desde el cliente vm-allow

# send request to foo www service
gcloud compute ssh vm-allow --zone=${ZONE_1} --command="
  curl -s www.foo.com"

Prueba desde el cliente vm-deny

# send request to foo www service
gcloud compute ssh vm-deny --zone=${ZONE_1} --command="
  curl -s www.foo.com"

NOTA: Esto se realiza correctamente porque el comportamiento de la regla de política de firewall predeterminada implícita para los balanceadores de cargas es --action=allow. Para cambiar esto, se necesita una regla de rechazo predeterminada (comodín).

Rechaza el tráfico predeterminado a fr-foo-www

Agrega una regla de política de firewall nueva con una prioridad más baja (un número de prioridad más alto).

  • Rechazar todo el tráfico desde cualquier dirección IP de origen
  • Se permitirá el tráfico de vm-allow a fr-foo-www antes de alcanzar la regla de denegación.

Crea una regla para rechazar la segmentación del tráfico 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

Consideraciones para las verificaciones de estado

Al igual que con las reglas de políticas de firewall dirigidas a las instancias de VM, la regla de entrada de denegación predeterminada (implícita) de catchall bloquea el tráfico proveniente de los rangos de sondeo de verificación de estado destinados a los backends del balanceador de cargas. Por lo tanto, se configuró una regla de permiso explícito para permitir los rangos de sondeo de verificación de estado de entrada (consulta la regla 1002).

IMPORTANTE: Del mismo modo, cuando crees una regla de rechazo de entrada general (explícita) para los destinos del balanceador de cargas, se debe crear otra regla de mayor prioridad (número de prioridad más bajo) para permitir la entrada desde el rango de sondeo de la verificación de estado. Esta regla debe dirigirse a los balanceadores de cargas.

# 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

Prueba desde el cliente vm-deny

# send request to foo www service
gcloud compute ssh vm-deny --zone=${ZONE_1} --command="
  curl -s www.foo.com"

Ahora debería fallar porque la regla de firewall 2999 deniega todo el tráfico proveniente de la red de VPC. La regla 2001 de mayor prioridad (número de prioridad más bajo) solo permitía un rango de origen que incluía vm-allow.

Detén el proceso curl presionando Ctrl+C.

# send request to foo api service
gcloud compute ssh vm-deny --zone=${ZONE_1} --command="
  curl -s api.foo.com:8080"

vm-deny aún puede acceder al servicio de la API. Esto se realizó correctamente porque la regla de firewall solo se aplicó específicamente a la regla de reenvío fr-foo-www y no se orientó a fr-foo-api.

Actualiza las reglas para segmentar todos los balanceadores de cargas

NOTA: Las reglas de la política de firewall se pueden aplicar a todos los balanceadores de cargas de una red de VPC si se omite --target-forwarding-rules=FR_NAME.

Cambia las reglas de la política de firewall para que ahora se apliquen a todos los destinos de las reglas de reenvío del balanceador de cargas en la red de VPC.

  1. Crea una nueva regla de permiso de entrada 2003 que tenga como objetivo todas las reglas de reenvío para permitir el tráfico de la VM (rango de IP vm-allow).
  2. Crea una regla de permiso de entrada nueva 2004 que tenga como objetivo todas las reglas de reenvío para permitir el tráfico de las verificaciones de estado (grupo de direcciones uhc-probes).
  3. Crea una nueva regla de rechazo de entrada 2998 que tenga como objetivo todas las reglas de reenvío como rechazo general para todo el tráfico restante.

Modifica las reglas de firewall para que se apliquen a todos los balanceadores de cargas

# 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

Se pueden quitar las reglas de la política de firewall anteriores que se dirigen a las reglas de reenvío del balanceador de cargas explícitas, ya que ahora son redundantes con las reglas que se dirigen a todas las reglas de reenvío en la red de 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}

Prueba desde el cliente vm-deny

# send request to foo api service
gcloud compute ssh vm-deny --zone=${ZONE_1} --command="
  curl -s api.foo.com:8080"

Ahora debería fallar porque fr-foo-api también es el destino de todas las reglas de política de firewall con --target-type=INTERNAL_MANAGED_LB.

Detén el proceso curl presionando Ctrl+C.

Prueba la descarga de un archivo de Google Cloud Storage a través del balanceador de cargas.

# 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"

Detén el proceso curl presionando Ctrl+C.

Prueba desde el cliente 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"

Verifica el contenido de la descarga

# send request from vm
gcloud compute ssh vm-allow --zone=${ZONE_1} --command="
  cat test-download-1.txt"

Todos los servicios de balanceadores de cargas están disponibles para vm-allow y se bloquearon correctamente para vm-deny.

Aquí concluye la sección de pruebas. A continuación, veremos brevemente el registro.

8. Registro de reglas de firewall

El formato de registro de firewall tiene campos y registros para las reglas que segmentan balanceadores de cargas (--target-type=INTERNAL_MANAGED_LB).

Los registros contendrán un campo adicional etiquetado como load_balancer_details con más información sobre el balanceador de cargas al que se dirigió la regla de política de firewall. Esto es análogo al formato del campo InstanceDetails cuando las instancias de VM son el destino de las reglas de políticas de firewall.

  • load_balancer_details.forwarding_rule_name muestra la regla de reenvío de destino de la regla de política de firewall
  • load_balancer_details.type indica qué variante del balanceador de cargas basado en proxy es el objetivo.
  • load_balancer_details.url_map_name registra el recurso del mapa de URL que se usa cuando el tipo es un balanceador de cargas de aplicaciones.

Ver registros

Consulta los registros del firewall para ver los resultados de las reglas de la política de firewall.

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
  )"

El resultado del registro muestra las reglas vigentes que aplica la política:

  • La regla 2011 permite todo el tráfico de vm-allow a todos los balanceadores de cargas.
  • La regla 2998 rechaza todo el tráfico destinado a los balanceadores de cargas.
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

Los registros también se pueden ver en la consola de Google Cloud con el Explorador de registros. Navega a console.cloud.google.com/logs/query y usa el registro de firewall de VPC estándar compute.googleapis.com/firewall.

logName=projects/${PROJECT_ID}/logs/compute.googleapis.com%2Ffirewall

Aquí concluye la sección de registro… ¡ahora a limpiar!

9. Limpieza

# 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. Conclusión

¡Felicitaciones! Configuraste correctamente Cloud NGFW Essentials para balanceadores de cargas.

Si tienes comentarios, preguntas o correcciones, usa este formulario de comentarios.

¡Gracias!