[squid-users] OpenBSD and pf - Transparent proxy

From: Chris Benesch <[email protected]>
Date: Mon, 28 Apr 2008 06:21:36 -0700

This is how to set up a transparent proxy with OpenBSD, pf, and Squid.

A transparent proxy is a proxy that intercepts all connections out of a
network on port 80. The reason that I wanted to have a transparent proxy is
because I wanted to cache all IPv4 traffic and allow IPv6 traffic to flow
unimpeded. I have the OpenBSD box running a NAT with the cable company,
serving a web site, and acting as a router for an IPv6 tunnel and my own /64
I was assigned by my tunnel broker.

I am using squid-2.6STABLE19 and OpenBSD 4.1, MP kernel.

<root:openbsd> [/root]
> uname -a
OpenBSD maricopacomputer.com 4.1 GENERIC.MP#1225 i386

First, compile and install Squid. I used the following options ./configure
--prefix=/var/squid --with-pthreads --enable-pf-transparent obviously
prefix is entirely up to the users choice.

Then inside squid.conf, all of the options are pretty much boilerplate
except for the following:

acl our_networks src 192.168.231.0/24 >>127.0.0.1<< http_access allow
our_networks

You must add 127.0.0.1 to your acl.

# Squid normally listens to port 3128
http_port 192.168.231.1:3128 transparent
>>http_port 127.0.0.1:3128 transparent<<

I had to have it listen on two ip addresses, one of which being localhost.
Also note the transparent keyword at the end.

Then in pf.conf, the following changes need to be made.

In the top portion where you set skip on your internal interfaces, remove
those lines. Those lines tell the pf filter not to do any processing on
packets coming in on an internal interface.
#set skip on $int_if << These lines commented out
#set skip on $wi_if

# redirect only IPv4 web traffic to squid
rdr pass inet proto tcp from 192.168.231.0/24 to any port 80 -> 127.0.0.1
port 3128

block in
pass in quick on $int_if
pass in quick on $wi_if
pass out keep state

Some pointers:

1 . Use "rdr pass" instead of "rdr on ..." part of the way that pf
evaluates packets, it would drop through and be allowed as is instead of
redirected if you don't use "rdr pass"
2 . Make sure and add the pass in quick lines. Myself I have two internal
interfaces, one for wired and one for wireless internet. Although there is
a bridge configured, strange things happen sometimes when you don't
explicitly allow all traffic on both interfaces. If you don't add these
lines, you will lose local network connectivity and have to go to the
console to figure it out.
3 . If it seems to be ignoring your changes and no redirection is happening,
make sure you removed the set skip on ... lines.
4 . To test if it worked, use the nc utility. From the command line type in
(as root) nc -l 3128 (with squid stopped of course) and then try to navigate
to a page with it running. You should see an output like this:

<root:openbsd> [/root]
> nc -l 3128
GET /mail/?ui=pb HTTP/1.1
User-Agent: Mozilla/5.0 (compatible; GNotify 1.0.25.0)
Host: mail.google.com
Connection: Keep-Alive
Cache-Control: no-cache
Cookie: GV=XXXXXXXX...You get the picture

From there on out, just set your browsers up normally with no proxy server,
and you should see the cache fill up and your browsing speed up.
Received on Mon Apr 28 2008 - 13:21:44 MDT

This archive was generated by hypermail 2.2.0 : Thu May 01 2008 - 12:00:04 MDT