Managing Egress Traffic with Cloud Secure Web Proxy (SWP) on Google Cloud Platform (GCP)

Hassene BELGACEM
Google Cloud - Community
9 min readMay 24, 2023

--

A secure web proxy is a critical component of any modern network infrastructure. It provides a way to control, secure, and monitor the web egress traffic of an organization’s network. Users of Google Cloud Platform (GCP) now have the opportunity to take advantage of a newly introduced pre-general availability service known as “Secure Web Proxy”. This article will walk you through the when this component is needed and how to set one up on GCP. We’ll also cover how to test and validate your setup using a client virtual machine (VM).

What is Secure Web Proxy ?

Secure Web Proxy is a new Cloud Platform (GCP) managed service designed to protect and control egress web traffic (HTTP/S). The service acts as a gateway for clients, processing requests from various sources, including virtual machine (VM) instances, containers, serverless environments using a serverless connector, and workloads outside of Google Cloud connected via Cloud VPN or Cloud Interconnect. It also supports policies based on cloud-first identities and web applications for increased flexibility and granular control.

Why Do We Need a Web Proxy?

A web proxy acts as an intermediary for requests from clients seeking resources from other servers. It essentially acts as a shield, standing between your servers and the internet. The need for a web proxy arises from several important aspects:

  1. Security: The proxy adds a layer of security by handling requests on behalf of the servers and thereby hiding their details. It can also prevent unauthorized access and protect the network from attacks.
  2. Filtering: Secure web proxies can help regulate internet usage by blocking access to certain websites. This is particularly useful in corporate environments to enforce internet usage policies.
  3. Caching (Not yet supported by Cloud SWP): Proxies can store (cache) frequently accessed pages. If multiple users access the same webpage, the proxy can serve the cached version instead of fetching the page from the internet again, improving response time and reducing bandwidth usage.

Design

In order to test the various features of the Secure Web Proxy service effectively, we will construct a real-world scenario. The chosen network architecture for this scenario is a hub-and-spoke topology.

  1. Hub and Spoke Network Topology: In this network model, the ‘hub’ is a central network to which other networks (the ‘spokes’) connect. This type of network topology is ideal for large-scale cloud infrastructures, as it allows for centralized management and enhanced security control.
  2. Shared Secure Web Proxy : The Secure Web Proxy service will be deployed in the hub of the network. This arrangement ensures all egress traffic from the spoke networks (which may represent different departmental networks or project areas) will go through the Secure Web Proxy for inspection and control. The filtering will be applied on secured (Https,TLS) and unsecured (http) traffic.
  3. Internet Access Through Static IPs: As part of the requirements, all internet access from the spokes must use static IP addresses. This is achieved using Google Cloud NAT (Network Address Translation), which enables instances without external IP addresses to access the internet.

Here is a high-level schema that represents this scenario:

Egress filtering with secure web proxy

This scenario provides a useful framework for evaluating how Secure Web Proxy manages and controls egress web traffic. By monitoring how it functions in this environment, you can gain a clear understanding of its capabilities and limitations, enabling you to configure it effectively for your own use.

How to build this design ?

In this section, we are going to deep dive into the procedure involved in constructing our desired design. We will unfold this process step by step, elaborating on each aspect in detail to provide a comprehensive understanding of how to achieve our target design.

  • Step 0: We will start with setting the necessary env variables, this will facilitate installation steps
export PROJECT_ID="your-project-id"
export REGION="your-region" # ex: europe-west3
export HUB_NETWORK_NAME="hub-network"
export HUB_SUBNET_NAME="hub-subnet"
export HUB_SWP_SUBNET_NAME="swp-subnet"
export SPOKE_NETWORK_NAME="spoke-network"
export SPOKE_SUBNET_NAME="spoke-subnet"

export SWP_IP_ADDRESS="192.168.0.10"
export SWP_HOST_NAME="proxy.example.local"
export SWP_CA_POOL="swp-pricateca"
export SWP_CERT_NAME="swp-certificate"
export TLS_POLICY_NAME="swp-tls-policy"
  • Step 1: To start, we need to construct a hub network with a least a dedicated subnet specifically designed for the web proxy. This subnet requires a size of at least /26. However, we advise opting for a subnet size of /23 which can house up to 512 dedicated proxy addresses/instances. In line with the specified requirements, we must ensure that internet access occurs via static IP addresses. This can be accomplished by establishing a NAT (Network Address Translation) gateway, no need to create it manually as Cloud SWP will instantiate one automatically.
# Create a Hub custom Network and its secure web proxy subnet
gcloud compute networks create $HUB_NETWORK_NAME \
--project=$PROJECT_ID \
--subnet-mode=custom
gcloud compute networks subnets create $HUB_SUBNET_NAME \
--project=$PROJECT_ID \
--network=$HUB_NETWORK_NAME \
--role="ACTIVE" \
--purpose="PRIVATE" \
--range=192.168.0.0/23 --region=$REGION
gcloud compute networks subnets create $HUB_SWP_SUBNET_NAME \
--project=$PROJECT_ID \
--network=$HUB_NETWORK_NAME \
--role="ACTIVE" \
--purpose="REGIONAL_MANAGED_PROXY" \
--range=192.168.2.0/23 --region=$REGION
Hub subnets
  • Step 2: Now, we move on to the creation of the Spoke network. The only requirement here is that the IP range of the Spoke network must not overlap with the Hub network’s IP range to avoid any IP conflicts.
# Create a Spoke custom Network and its subnet
gcloud compute networks create $SPOKE_NETWORK_NAME \
--project=$PROJECT_ID \
--subnet-mode=custom
gcloud compute networks subnets create $SPOKE_SUBNET_NAME \
--project=$PROJECT_ID \
--network=$SPOKE_NETWORK_NAME \
--range=10.0.1.0/24 --region=$REGION

# Get Default Route internet
ROUTE_NAME=$(gcloud compute routes list --filter="network: $SPOKE_NETWORK_NAME AND nextHopGateway:default-internet-gateway" --format="value(name)")

# Delete the route
gcloud compute routes delete $ROUTE_NAME --quiet
Network configuration
  • Step 2 : Next, we need to establish network peering between the Hub network and each of the Spoke networks.
# Hub to spoke 1
gcloud compute networks peerings create hub-to-spoke \
--project=$PROJECT_ID \
--network=$HUB_NETWORK_NAME --peer-network=$SPOKE_NETWORK_NAME \
--auto-create-routes
gcloud compute networks peerings create spoke-to-hub \
--project=$PROJECT_ID \
--network=$SPOKE_NETWORK_NAME --peer-network=$HUB_NETWORK_NAME \
--auto-create-routes

The result must be something like this:

Create peering
  • Step 3 (optional): Having successfully set up your network, it’s time to create a private DNS zone for more real-world environment simulation. Let’s name this zone “example.local”, within which we will establish our Web Proxy DNS record named “proxy.example.local”. This record is crucial as it will be utilized during the generation of certificates.
#create a managed private DNS zone "example.local"
gcloud dns managed-zones create local-zone \
--dns-name="example.local." \
--description="Local DNS Zone" \
--networks $HUB_NETWORK_NAME,$SPOKE_NETWORK_NAME \
--visibility private

#create new record description as YAML file
cat > swp-record.yml <<EOF
kind: dns#resourceRecordSet
name: ${SWP_HOST_NAME}.
rrdatas:
- $SWP_IP_ADDRESS # replace with the actual IP address
ttl: 300
type: A
EOF

#Finally, you need to import the record
gcloud dns record-sets import -z=local-zone \
--delete-all-existing swp-record.yml
  • Step 4: The Gateway will manage TLS traffic, this why we need to provide a certificate. For the purpose of this lab, we will use a locally generated key. However, in a production environment, it is essential to generate and securely store the keys using a key store.
# Generate ssl certificate
openssl req -x509 -newkey rsa:2048 \
-keyout swp.key \
-out swp.cer -days 365 \
-subj '/CN=${SWP_HOST_NAME}' -nodes -addext \
"subjectAltName=DNS:${SWP_HOST_NAME}"

# Upload the SSL certificate to Certificate Manager
gcloud certificate-manager certificates create $SWP_CERT_NAME \
--certificate-file=swp.cer \
--private-key-file=swp.key \
--location=$REGION
  • Step 5 (optional : TLS inspection) : At this point in the process, it’s necessary to consider whether TLS inspection is required for your traffic. In this scenario, the web proxy functions as a Man-in-the-Middle (MitM), decrypting the encrypted TLS traffic flowing between clients and servers. This requires a local certificate authority that will be employed to generate a temporary certificate for each instance when users and applications access a website. The following steps need for creating this your CA
# Enable private CA API
gcloud services enable privateca.googleapis.com

# Create pricate CA pool, use the "devops" tier beacuse we dont need to manage certificate lifecycle
gcloud privateca pools create $SWP_CA_POOL \
--project=$PROJECT_ID \
--tier="DEVOPS" \
--location=$REGION

# Create a service account with the persmission of managing CA pool
gcloud beta services identity create \
--service=networksecurity.googleapis.com \
--project=$PROJECT_ID
gcloud privateca pools add-iam-policy-binding $SWP_CA_POOL \
--member="serviceAccount:service-< replace with project number >@gcp-sa-networksecurity.iam.gserviceaccount.com" \
--role='roles/privateca.certificateManager' \
--location=$REGION

# Create CA
gcloud privateca roots create swp-root-ca --pool=$SWP_CA_POOL \
--location=$REGION \
--subject="CN=${SWP_HOST_NAME}, O=example.local"
  • Step 6 (optional : TLS inspection) : Create your TLS inspection policy that will be associated with you global policy created in the next step.
# Create policy file
cat << EOF > tlsInspectionPolicy.yaml
name: projects/$PROJECT_ID/locations/$REGION/tlsInspectionPolicies/$TLS_POLICY_NAME
caPool: projects/$PROJECT_ID/locations/$REGION/caPools/$SWP_CA_POOL
EOF

# Import TLS policy
gcloud network-security tls-inspection-policies import $TLS_POLICY_NAME \
--source=tlsInspectionPolicy.yaml \
--location=$REGION
  • Step 7: Create your inspection policy that will associated later with your Web Proxy.
# Create config file
cat << EOF > policy.yaml
description: Secure Web Proxy policy
name: projects/$PROJECT_ID/locations/$REGION/gatewaySecurityPolicies/swp-policy
tlsInspectionPolicy: projects/$PROJECT_ID/locations/$REGION/tlsInspectionPolicies/$TLS_POLICY_NAME
EOF

# Import policy
gcloud network-security gateway-security-policies import swp-policy \
--source=policy.yaml \
--location=$REGION
  • Step 8: Now its time to create your secure web proxy instance.
# Create config file
cat << EOF > gateway.yaml
name: projects/$PROJECT_ID/locations/REGION/gateways/swp-gwt
type: SECURE_WEB_GATEWAY
addresses: ["${SWP_IP_ADDRESS}"]
ports: [443]
certificateUrls: ["projects/$PROJECT_ID/locations/$REGION/certificates/$SWP_CERT_NAME"]
gatewaySecurityPolicy: projects/$PROJECT_ID/locations/$REGION/gatewaySecurityPolicies/swp-policy
network: projects/$PROJECT_ID/global/networks/$HUB_NETWORK_NAME
subnetwork: projects/$PROJECT_ID/regions/$REGION/subnetworks/$HUB_SUBNET_NAME
scope: basic-scope
EOF

gcloud network-services gateways import swp-instance \
--source=gateway.yaml \
--location=$REGION
Secure web proxy instance

Test and validate this design ?

Testing and validation of a network design are critical steps. To accomplish this, a virtual machine (VM) can be installed within the spoke network, acting as a representative client for the network’s endpoints. By utilizing the ‘curl’ command, it is possible to simulate internet access and evaluate the network’s ability to establish connections, route traffic, and resolve DNS queries.

  • Step 1: Create a client virtual machine within the spoke network
# Create VM
gcloud compute instances create client-vm \
--project=$PROJECT_ID \
--zone=${REGION}-a \
--machine-type=e2-medium \
--network=$SPOKE_NETWORK_NAME \
--subnet=$SPOKE_SUBNET_NAME \
--tags client-vm --metadata enable-oslogin=TRUE

# Allow ssh ingress traffic
gcloud compute firewall-rules create allow-ssh-ingress \
--project=$PROJECT_ID \
--network=$SPOKE_NETWORK_NAME \
--action=allow \
--direction=INGRESS \
--rules=tcp:22 \
--destination-ranges="0.0.0.0/0"
# Allow egress traffic
gcloud compute firewall-rules create allow-egress \
--project=$PROJECT_ID \
--network=$SPOKE_NETWORK_NAME \
--action=allow \
--direction=EGRESS \
--rules="tcp:0-65535,udp:0-65535" \
--destination-ranges="0.0.0.0/0"
  • Step 2: At this stage, it’s essential to establish an SSH connection to the Virtual Machine (VM) you’ve recently set up. This can be achieved by simply utilizing the “ssh” button found in the console. As we did not define any rules, you will get “Access denied” when trying to access any website.
# Must replace $SWP_HOST_NAME with its value, ex: proxy.example.local
curl --proxy https://$SWP_HOST_NAME --proxy-insecure https://google.com

# Result must be : Access denied
  • Step 3: You now need to set up a rule that allow access to “google.com”. Afterward, you can reattempt the test by employing the same “curl” command. Here’s an example illustrating how you can accomplish this through the command console.
Secure web proxy rule
# Must replace $SWP_HOST_NAME with its value, ex: proxy.example.local
$ curl --proxy https://$SWP_HOST_NAME --proxy-insecure https://google.com

<HTML><HEAD><meta http-equiv="content-type" content="text/html;charset=utf-8">
<TITLE>301 Moved</TITLE></HEAD><BODY>
<H1>301 Moved</H1>
The document has moved
<A HREF="http://www.google.com/">here</A>.
</BODY></HTML>

Conclusion

In conclusion, we’ve navigated through the steps involved in setting up a Secure Web Proxy with the help of Google’s managed service bearing the same name. Given its relative novelty, we expect it to incorporate new features in the future, such as a bundled list of sites earmarked for blocking.

Originally published at https://hassene.belgacem.io .

--

--

Hassene BELGACEM
Google Cloud - Community

Cloud Architect | Trainer . Here, I share my thoughts and exp on the topics like cloud computing and cybersecurity. https://www.linkedin.com/in/hassene-belgacem