If you are used to doing http inline caching or filtering with Squid2 on a different machine to your router and previously used DNAT in iptables then you are in for a shock when you try to move your stuff to Squid3!
See the first comment below this article for further information on the changes made. I appear to have assumed wrong, read wrong or misinterpreted information about the cause of the errors.
Squid3 changes the interception mode to MASQUERADE as the source IP that NATTED the request in the first place. This means instead of squid going “oh, a request” and processing it and then sending the GET request to the website from the IP of the squid box… squid tries to set the source IP of the GET request to the IP of the machine that made the request. (Basically spoofing the IP). However if you just fire up squid in the configuration you expect then you get errors similar to this in the cache.log:
2015/10/19 19:24:12| NF getsockopt(SO_ORIGINAL_DST) failed on local=10.10.10.141:3128 remote=10.10.10.1:53238 FD 6 flags=33: (92) Protocol not available This is because squid doesn’t have the ability to set the from IP.
This issue is simply solved by allowing Masquerade on the squid machine:
iptables -t nat -A POSTROUTING -o eth0 -j MASQUERADE This then triggers another problem.. the IPTables rule on the router then can’t tell that the request is from the Squid box and just routes the request back to squid. Squid then rejects the requests with:
WARNING: Forwarding loop detected for: (and then prints the request) Which is a pretty annoying pain in the ass.
It seems that due to a security flaw they changed the way NAT is handled in Squid3.
Further reading here: https://squidproxy.wordpress.com/2014/12/19/squid-3-2-mythbusting-nat/
The squid documentation has very complicated instructions on how you are supposed to get around this..
For some reason I didn’t have much luck with it. I think the documentation is lacking on what each step actually does or means.
I then came across the following helpful post on Reddit:
But before I could read and digest it.. a friend also came across the following stackexchange post which is even simpler!
I’m reposting the commands I used here in case the above url goes down!
On your router (in my example 10.10.10.141 is my squid box):
#!/bin/bash iptables -t mangle -A PREROUTING -j ACCEPT -p tcp --dport 80 -s 10.10.10.141 iptables -t mangle -A PREROUTING -j MARK --set-mark 8 -p tcp --dport 80 ip rule add fwmark 8 table 2 ip route add default via 10.10.10.141 dev ETH00 table 2
You then need the following on the squid box:
iptables -A PREROUTING -t nat -i eth0 -p tcp --dport 80 -j REDIRECT --to-port 3128
The squid config needs to have http_port set to “intercept” like so:
http_port 3128 intercept
Remember you also need a line without an intercept for Squid to function:
Otherwise you get this error in cache.log:
“ERROR: No forward-proxy ports configured.”