0

I've re-edited the original question, because I have changed the setup since the original answer, which was for NAT based setup. NAT is no longer being used and has been replaced with TPROXY for IPv6 compatibility.

I'm running squid in a small network. I've setup a couple of squid listening ports for different scenarios.

Excerpt of squid.conf

  • http_port 3128 - This is will be pushed to Windows clients via domain policy, with the HTTP Proxy set via WPAD.
  • http_port 3129 tproxy - This is for clients that are having traffic on port 80 intercepted.

For the TPROXY setup I'm using the following iptables/ip6tables rules on my DD-WRT router with iproute2 to mark and redirect traffic to the proxy. The problem is in this setup all traffic is tagged, including IPv4 and IPv6 traffic that is going to the Squid proxy via the 3128 port setup.

I need a way to exclude this traffic because it is is adding overhead and breaking connectivity (particularly IPv6) on LAN clients that have the proxy applied directly.

I'm aware I could add specific clients to the PREROUTING table with an ACCEPT rule, but doing this for both IPv4 and IPv6 will become hard to manage quickly. I need to find a generic way to exclude all LAN clients that go through the Squid Proxy on port 3128 at router level but I don't know the best way to do it.

Current DD-WRT Squid policy routing:

# Squid transparent proxy
PROXY_IPV4=192.168.x.x
PROXY_IPV6=2001:470:xxxx:xx::x
CLIENTIFACE=br0
FWMARK=3

iptables -t mangle -A PREROUTING -i $CLIENTIFACE -s $PROXY_IPV4 -p tcp --dport 80 -j ACCEPT
ip6tables -t mangle -A PREROUTING -i $CLIENTIFACE -s $PROXY_IPV6 -p tcp --dport 80 -j ACCEPT

iptables -t mangle -A PREROUTING -i $CLIENTIFACE -p tcp --dport 80 -j MARK --set-mark $FWMARK
iptables -t mangle -A PREROUTING -m mark --mark $FWMARK -j ACCEPT
ip6tables -t mangle -A PREROUTING -i $CLIENTIFACE -p tcp --dport 80 -j MARK --set-mark $FWMARK
ip6tables -t mangle -A PREROUTING -m mark --mark $FWMARK -j ACCEPT

iptables -t filter -A FORWARD -i $CLIENTIFACE -o $CLIENTIFACE -p tcp --dport 80 -j ACCEPT
ip6tables -t filter -A FORWARD -i $CLIENTIFACE -o $CLIENTIFACE -p tcp --dport 80 -j ACCEPT

ip rule add fwmark $FWMARK table 2
ip -6 rule add fwmark $FWMARK table 2
ip route add default via $PROXY_IPV4 table 2
ip -6 route add default via $PROXY_IPV6 table 2

# End Squid intercept proxy config
James White
  • 674
  • 3
  • 18
  • 32
  • Firstly, traffic that clients explicitly send to the proxy on port 3128 won't be marked, as you're selecting on port 80 in the marking rules; so those shouldn't be affected. Secondly, does it work, using the proxy as the default route? I think you should probably be DNATing that traffic to the proxy IP instead of routing it there; unless you have a PREROUTING nat table rule on the proxy itself to redirect all port 80 traffic to itself. – wurtel Oct 12 '15 at 08:02
  • On the Squid box side I have the following rules: http://wiki.squid-cache.org/Features/Tproxy4#iptables_on_a_Router_device. Both in iptables and ip6tables. The traffic the DD-WRT router is pushing to the squid box is then handled accordingly. IPv6 connectivity was broken until I added the following on the router `iptables -t mangle -I PREROUTING -p tcp --dport 80 -s 192.168.xx.xx -j ACCEPT` `ip6tables -t mangle -I PREROUTING -p tcp --dport 80 -s 2001:470:xxxx:xx::x` These are the configured outgoing IP addresses Squid uses. LAN clients IPv6 is now fixed. TPROXY IPv6 is broken still. – James White Oct 12 '15 at 08:46
  • Sorry, I have no experience with TPROXY; the rest of the config looks OK – wurtel Oct 12 '15 at 12:55
  • No worries. It is working with the exception of the IPv6 clients that use the TPROXY port. – James White Oct 12 '15 at 17:02

1 Answers1

1

Add an iptables rule to ACCEPT traffic on port 80 from the squid server. After that rule you can have the DNAT rules.

As soon as a rule matches the chain isn't followed anymore so the ACCEPT will short-circuit the DNAT for traffic from squid.

EDIT: The DNAT rule already excludes the $PROXY_IP so adding an extra rule shouldn't be necessary. I personally prefer to add an explicit rule to ACCEPT traffic from the proxy so that any further rules won't affect that traffic.

For those clients that obey the proxy rules to use the proxy explicitly on port 3128, that traffic won't go via the router as the clients can access the proxy directly; at least I'm hoping that the proxy and the clients are in the same subnet? If for some reason the proxy and the clients are on different subnets but on the same physical LAN network, then the router should send ICMP redirects to the client when traffic destined for the proxy from a client arrives at the router.

wurtel
  • 3,864
  • 12
  • 15
  • So place an additional iptables rule on my DD-WRT router before DNAT to allow port 80 from $PROXY_IP? – James White Jul 16 '15 at 07:36
  • Hmm, now I look at your rules in more detail I see you already exclude `$PROXY_IP` in the `DNAT` rule. I prefer to explicitly `ACCEPT` traffic from that address so that any further rules won't be checked, but in this situation your solution should work as well. I'll edit my answer to address your main concern. – wurtel Jul 16 '15 at 07:43
  • Yes, all clients are within 192.168.1.0/24. To confirm, the ACCEPT rule is still being applied at the router level? – James White Jul 16 '15 at 07:53
  • Yes, `iptables -t nat -A PREROUTING -i br0 -s "$PROXY_IP" -p tcp --dport 80 -j ACCEPT` as first rule in the list you show in your question. – wurtel Jul 16 '15 at 07:58
  • Thanks this appears to be working. I checked the access.log of Squid and saw the GET requests are coming from the actual IP of the LAN client, rather than the router when using 3128. – James White Jul 16 '15 at 08:13
  • I've edited the original question with 100 bounty reward, could you provide a fix that works with the updated setup mentioned? – James White Oct 10 '15 at 06:53