Created
March 29, 2024 18:35
-
-
Save mikesparr/c902f6979a6752f1d62c7dba87befdee to your computer and use it in GitHub Desktop.
Experiment using Google Cloud Secure Web Proxy and Cloud NAT
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/usr/bin/env bash | |
##################################################################### | |
# REFERENCES | |
# - https://cloud.google.com/secure-web-proxy/docs/initial-setup-steps | |
# - https://cloud.google.com/certificate-manager/docs/deploy-google-managed-regional | |
# - https://cloud.google.com/secure-web-proxy/docs/quickstart | |
# - https://cloud.google.com/secure-web-proxy/docs/enable-tls-inspection (OPTIONAL) | |
##################################################################### | |
export PROJECT_ID=$(gcloud config get-value project) | |
export PROJECT_USER=$(gcloud config get-value core/account) # set current user | |
export PROJECT_NUMBER=$(gcloud projects describe $PROJECT_ID --format="value(projectNumber)") | |
export IDNS=${PROJECT_ID}.svc.id.goog # workflow identity domain | |
export GCP_REGION="us-central1" # CHANGEME (OPT) | |
export GCP_ZONE="us-central1-a" # CHANGEME (OPT) | |
export NETWORK_NAME="default" | |
# enable apis | |
gcloud services enable compute.googleapis.com \ | |
storage.googleapis.com \ | |
certificatemanager.googleapis.com \ | |
networksecurity.googleapis.com \ | |
networkservices.googleapis.com | |
# configure gcloud sdk | |
gcloud config set compute/region $GCP_REGION | |
gcloud config set compute/zone $GCP_ZONE | |
############################################################ | |
# Networking | |
############################################################ | |
export NETWORK_NAME="demo-network" | |
export RESERVED_RANGE_NAME="google-managed-services" | |
export PROXY_SUBNET_NAME="secure-proxy" | |
export PROXY_SUBNET_RANGE="192.168.0.0/23" | |
export TEST_SUBNET_NAME="test-vms" | |
export TEST_SUBNET_RANGE="10.201.0.0/24" | |
export AUTHORIZATION_NAME="cert-auth-dns" | |
export DOMAIN_NAME="proxy.msparr.com" # CHANGEME | |
export CERTIFICATE_NAME="proxy-cert" | |
# create network (custom-mode) | |
gcloud compute networks create $NETWORK_NAME \ | |
--subnet-mode=custom | |
# create ssh firewall rule | |
gcloud compute firewall-rules create allow-ssh \ | |
--direction=INGRESS \ | |
--priority=1000 \ | |
--network=$NETWORK_NAME \ | |
--action=ALLOW \ | |
--rules=tcp:22 \ | |
--source-ranges=0.0.0.0/0 | |
# create proxy subnet | |
gcloud compute networks subnets create $PROXY_SUBNET_NAME \ | |
--purpose=REGIONAL_MANAGED_PROXY \ | |
--role=ACTIVE \ | |
--region=$GCP_REGION \ | |
--network=$NETWORK_NAME \ | |
--range=$PROXY_SUBNET_RANGE \ | |
--enable-private-ip-google-access | |
# create vm subnet | |
gcloud compute networks subnets create $TEST_SUBNET_NAME \ | |
--region=$GCP_REGION \ | |
--network=$NETWORK_NAME \ | |
--range=$TEST_SUBNET_RANGE \ | |
--enable-private-ip-google-access | |
# create dns authorization for regional managed cert | |
gcloud certificate-manager dns-authorizations create $AUTHORIZATION_NAME \ | |
--domain="$DOMAIN_NAME" \ | |
--type=PER_PROJECT_RECORD \ | |
--location=$GCP_REGION | |
# describe dns auth to get CNAME for updating records | |
gcloud certificate-manager dns-authorizations describe $AUTHORIZATION_NAME \ | |
--location=$GCP_REGION | |
# update your DNS records to add CNAME as this example: | |
# - cname: _acme-challenge_tprcqly2gkqiluqe.proxy.msparr.com | |
# - data: b7f8c0a6-3637-47ec-ba93-6f1c0bbbf267.2.us-central1.authorize.certificatemanager.goog. | |
# create regional managed certificate | |
gcloud certificate-manager certificates create $CERTIFICATE_NAME \ | |
--domains=$DOMAIN_NAME \ | |
--dns-authorizations=$AUTHORIZATION_NAME \ | |
--location=$GCP_REGION | |
############################################################ | |
# Secure Web Proxy | |
############################################################ | |
export INSTANCE_NAME="swp-test-vm" | |
export POLICY_NAME="policy1" | |
export POLICY_FILE_NAME="policy.yaml" | |
export RULE_NAME="allow-wikipedia-org" | |
export RULE_FILE_NAME="rule.yaml" | |
export GATEWAY_NAME="swp1" | |
export GATEWAY_FILE_NAME="gateway.yaml" | |
export GATEWAY_ADDRESSES="[10.201.0.200]" | |
export GATEWAY_PORTS="[443]" | |
# create policy file (skipped TLS inspection / CA setup for simplicity) | |
cat > $POLICY_FILE_NAME << EOF | |
description: basic Secure Web Proxy policy | |
name: projects/$PROJECT_ID/locations/$GCP_REGION/gatewaySecurityPolicies/$POLICY_NAME | |
EOF | |
# create the swp policy | |
gcloud network-security gateway-security-policies import $POLICY_NAME \ | |
--source=$POLICY_FILE_NAME \ | |
--location=$GCP_REGION | |
# create swp rules file (skipped TLS inspection / CA setup for simplicity) | |
cat > $RULE_FILE_NAME << EOF | |
name: projects/$PROJECT_ID/locations/$GCP_REGION/gatewaySecurityPolicies/$POLICY_NAME/rules/$RULE_NAME | |
description: Allow wikipedia.org | |
enabled: true | |
priority: 1 | |
basicProfile: ALLOW | |
sessionMatcher: host() == 'wikipedia.org' | |
EOF | |
# create the swp rule | |
gcloud network-security gateway-security-policies rules import $RULE_NAME \ | |
--source=$RULE_FILE_NAME \ | |
--location=$GCP_REGION \ | |
--gateway-security-policy=$POLICY_NAME | |
# create the gateway config file | |
cat > $GATEWAY_FILE_NAME << EOF | |
name: projects/$PROJECT_ID/locations/$GCP_REGION/gateways/$GATEWAY_NAME | |
type: SECURE_WEB_GATEWAY | |
addresses: $GATEWAY_ADDRESSES | |
ports: $GATEWAY_PORTS | |
certificateUrls: ["projects/$PROJECT_ID/locations/$GCP_REGION/certificates/$CERTIFICATE_NAME"] | |
gatewaySecurityPolicy: projects/$PROJECT_ID/locations/$GCP_REGION/gatewaySecurityPolicies/$POLICY_NAME | |
network: projects/$PROJECT_ID/global/networks/$NETWORK_NAME | |
subnetwork: projects/$PROJECT_ID/regions/$GCP_REGION/subnetworks/$TEST_SUBNET_NAME | |
scope: samplescope | |
EOF | |
# create the gateway | |
gcloud network-services gateways import $GATEWAY_NAME \ | |
--source=$GATEWAY_FILE_NAME \ | |
--location=$GCP_REGION | |
############################################################ | |
# Testing the proxy | |
############################################################ | |
export INSTANCE_NAME="swp-test-vm" | |
# create a VM instance for testing (doesn't use proxy-only subnet which is reserved per region) | |
gcloud compute instances create $INSTANCE_NAME \ | |
--subnet=$TEST_SUBNET_NAME \ | |
--zone=$GCP_ZONE \ | |
--image-project=debian-cloud \ | |
--image-family=debian-11 | |
# test the connection (allowed) | |
gcloud compute ssh $INSTANCE_NAME \ | |
--zone $GCP_ZONE \ | |
-- curl -x https://10.201.0.200:443 https://wikipedia.org --proxy-insecure | |
# test the connection (denied) | |
gcloud compute ssh $INSTANCE_NAME \ | |
--zone $GCP_ZONE \ | |
-- curl -x https://10.201.0.200:443 https://yahoo.com --proxy-insecure | |
# next steps (optional): | |
# - https://cloud.google.com/secure-web-proxy/docs/use-tags | |
# - https://cloud.google.com/secure-web-proxy/docs/use-url-list | |
# - https://cloud.google.com/secure-web-proxy/docs/assign-static-ip-addresses-for-egress-traffic | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Google Cloud Secure Web Proxy Demo
This experiment illustrates setting up Secure Web Proxy and testing initial policy against an approved external domain (
wikipedia.org
) and an unapproved domain (yahoo.com
).Allowed host (success)
You can see that the approved domain reaches the target host (which subsequently redirects but still reached them)
Not allowed host (denied)
Here a random host did not meet the gateway policy domain so it was denied
Certificate creation
You can use your own domain and DNS as I did in this example, or leverage Cloud DNS per docs examples. This is how I set up mine using a domain I control outside of GCP.
Fetch CNAME from cert config
Configure DNS