Foto di Ar_TH da Shutterstock
Introduzione
Nel vasto panorama del cloud computing, la gestione della rete è una componente fondamentale per garantire il corretto funzionamento di applicazioni e servizi. Un aspetto cruciale di questa gestione è l'assegnazione degli indirizzi IP (Internet Protocol) alle varie risorse dell'ambiente cloud. Gli indirizzi IP fungono da identificativo digitale per le risorse cloud e ne consentono la comunicazione reciproca e con Internet.
Quando si progetta una rete, sia in un ambiente on-premises tradizionale sia su una piattaforma cloud come Google Cloud Platform (GCP), entrano in gioco i concetti di range di indirizzi IP sovrapposti e non sovrapposti.
Si parla di range IP sovrapposti quando due o più range di indirizzi IP condividono indirizzi comuni, sovrapponendosi di fatto tra loro.
I range IP non sovrapposti sono invece insiemi di indirizzi IP in cui ciascun indirizzo è univoco e non si interseca né si sovrappone con quelli di un altro range.
Ogni rete Virtual Private Cloud (VPC) in GCP è composta da una o più subnet che possono sovrapporsi o meno ai range di indirizzi IP delle altre VPC. È fondamentale utilizzare un range IP non sovrapposto per le subnet, poiché tra subnet sovrapposte l'accesso privato alla rete non è consentito per impostazione predefinita.
Nel mio precedente articolo ho spiegato come utilizzare Private Service Connect (PSC) per accedere in modo privato ai servizi in reti VPC con range IP sovrapposti.
GCP ha recentemente introdotto Private NAT in versione Preview, con l'obiettivo di facilitare la comunicazione privata tra reti sovrapposte. In questo articolo vedremo come configurare Inter-VPC NAT per accedere in modo privato a servizi in esecuzione in diverse reti VPC contenenti range IP sovrapposti e non.
Cos'è **Inter-VPC NAT?**
In GCP il VPC peering non è consentito tra reti sovrapposte, perché non permette di condividere subnet specifiche tra VPC. Inter-VPC NAT è un'offerta di gateway Private NAT che consente alle risorse di una rete VPC in subnet sovrapposte di comunicare con le risorse in subnet non sovrapposte attraverso un'altra VPC, anche in presenza di altre subnet sovrapposte, sfruttando una configurazione NAT con type=PRIVATE.
Funziona insieme a Network Connectivity Center, un sistema unificato e semplificato per la gestione della connettività di rete. È progettato per riunire le diverse funzionalità di networking di Google Cloud in un'unica interfaccia, semplificando la connessione e la gestione delle reti cloud e on-premises.
Network Connectivity Center adotta un modello hub-and-spoke per la connettività di rete. L'hub è il punto centrale di connettività verso le reti Virtual Private Cloud (VPC): si può immaginare come un router virtuale che aggrega la connettività dei vari spoke. Gli spoke possono essere VPN, Interconnect, router di terze parti o altre reti VPC.
Per abilitare Inter-VPC NAT tra reti VPC è necessario configurare ciascuna rete VPC come VPC spoke di un hub di Network Connectivity Center. I VPC spoke permettono di connettere più reti VPC e di scambiare specifiche route di subnet IPv4, cosa non possibile con il VPC peering. In questo modo si ottiene piena connettività IPv4 tra tutti i workloads che risiedono in queste reti VPC.
Quando si crea lo spoke, occorre impedire che i range di indirizzi IP sovrapposti vengano condivisi con altri VPC spoke.
Limitazioni
Inter-VPC NAT presenta attualmente le seguenti limitazioni principali in Preview.
- Inter-VPC NAT non supporta l'Endpoint-Independent Mapping.
- Il supporto cross-project per Inter-VPC NAT non è disponibile in Preview.
- Il supporto al logging per Inter-VPC NAT non è disponibile in Preview.
- In Preview è necessario utilizzare esclusivamente la gcloud CLI per aggiornare un gateway Private NAT esistente. L'uso della console Google Cloud per aggiornare un gateway Private NAT esistente potrebbe portare a una configurazione errata.
- Inter-VPC NAT supporta solo connessioni TCP e UDP.
- Inter-VPC NAT supporta la network address translation (NAT) solo tra VPC spoke di Network Connectivity Center, non con reti Virtual Private Cloud connesse tramite VPC Network Peering.
- Un'istanza di macchina virtuale (VM) in una rete VPC può raggiungere solo destinazioni in una subnet non sovrapposta di una rete in peering, e non in una subnet sovrapposta.
GCP potrebbe rimuovere alcune limitazioni prima del rilascio GA del servizio. Per gli aggiornamenti, consultare la documentazione ufficiale.
Architettura di riferimento
In questo setup, vpc-a e vpc-b hanno una subnet con un range di indirizzi IP sovrapposto. vpc-b dispone inoltre di una subnet non sovrapposta che ospita un'applicazione di esempio.
In vpc-a verrà distribuito un gateway Private NAT per consentire alle istanze nella subnet sovrapposta di connettersi all'applicazione di esempio nella subnet non sovrapposta.

https://cloud.google.com/nat/docs/private-nat#pvt-nat-flow-example
Configurare la rete e distribuire l'applicazione di esempio
Passo 1: impostare le variabili di ambiente necessarie.
export PROJECT_ID="your-project-id" #ex: chimbu-playground
export VPC_A_SUBNET_REGION="us-east1"
export VPC_A_SUBNET_A_CIDR="192.168.1.0/24"
export VPC_B_SUBNET_REGION="us-west1"
export VPC_B_SUBNET_B_CIDR="192.168.2.0/24" #non-overlapping subnet between vpc-a and vpc-b
export VPC_B_SUBNET_C_CIDR="192.168.1.0/24" #overlapping subnet between vpc-a and vpc-b
export VPC_A_PRIVATE_NAT_GW_CIDR="10.1.2.0/29"
Passo 2: creare le reti VPC e le subnet.
#Create vpc-a custom Network and subnet
gcloud beta compute networks create vpc-a \
--subnet-mode=custom
gcloud beta compute networks subnets create subnet-a \
--network="vpc-a" \
--role="ACTIVE" \
--purpose="PRIVATE" \
--range=$VPC_A_SUBNET_A_CIDR \
--region=$VPC_A_SUBNET_REGION
# Create vpc-b custom Network and subnets
gcloud beta compute networks create vpc-b \
--subnet-mode=custom
gcloud beta compute networks subnets create subnet-b \
--network="vpc-b" \
--role="ACTIVE" \
--purpose="PRIVATE" \
--range=$VPC_B_SUBNET_B_CIDR \
--region=$VPC_B_SUBNET_REGION
gcloud beta compute networks subnets create subnet-c \
--network="vpc-b" \
--role="ACTIVE" \
--purpose="PRIVATE" \
--range=$VPC_B_SUBNET_C_CIDR \
--region=$VPC_B_SUBNET_REGION
Passo 3: creare le regole firewall per il forwarding TCP di Identity-Aware Proxy (IAP) e abilitare l'accesso SSH alle istanze VM.
Nei passaggi successivi creeremo istanze VM senza IP esterni; il forwarding TCP di IAP consente di stabilire un tunnel cifrato attraverso il quale instradare traffico SSH, RDP e altro verso le istanze VM.
Verificare che agli utenti sia assegnato il ruolo roles/iap.tunnelResourceAccessor, necessario per eseguire il forwarding TCP e le attività correlate.
gcloud compute firewall-rules create vpc-a-iap \
--direction=INGRESS \
--priority=1000 \
--network=vpc-a \
--action=ALLOW \
--rules=tcp:22 \
--source-ranges=35.235.240.0/20
gcloud compute firewall-rules create vpc-b-iap \
--direction=INGRESS \
--priority=1000 \
--network=vpc-b \
--action=ALLOW \
--rules=tcp:22 \
--source-ranges=35.235.240.0/20
Passo 4: creare un'istanza Cloud NAT per l'accesso a Internet. Questa istanza Cloud NAT non abilita la comunicazione privata tra VPC: ce ne occuperemo separatamente.
#vpc-a Cloud router and NAT
gcloud compute routers create vpc-a-internet-nat-router \
--network=vpc-a \
--region=$VPC_A_SUBNET_REGION
gcloud beta compute routers nats create vpc-a-internet-nat \
--router=vpc-a-internet-nat-router \
--nat-all-subnet-ip-ranges \
--region=$VPC_A_SUBNET_REGION \
--auto-allocate-nat-external-ips
#vpc-b Cloud router and NAT
gcloud compute routers create vpc-b-internet-nat-router \
--network=vpc-b \
--region=$VPC_B_SUBNET_REGION
gcloud beta compute routers nats create vpc-b-internet-nat \
--router=vpc-b-internet-nat-router \
--nat-all-subnet-ip-ranges \
--region=$VPC_B_SUBNET_REGION \
--auto-allocate-nat-external-ips

Cloud NAT per l'accesso a Internet delle istanze Compute Engine nella rete
Passo 5: creare istanze Compute Engine di test senza IP esterno.
#Test instance in vpc-a network and subnet-a
gcloud compute instances create vpc-a-subnet-a-test \
--project=$PROJECT_ID \
--zone="us-east1-b" \
--machine-type=e2-medium \
--network-interface=stack-type=IPV4_ONLY,subnet=subnet-a,no-address \
--tags=http-server \
--create-disk=auto-delete=yes,boot=yes,device-name=vpc-a-subnet-a-test,image=projects/debian-cloud/global/images/debian-11-bullseye-v20230814,mode=rw,size=10,type=projects/$PROJECT_ID/zones/us-east1-b/diskTypes/pd-balanced
#Test instance in vpc-b network and subnet-b, Also deployed nginx service.Cloud NAT to download the required ngninx packages.
gcloud compute instances create vpc-b-subnet-b-test \
--project=$PROJECT_ID \
--zone="us-west1-a" \
--machine-type=e2-medium \
--network-interface=stack-type=IPV4_ONLY,subnet=subnet-b,no-address \
--metadata=startup-script=\#/bin/sh$'\n'sudo\ \
apt\ update$'\n'sudo\ apt\ install\ nginx\ -y\ \
--tags=http-server \
--create-disk=auto-delete=yes,boot=yes,device-name=vpc-b-subnet-b-test,image=projects/debian-cloud/global/images/debian-11-bullseye-v20230814,mode=rw,size=10,type=projects/$PROJECT_ID/zones/us-west1-a/diskTypes/pd-balanced
#Test instance deployed in vpc-b network and subnet-c
gcloud compute instances create vpc-b-subnet-c-test \
--project=$PROJECT_ID \
--zone="us-west1-a" \
--machine-type=e2-medium \
--network-interface=stack-type=IPV4_ONLY,subnet=subnet-c,no-address \
--tags=http-server \
--create-disk=auto-delete=yes,boot=yes,device-name=vpc-b-subnet-c-test,image=projects/debian-cloud/global/images/debian-11-bullseye-v20230814,mode=rw,size=10,type=projects/$PROJECT_ID/zones/us-west1-a/diskTypes/pd-balanced

Istanze Compute Engine
A questo punto, l'istanza vpc-a-subnet-a-test in vpc-a non riesce ad accedere al servizio in esecuzione sull'istanza vpc-b-subnet-b-test per l'assenza di connettività di rete, e non è possibile creare un VPC peering tra le due reti a causa della subnet sovrapposta.
Configurare Hub e VPC Spoke in Network Connectivity Center
Per abilitare la comunicazione tra due reti VPC con range IP di subnet sovrapposti, è necessario configurarle come VPC spoke connessi allo stesso hub di Network Connectivity Center.
Passo 6: creare un hub di Network Connectivity Center.
gcloud network-connectivity hubs create private-nat-demo-vpc-hub

Passo 7: aggiungere le reti VPC come spoke all'hub, assicurandosi di escludere le reti sovrapposte dall'export.
#Add vpc-a to the hub and exclue VPC_A_SUBNET_A_CIDR from export.
gcloud network-connectivity spokes linked-vpc-network create vpc-a \
--hub="https://www.googleapis.com/networkconnectivity/v1/projects/$PROJECT_ID/locations/global/hubs/private-nat-demo-vpc-hub" --global \
--vpc-network="https://www.googleapis.com/compute/v1/projects/$PROJECT_ID/global/networks/vpc-a" \
--exclude-export-ranges=$VPC_A_SUBNET_A_CIDR
#Add vpc-b to the hub and exclue VPC_B_SUBNET_C_CIDR from export.VPC_B_SUBNET_B_CIDR will be exported between the VPCs.
gcloud network-connectivity spokes linked-vpc-network create vpc-b \
--hub="https://www.googleapis.com/networkconnectivity/v1/projects/$PROJECT_ID/locations/global/hubs/private-nat-demo-vpc-hub" --global \
--vpc-network="https://www.googleapis.com/compute/v1/projects/$PROJECT_ID/global/networks/vpc-b" \
--exclude-export-ranges=$VPC_B_SUBNET_C_CIDR

VPC Spoke

Route scambiata tra le VPC
Configurare Inter-VPC NAT
Inter-VPC NAT richiede una subnet dedicata con purpose PRIVATE_NAT. Il gateway Private NAT utilizza i range di indirizzi IP di questa subnet per eseguire il NAT. La subnet non deve sovrapporsi ad alcuna subnet già esistente nei VPC spoke collegati allo stesso hub di Network Connectivity Center, e viene utilizzata esclusivamente per Private NAT.
Passo 8: creare una subnet per Private NAT. Verrà creata in vpc-a poiché è da qui che si deve accedere al servizio in esecuzione in vpc-b. Private NAT esegue il NAT solo sulle richieste in uscita.
gcloud beta compute networks subnets create private-nat-gateway \
--network=vpc-a \
--region=$VPC_A_SUBNET_REGION \
--range=$VPC_A_PRIVATE_NAT_GW_CIDR \
--purpose=PRIVATE_NAT

Passo 9: creare un Cloud Router e un gateway Private NAT.
gcloud compute routers create vpc-a-private-nat-gw-router \
--network="vpc-a" \
--region=$VPC_A_SUBNET_REGION
gcloud beta compute routers nats create vpc-a-private-nat-gw \
--router=vpc-a-private-nat-gw-router \
--type=PRIVATE \
--nat-all-subnet-ip-ranges \
--region=$VPC_A_SUBNET_REGION
Passo 10: creare una regola NAT nel gateway Private NAT per applicare il NAT al traffico in uscita dal VPC spoke di origine verso uno qualsiasi dei VPC spoke peer collegati a un hub di Network Connectivity Center corrispondente. In base alla regola NAT, il gateway Private NAT assegna gli indirizzi IP di NAT prelevandoli dalla subnet Private NAT.
gcloud beta compute routers nats rules create 1000 \
--router=vpc-a-private-nat-gw-router \
--nat=vpc-a-private-nat-gw \
--match='nexthop.hub == "//networkconnectivity.googleapis.com/projects/chimbuc-playground/locations/global/hubs/private-nat-demo-vpc-hub"' \
--source-nat-active-ranges=private-nat-gateway \
--region=$VPC_A_SUBNET_REGION

Gateway Private NAT
Passo 11: creare una regola firewall in vpc-b per consentire le connessioni dal gateway Private NAT.
gcloud compute firewall-rules create vpc-b-allow-ingress-private-nat-gw \
--direction=INGRESS \
--priority=1000 \
--network=vpc-b \
--action=ALLOW \
--rules=tcp \
--source-ranges=$VPC_A_PRIVATE_NAT_GW_CIDR
Passo 12: verificare la connettività tra le reti vpc-a e vpc-b.

Lo screenshot conferma che l'istanza in vpc-a riesce ad accedere al servizio in esecuzione nella subnet non sovrapposta di vpc-b tramite Inter-VPC NAT.
Inter-VPC NAT è uno strumento potente che semplifica la comunicazione privata tra reti sovrapposte. Grazie a Inter-VPC NAT, una risorsa può comunicare in modo privato con risorse in subnet non sovrapposte di altre VPC, anche quando si trova in una subnet che si sovrappone ad altre.
Per abilitare la comunicazione privata tra subnet sovrapposte, si può utilizzare Private Service Connect. Spero che questo articolo le sia stato utile: non esiti a contattarmi per qualsiasi domanda.