[lug] Transparent proxy on localhost

Michael Hirsch mdhirsch at gmail.com
Wed Aug 22 22:36:23 MDT 2007


On 8/22/07, Zan Lynx <zlynx at acm.org> wrote:
> On Tue, 2007-08-21 at 22:48 -0600, Michael Hirsch wrote:
> > On 8/21/07, Zan Lynx <zlynx at acm.org> wrote:
> > > On Mon, 2007-08-20 at 22:31 -0600, Michael Hirsch wrote:
> > > > I'm trying to set up a transparent proxy on localhost.  (I'm trying to
> > > > filter my kids' web browsing.)  I have the proxy all setup and
> > > > working, but I can't figure out how to get it to happen transparently.
> > > >  Here's what I've tried:
> > > [snip]
> > > > iptables -t nat -i lo -A PREROUTING -p tcp --dport 80 -j LOG
> > > > iptables -t nat -i lo -A PREROUTING -p tcp --dport 80 -j REDIRECT
> > > > --to-ports 8080
> > > >
> > > > but there's no change in behavior.  The web connection is unfiltered.
> > > >
> > > > What am I doing wrong?
> > >
> > > Try the nat OUTPUT chain instead.  Connections from the local machine
> > > are handled specially in both the nat and filter tables.
> >
> > The OUTPUT chain does have an effect.  I can see the proxy being
> > contacted, but it never returns the web page.
> >
> > I don't see how you can avoid an infinite regression:
> > 1. The browser tries to reach port 80 on google.com
> > 2. iptables redirects to the filter.
> > 3. the filter tries to reach port 80,
> > 4. goto 2.
> >
> > Is there a trick to make iptables not redirect when coming from the
> > filter, but to do so for the client?  I don't see how this scheme
> > could ever work.
>
> I believe you can filter by user ID on local packets.  You can use that
> to bypass the rule for port 80 packets from root, or whatever UID the
> proxy runs as.

Thanks, Zan.  That clued me in.  It's funny, I thought you could do
that too, but until you mentioned it I didn't see it in the
documentation.  With you backing me up I found it immediately.  :-)

In case anyone cares, here's how I set up a box to be it's own
transparent proxy.

First, setup dansguardian and tiny proxy specified in
http://www.linuxjournal.com/node/9044, except that I also configured
tinyproxy to run as the "dansguardian" user.  It' runs as "nobody" by
default and I couldn't seem to filter on that.

Make tiny proxy and dansguardian run at boot.

Add these lines to your rc.local:
----start rc.local----
modprobe iptable_nat
echo 1 > /proc/sys/net/ipv4/ip_forward

iptables -F
iptables -X
iptables -t nat -F
iptables -t nat -X

#let dansguardian and tinyproxy talk to the world
iptables -t nat -A OUTPUT -p tcp --dport 80 -m owner --uid-owner
dansguardian -j ACCEPT

# make everyone else go through dansguardian
iptables -t nat -A OUTPUT -p tcp --dport 80 -j REDIRECT --to-ports 8080
----end rc.local----

Of course, this only works for servers on port 80, so there are pretty
simple workarounds, but I expect this will suffice for a few years.

Thanks again for the help, Zan.

Michael



More information about the LUG mailing list