Squid http(s) transparent proxy with Juniper SRX | part 2
How to intercept HTTP/HTTPS connections with Juniper SRX, FreeBSD and Squid -part 2
Network diagram:

Part 2 of this tutorial focuses on preparing the FreeBSD Squid/PF box for intercepting HTTP/HTTPS connections.
As mentioned in part 1 of this tutorial (
http://forum.ivorde.ro/how-to-intercept ... 14111.html), starting with Squid version 3.2, packets arriving to SQUID port need to be destination NATed, but the difference is that squid needs to look at the nat table to see original destination IP address of each HTTP request.
This is done in order for Squid to check the destination domain IP address (from DNS records) of the request against the original destination IP (taken from the NAT table).
Since Squid cannot look at NAT table of the SRX or whatever networking device is used as in my above diagram, traffic needs to be "detoured" to PF/Squid box by the SRX. How it's done, it will be described in part 3 of this tutorial (coming soon).
Let's focus on PF firewall part.
As a side note, before I begin: squid needs the "intercept" keyword on the ports that will expect HTTP requests (GET /index.html) and not proxy requests (CONNECT
http://www.site.com/index.html).
IP address of the PF/Squid FreeBSD box, as seen in the diagram is 10.1.20.2. All I know for now is that packets will be "detoured" by the SRX so all HTTP/HTTPS request reaching em0 interface will have source address from the "trust" security zone (192.168.2.x) and destination IP addresses from the "untrust"/Internet security zones. Example: from 192.168.2.67 -> 91.195.7.1:80.
Here are my PF rules to destination NAT this traffic:
Code:
# cat /etc/pf.conf
if0="em0"
if0_ip0="10.1.20.2"
rdr pass inet proto tcp from 192.168.2.0/24 to any port 80 -> 10.1.20.2 port 3128
rdr pass inet proto tcp from 192.168.2.0/24 to any port 443 -> 10.1.20.2 port 3129
pass in quick on $if0
pass out keep state
Below is an entry from the PF session state ( showing NAT) that squid will use to check original destination IP against the IP of the destination domain:
Code:
# pfctl -s state | grep 192.168.2.67
...
all tcp 10.1.20.2:3128 (91.195.7.1:80) <- 192.168.2.67:2566 ESTABLISHED:ESTABLISHED
This means that packet IP header from trust to SRX is: 192.168.2.67:2566->91.195.7.1:80
Packet IP header from SRX to PF is: 192.168.2.67:2566->91.195.7.1:80
Packet IP header from PF to Squid is: 192.168.2.67:2566->10.1.20.2:3128.
Important notes:Squid needs read permissions to /dev/pf device in order to perform this check. Otherwise, it will fail ( I think it can be disabled with "host_verify_strict" -
http://www.squid-cache.org/Doc/config/h ... fy_strict/), but it's not the purpose of this article. If it hasn't read permissions, you will see following errors in squid logs:
Code:
2013/05/07 15:34:08 kid1| PF open failed: (13) Permission denied
To allow squid read permissions to "/dev/pf" device, use chmod:
Code:
# chown root:squid /dev/pf
# chmod 0640 /dev/pf
And to make these permanent, devfs conf file (/etc/devfs.conf )has to have following two lines:
Code:
own pf root:squid
perm pf 0640