Squid transparent proxy masquerading as Client IPs

Abu Khaled khaled.abu at gmail.com
Thu Jun 9 01:51:41 GMT 2005


Some ISPs use Linux with tproxy kernel patch to masquerade the
requests from clients and make them appear as if they came from the
client with no proxy connection. After digging around the squid-cache
archives and mailing lists, Henrik Nordstrom suggested using
tcp_outgoing_address and nat to achieve the same on FreeBSD and Squid
in transparent (intercepting mode).

The Idea is to assign for each Client a private IP on the Squid Server
(as aliases worked fine). In squid.conf we add

header_access Via deny all
header_access X-Forwarded-For deny all
# this removes both headers

# and for each client we need
acl clientxxx src <real ip> 
tcp_outgoing_address <private ip> clientxxx

Squid binds requests from clientxxx's <real ip> to the <private ip>
then we nat those to the <real ip> making the request appear as if it
came directly from the client not the proxy.

To make things easy I used two scripts.
 
1. I added the add-alias.sh script to /etc/rc.local to create the
aliases on startup

# < add-alias.sh > start
IP=110
MAXIP=150
PRIV=10.10.10
ALIASIF=<Ethernet Interface>
# I used lo0 to do the aliases on
# Also I tested a virtual interface (netgraph)
# Just to make sure no conflicts with transparent proxy rules (loops)
while [ $IP -le $MAXIP ]
do
        if !( ifconfig $ALIASIF inet $PRIV.$IP netmask 0xffffffff alias ) then
                echo Error Creating Alias $PRIV.$IP on $ALIASIF
                exit
        fi
IP=$(( $IP + 1 ))
done
# < add-alias.sh > end

2. The squid-ipnat.sh script deletes the old ipnat.conf file and
creates a new one with rules for the external interface. It also
creates 2 files with ACLs for squid I used it once to create the
ipnat.conf file and keep it just in case I need to change the IPs
(real/private). And the 2 files with ACLs for squid were used to copy
and paste the ACLs to squid.conf. Oh ya backup you configuration files
just in case.

# < squid-ipnat.sh > start
IP=110
MAXIP=150
PRIV=10.10.10
REAL=xxx.xxx.xxx
EXTIF=<External Interface>
# I used the external interface for nat 
cd <path to ipnat>
rm ipnat.conf          # carefull deletes old ipnat.conf file
rm squid_acl.conf
rm squid_tcp.conf
while [ $IP -le $MAXIP ]
do
     echo "bimap $EXTIF from $PRIV.$IP/32 to 0.0.0.0/0 port = 80 ->
$REAL.$IP/32" >> ipnat.conf
     echo "acl Client$IP src $REAL.$IP" >> squid_acl.conf
     echo "tcp_outgoing_address $PRIV.$IP Client$IP" >> squid_tcp.conf
# Client$IP is the name for the ACL expands from Client110 to Client150
# squid_acl.conf and squid_tcp.conf end in <path to ipnat> copy and
paste to squid.conf both
IP=$(( $IP + 1 ))
done
# < squid-ipnat.sh > end

As you can see, I used IPNAT's bimap and tested the configuration for
40+ clients.
My network is small and I wonder if someone can use this to test a
larger network. Also test PF or IPFW/DIVERT/NAT and see what performs
better or just for fun.

One last note the tcp_outgoing_address does not follow the
X-Forwarded-For patch and it caused me to lose my head since I had
Dansguardian in front of Squid. The Delay pools followed-X fine and
that caused me to think there was a problem with my configuration.
After Disabling Dansguardian the configuration worked as expected. So
do not wonder if it does not work if you use another proxy before
squid.

-- 
Kind regards
Abu Khaled


More information about the freebsd-isp mailing list