Using Squid and Juniper PBR as a transparent proxy

Organisations can use proxy servers for various reasons; to restrict access to certain content, to cache web pages and reduce internet traffic – whatever the reason various approaches can be used:

  • Explicitly specify a proxy server in applications such as Internet Explorer
  • Use Proxy auto-config
  • Transparently force HTTP traffic through a proxy server

This blog post will focus on the last option, transparently routing traffic through a proxy server. There are some disadvantages to this approach:

  • Authentication can’t be performed on a per-user basis as the web browser is unaware that traffic is bring sent through a proxy server
  • Without having client computers trust a custom CA and performing a man-in-the-middle attack on all HTTPS traffic, SSL/TLS traffic can’t be sent through the proxy

Once implemented, this will look something like the following:

Squid Policy Based Routing

The below steps assume you already have a Debian/Ubuntu server installed with a single interface. A Juniper ScreenOS based router will be used to setup policy based routing (PBR). The example in this blog post uses the following network addresses:

Corporate network: /24
Corporate network gateway:
Trust (Internal) interface on firewall: ethernet0/0
Untrust (External) interface on firewall: ethernet0/2
Proxy server address:

Squid 3 installation and configuration

The latest version of Squid 3 (at the time of writing) is capable of acting as a transparent proxy server. To install on either Debian or Ubuntu execute the following command as root:

# aptitude install squid3

Once installed, as single word change is needed to the default configuration file. Add the keyword “transparent” to /etc/squid3/squid.conf:

http_port 3128 transparent

Configure IPTables

We’ll be using the ScreenOS device to forward traffic to our Linux server and need to use iptables to accept that traffic and pass it to Squid. To achieve that we can use a rule in the PREROUTING chain:

iptables -t nat -A PREROUTING -i eth0 -p tcp --dport 80 -j REDIRECT --to-port 3128

Don’t forget to save your updated firewall rules (iptables-save > /etc/iptables.rules). To ensure these rules are loaded at startup add the following line to /etc/network/interfaces

# The primary network interface
auto eth0
iface eth0 inet static
pre-up iptables-restore < /etc/iptables.rules

Juniper Netscreen configuration

Policy Based Routing (PBR) will be used to re-route traffic destined for the internet to our internal Squid proxy server. To make use of this functionality you must be running ScreenOS 5.4 or later.

In our scenario we want to route outbound HTTP traffic from our corporate LAN to an internal server.

Extended ACLs

Extended ACLs match traffic based on IP addresses and Ports. Each ACL can contain multiple entries for different ports or addresses. The below commands create an ACL match outbound HTTP traffic from the corporate network.

set access-list extended 10 src-ip dst-port 80-80 protocol tcp entry 10

We also need to create an ACL so that our proxy server traffic doesn’t get routed back to itself.

set access-list extended 20 src-ip dst-port 80-80 protocol tcp entry 20

Match Groups

A match group is a collection of one or more Extended ACL’s, with a human-readable name. Create a match group named “Proxy” with an ID of 10 containing our extended ACL.

set match-group name Proxy
set match-group Proxy ext-acl 10 match-entry 10

We need to create another match group so that we can exclude systems from being routed through the proxy.

set match-group name DirectHTTP
set match-group DirectHTTP ext-acl 20 match-entry 20

Action Groups

Action groups are a set of instructions for what some traffic should do next. When multiple actions are available the first is always used. Create an action group which routes traffic to the proxy server on our internal network.

set action-group name Proxy
set action-group Proxy next-interface ethernet0/0 next-hop action-entry 10

We now need to create another action group that routes traffic as it would do normally:

set action-group name DirectHTTP
set action-group DirectHTTP next-interface ethernet0/2 action-entry 10


A policy combines what we’ve created so far. When no policy is matched the normal routing tables are used. Create a new policy named “Proxy” with two entries. The first policy is used for direct traffic that should bypass the proxy, the second routes traffic through the proxy.

set pbr policy name Proxy
set pbr policy Proxy match-group DirectHTTP action-group DirectHTTP 10
set pbr policy Proxy match-group Proxy action-group Proxy 20

The final step is to apply the policy so that it takes effect, apply the policy to the “Trust” interface.

set interface ethernet0/0 pbr Proxy

And there you have it, your outbound HTTP traffic is now being silently routed through a proxy server.

Published by

Dave Hope

Dave works in IT for a leading UK based retirement developer, in his spare time he enjoys tinkering with technology and rock climbing.

4 thoughts on “Using Squid and Juniper PBR as a transparent proxy”

  1. Hi,
    Interesting read!
    Could I use this method also to redirect TCP80/443 to the Symantec Web Filter service in the cloud (internet)? This is in fact the service of Messagelabs, bought by Symantec a few years ago. They use in fact a modified squid.
    Traffic should be redirected to TCP 3128

Leave a Reply

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

This site uses Akismet to reduce spam. Learn how your comment data is processed.