How to set up a transparent proxy on Linux

A transparent proxy sits between clients and the Internet, acting as a gateway for the clients. It's called transparent because clients are not required to configure anything for the proxy. A transparent proxy is useful when it's not possible or desirable to modify client configurations, ant yet it's still necessary to intercept client's requests.

If you need to set up a transparent proxy on Linux, one of the easiest ways is to use Squid, an open-source proxy server software. While Squid has rich feature sets as a general web-caching proxy server, I won't explore all those features here. Here is how you configure a transparent proxy using Squid.

To install Squid on Ubuntu or Debian:

$ sudo apt-get install squid

To install Squid on CentOS or RHEL:

$ sudo yum install squid

This will install Squid version 3 (squid3) on your system, and create a default Squid configuration file in /etc/squid3. Squid is set to start automatically upon boot. To configure Squid for transparent proxy, modify its configuration file, and restart it as follows.

$ sudo vi /etc/squid3/squid.conf
acl localhost src 100.100.100.0/24 ::1
http_port 3128 transparent
cache_peer 100.100.100.10 parent 8000 0 no-query default
cache_effective_user proxy
cache_effective_group proxy
$ sudo /etc/init.d/squid3 restart

The line starting with "acl" specifies the clients which are allowed to use the proxy. In this case, those whose IP address belongs to 100.100.100.0/24 are added to the proxy's white list. The line starting with "cache_peer" is optional, and needed only when your network is behind a corporate proxy or firewall. Essentially this line declares the corporate proxy (i.e., 100.100.100.10:8000) as a "parent" proxy to connect to in order to reach any external networks.

Next, you need to set up iptables rules so that any http traffic (e.g., destined to port 80) is routed through Squid. For that, you can run the following script called proxy.sh.

#!/bin/sh

# squid proxy's IP address (which is attached to eth0)
SQUID_SERVER=`ifconfig eth0 | sed -ne 's/.*inet addr:\([^ ]*\).*/\1/p'`

# interface connected to WAN
INTERNET="eth0"

# interface connected to LAN
LAN_IN="eth1"

# squid port
SQUID_PORT="3128"

# clean old firewall
iptables -F
iptables -X
iptables -t nat -F
iptables -t nat -X
iptables -t mangle -F
iptables -t mangle -X

# load iptables modules for NAT masquerade and IP conntrack
modprobe ip_conntrack
modprobe ip_conntrack_ftp

# define necessary redirection for incoming http traffic (e.g., 80)
iptables -t nat -A PREROUTING -i $LAN_IN -p tcp --dport 80 -j REDIRECT --to-port $SQUID_PORT

# forward locally generated http traffic to Squid
iptables -t nat -A OUTPUT -p tcp --dport 80 -m owner --uid-owner proxy -j ACCEPT
iptables -t nat -A OUTPUT -p tcp --dport 80 -j REDIRECT --to-ports $SQUID_PORT

# forward the rest of non-http traffic
iptables --table nat --append POSTROUTING --out-interface $INTERNET -j MASQUERADE
iptables --append FORWARD --in-interface $INTERNET -j ACCEPT

# enable IP forwarding for proxy
echo 1 > /proc/sys/net/ipv4/ip_forward

Once you have set up iptables rules using this script, you can save the current iptables rules permanently, so that you don't need to re-run the script.

Finally, those clients who wish to use the transparent proxy should specify the IP address of the transparent proxy as their default gateway.

Subscribe to Xmodulo

Do you want to receive Linux FAQs, detailed tutorials and tips published at Xmodulo? Enter your email address below, and we will deliver our Linux posts straight to your email box, for free. Delivery powered by Google Feedburner.

The following two tabs change content below.
Dan Nanni is the founder and also a regular contributor of Xmodulo.com. He is a Linux/FOSS enthusiast who loves to get his hands dirty with his Linux box. He likes to procrastinate when he is supposed to be busy and productive. When he is otherwise free, he likes to watch movies and shop for the coolest gadgets.
Your name can also be listed here. Write for us as a freelancer.

Leave a comment

Your email address will not be published. Required fields are marked *