Squid http(s) transparent proxy with Juniper SRX | part 1
How to intercept HTTP/HTTPS connections with Juniper SRX, FreeBSD and Squid -part 1
In this article, I will share my config, thoughts and resources on setting up a transparent proxy for both HTTP connections and HTTPS (man in the middle).
This is only for proof of concept purpose.
What needs to be known:
- when a browser is set up to use a proxy, it will send commands in following format "CONNECT http://www.website.com
", intercepting http/https connections means that the browser and of course, user are not aware of any proxy in between.
For this, the squid proxy has to know and the "intercept" (and "transparent" for squid 3.1 and below) keyword for the port that it will listen to has to be given.
- HTTPS connections cannot just be intercepted transparently. This is because of the certificate signature trust mechanism implemented in the browsers. To overcome this, I will use a custom CA and will import the CA certificate in the browser, as a Trusted Certificate Authority, to avoid security warnings regarding the certificate.
- up until and including Squid 3.1, a packet hitting squid intercept/transparent port allowed for destination nat from external router/firewall so that the destination IP address of the packet to be the ip of squid. Starting with squid 3.2 this is still valid, but as a security SQUID needs to check the NAT table for the original destination IP address if it is indeed the IP of the host in the http request. This means that if the traffic is passing through an external box (like my case), it needs to be directed to squid FreeBSD/Linux with original destination ip. Details below on squid changes:ftp://ftp.itb.it/Squid/pub/squid/squid- ... html#ss2.1http://web.nvd.nist.gov/view/vuln/detai ... -2009-0801http://www.squid-cache.org/mail-archive ... /0061.html
The above means that an Junos device (SRX firewall in this case), instead of doing destination nat, it has to use different next-hop for packets with tcp destination ports [ 80 443] and keep same destination ip address.
Juniper calls this source based routing (more or less, here).
- Squid 3.2.9 and 3.3.3 (up until versions released on 26 of April 2013) compiled against OpenSSL 1.X will produce core dumps in certain situations ( if an OpenSSL method SSL_get_certificate is called before the cert is sent to client). See http://bugs.squid-cache.org/show_bug.cgi?id=3816
- the firewall doing NAT is actually FreeBSD PF running on the FreeBSD box. This way, squid has access to NAT table.
!!!!!!!!!! make sure /dev/pf has read permissions for squid user otherwise you will bang your head against first wall !!!!
This is a quick fix (set appropriate in your case).
# ls -la /dev/pf
crwxr-xr-x 1 root wheel 0x64 Apr 25 13:07 /dev/pf
Step 1. Installing Squid 3.3.4 on FreeBSD 9.1
# wget http://www.squid-cache.org/Versions/v3/3.3/squid-3.3.4.tar.gz
# tar zxvf squid-3.3.4.tar.gz
# cd squid-3.3.4
# ./configure --with-default-user=squid --bindir=/usr/local/sbin --sbindir=/usr/local/sbin --datadir=/usr/local/etc/squid --libexecdir=/usr/local/libexec/squid --localstatedir=/var/squid --sysconfdir=/usr/local/etc/squid --with-logdir=/var/log/squid --with-pidfile=/var/run/squid/squid.pid --enable-auth --enable-loadable-modules --enable-removal-policies="lru heap" --disable-epoll --disable-linux-netfilter --disable-linux-tproxy --disable-translation --enable-auth-basic="DB MSNT MSNT-multi-domain NCSA PAM POP3 RADIUS fake getpwnam" --enable-auth-digest="file" --enable-external-acl-helpers="file_userip unix_group" --enable-auth-negotiate=none --enable-storeio="diskd rock ufs aufs" --enable-disk-io="AIO Blocking DiskDaemon IpcIo Mmapped DiskThreads" --enable-log-daemon-helpers=file --enable-url-rewrite-helpers --disable-ipv6 --enable-ssl --enable-ssl-crtd --enable-htcp --enable-forw-via-db --with-large-files --enable-large-cache-files --disable-cache-digests --disable-wccp --disable-wccpv2 --disable-eui --disable-ipfw-transparent --enable-pf-transparent --disable-ipf-transparent --disable-follow-x-forwarded-for --enable-ecap --enable-icap-client --disable-esi --disable-kqueue --prefix=/usr/local --mandir=/usr/local/man --infodir=/usr/local/info --with-openssl=/usr --with-pthreads
# make && make install
# ldd `which squid`| grep -E "ssl|crypt"
libssl.so.8 => /usr/local/lib/libssl.so.8 (0x8010a8000)
libcrypto.so.8 => /usr/local/lib/libcrypto.so.8 (0x801dc6000)
libcrypt.so.5 => /lib/libcrypt.so.5 (0x80261a000)
libcrypto.so.6 => /lib/libcrypto.so.6 (0x8034d6000)
As mentioned, my FreeBSD system is running openssl 1.0.1e and squid is linked to it's libraries.
Step 2. Squid transparent proxy configuration for http on port 3128 and HTTPS on port 3129
acl snmppublic snmp_community public
acl allowed_nets src 192.168.2.0/24
acl SSL_ports port 443
acl Safe_ports port 80 # http
acl Safe_ports port 1935 # http
acl Safe_ports port 21 # ftp
acl Safe_ports port 443 # https
acl Safe_ports port 70 # gopher
acl Safe_ports port 210 # wais
acl Safe_ports port 1025-65535 # unregistered ports
acl Safe_ports port 280 # http-mgmt
acl Safe_ports port 488 # gss-http
acl Safe_ports port 591 # filemaker
acl Safe_ports port 777 # multiling http
acl CONNECT method CONNECT
http_access allow allowed_nets
http_access deny !Safe_ports
http_access deny CONNECT !SSL_ports
http_access allow localhost
htcp_access deny all
miss_access allow all
http_port 3127 ssl-bump generate-host-certificates=on dynamic_cert_mem_cache_size=4MB options=ALL cert=/usr/local/etc/squid/ssl/myCA.pem
http_port 3128 intercept
https_port 3129 intercept ssl-bump cert=/usr/local/etc/squid/ssl/myCA.pem generate-host-certificates=on dynamic_cert_mem_cache_size=4MB cipher=ECDHE-RSA-AES128-SHA256:AES128-GCM-SHA256:RC4:HIGH:!MD5:!aNULL:!EDH options=CIPHER_SERVER_PREFERENCE,SINGLE_DH_USE dhparams=/usr/local/etc/squid/ssl/dhparams.pem
always_direct allow all
ssl_bump server-first all
sslproxy_cert_error deny all
sslcrtd_program /usr/local/libexec/squid/ssl_crtd -s /var/squid/lib/ssl_db -M 4MB
I'm using NSS labs trusted CAs (FreeBSD port ca_root_nss-3.14.3), but you can use whatever bundle you trust.
Before starting squid, the ssl_db directory needs to be initiated:
# mkdir /var/squid/lib
# /usr/local/libexec/squid/ssl_crtd -s /var/squid/lib/ssl_db -c
Initialization SSL db...
# chown -R squid:squid /var/db/squid
!!!!Very important to set the correct owner on this directory
/usr/local/etc/squid/ssl/myCA.pem file is a self signed CA bundle containing CA key and CA public file. This bundle will be used by squid to sign dynamic certificates (generate-host-certificates=on) for all SSL domains it will intercept.
The CA certificate needs to be imported in all the browsers in the network to avoid security warnings.