# iptables PREROUTING on "almost" all hosts

## paziu

Hello,

since I set up a box where all traffic is being redirected to port 80   :Embarassed:   I am unable to connect to it at this moment, and at least try to figure out this myself. So please, if possible give me an idea on the following scenario:

i am using prerouting to forward ALL tcp traffic to port 80, and it works good.

I need to set up just a couple of systems ( source IP's known ) which will pass the NAT without any limits, without the prerouting rules.

Thank you for any suggestions,

paziu

----------

## Hu

Insert a rule to match those systems and ACCEPT the traffic before it hits the REDIRECT rule.  Better yet, stop rerouting non-HTTP traffic to port 80.  :Smile: 

----------

## paziu

Thank you for your reply,

Well I need to redirect ALL TCP to port 80 on all hosts but two :

iptables -t nat -I PREROUTING -i eth0 -s ! 10.15.11.101 -p tcp -j REDIRECT --to-port 80

iptables -t nat -I PREROUTING -i eth0 -s ! 10.15.11.8 -p tcp -j REDIRECT --to-port 80

and redirect all dest 80 from these two hosts to proxy port 3128:

iptables -t nat -I PREROUTING -i eth0 -s 10.15.11.101 -p tcp --dport 80 -j REDIRECT --to-port 3128

iptables -t nat -I PREROUTING -i eth0 -s 10.15.11.8 -p tcp --dport 80 -j REDIRECT --to-port 3128

now, if I have just 11.101 it works great all dest packets going trough 3128 and all other packets being forwarded. If I add the second 11.8 , all TCP is redirected to 80, incl ssh telnet etc.

my understanding is :

this should forward all traffic to 80 but from 11.101:

iptables -t nat -I PREROUTING -i eth0 -s ! 10.15.11.101 -p tcp -j REDIRECT --to-port 80

and this should redirect only dest 80 from 11.101 to port 3128:

iptables -t nat -I PREROUTING -i eth0 -s 10.15.11.101 -p tcp --dport 80 -j REDIRECT --to-port 3128

it is true and working great, if I have ONE source host, with multiples, i get all 80 dest redirected to 3128 ( which is great ) BUT all other traffic to port 80 ( which is NOT GOOD )

iptables -t nat -nvL:

Chain PREROUTING (policy ACCEPT 49942 packets, 8659K bytes)

pkts bytes target prot opt in out source destination

1 64 REDIRECT tcp -- eth0 * !10.15.11.8 0.0.0.0/0 redir ports 80

1 60 REDIRECT tcp -- eth0 * !10.15.11.101 0.0.0.0/0 redir ports 80

0 0 REDIRECT tcp -- eth0 * 10.15.11.8 0.0.0.0/0 tcp dpt:80 redir ports 3128

0 0 REDIRECT tcp -- eth0 * 10.15.11.101 0.0.0.0/0 tcp dpt:80 redir ports 3128

So what would be the way of specifying rules for multiple hosts, adding several ips to -s for source returns an error since the syntax is not correct,

I do not want to specify a range. just specific hosts,

Thank you,

paziu

----------

## malern

Iptables uses the first rule that matches.

10.15.11.8 matches this rule first

iptables -t nat -I PREROUTING -i eth0 -s ! 10.15.11.101 -p tcp -j REDIRECT --to-port 80

and therefore gets redirected to port 80

10.15.11.101 matches this rule first

iptables -t nat -I PREROUTING -i eth0 -s ! 10.15.11.8 -p tcp -j REDIRECT --to-port 80 

and therefore also gets redirected to port 80

Try swapping your rules around so you have

iptables -t nat -I PREROUTING -i eth0 -s 10.15.11.101 -p tcp --dport 80 -j REDIRECT --to-port 3128

iptables -t nat -I PREROUTING -i eth0 -s 10.15.11.8 -p tcp --dport 80 -j REDIRECT --to-port 3128 

iptables -t nat -I PREROUTING -i eth0 -s ! 10.15.11.101 -p tcp -j REDIRECT --to-port 80

iptables -t nat -I PREROUTING -i eth0 -s ! 10.15.11.8 -p tcp -j REDIRECT --to-port 80

But really you only need 3 rules

iptables -t nat -I PREROUTING -i eth0 -s 10.15.11.101 -p tcp --dport 80 -j REDIRECT --to-port 3128

iptables -t nat -I PREROUTING -i eth0 -s 10.15.11.8 -p tcp --dport 80 -j REDIRECT --to-port 3128 

iptables -t nat -I PREROUTING -i eth0 -p tcp -j REDIRECT --to-port 80

The last rule will catch all hosts that arn't 10.15.11.101 or 10.15.11.8

----------

## paziu

Thank you malern, I will try this,

 *malern wrote:*   

> 
> 
> But really you only need 3 rules
> 
> iptables -t nat -I PREROUTING -i eth0 -s 10.15.11.101 -p tcp --dport 80 -j REDIRECT --to-port 3128
> ...

 

in this case the 11.101 and 11.8 will have dport 80 redirected to 3128

but they will also have all other ports redirected to local 80

what I want to accomplish is to have all ports on all hosts tcp redirected to 80 while

2 of them will have forwarding on all ports but dest 80 which will be redirected to 3128

this works great if I have one host:

iptables -t nat -I PREROUTING -i eth0 -s ! 10.15.11.8 -p tcp -j REDIRECT --to-port 80

iptables -t nat -I PREROUTING -i eth0 -s 10.15.11.8 -p tcp --dport 80 -j REDIRECT --to-port 3128 

if I add the second one, ALL ports are being redirected to local 80 and just dest 80 to 3128 works the way it should,

this means I have no connectivity on any TCP service but HTTP.

I tried to shuffle the rules finally, and no positive result, I do not understand this...

I am running  2.6.29-gentoo-r3 & iptables v1.3.8 

Thank you again,

paziu

----------

## Hu

Why are you doing this?  Redirecting all traffic like that is likely to confuse any non-HTTP applications that get trapped by it.

----------

## paziu

 *Hu wrote:*   

> Why are you doing this?  Redirecting all traffic like that is likely to confuse any non-HTTP applications that get trapped by it.

 

Hello Hu,

Since there is no authorization on squid in transparent mode (to my knowledge), and I want to control users by providing them with an access password for example.

Since all TCP traffic is redirected to 80 they are unable to use any TCP, and they are required to get the password from the admin.

once the password is entered, ipchains gets updated with a new rule which excludes their host from ALL blocked :

iptables -t nat -A PREROUTING -i eth0 -s ! 10.15.11.101 -p tcp -j REDIRECT --to-port 80

and sets the dest 80 to use 3128 :

iptables -t nat -A PREROUTING  -i eth0 -s 10.15.11.101 -p tcp --dport 80 -j REDIRECT --to-port 3128

so they got web filtering, full tcp access plus they are authenticated - this is the reason.

and now again, this config works fine with a single IP, but it does not with multiple.

I can remove the first redirect, multiple hosts will work fine, and which will still make the users have to authenticate the HTTP, but they will be able to use any other TCP connectivity before the authentication.

So the goal is : block ALL TCP but 80, have them authenticate, enable all TCP and forward dest 80 to 3128 for filter purposes....

so far I have it working in 50%...

Thanks you!

paziuLast edited by paziu on Sat Jun 27, 2009 4:47 am; edited 4 times in total

----------

## paziu

if by adding the second host, one of the two would not work, i would think that the rules are overlapping, location etc,

but both systems are messed up....this seems to make not much sense to me.

paziu

----------

## Hu

That goal makes sense, though I think it might be better to return an ICMP "administratively prohibited" error for most ports in the pre-authentication step.  It would produce a better experience to be unable to connect than to get a fake connection to a server speaking the wrong protocol.

As malern mentioned, rules are tried in order until one matches.  You need to have all the rules that permit authorized traffic before any of the rules that trap unauthorized traffic.  It might be easier to make your rules for unauthorized traffic apply to all hosts, without regard to source IP.  Any hosts that should always be immune to filtering would be added as explicitly authorized entries above the catch-all rule, and would be managed outside the scope of your code that adds and removes password-authenticated users.  Thus, you would have something like:

```

# Whitelisted systems that never require authentication

-A PREROUTING -s hr1 -j ACCEPT # Human Resources is never filtered

-A PREROUTING -s noc1 -j ACCEPT # NOC may need access to do research if the filter breaks

# Begin systems which are authenticated and have temporary access

-A PREROUTING -s guest1 -j filter

-A PREROUTING -s guest2 -j filter

# End temporary systems

# Trap everything else

-A PREROUTING -j REDIRECT --to-port 3128

-A filter -p tcp -m tcp --dport 80 -j REDIRECT --to-port 3128

-A filter -j ACCEPT
```

----------

## paziu

I appreciate all your help and suggestions, I will try this approach as soon asap and share the results. Thanks again.

----------

## paziu

Thank you Hu and malern, I got it working!

The beauty about ipchains is you can reach the goal in several ways, I was probably too stubborn.

# dynamically assigned temp hosts:

iptables -t nat -A PREROUTING  -i eth0 -s 10.0.0.101 -p tcp --dport 80 -j REDIRECT --to-port 3128

iptables -A FORWARD -i eth0 -s 10.0.0.101 -o eth1 -p tcp -j ACCEPT

iptables -t nat -A PREROUTING  -i eth0 -s 10.0.0.100 -p tcp --dport 80 -j REDIRECT --to-port 3128

iptables -A FORWARD -i eth0 -s 10.0.0.100 -o eth1 -p tcp -j ACCEPT

# new temp host? time for authentication...

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

# reject other tcp protocols

iptables -A FORWARD -i eth0 -o eth1 -p tcp -j REJECT

# finito

now all new systems are forced to provide the network access password

and once provided:

iptables being updated

all http traffic travels via filtering squid

all other traffic travels via nat

really cool, Thank you a very much!

paziu

----------

## chantha_21

Hi

I used this command iptables -t nat -I PREROUTING -i eth0 -s ! Squid-IP -p tcp -j REDIRECT --to-port 80. I didn't understand when i using this command the download rate around 20K but when i didn't use it the download rate aroute 80K.

Can anyone help me about this problem.

Thank for your valued time.

Chantha

----------

## Rexilion

 *chantha_21 wrote:*   

> Hi
> 
> I used this command iptables -t nat -I PREROUTING -i eth0 -s ! Squid-IP -p tcp -j REDIRECT --to-port 80. I didn't understand when i using this command the download rate around 20K but when i didn't use it the download rate aroute 80K.
> 
> Can anyone help me about this problem.
> ...

 

Please open a seperate thread for that issue. It seems that prerouting slows down connectivity.

----------

