Setup Squid Forward Proxy

If you’re reading this article, you’re probably frustrated  by the lack of relevant information about Squid, a very popular forward proxy. Some of these frustrations involve major usability changes occurring after minor software revisions, misconceptions about what’s actually happening behind-the-scenes, and genuinely poor documentation. This aims to be a comprehensive primer which will get you up and running with Squid.

First though, why might you want to use a forward proxy? Back in the day, it used to be very popular to terminate all outgoing connections at a proxy before sending them out to the internet. This is no longer as popular in the enterprise, but is something you might still run into on occasion. Squid however, can do much more than intercept plain-text communications – it can decrypt SSL/TLS communications on-the-fly as well in a couple of different configurations which have respective security implications.

There are two subtypes of forward proxies – explicit and implicit, and two ways to proxy SSL/TLS communication – terminating and non-terminating. Any of the four combinations are possible, and each has their own set of requirements. Explicit v. Implicit simply refers to whether the client has to specify (and possibly authenticate to) the forward proxy on their end. In this situation the client is aware that this is happening. It uses CONNECT messages to interface with the proxy and help it negotiate a connection to the destination.

Implicit connections on the other hand are a little bit trickier, and a lot more dangerous. In this configuration, the proxy is performing what in another context would be considered a man-in-the-middle attack. The client is completely unaware that somewhere their traffic is being sent is posing as the destination, decrypting their communication, and re-encrypting it to send to the real target server. Responses are captured on-the-fly as well, and sent back to the origin server. As we know, SSL/TLS prevents man-in-the-middle attacks twofold – by using asymmetric cryptography to secure communication with a private key and by maintaining a registry of trusted public keys. Implicit forward proxies bypass both of these protections (though often intentionally, and sometimes even securely). Instead of explicitly specifying the connection, the client simply sends off its traffic as it usually would. Somewhere upstream, the traffic is literally routed by a layer 3 device to the proxy, which then NATs the traffic to another interface in order to be able to avoid detection on the other end. It presents a certificate valid for any domain that it generates as requests hit it in real time, and because the client needs to be configured to trust the same root CA certificate the proxy uses, will allow the connection. (Remember, any certificate trusted as a root certificate can sign valid certificates for any and all domains and paths, not just its own.)

This configuration is incredibly useful however. Because the proxy terminates the connection and re-negotiates with the destination, it can actually change the kind of encryption used in-flight. Say you have older software that uses Java 6. You can put the Squid proxy in front of this server to allow it to achieve PCI compliance, as even though the software can only communicate via either plain old HTTP or HTTPS using TLS v1 (currently non-compliant), the proxy will re-encrypt the traffic using the TLS 1.2 gold standard.

How does one configure such a configuration? Well, it can certainly be a little bit of a hassle. It’s also different for every Operating System, but the basics are the same. This is not for the faint of heart, some experience compiling software in Linux is required.

As of  this writing, the best version to use is Squid 3.5. Download it from the project website and unzip it to a directory. You will need gcc, make, and potentially other development environment tools for your linux distribution. On ubuntu in particular, installing build-essential should cover you. You’ll need two NICs on this box so that you can NAT between them.

You’ll want to create a user, named aptly: squid.

Make sure to use these flags to correctly link to libraries you will need.

Follow with make, and then make install.

You’ll need to generate your own CA.

  • You might determine that your CA should be valid for longer than 1 year.

This .der will be the certificate your client needs to trust.

You will need to set the UID bit on the squid helper application “pinger”.

Your squid.conf should look something like this:

Start the squid service with the command your operating system supplies. Make sure there are no errors in /var/log/squid

You can use the command:

to make sure that squid has successfully bound to the port.

This command will need to be applied at each boot to NAT traffic destined for port 443 on the IP traffic will be routed to (either using a static route on your origin device – y.y.y.y or on a network component) to the port squid is listening on on the other NIC bound to squid (x.x.x.x)

Assuming the client trusts the root certificate, the squid proxy will transparently proxy all connections destined outbound.