Iptables – Bypass transparent Squid proxy on Tomato USB for specific sites

iptablessquidtomatotransparent-proxy

I'm using a router with Tomato USB to forward port 80 requests to a Ubuntu Server with Squid 3 in transparent mode.
Someone on the Tomato forum adapted these instructions for Tomato:

#!/bin/sh
INTERNAL_NETWORK="192.168.1.0/24"
ROUTER_IP="192.168.1.1"
PROXY_SERVER="192.168.1.3"
PROXY_PORT="3128"

/usr/sbin/iptables -t nat -A PREROUTING -i br0 -s $INTERNAL_NETWORK -d $INTERNAL_NETWORK -p tcp --dport 80 -j ACCEPT
/usr/sbin/iptables -t nat -A PREROUTING -i br0 -s ! $PROXY_SERVER -p tcp --dport 80 -j DNAT --to $PROXY_SERVER:$PROXY_PORT
/usr/sbin/iptables -t nat -A POSTROUTING -o br0 -s $INTERNAL_NETWORK -p tcp -d $PROXY_SERVER -j SNAT --to $ROUTER_IP
/usr/sbin/iptables -t filter -I FORWARD -s $INTERNAL_NETWORK -d $PROXY_SERVER -i br0 -o br0 -p tcp --dport $PROXY_PORT -j ACCEPT

Forwarding works as it should, the requests are processed by Squid. The instructions show the rule to bypass certain machines on the network. My problem is that I need to bypass some sites that have problems with proxies, not a specific machine. I tried adding this:

/usr/sbin/iptables -t nat -A PREROUTING -d caixa.gov.br -j ACCEPT

This rule doesn't work. I don't want caixa.gov.br (and a few others) to be forwarded to the proxy at all. But Tomato is still forwarding all sites.

Is it possible to add a rule for each site I don't want to forward?

Best Answer

iptables -A ... puts the rule at the end of a chain. Thus your one never matches (or at least with no effect) because the second (-s ! $PROXY_SERVER) already got those packets / connections.

Instead of iptables -A PREROUTING you need iptables -I PREROUTING 2. Or you create chains to make the structure easier to understand:

#!/bin/bash
INTERNAL_NETWORK="192.168.1.0/24"
ROUTER_IP="192.168.1.1"
PROXY_SERVER="192.168.1.3"
PROXY_PORT="3128"


if iptables -L prerouting_exceptions -n &>/dev/null; then
  iptables -t nat -F prerouting_exceptions
else
  iptables -t nat -N prerouting_exceptions
fi
# this prevents the same rule being inserted with each script call
if ! iptables -L FORWARD -n | grep -q proxy; then
  iptables -t filter -I FORWARD -s $INTERNAL_NETWORK -d $PROXY_SERVER -i br0 \
    -o br0 -p tcp --dport $PROXY_PORT -j ACCEPT -m comment --comment proxy
fi
iptables -t nat -F PREROUTING
iptables -t nat -A PREROUTING -j prerouting_exceptions
iptables -t nat -A PREROUTING -i br0 -s ! $PROXY_SERVER -p tcp \
  --dport 80 -j DNAT --to $PROXY_SERVER:$PROXY_PORT

iptables -t nat -A prerouting_exceptions -i br0 -s $INTERNAL_NETWORK \
  -d $INTERNAL_NETWORK -p tcp --dport 80 -j ACCEPT
iptables -t nat -A prerouting_exceptions -d caixa.gov.br -j ACCEPT