# iptables + PREROUTING problem

## ajls

Hi

I am having some problems with iptables PREROUTING + Squid on linux-2.6.20.15 (with all the iptables stuff compiled in - I am *quite* confident that I have all the correct iptables support)

The directive: 

```

iptables -t nat -A OUTPUT -p tcp --dport 80 -j REDIRECT --to-port 3128

```

works fine, whereas the following directive does not do any REDIRECT'ing

```

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

```

I have been trying to solve this for a while now and have found no conclusive solution.  I am no

routing expert and am not sure if it is related to my machine's routes:

```

puffin ~ # route -n

Kernel IP routing table

Destination     Gateway         Genmask         Flags Metric Ref    Use Iface

194.145.148.XXX 0.0.0.0         255.255.255.255 UH    0      0        0 ppp0

192.168.0.0     0.0.0.0         255.255.255.0   U     0      0        0 eth0

127.0.0.0       0.0.0.0         255.0.0.0       U     0      0        0 lo

0.0.0.0         194.145.148.XXX 0.0.0.0         UG    0      0        0 ppp0

```

My firewall script is scarily simple (I have stripped the other gumph ).

```

#!/bin/bash

set -x

echo 1 > /proc/sys/net/ipv4/ip_forward

iptables --flush

iptables -t nat --flush

iptables -t mangle --flush

iptables --policy INPUT DROP

iptables --policy OUTPUT ACCEPT 

iptables -A INPUT -i lo -j ACCEPT

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

```

What is really peculiar is that the same script works on a "canned" ubuntu 

on eth0 (rather than ppp0).   I cannot determine whther my issue is routing

or possibly kernel -related.

Any help would be much appreciated.

----------

## massimo

You probably need to specify an interface (e.g. -i eth0).

----------

## ajls

Thanks for the pointer, but I have tried using the the "-i ppp0" option (and, in desperation "-i eth0" ). I revisited my ubuntu installation (at work) and it turns out that REDIRECT on the prerouting doesn't work either! (I had been using the LAN interface). I saw a posting on a list somewhere (I cannot seem to find it again) that there was subtle change to REDIRECT in kernel 2.6.1X and I think it was related in some way to ipv6.

All the transparent proxy HOWTOs suggests that my config should work.

Can anybody verify that REDIRECT works on the PREROUTING chain on the "same machine" ? If so, your iptables config may help me.

or

Could this be related to xtables ?  (I don't know too much about them)

Many TIA

----------

## nastasa_andrey

$IPTABLES -t nat -A PREROUTING -o ethX -p tcp --dport 80 -j REDIRECT --to-port 3128

where ethX is your external interface

----------

## ajls

Thanks again for the help, but using the "-o ppp0" flag results in

```

./squid-fw.sh 

iptables v1.3.5: Can't use -o with PREROUTING

Try `iptables -h' or 'iptables --help' for more information.

```

It is really weird that PREROUTING is just not getting picked up.   This documentation, somewhat outdated, suggests it should

http://www.netfilter.org/documentation/FAQ/netfilter-faq-3.html#ss3.13

Do you have this working ? I still think my probelm is routing related

----------

## Rob1n

I've had a quick look into this and testing suggests that REDIRECT works fine from remote systems but local packets do not pass through the PREROUTING chain.  Have you tested it from a remote system and do you require it to work locally?

----------

## nastasa_andrey

For me it worked with -o ethX and with a transparent proxy. It does not work if i remove -o ethX

----------

## frostschutz

Here is a nice graph of how packets traverse the iptables chains, it can really be a great help in understanding how iptables rules work:

http://www.docum.org/docum.org/kptd/

----------

## ajls

Thanks to all for your responses

Att: nastasa_andrey

hmmm, curious .. are you using iptables 1.3.5 ? with a *new* kernel ?

Att: Rob1n

I need both remote and local packets to be transparently proxied.

* remote (LAN) connections can be redirect using DNAT

* local requests seem to be bypassing the PREROUTING chain and is not being REDIRECTed 

Att: frostschutz

Thanks for the resource, looks interesting, under the UPDATES section:

"All connection tracking is handled in the PREROUTING chain, except locally generated packets which are handled in the OUTPUT chain ..."

seems to suggest that locally generated packets are only handled by the OUTPUT chain, which suggests that the issues i'm experiencing is consistent, BUT, it would suggest thatl the Transparent Proxy HOWTOs are no longer correct !   Is this assumption correct ?

----------

## Rob1n

 *nastasa_andrey wrote:*   

> For me it worked with -o ethX and with a transparent proxy. It does not work if i remove -o ethX

 

I'd love to know how it figures out what output interface will be used in the PREROUTING stage!  Are you absolutely certain this is where your rule is, and not in the OUTPUT stage?

----------

## Rob1n

 *ajls wrote:*   

> "All connection tracking is handled in the PREROUTING chain, except locally generated packets which are handled in the OUTPUT chain ..."
> 
> seems to suggest that locally generated packets are only handled by the OUTPUT chain, which suggests that the issues i'm experiencing is consistent

 

Indeed - it certainly matches my experience anyway.

 *Quote:*   

> , BUT, it would suggest thatl the Transparent Proxy HOWTOs are no longer correct !   Is this assumption correct ?

 

Not exactly - the HOWTOs will all work if your proxy server is not the source of the traffic.  In most situations this is the case - the transparent proxy is sitting in between the users systems and the internet.

Anyway, you should be able to just add an extra rule/chain on the OUTPUT stage to pick up locally generated packets (excluding those generated by the proxy server).  Something like:

```

iptables -t NAT -N local_proxy

iptables -t NAT -A local_proxy -m owner --owner $PROXY_USER -j RETURN

iptables -t NAT -A local_proxy -j REDIRECT --to-port 3128

iptables -t NAT -A OUTPUT -p tcp --dport 80 --j local_proxy

```

----------

## pteppic

 *Rob1n wrote:*   

> 
> 
> ```
> iptables -t NAT -N local_proxy
> 
> ...

 

Looks good to me, but wouldn't

```
iptables -t NAT -A OUTPUT -p tcp --dport 80 -m owner --uid-owner ! $PROXY_UID -j REDIRECT --to-port 3128
```

be easier?

I have

```
-A PREROUTING -i eth1 -p tcp -m tcp --dport 80 -j REDIRECT --to-ports 3128
```

 and it has always worked, but should work as well with 

```
-A PREROUTING -s 192.168.0.0/24 -p tcp -m tcp --dport 80 -j REDIRECT --to-ports 3128
```

----------

## Rob1n

 *pteppic wrote:*   

> 
> 
> Looks good to me, but wouldn't
> 
> ```
> ...

 

Yes - I wasn't sure whether the uid-owner option would take a negative option there though (it didn't look clear from the manual).

 *Quote:*   

> I have
> 
> ```
> -A PREROUTING -i eth1 -p tcp -m tcp --dport 80 -j REDIRECT --to-ports 3128
> ```
> ...

 

Either one should do the same thing, yes.

----------

