This tutorial shows how to deploy and prevent threats with Google Cloud NGFW Enterprise, a native Google Cloud service powered by Palo Alto Networks Threat Prevention technologies.
Cloud NGFW Enterprise is a fully distributed firewall service with advanced protection capabilities to protect your Google Cloud workloads from internal & external threats, including: intrusion, malware, spyware, and command-and-control. The service works by creating Google-managed zonal firewall endpoints that use packet intercept technology to transparently intercept workload traffic for deep packet inspection.
The following outline the required tools and IAM roles to complete this tutorial
- Access to Google Cloud Shell, or a local machine with a Terraform or gcloud installation.
- A Google Cloud project to host the deployment.
- A Google Cloud billing project.
Ability | Level | Roles |
---|---|---|
Create/modify/view firewall endpoints, endpoint associations, security profiles, and security profile groups. | Organization | compute.networkAdmin compute.networkUser compute.networkViewer |
Create/modify/view global network firewall policies and view effective rules for VPC networks and virtual machines. | Project | compute.securityAdmin compute.networkAdmin compute.networkViewer compute.viewer compute.instanceAdmin |
For more information, please see:
- IAM Roles - Firewall Endpoints
- IAM Roles - Firewall Endpoint Associations
- IAM Roles - Security Profiles
- IAM Roles - Global Network Firewall Policies
In this tutorial, a VPC network contains two virtual machines, client-vm
& web-vm
. The client-vm
simulates threats for both north/south internet traffic and east/west traffic to a web application on the web-vm
.
To prevent the malicious traffic, a Cloud NGFW endpoint is created and associated to the network, where network firewall policies define how the traffic should be inspected by Cloud NGFW.
Enable the required APIs, retrieve the deployment files, and configure the environment variables.
Important
This tutorial assumes you are using Cloud Shell to provision all resources.
-
Open Google Cloud Shell and enable the required APIs.
gcloud services enable compute.googleapis.com gcloud services enable networksecurity.googleapis.com gcloud services enable firewallinsights.googleapis.com
-
Set environment variables for your deployment project and billing project.
export PROJECT_ID=YOUR_PROJECT_ID export BILLING_ID=YOUR_BILLING_PROJECT_ID
-
Set environment variables for your organization ID, deployment region, zone, and naming prefix.
export ORG_ID=$(gcloud projects describe $PROJECT_ID --format=json | jq -r '.parent.id') export REGION=us-central1 export ZONE=us-central1-a export PREFIX=panw
-
Select a deployment option. Both options deploy identical environments.
- Option 1. Deploy using Terraform
- All of the cloud resources required for the tutorial are deployed using a single Terraform plan.
- Option 2. Deploy using gcloud
- Each cloud resource is deployed individually using
gcloud
.
- Each cloud resource is deployed individually using
- Option 1. Deploy using Terraform
-
In Cloud Shell, clone the repository and change directories to
/terraform
.git clone https://github.com/PaloAltoNetworks/google-cloud-ngfw-tutorial cd google-cloud-ngfw-tutorial/terraform
-
Create a
terraform.tfvars
file.cp terraform.tfvars.example terraform.tfvars
-
Edit the
terraform.tfvars
file and set values for the following variables.Key Value org_id
The organization ID of your Google Cloud organization. project_id
The deployment project ID. billing_project
The billing project for your Google Cloud organization. region
The region for the deployment. zone
The zone with region
for the cloud resources.prefix
A unique string to prepend to the created resources. -
Initialize and apply the Terraform plan.
terraform init terraform apply
Enter
yes
to create the resources. -
Once the Terraform plan completes, proceed to Prevent Threats with Cloud NGFW.
-
Create a VPC network, Cloud NAT, and the
client-vm
&web-vm
virtual machines.gcloud compute networks create $PREFIX-vpc \ --subnet-mode=custom \ --project=$PROJECT_ID gcloud compute networks subnets create $PREFIX-$REGION-subnet \ --network=$PREFIX-vpc \ --range=10.0.0.0/24 \ --region=$REGION \ --project=$PROJECT_ID gcloud compute routers create $PREFIX-router \ --network=$PREFIX-vpc \ --region=$REGION gcloud compute routers nats create $PREFIX-nat \ --router=$PREFIX-router \ --router-region=$REGION \ --nat-all-subnet-ip-ranges \ --auto-allocate-nat-external-ips gcloud compute instances create $PREFIX-client-vm \ --zone=$ZONE \ --machine-type=f1-micro \ --image-project=ubuntu-os-cloud \ --image-family=ubuntu-2004-lts \ --network-interface subnet=$PREFIX-$REGION-subnet,private-network-ip=10.0.0.10,no-address \ --project=$PROJECT_ID \ --metadata=startup-script='#! /bin/bash apt-get update apt-get install apache2-utils mtr iperf3 tcpdump -y' gcloud compute instances create $PREFIX-web-vm \ --zone=$ZONE \ --machine-type=f1-micro \ --image-project=ubuntu-os-cloud \ --image-family=ubuntu-2004-lts \ --network-interface subnet=$PREFIX-$REGION-subnet,private-network-ip=10.0.0.20,no-address \ --project=$PROJECT_ID \ --metadata=startup-script='#! /bin/bash sudo apt-get update sudo apt-get install coreutils -y sudo apt-get install php -y sudo apt-get install apache2 tcpdump iperf3 -y sudo a2ensite default-ssl sudo a2enmod ssl sudo rm -f /var/www/html/index.html sudo wget -O /var/www/html/index.php https://raw.githubusercontent.com/wwce/terraform/master/azure/transit_2fw_2spoke_common/scripts/showheaders.php sudo systemctl restart apache2'
-
Create a Security Profile and a Security Profile Group.
export ORG_ID=$(gcloud projects describe $PROJECT_ID --format=json | jq -r '.parent.id') gcloud network-security security-profiles threat-prevention create $PREFIX-profile \ --location=global \ --project=$PROJECT_ID \ --organization=$ORG_ID \ --quiet gcloud network-security security-profile-groups create $PREFIX-profile-group \ --threat-prevention-profile "organizations/$ORG_ID/locations/global/securityProfiles/$PREFIX-profile" \ --location=global \ --project=$PROJECT_ID \ --organization=$ORG_ID \ --quiet
π‘ Information
A security profile defines the threat prevention profile applied to traffic. A Security profile groups serve as a container for these profiles and are referenced within network firewall policy rules to intercept traffic.
-
Set the default action to
ALERT
for threat severity levels within the security profile.gcloud network-security security-profiles threat-prevention add-override $PREFIX-profile \ --severities=INFORMATIONAL,LOW,MEDIUM,HIGH,CRITICAL \ --action=ALERT \ --location=global \ --organization=$ORG_ID \ --project=$PROJECT_ID
π‘ Information
Security profiles have predefined actions that are determined by a detected threat's severity level.
-
Create a Network Firewall Policy with rules that use the security profile group as its action.
gcloud compute network-firewall-policies create $PREFIX-policy \ --global \ --project=$PROJECT_ID gcloud compute network-firewall-policies rules create 10 \ --firewall-policy=$PREFIX-policy \ --global-firewall-policy \ --layer4-configs=tcp:80,tcp:443,tcp:22 \ --direction=INGRESS \ --enable-logging \ --src-ip-ranges=0.0.0.0/0 \ --dest-ip-ranges=10.0.0.0/24 \ --action=apply_security_profile_group \ --security-profile-group=//networksecurity.googleapis.com/organizations/$ORG_ID/locations/global/securityProfileGroups/$PREFIX-profile-group \ --project=$PROJECT_ID gcloud compute network-firewall-policies rules create 11 \ --firewall-policy=$PREFIX-policy \ --global-firewall-policy \ --layer4-configs=all \ --direction=EGRESS \ --enable-logging \ --src-ip-ranges=10.0.0.0/24 \ --dest-ip-ranges=0.0.0.0/0 \ --action=apply_security_profile_group \ --security-profile-group=//networksecurity.googleapis.com/organizations/$ORG_ID/locations/global/securityProfileGroups/$PREFIX-profile-group \ --project=$PROJECT_ID
-
Associate the Network Firewall Policy with the VPC network.
gcloud compute network-firewall-policies associations create \ --firewall-policy=$PREFIX-policy \ --network=$PREFIX-vpc \ --name=$PREFIX-policy-association \ --global-firewall-policy \ --project=$PROJECT_ID
π‘ Information
A Network Firewall Policy is an organizational resource, enabling you to apply policies across networks within your Google Cloud organization.
-
Create a Cloud NGFW Endpoint.
gcloud network-security firewall-endpoints create $PREFIX-endpoint \ --zone=$ZONE \ --billing-project=$BILLING_ID \ --organization=$ORG_ID \ --quiet while true; do STATUS_EP=$(gcloud network-security firewall-endpoints describe $PREFIX-endpoint \ --zone=$ZONE \ --project=$PROJECT_ID \ --organization=$ORG_ID \ --format="json" | jq -r '.state') if [[ "$STATUS_EP" == "ACTIVE" ]]; then echo "Firewall endpoint $PREFIX-endpoint is now active." sleep 30 break fi echo "Waiting for the firewall endpoint to be created. This can take up to 20 minutes..." sleep 1 done
π‘ Information
A firewall endpoint is a organizational resource which inspects traffic with Palo Alto Networks Threat Prevention technologies.
-
Associate the endpoint with the VPC network by creating a Firewall Endpoint Association.
gcloud network-security firewall-endpoint-associations create $PREFIX-assoc \ --endpoint "organizations/$ORG_ID/locations/$ZONE/firewallEndpoints/$PREFIX-endpoint" \ --network=$PREFIX-vpc \ --zone=$ZONE \ --quiet \ --project=$PROJECT_ID while true; do STATUS_ASSOC=$(gcloud network-security firewall-endpoint-associations describe $PREFIX-assoc \ --zone=$ZONE \ --project=$PROJECT_ID \ --format="json" | jq -r '.state') if [[ "$STATUS_ASSOC" == "ACTIVE" ]]; then echo "Endpoint association $PREFIX-assoc is now active." sleep 10 break fi echo "Waiting for the endpoint association to be created. This can take up to 10 minutes..." sleep 1 done
π‘ Information
The firewall endpoint can be associated with one or more VPC networks within the same zone.
-
(Optional) Review the created resources.
- Firewall Endpoint
- Firewall Endpoint VPC Network Association
- Security Profile
- Network Firewall Policy
Verify Cloud NGFW is able to detect threats initiated from the client-vm
to the internet (north-south) and to the web-vm
(east-west). Then, modify the security profile to DENY
traffic containing MEDIUM
, HIGH
, & CRITICAL
threats.
-
In Cloud Shell, set an environment variable to a script that will generate malicious traffic.
REMOTE_SCRIPT=' ns1=$(curl -s -o /dev/null -w "%{http_code}\n" http://www.eicar.org/cgi-bin/.%2e/.%2e/.%2e/.%2e/bin/sh --data "echo Content-Type: text/plain; echo; uname -a" --max-time 2) ns2=$(curl -s -o /dev/null -w "%{http_code}\n" http://www.eicar.org/cgi-bin/user.sh -H "FakeHeader:() { :; }; echo Content-Type: text/html; echo ; /bin/uname -a" --max-time 2) ns3=$(curl -s -o /dev/null -w "%{http_code}\n" http://www.eicar.org/cgi-bin/.%2e/.%2e/.%2e/.%2e/etc/passwd --max-time 2) ew1=$(curl -w "%{http_code}\\n" -s -o /dev/null http://10.0.0.20/cgi-bin/.%2e/.%2e/.%2e/.%2e/bin/sh --data "echo Content-Type: text/plain; echo; uname -a" --max-time 2) ew2=$(curl -w "%{http_code}\\n" -s -o /dev/null http://10.0.0.20/cgi-bin/user.sh -H "FakeHeader:() { :; }; echo Content-Type: text/html; echo ; /bin/uname -a" --max-time 2) ew3=$(curl -w "%{http_code}\\n" -s -o /dev/null http://10.0.0.20/cgi-bin/.%2e/.%2e/.%2e/.%2e/etc/passwd --max-time 2) echo "" echo "Response Codes (north/south) : $ns1 $ns2 $ns3" echo "Response Codes (east/west) : $ew1 $ew2 $ew3" echo ""'
-
Execute remote script on the
client-vm
to simulate malicious internet and east-west traffic to theweb-vm
.gcloud compute ssh $PREFIX-client-vm --zone=$ZONE --tunnel-through-iap --command="bash -c '$REMOTE_SCRIPT'"
(output)
Response Codes (north/south) : 400 301 400
Response Codes (east/west) : 400 404 400π‘ Information
The threats from theclient-vm
return successful response codes. This is because the security profile is set toALERT
on all detected threats.
-
Update the security profile to
DENY
traffic containingMEDIUM
,HIGH
, &CRITICAL
threats.gcloud network-security security-profiles threat-prevention update-override $PREFIX-profile \ --severities=MEDIUM,HIGH,CRITICAL \ --action=DENY \ --location=global \ --organization=$ORG_ID \ --project=$PROJECT_ID for i in {0..119}; do remaining_seconds=$((600 - i * 5)) echo "Waiting for the changes to propagate... $((remaining_seconds / 60)) minutes $((remaining_seconds % 60)) seconds remaining." sleep 5 done echo "Good job. 10 minutes have passed."
π‘ Information
It takes ~10 minutes for the security profile to propagate through the Cloud NGFW endpoints.
-
Re-run the remote script on the
client-vm
to simulate malicious internet and east-west traffic again.gcloud compute ssh $PREFIX-client-vm --zone=$ZONE --tunnel-through-iap --command="bash -c '$REMOTE_SCRIPT'"
(output)
Response Codes (north/south) : 000 000 000
Response Codes (east/west) : 000 000 000π‘ Information
The malicious traffic from theclient-vm
return failed response codes. This is because the security profile is set toDENY
onMEDIUM-CRITICAL
threats.
-
In the Google Cloud console, go to Network Security β Threats to view the threat logs.
Note
At first, the logs show Cloud NGFW alerted on the detected threats. After modifying the security profile, the logs should then show Cloud NGFW blocking traffic with MEDIUM
, HIGH
, and CRITICAL
threats.
Cloud NGFW can decrypt and inspect TLS traffic by using short-lived intermediate certificates generated through Certificate Authority Service (CAS). After inspection, the traffic is re-encrypted before sending it to its intended destination.
For more information, see TLS Inspection.
Create a CA pool and a root CA within CAS. Then, create a service account to manage certificates within your CA pool along with a trust config to generate server certificates.
-
Enable the required APIs.
gcloud services enable privateca.googleapis.com gcloud services enable certificatemanager.googleapis.com
-
Create CA pool and a root CA certificate within CAS.
gcloud privateca pools create $PREFIX-ca-pool \ --project=$PROJECT_ID \ --location=$REGION \ --tier=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 Test" \ --auto-enable
-
Create a service account to generate certificates within your CA pool.
gcloud beta services identity create \ --service=networksecurity.googleapis.com \ --project=$PROJECT_ID export PROJECT_NUMBER=$(gcloud projects describe $PROJECT_ID --format="get(projectNumber)") gcloud privateca pools add-iam-policy-binding $PREFIX-ca-pool \ --project=$PROJECT_ID \ --location=$REGION \ --role=roles/privateca.certificateRequester \ --member=serviceAccount:service-$PROJECT_NUMBER@gcp-sa-networksecurity.iam.gserviceaccount.com
-
Create a file (
trust_config.yaml
) to represent your trust config, using your root CA as the trust anchor.export NGFW_ROOT_CA=$(gcloud privateca roots describe $PREFIX-ca-root \ --project=$PROJECT_ID \ --pool=$PREFIX-ca-pool \ --location=$REGION \ --format="value(pemCaCertificates)" | sed 's/^/ /') printf "name: '$PREFIX-trust-config'\ntrustStores:\n- trustAnchors:\n - pemCertificate: |\n%s\n" "$(echo "$NGFW_ROOT_CA" | sed 's/^/ /')" > trust_config.yaml
-
Import the
trust_config.yaml
into into Certificate Manager.gcloud certificate-manager trust-configs import $PREFIX-trust-config \ --project=$PROJECT_ID \ --location=$REGION \ --source=trust_config.yaml
Caution
If the import fails, verify your trust_config.yaml
is indented as follows:
name: 'panw-trust-config'
trustStores:
- trustAnchors:
- pemCertificate: |
-----BEGIN CERTIFICATE-----
MIIFhTC3A22gAwIBAgIUASvM1sh
...
gADX9iK6YUp2jenA6VL5J+afw==
-----END CERTIFICATE-----
Create a TLS Inspection Policy and attach it to your firewall endpoint association to intercept TLS traffic. Then, update your INGRESS
and EGRESS
network firewall rules to decrypt traffic.
-
Create a manifest file (
tls_policy.yaml
) to define the TLS inspection policy.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 minTlsVersion: TLS_1_1 tlsFeatureProfile: PROFILE_COMPATIBLE trustConfig: projects/$PROJECT_ID/locations/$REGION/trustConfigs/$PREFIX-trust-config EOF
-
Import the
tls_policy.yaml
to create the TLS inspection policy.gcloud network-security tls-inspection-policies import $PREFIX-tls-policy \ --project=$PROJECT_ID \ --location=$REGION \ --source=tls_policy.yaml
-
Update the firewall endpoint association with your VPC network to use the TLS inspection policy.
gcloud network-security firewall-endpoint-associations update $PREFIX-assoc \ --zone=$ZONE \ --project=$PROJECT_ID \ --tls-inspection-policy=$PREFIX-tls-policy \ --tls-inspection-policy-project=$PROJECT_ID \ --tls-inspection-policy-region=$REGION
-
Update the
INGRESS
andEGRESS
network firewall rules to decrypt TLS traffic.gcloud compute network-firewall-policies rules update 10 \ --firewall-policy=$PREFIX-policy \ --global-firewall-policy \ --tls-inspect gcloud compute network-firewall-policies rules update 11 \ --firewall-policy=$PREFIX-policy \ --global-firewall-policy \ --tls-inspect
π‘ Information
The--tls-inspect
flag enables TLS decryption for traffic matching the firewall rule. When traffic hits this rule, Cloud NGFW generates a new server certificate for the matched TLS traffic.
Upload the root CA to the client-vm
to enable TLS inspection for egress traffic. Then, within CAS, create a server certificate and upload it to the web-vm
to enable TLS inspection for the web application.
-
Write the root CA certificate to a file named
local_ca_root.crt
.gcloud privateca roots describe $PREFIX-ca-root \ --project=$PROJECT_ID \ --location=$REGION \ --pool=$PREFIX-ca-pool \ --format="value(pemCaCertificates)" >> local_ca_root.crt
-
Upload the
local_ca_root.crt
to theclient-vm
.gcloud compute scp local_ca_root.crt --tunnel-through-iap $PREFIX-client-vm:~/ --zone=$ZONE
-
Update the trust store on the
client-vm
to use the new certificate.gcloud compute ssh $PREFIX-client-vm --zone=$ZONE --tunnel-through-iap --command="bash -s" <<EOF sudo mv local_ca_root.crt /usr/local/share/ca-certificates/ sudo update-ca-certificates EOF
-
Create server certificate (
server.pem
) and key (key.pem
) for the web app onweb-vm
.export WEB_VM_IP=$(gcloud compute instances describe $PREFIX-web-vm --project=$PROJECT_ID --zone=$ZONE --format='get(networkInterfaces[0].networkIP)') gcloud privateca certificates create \ --issuer-location=$REGION \ --issuer-pool $PREFIX-ca-pool \ --subject "CN=Cloud NGFW Enterprise,O=Google" \ --ip-san=$WEB_VM_IP \ --generate-key \ --key-output-file=./key.pem \ --cert-output-file=./server.pem
-
Transfer the server certificate to the
web-vm
.gcloud compute scp --tunnel-through-iap server.pem $PREFIX-web-vm:~/ --zone=$ZONE gcloud compute scp --tunnel-through-iap key.pem $PREFIX-web-vm:~/ --zone=$ZONE
-
On the
web-vm
, update the web application's SSL configuration to use the server certificate.gcloud compute ssh $PREFIX-web-vm --zone=$ZONE --tunnel-through-iap --command="bash -s" <<EOF sudo mv server.pem /etc/ssl/certs/ sudo mv key.pem /etc/ssl/private/ sudo sed -i 's/ssl-cert-snakeoil.pem/server.pem/g' /etc/apache2/sites-available/default-ssl.conf sudo sed -i 's/ssl-cert-snakeoil.key/key.pem/g' /etc/apache2/sites-available/default-ssl.conf sudo systemctl restart apache2 sudo systemctl status apache2 EOF
Verify Cloud NGFW is able to intercept, decrypt, and inspect TLS traffic from the client-vm
and web-vm
.
-
Set an environment variable to a script that will generate malicious TLS traffic.
REMOTE_SCRIPT_TLS=' ns1=$(curl -s -o /dev/null -w "%{http_code}\n" https://www.eicar.org/cgi-bin/.%2e/.%2e/.%2e/.%2e/bin/sh --data "echo Content-Type: text/plain; echo; uname -a" --max-time 2) ns2=$(curl -s -o /dev/null -w "%{http_code}\n" https://www.eicar.org/cgi-bin/user.sh -H "FakeHeader:() { :; }; echo Content-Type: text/html; echo ; /bin/uname -a" --max-time 2) ns3=$(curl -s -o /dev/null -w "%{http_code}\n" https://www.eicar.org/cgi-bin/.%2e/.%2e/.%2e/.%2e/etc/passwd --max-time 2) ew1=$(curl -w "%{http_code}\\n" -s -o /dev/null https://10.0.0.20/cgi-bin/.%2e/.%2e/.%2e/.%2e/bin/sh --data "echo Content-Type: text/plain; echo; uname -a" --max-time 2) ew2=$(curl -w "%{http_code}\\n" -s -o /dev/null https://10.0.0.20/cgi-bin/user.sh -H "FakeHeader:() { :; }; echo Content-Type: text/html; echo ; /bin/uname -a" --max-time 2) ew3=$(curl -w "%{http_code}\\n" -s -o /dev/null https://10.0.0.20/cgi-bin/.%2e/.%2e/.%2e/.%2e/etc/passwd --max-time 2) echo "" echo "Response Codes (north/south) : $ns1 $ns2 $ns3" echo "Response Codes (east/west) : $ew1 $ew2 $ew3" echo ""'
-
Execute the script remotely on the
client-vm
to simulate threats for outbound internet traffic and east-west traffic to theweb-vm
.gcloud compute ssh $PREFIX-client-vm --zone=$ZONE --tunnel-through-iap --command="bash -c '$REMOTE_SCRIPT_TLS'"
(output)
Response Codes (north/south) : 000 000 000
Response Codes (east/west) : 000 000 000π‘ Information
Each curl should result in a000
response code indicating Cloud NGFW has decrypted, inspected, and blocked the pseudo-malicious traffic.
-
In the Google Cloud console, go to Network Security β Threats to view the threat logs.
Warning
If the threats using tcp:443
do not appear, please wait several minutes and re-run the REMOTE_SCRIPT_TLS
from the client-vm
again.
Note
You should see the actions taken by the firewall endpoint, indicating the service has detected and/or stopped the threats encrypted within TLS.
To delete the created resources, delete your Google Cloud deployment project. If you cannot delete your project, follow the steps below to delete the cloud resources created in this tutorial.
-
In Cloud Shell, destroy the resources created within the Terraform plan.
cd cd google-cloud-ngfw-tutorial/terraform terraform destroy
Enter
yes
to destroy the resources. -
If you configured TLS inspection, delete the CAS resources.
cd .. delete_tls.sh
-
Clone the repository to Cloud Shell.
git clone https://github.com/PaloAltoNetworks/google-cloud-ngfw-tutorial cd google-cloud-ngfw-tutorial
-
Execute the script to delete the resources created in the tutorial.
delete_tutorial.sh
-
If you configured TLS inspection, delete the CAS resources used to decrypt TLS traffic.
delete_tls.sh
Please see the materials below for more information about the topics discussed in this tutorial.