Monday, April 14, 2008

Transparent Proxying with Shorewall, SQUID and Privoxy on Ubuntu

note: This article is intended for a technical audience -- and while it seems to works for the two systems i've tried it on since, you should use caution when modifying a production system -- caveat emptor.

A 'remember these for later brain' post, mainly because I always forget the order when I haven't done it for a while.

note:, you can do this with any distribution -- Ubuntu Server works and I use that, but you can substitute the names of your distributions packages instead and still get much the same result.

First, having installed Ubuntu Server, you'll need the universe repository, as privoxy isn't officially blessed by the Ubuntu maintainers.

Next, you'll need to install the various packages you'll need to make this fly -- as root, run:

apt-get install squid privoxy shorewall

After that's done, you'll want to make SQUID work first -- using Ubuntu 8.04, this entails opening the default SQUID configuration at /etc/squid/squid.conf and:

  1. Adding transparent to the port configuration by changing:

    --- http_port 3128
    +++ http_port 8080 transparent

  2. Adding your {W/L}AN block to the ACL list by adding:

    +++ ACL local_network src

    ... and enabling it in the http_access list by adding:

    +++ http_access allow local_network

Save the configuration and exit the editor.

Now restart SQUID with: /etc/init.d/squid restart to have your changes take effect.

At this point, configure a browser to use a manual proxy on the server's IP address on port 8080 and make sure it actually works, if you receive an error that talks about Access Control Lists, check that you added the right network mask to the SQUID local_network line you added above.

If that works, we can move on to the Privoxy part of things. Privoxy, for those who are unaware is one of the best 'web-crud(tm)' filters i've ever had the pleasure of using, it was originally built from the Internet Junkbuster (IJB) but has now got many more features, is stable on pretty much any platform for a wide-variety of users and protects your privacy too.

By far, the easiest way to configure Privoxy is via the web-interface, but the Ubuntu package disables that by default, so before we hook it up to SQUID, we should enable that.

Open the /etc/privoxy/config file and make the following changes:

  1. Enable editing of actions via the web interface by changing:

    --- enable-edit-actions 0
    +++ enable-edit-actions 1

Save the configuration and exit the editor.

Now restart Privoxy with: /etc/init.d/privoxy restart to have your changes take effect.

Now, we need to hook Privoxy up to our proxy as the default parent cache -- you'll need to open the SQUID configuration file again and make the following adjustments:

note: If you haven't done so already, it's a good idea at this point to make a backup copy of your /etc/squid/squid.conf file before making these changes.

  1. Adding Privoxy as a cache peer by changing:

    +++ cache_peer parent 8118 0 no-query no-delay no-digest no-netdb-exchange

    note: because Privoxy cannot influence any of SQUID's cache settings, setting no-query no-delay no-digest no-netdb-exchange as options for the peer cache lessens the delay between Privoxy filtering the transaction and SQUID caching it of up to a second on slower hardware (for example, a Pentium 4 1.2Ghz machine with 1GB of memory).

  2. Telling SQUID to always send traffic from the firewall directly to the internet by changing:

    +++ always_direct allow localhost

  3. Telling SQUID to never send traffic from the local LAN (thereby forcing users to use the Privoxy/SQUID cache) directly to the internet by changing:

    +++ never_direct allow local_network

Save the configuration and exit the editor.

Now restart SQUID with: /etc/init.d/squid restart to have your changes take effect.

Finally we need to add the rules for transparently using our proxy to our Shorewall Firewall Configuration -- you'll need to open the Shorewall rules configuration file and make the following alteration:

note: For the purposes of simplicity, i'm assuming that your WAN interface is eth0, your LAN interface is eth1, your LAN IP range is and your Shorewall configuration is already complete (for some reason I still don't fully understand, the Debian and Ubuntu packages don't ship with a default configuration file, so if you don't see a /etc/shorewall/rules file, you'll need to download one, or grab a prefabricated copy from the /usr/share/doc/shorewall directory and set it up first.

  1. Adding a redirection to our transparent proxy by changing:

    +++ REDIRECT     loc     8080     tcp     www     -
    +++ ACCEPT     $FW     net     tcp     www

note: the minus (-) with the trailing space at the end of the redirect line is important, it means it will ignore the source port when working out the request and force any already established request to continue to use the proxy.

Save the configuration and exit the editor.

Now restart the Shorewall Firewall with: /etc/init.d/shorewall restart -- fire up a browser, make sure it is not configured to use a proxy (ie. it uses a direct connection to the internet) and browse to your hearts content.