Skip to main content

Proxy on GCP โ€“ Harder, Better, Faster, Stronger ๐Ÿค–

ยท 10 min read

The week before the pentest...

Work it harder, make it better
Do it faster, makes us stronger
More than ever, hour after
Hour, work is never over

French army band medleys Daft Punk following Bastille Day parade

The situation is nothing to write home about. C2 malware, ransomware, default telemetry, use of plaintext protocols across the Internet, escalating data egress charges โ€“ you name it โ€“ this one unplugged gap in the Cloud, the outbound connections originating from your deployments, keeps on giving (or taking.)

With no human-readable visibility on any egress flows, not much you can do with all those IP addresses in the flow logs. Talk about flying blind. It's time to install a filtering proxy, and Squid is the word on the grapevine.

Let's take a deep-dive ๐Ÿ”Ž

A minimal allowlisting Squid configโ€‹

# /etc/squid/squid.conf

cache deny all

# ensure only trusted client subnets are listed
acl localnet src
acl localnet src
acl localnet src

acl allowlist dstdomain "allowlist.txt"

http_access allow localnet allowlist
http_access deny all

http_port 3128
# /etc/squid/allowlist.txt

# from Thu, 29 Aug 2021 06:00:00 +0000 cutover to the new subdomain at

Now the only things we need to worry about are:

โžŸ tying specific allowlists or policies to specific applications by introducing authentication or creating ACLs per subnet (and run an application per subnet)
โžŸ develop a mechanism to change config files on the fly, perhaps by pulling down from a bucket every so often and sending the squid process a HUP signal or redeploying stateless containers and monitoring the fronting load balancer
โžŸ create a log trail for auditability of changes made to these config files and subsequent production deployments
โžŸ ensure logs are parsed and can be searched effectively at the indexer
โžŸ perhaps suppress the healthcheck logs
โžŸ set minimum inbound and outbound TLS version levels
โžŸ create TCP port-based ACLs for letting SSH through, allowed to specific static IP addresses
โžŸ reconfigure all applications with http_proxy, https_proxy and no_proxy config, so they route http requests efficiently

...and the proxy server config grows tentacles ๐Ÿฆ‘โ€‹

# /etc/squid/squid.conf

# here be dragons ๐Ÿ€„

...scripts to "orchestrate" โ™ซ emergeโ€‹

# don't forget to install bash

set -e # at least stop if a command fails, without a helpful error message


Write it, cut it, paste it, save it
Load it, check it, quick - rewrite it

...applications become less portable, less testableโ€‹

val proxyHost = "squid-somewhere.some-zone.local"
val proxyPort = 3128

val httpsProxyTransport = ClientTransport.httpsProxy(InetSocketAddress.createUnresolved(proxyHost, proxyPort))

val settings = ConnectionPoolSettings(system).withTransport(httpsProxyTransport)
Http().singleRequest(HttpRequest(uri = ""), settings = settings)

Maybe a proxy-less solution?โ€‹

A discriminating, next-gen firewall might just be what you need instead ๐Ÿ’Š

So, how does discrimiNAT compare to Squid then?

ย SquiddiscrimiNAT
Sufficient Depth of Checks๐ŸŸข yes
proxies terminate incoming connections, read metadata, and launch new outbound connections, therefore, working around the need to carry out more checks because they are acting on the client's behalf
๐ŸŸข yes
inspects raw packets for protocol-level anomalies and also conducts asynchronous, out-of-band DNS checks to verify hostnames against IP addresses
Protocol Downgrade Protection๐ŸŸ  maybe
such a capability must be explicitly configured in the config file for both requests and responses of a TLS handshake
๐ŸŸข yes
enforces minimum protocol level versions (such as 1.2 for TLS), as per contemporary standards, for both sides of a handshake
Per-Application Policies๐ŸŸ  maybe
will require apps to proxy-authenticate so they can be identified and corresponding ACLs applied, or hardcoding of distinct source IP ranges/subnets mapped to specific policies in the config file
๐ŸŸข yes
integrates with the Cloud providers' native application-level firewall constructs such as Security Groups in AWS and Firewall Rules in GCP, deriving policies from these resources' built-in fields
Monitor Flows๐ŸŸ  maybe
per-application policies are difficult to accomplish as discussed, therefore, any relaxation of enforcement (so logs can be collected) puts the entire VPC at risk. Morever, the entire range of ports and protocols accessed by an application will surely be missed by Squid's typical network topology
๐ŸŸข yes
the see-thru mode is able to capture and generate filterable logs for specific applications, therefore, keeping policies enforced for the rest of the VPC. Logs also indicate whether current rules would cover the traffic seen or not and can be filtered on this criteria too
SSH (or SFTP) Protocol Support๐Ÿ”ด no
proxying at a TCP port level does not validate protocol soundness, requires workarounds on the client-side, and only IP address-based policies may be applied; it is an HTTP proxy after all
๐ŸŸข yes
protocol is implemented natively for deep packet inspection, and policies can be applied on destination FQDNs
TLS (or HTTPS) Protocol Support๐ŸŸข yes
proxies have their own implementation written in low-level languages such as C and C++, linked to common libraries such as OpenSSL
๐ŸŸข yes
deep packet inspection engines do not implement the protocols per se but only a subset of the specifications so packets on the wire can be parsed; discrimiNAT is written in Rust, a low-level but memory-safe language
TLS Decryption๐ŸŸ  maybe
if the proxy's CA certificates are installed on clients to trust, it can be configured to decrypt TLS connections and inspect their payload; the onward connection to the intended destination would be initiated by the proxy, and only the proxy will see the true SSL certificate; the client will see an SSL certificate from the proxy, and the boundary of unencrypted data will move to the proxy node
๐Ÿ”ด no
at this time, discrimiNAT does not implement decryption of the full payload or installation of CA keys; the boundary of unencrypted data does not move to this gateway at the internet/public edge of your network
Connection Termination๐Ÿ”ด yes
proxies by definition terminate the inbound connection and launch a similar one outbound; this adds huge latency with TCP and TLS handshakes having to be carried out twice for each connection, and cipher preferences from the client can get diluted
๐ŸŸข no
packets are inspected as they flow on the wire with deep packet inspection; since no connections are terminated or new ones initiated, all original handshake preferences are preserved; no impact on latency either
Cloud-Native Rules Management๐Ÿ”ด no
rules in the form of ACLs are described in config files, and any updates to them would involve delivering changes to such files and sending a HUP signal to Squid's processes or restarting them; this could involve a lot of work, especially with auditability thrown in
๐ŸŸข yes
config is pulled from Cloud providers' native firewall constructs such as Security Groups in AWS and Firewall Rules in GCP, therefore enabling the use of their web consoles, any existing infrastructure as code tools such as Terraform, and with auditability since it's an integral part of the Cloud platform
Cloud-Native Logging๐Ÿ”ด no
an HTTP proxy's logs are very application-layer oriented and are usually very noisy; shipping these into the Cloud platform's logging service in a parseable format requires fragmented, delicate config
๐ŸŸข yes
whether it's CloudWatch or StackDriver, proper, structured flow and audit logs are separately indexed in mere seconds with rich security-oriented metadata
Application Config Required๐Ÿ”ด yes
a smooth operation can only be achieved if the applications have HTTP_PROXY, HTTPS_PROXY and NO_PROXY configured appropriately; this is so that http:// and https:// traffic is force-routed through the proxy at the application-layer and the inter-VPC, intra-VPC and instance metadata traffic on the link-local interface does not route through the proxy
๐ŸŸข no
zero config change required on the applications no matter which application-layer protocol is involved; all routing is carried out as natively defined on the Cloud platform's route tables and firewall rules
Transparent Operation๐ŸŸ  maybe
with complex routing and a range of ports defined upfront, and with limitations around TLS interception, some transparent operation can be achieved
๐ŸŸข yes
since this replaces the NAT, packets are naturally routed via it at an IP level, and the use of deep packet inspection enables it to work by observation rather than termination
Safe To Operate๐Ÿ”ด no
with hundreds of config options and opportunities for policy-bypass with the use of port-based ACLs tied together with IP addresses in hand-crafted config files, it is easy to end up with a security stance that isn't safe, even by knowledgeable experts, and may inadvertently have holes in it
๐ŸŸข yes
has been designed upfront to not have features that can downgrade the security stance expected of an internet gateway, and is built for and tested thoroughly on the supported Cloud platforms โ€“ so no specialised knowledge is required to configure and operate it, and the security champions can confidently hand it over for self-service operation

Lecture 18 and Lecture 19 from "Computer and Network Security" at Purdue University are an excellent read for those interested in an in-depth course on proxies vs packet-filtering firewalls.

โ›… Enter DX: Developer Experienceโ€‹

The discrimiNAT firewall has been engineered from the ground up with DX in mind.

๐Ÿ‘‰ No application config required for when and when not to use a proxy ๐Ÿ‘‡

$ env | grep _PROXY

๐Ÿ‘‰ Firewall config in Cloud console, precisely where it should be ๐Ÿ‘‡

๐Ÿ‘‰ Keep using Terraform or any other Infrastructure as Code tool ๐Ÿ‘‡

fqdns_saas_auth = [

๐Ÿ‘‰ Support the SSH protocol as well for those SFTP and git clone jobs ๐Ÿ‘‡

git clone

๐Ÿ‘‰ Structured logs with well thought out fields in your Cloud's logging service ๐Ÿ‘‡

"outcome": "allowed",
"fqdn": "",

๐Ÿ‘‰ Meet regulatory and compliance standards of encryption out of the box ๐Ÿ‘‡

"proto": "tls",
"proto_v": "1.2",
๐Ÿ‘‰ Pass that pentest ๐Ÿ‘‡

We are human... after all
Much in common. After all

Next stepsโ€‹

๐Ÿš€ Launch a free trial now from the GCP Marketplace

๐Ÿš€ Get in touch with our stellar DevSecOps who will:

  • not only guide you through the best architecture for your use-case
  • but also troubleshoot any issues you may encounter
  • and answer any geeky questions on protocols and whatnot

๐Ÿš€ See our Quick Start guide for GCP

๐Ÿš€ Watch a brief demo video