jueves, 11 de diciembre de 2014

Squid proxy being transparent also for ssl and other tcp connections by using ssl bump

A long time ago I was trying to have a transparent proxy setup by using squid, but squid traditionally only knows about http, ftp and https in explicit proxy mode. There is no way to handle non http (for example https) transparently on a traditional setup, so that setup was not what I was looking for.

After looking into TLS SNI and other things, trying even to implement things like that on some tools like socat that would proxify things for squid, I discovered ssl bump on squid3, which just does all the magic I was looking for.

Squid traditionally has several ways of listening to requests, one of which is the explicit proxy port (http_port 3128) and the other typical ones are for transparent proxy, this is indicated by flags:

transparent: used to intercept server queries and parse http host headers to forward them through squid to the servers

tproxy: used to spoof outgoing address to that of the client, so that squid is really transparent

Well, none of this allows us to forward https or tcp requests (say for example ssh, imap, ...) for a client that doesn't have explicit proxy support. Unluckily this means that a transparent proxy using this technology nowadays is of no use.

This is where ssl bump comes to the rescue, the old transparent mode of squid, which is currently called intercept, on squid3 has an extra flag: ssl-bump, which has the power of being able to intercept ssl traffic and things like that, allowing squid to cache https webs, but to do this, one has to create a Certificate Authority and the clients must trust this CA that squid uses to issue certificates for the web sites we want to visit.

However ssl-bump can work without issuing these certificates and in this case squid won't mess with https requests, but it will still allow us to do a pretty neat thing, which is to forward all tcp connections from any client (doesn't even have to know what a proxy is) transparently. In this case what squid does is to ask netfilter (iptables) where was the connection that squid is handling supposed to go, and squid makes this connection for the client so that it starts talking to the other end with all the traffic going through squid.

One might ask himself why would he want this traffic on squid, well, you'll have all of squid features, you can control the speed, you get all the typical logs and acls, ...

Of course that if you don't want this you can go with iptables and traffic shaper and that's good as well.

So... you like this idea? Well, then if your distro has squid compiled with ssl support you can read the config section, but if you are (like me) using Debian, you must recompile your squid3 with ssl support. Debian doesn't compile squid3 with ssl support as there are problems between openssl license and squid3 one (squid developers are looking forward to somebody porting the code to gnutls :-)

Rebuilding squid3 with ssl-bump

Well, to rebuild the squid3 package with ssl support you must install the needed packages:

apt-get install fakeroot libssl-dev
apt-get build-dep squid3

There you may find that your distro doesn't have all the packages needed to compile, like for example libecap2-dev, in this case you'll have to apt-get source these packages, compile and install them like we'll do with squid3

And then do a few things as user (we'll use fakeroot which we have just installed) I've tested this using squid3 from Debian testing (the next version, which will be Jessie)

Start with:

apt-get source squid3

And then we'll edit a couple of files on the source, so cd into the source dir and in the debian/control file you must add to the build-depends: libssl-dev and in the debian/rules file you must add this configure options:

--enable-ssl \
--enable-ssl-crtd \

One can then run debchange -i and add something like this on the changelog:

Build with --enable-ssl and --enable-ssl-crtd.

Now the source is ready to build using your favourite command, like for example:

dpkg-buildpackage -rfakeroot

and at last install the needed packages using dpkg -i

Configuration

The main configuration file is stored at /etc/squid3/squid.conf, even though it can be split into separate files. On these files we must set as SSL_ports all the ports for the protocols that we want to allow through squid using an acl like this:

The direct thing is to force the squid server to send ssl-bump requests directly and not through other caches, as this wouldn't work at all. The certificate is needed even though we won't be using it, just generate one using make-ssl-cert from the ssl-cert package or plain openssl x509 power.

Make sure we have all our client networks listed on our localnet acl and that they are allowed to use the proxy:

Several misc settings like: make sure that ssl-bump doesn't generate certificates for any host at all (just in case), set the language for the errors and allow a good number of filedescriptors so that we don't run out of them

ssl_bump none all
error_default_language es
max_filedescriptors 8192

And that is pretty much what is needed on the squid configuration, of course you can do this and more writing it all in different ways. I have found out that the directory for the ssl certs is not created by default, we must run: /usr/lib/squid3/ssl_crtd -c -s /var/lib/ssl_db

Routing it all through squid

You may be wondering how does all the traffic that we are going to allow through squid get to it. Well, the answer is easy if you have ever configured some kind of transparent proxy or similar, we do it through iptables, in the PREROUTING chain of the nat table we send things to the ssl-bump port or to our transparent proxy port as we like and then we open the ports on which we are serving all this on the INPUT chain of the filter table with something like this which can be loaded with iptables-restore myiptables.cfg:

I believe that's all, of course this is generally speaking and you'll have to adapt it to fit your needs, but there it is. Just add a dhcp server for convenience and ntp and dns servers so that you don't need to forward those protocols and in order to save more bandwith using the dns server cache and local ntp answers and you're done.

Note that these iptables are dropping all forwarding as in the example the kernel doesn't need to forward anything, squid does it, and for dns and ntp we are using local servers. Of course that if you want to forward some udp traffic, you'll need to add forwarding rules for that.

4 comentarios:

I was wondering, you mention that with ssl-bump you can log the https request but not the content of it, so you don't have to issue a ca certificate.

Did i get it right?

So, then as expected, there is no way for caching https files without compromising the "security" system around SSL, but you can manage the flow, like putting a finger on the garden hose to regulate the flow, passing the data through Squid without security compromise.