Implementing PBR and Squid3 as a transparent proxy
There are various methods of implementing URL filtering in an organisation, my preferred approach is to silently route traffic through a proxy server. This has a few distinct advantages:
- No end user configuration is required (via wpad.dat or Group Policy etc);
- If something breaks, it’s extremely simple to remove;
- Most people wouldn’t even know it was in place;
There are some downsides to this approach however:
- HTTPS traffic cannot be silently routed through the proxy server;
- NTLM authentication cannot be used
The best place to start is by setting up a Linux server. This can be physical or virtual, running whichever distribution you prefer (I’d go with Ubuntu, but the choice is yours). If linux isn’t your bag, the following Ubuntu install documentation will help.
This guide will use the following example configuration information:
Corporate network | 192.168.168.0 / 24 |
Corporate network gateway | 192.168.168.254 |
Trust (Internal) interface on firewall | ethernet0/0 |
Untrust (External) interface on firewall | ethernet0/2 |
Proxy server address | 192.168.168.253 |
Install and configure Squid
Once your Linux system is up and running, you’ll want to install the latest (stable) version of Squid. If you went with Ubuntu this couldn’t be easier:
# aptitude install squid3
We can accept a very basic configuration. The only change you need to make is to set the default squid port to be “transparent”. Change the following in /etc/squid3/squid.conf
http_port 3128 transparent
Configure iptables on the proxy server
We also need to configure the Linux kernel firewall (iptables) to forward any traffic routed to it on port 80 to the port used by our proxy server. This can be done as follows:
# iptables -t nat -A PREROUTING -i eth0 -p tcp --dport 80 -j REDIRECT --to-port 3128
Save our current iptables configuration using the iptables-save command:
# iptables-save > /etc/iptables.rules
We now need load the configuration whenever the network interface comes up, edit /etc/network/interfaces adding the following line to the relevant interface.
# The primary network interface
auto eth0
iface eth0 inet static
address 192.168.168.253
netmask 255.255.255.0
gateway 192.168.168.254
pre-up iptables-restore < /etc/iptables.rules
Finally, we’re onto the firewall configuration. This is going to vary depending on your device (Cisco PIX, Juniper Netscreen etc). My familiarity is with the ScreenOS product line so that’s what I’ll cover here.
Policy based routing (PBR) allows us to setup some pre-defined rules which determine how traffic is routed. In our scenario we want to route any outbound traffic from our corporate LAN destined for port 80 via a server on our network (or in a DMZ). The below instructions are for Juniper Netscreen firewalls running ScreenOS.
Extended ACLs
An extended ACL is the criteria for matching certain traffic; each ACL can contain multiple matching rules. You may wish to match all traffic on port 80 destined for a few subnets, in which case you’d create an Extended ACL with multiple entries.
Create an ACL matching traffic from the corporate network for outbound HTTP traffic:
set access-list extended 10 src-ip 192.168.168.0/24 dst-port 80-80 protocol tcp entry 10
We also need to create an ACL so that our proxy server trafffic doesn’t get routed back to itself:
set access-list extended 20 src-ip 192.168.168.253/32 dst-port 80-80 protocol tcp entry 20
Match Groups
A match groups 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
A group of one or more actions to perform, when multiple actions are available the first action is 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 192.168.168.253 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
Policy
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 ensures that non-proxy traffic gets routed normally, 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 exit
Policy Binding
The final step is to apply (or, ‘Bind’) the policy so that it takes effect. We have a few choices as to where we can bind the policy:
- A virtual router
- A zone
- An interface
We can apply multiple bindings, in which case the most specific binding takes effect. In our configuration we’ll bind the policy we’ve created to traffic passing out of our “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.
Hi,
thank you for this tutorial, i have a netscreen 5gt and a squid, found your HOWTO because wanted to make exactly this, redirect all http traffic to the internal squid. And it works now :). Thanks
needle
No problem, glad to have helped!
Please,
could you post your configuration for 5gt? i’m trying to use it on junipper and it’s not working (ssg5).
sincerely
Tiago,
Afraid not. How far are you getting? Do you get errors when trying to enable certain bits, or does traffic not flow after enabling PBR?
Dave
Occurs that everything remains the same. My traffic flows normally for machines that not have proxy “setted up”. For example I have a proxy that is setted up by “Active Directory Policy”, but for some users that connects out the “AD” i would like to block access to some internet pages.
I’m using Forefront TMG 2010 as proxy transparent and i want to create one route for all requests made to Juniper to pass first by this proxy.
Nothing changed.
sorry man… it was my fault…
in line:
set access-list extended 20 src-ip 192.168.168.253/32 dst-port 80-80 protocol tcp entry 20
i have inserted:
as 192.168.168.253/24
tipical newbie error!
The problem with HTTPS is it’s a secure transport, if it could be intercepted (and therefore read) it would not be secure and no transaction would be safe. Most squid based systems to the best of my knowledge will not be able to filter HTTPS.
But…..
If you want to restrict access to a site (I work in a school, where we have to filter out many sites) such as facebook, there is a little cheat.
In group policy I’ve set the HTTPS facebook page as an exception in the proxy settings in internet explorer. Basically when it a request for https facebook comes it tries to look locally for it and fails creating a time out.
It’s only worth doing if you need to block a few https sites.
If that works for you, then that’s great. What we do is allow all HTTPS traffic and then block specific https sites on our edge firewalls. Means that users have no easy way to bypass it.