# Using iptables for fixed ip-to-ip mapping

## Proteus

Hi everyone!

I need to setup a router for an internet café, now I have trouble finding a tutorial for what I want to do. I read the doc section at the iptables homepage but that did'nt help...

So, what I want to do is the following:

I want to map a LAN address (192.168.1.X) to a public ip (something like 217.76.40.X).

This is not standard NAT where every outgoing packet is changed to look like it comes from just one address. I found many tutorials for that purpose - not for this case.

I suppose it can be done using DNAT and SNAT but frankly I get confused where exactly to use those rules (in which chain? PREROUTING, POSTROUTING?). Also, I am not sure if I need just a set of 2 rules per ip or if I need 4 rules.

If anyone has knowledge how to do this or has done it before, please help me out...

----------

## spudicus

```
#Redirect internet requests to internal machine

iptables -t nat -A PREROUTING -i <extInterface> -p tcp -d 217.76.40.x --dport 80 -j DNAT --to-destination 192.168.1.x

#redirect internal requests to internal machine

iptables -t nat -A POSTROUTING -o <externInterface> -p tcp -d 192.168.1.x --dport 80 -j SNAT --to-source 192.168.1.x

#Allow connections to be forwarded to internal host

iptables -A FORWARD -i <extInterface> -p tcp -d 192.168.2.x --dport 80 -j ACCEPT
```

Dnat will automatically map and pass external requests to the desired machine, and snat will keep internal requests inline.

Note: The above rules may need to be changed to fit your setup, but the general idea remains the same.

A good tutorial is:

http://iptables-tutorial.frozentux.net/iptables-tutorial.html

Edit: Had -i $interface on the above SNAT/POSTROUTING rule when it should have been -o $interface.  :Embarassed: Last edited by spudicus on Tue Jun 29, 2004 12:46 am; edited 1 time in total

----------

## Proteus

Ok, thanks for your quick answer.

But I still have questions, maybe you can answer them:

1)

 *Quote:*   

> #redirect internal requests to internal machine 
> 
> iptables -t nat -A POSTROUTING -i <internInterface> -p tcp -d 192.168.1.x -j SNAT --to-source 192.168.1.x 

 I do not understand what happens here. Why should I cange the source-address of packets that have 192.168.1.x as destination?

------------------------------------------------------------------------------------------------------------------------------------------------------------------

2

 *Quote:*   

> #Allow connections to be forwarded to internal host 
> 
> iptables -A FORWARD -i <extInterface> -p tcp -d 192.168.2.x -j ACCEPT

 Is this the same as this: *Quote:*   

> #enable forwarding
> 
> echo 1 > /proc/sys/net/ipv4/ip_forward
> 
> iptables -P FORWARD ACCEPT

 Or is this something completely different?

------------------------------------------------------------------------------------------------------------------------------------------------------------------

3

Also I try to filter out all Netbios traffic like this: *Quote:*   

> #DROP Netbios everywhere
> 
> #
> 
> iptables -A INPUT -p udp --dport netbios-ns  -j DROP
> ...

 Is this correct or am I missing something here?

------------------------------------------------------------------------------------------------------------------------------------------------------------------

Note: I deleted all the --dport 80 statements because I have to route all ports not just www (internet games are played in the café as well).

----------

## splooge

hmm this should work for basic one-to-one nat:

iptables -t nat -A PREROUTING -d 207.76.40.1 -j DNAT --to 192.168.0.1

iptables -t nat -A POSTROUTING -s 192.168.0.1 -j SNAT --to 207.76.40.1

As far as dropping netbios packets goes, I can't remember the order in which the packets traverse the chains, but you've got the right idea using this: iptables -A INPUT -p udp --dport netbios-ns -j DROP, though you may need to put it on your prerouting chain.

----------

## splooge

Edit: here we go

http://iptables-tutorial.frozentux.net/images/tables_traverse.jpg

----------

## spudicus

 *Proteus wrote:*   

>  *Quote:*   #redirect internal requests to internal machine 
> 
> iptables -t nat -A POSTROUTING -i <internInterface> -p tcp -d 192.168.1.x -j SNAT --to-source 192.168.1.x  I do not understand what happens here. Why should I cange the source-address of packets that have 192.168.1.x as destination?

 

It's explained better than I can here (scroll down to the traversal example):

http://iptables-tutorial.frozentux.net/iptables-tutorial.html#DNATTARGET

 *Proteus wrote:*   

>  *Quote:*   #Allow connections to be forwarded to internal host 
> 
> iptables -A FORWARD -i <extInterface> -p tcp -d 192.168.2.x -j ACCEPT Is this the same as this: *Quote:*   #enable forwarding
> 
> echo 1 > /proc/sys/net/ipv4/ip_forward
> ...

 

echo 1 > /proc/etc/etc, turns forwarding on but doesn't enable it in iptables.

Your iptables -P method allows complete access, my method denies by default (assuming iptables -P FORWARD DROP is set) and only lets through those I specify. My way is the generally prefered way but if your allowing total access to you internal machines, use your way.

 *Proteus wrote:*   

> Also I try to filter out all Netbios traffic like this: *Quote:*   #DROP Netbios everywhere
> 
> #
> 
> iptables -A INPUT -p udp --dport netbios-ns  -j DROP
> ...

 

That will work, although you could do it like this (if you compile in support for multiport):

```

winport="netbios-ns,netbios-dgm,netbios-ssn"  

iptables -A INPUT -p ! icmp -m multiport --dports $winport -j DROP  #drop both tcp and udp

iptables -A FORWARD -p ! icmp -m multiport --dports $winport -j DROP #drop both tcp and udp
```

 *Proteus wrote:*   

> Note: I deleted all the --dport 80 statements because I have to route all ports not just www (internet games are played in the café as well).

  Fair enough, however, I'm curious why your allow complete outside access into the cafe? This will require you to have a larger public address space to map to each individual internal addresses.Last edited by spudicus on Wed Jun 30, 2004 2:14 am; edited 3 times in total

----------

## spudicus

 *splooge wrote:*   

> hmm this should work for basic one-to-one nat:
> 
> iptables -t nat -A PREROUTING -d 207.76.40.1 -j DNAT --to 192.168.0.1
> 
> iptables -t nat -A POSTROUTING -s 192.168.0.1 -j SNAT --to 207.76.40.1

 

You still need a forward chain to do the actual routing.

 *splooge wrote:*   

> Actually now that I think about it I think the order it travels the chains is like so: Input, Prerouting, Forwarding, Postrouting, Output, so you should be able to block all that netbios traffic at the input chain with the 3 lines you posted:
> 
> iptables -A INPUT -p udp --dport netbios-ns -j DROP 
> 
> iptables -A INPUT -p udp --dport netbios-dgm -j DROP 
> ...

 

Actually it travels:

```

                            V

                      Prerouting

                            V

                    V--------------V

                   Input             V

                    V                 Forward

                   Output           V

                    V--------------V

                             V

                         Postrouting 

```

 *spudicus wrote:*   

> So you could block use the prerouting chain, but it would be better to block input and forward

 

Actually, in hindsight, this a bad idea (i.e. blocking on the prerouting chain), because only the first packet is inspected. Eitherway, stick with the approach your taking i.e. block on input and forward.

Another consideration, though, is that if your blocking all input packets by default to the firewall, you can get away with just the forward chain.

----------

## Proteus

 *Quote:*   

> You still need a forward chain to do the actual routing. 

 Ok, so how can I establish one?   :Question: 

 *Quote:*   

> Fair enough, however, I'm curious why your allow complete outside access into the cafe? This will require you to have a larger public address space to map to each individual internal addresses.

 I think it is too hard to filter outside access. When a new game comes out and everybody want to play it the firewall would have to be re-configured to allow the new ports for the game to be accessible from the internet. And I am the only one who could do that - but I am not always here...

And yes, we have an unusual large public-ip address space. I do not know how we got it (I am not the owner of the café) but we have one public ip for each of our computers (about 30 pcs).

I think the owner first tried to do it with one ip and masquerading but that is not really compatible with a lot of games and couldn't be used therefore.

So what I want to achive is basic 1-on-1, WAN-to-LAN, mapping. All I want to filter is Netbios broadcast because we have to pay for our traffic.   :Wink: 

----------

## Proteus

Currently I try it like this:

 *Quote:*   

> iptables -t nat -A PREROUTING -i eth0 -j DNAT --to-destination 192.168.1.11
> 
> ftp / # iptables -t nat -A POSTROUTING -s 192.168.1.11 -o eth0 -j SNAT --to-source 217.76.40.11

  But this does not work. I can't connect.

When I do "cat /proc/net/ip_conntrack | less" it tells me this (it seems it's trying to contact a DNS server but gets no response): *Quote:*   

> udp      17 28 src=192.168.1.11 dst=194.25.0.68 sport=1049 dport=53 [UNREPLIED] src=194.25.0.68 dst=217.76.40.11 sport=53 dpor
> 
> t=1049 use=1

 

----------

## splooge

Make sure ip_forward is on   :Very Happy: 

----------

## Proteus

It is. I use this command:

 *Quote:*   

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

 

----------

## splooge

I know this defeats the purpose but just for giggles -- see if -j MASQUERADE works.

----------

## Proteus

If i use MASQUERADE ist works perfectly.   :Confused: 

Unfortunately it s not usable for me with MASQUERADE...

I can't explain why it does not work without MASQUERADE. I thought about it all day and it should... Did I overlook something?

----------

## splooge

I had this same exact problem, don't remember how I fixed it!

I assume you've turned on CONFIG_IP_NF_NAT in your kernel?

----------

## Proteus

yes, I did.

----------

## splooge

Ahh ok check this.

This is weird.  On my system, this:

```
iptables -t nat -A POSTROUTING -s 192.160.0.200 -o eth1 -j SNAT --to 24.55.66.17
```

Does NOT work.  HOWEVER:

```
iptables -t nat -A POSTROUTING -o eth1 -j SNAT --to 24.55.66.17
```

 DOES work.  Strange.  There's obviously something going on that I can't figure out there.  I suspect it has to do with the way the packets traverse the chains.

Anyways, I was poking around and also heard about some new NETMAP feature that exists in the 2.6 kernel, CONFIG_IP_NF_TARGET_NETMAP:

 *Quote:*   

> NETMAP is an implementation of static 1:1 NAT mapping of network addresses.  It maps the network address part, while keeping the host address prt intact.  It is similar to Fast NAT, except that Netfilter's connection tracking doesn't work well with Fast NAT.

 

Looks like you can do a whole subnet with a few lines:

Assuming 192.168.10.0/24 is private:

 *Quote:*   

> iptables -t nat -A PREROUTING -d 10.1.1.0/24 -j NETMAP --to 192.168.10.0/24
> 
> iptables -t nat -A POSTROUTING -s 192.168.10.0/24 -j NETMAP --to 10.1.1.0/24

 

Try that on for size.

----------

## Proteus

 *Quote:*   

> iptables -t nat -A POSTROUTING -o eth1 -j SNAT --to 24.55.66.17

 It seems to me that this is nice but not yet usable for me because I cannot map the 24.55.66.17 ip to a certain LAN ip.   :Confused: 

I need to know what LAN-ip a packet comes from in order to map it to the right public-ip. 

NETMAP looks cool but I am afraid it's too much time to compile a 2.6 kernel, change the rest of the system (do I need to change a lot to switch to 2.6?) only to find out it sounds good but does not work either...

----------

## spudicus

 *Proteus wrote:*   

>  *Quote:*   iptables -t nat -A POSTROUTING -o eth1 -j SNAT --to 24.55.66.17 It seems to me that this is nice but not yet usable for me because I cannot map the 24.55.66.17 ip to a certain LAN ip.   

 

That correct syntax is

```
iptables -t nat -A POSTROUTING -d $internalAddress -s SNAT --to $externalAddress
```

not

```
iptables -t nat -A POSTROUTING -s $internalAddress -s SNAT --to $externalAddress
```

See her for details:

http://iptables-tutorial.frozentux.net/iptables-tutorial.html#DNATTARGET

If your doing minimal filtering, why no assign each internal address their relevant public address, and just forward them through the firewall box only filtering netbios?

It's then just a matter of

```

echo 1>/proc/etc/etc/turn on forwarding

<insert firewall specific rules>

iptables -P FORWARD ACCEPT
```

You don't need to do any trickery then because the address's that they were going to be linked to are now already assigned.

 *Proteus wrote:*   

> I need to know what LAN-ip a packet comes from in order to map it to the right public-ip. 

 

If there aren't going to be an connections initiated from the internet, you don't need to map the address's this way. Iptables will keep connection state, so any connections made from internal address's will routed correctly. The only reason (I can think of) you would need to map a public address to an internal address, is if you a serving something to the public, which you don't appear to be doing.

 *Proteus wrote:*   

> I think it is too hard to filter outside access. When a new game comes out and everybody want to play it the firewall would have to be re-configured to allow the new ports for the game to be accessible from the internet. And I am the only one who could do that - but I am not always here...

 

Not hard at all. I know games like Battlefield 1942, Call of Duty etc. which have an in game server browser, don't need any outside forwarding at all. Usually, it's only gameplanet/direct play games that need forwarding, and the ports are well documented e.g.

```
    # Forwards for hosting DirectPlay games

iptables -A FORWARD -i eth0 -o eth1 -p tcp --dport 47624 -m state --state NEW,ESTABLISHED -j ACCEPT

iptables -t nat -A PREROUTING -i eth0 -p tcp --dport 47624 -j DNAT --to-destination 192.168.1.10:47624

iptables -A FORWARD -i eth0 -o eth1 --dport 2300:2400 -m state --state NEW,ESTABLISHED -j ACCEPT

iptables -t nat -A PREROUTING -i eth0 --dport 2300:2400 -j DNAT --to-destination 192.168.1.10:2300-2400
```

You generally only need to forward game ports if your serving them. If this is too much of a problem, block all ports below 1024, and forward all other ports e.g.

```
iptables -P Forward DROP

iptables -A FORWARD -i $externalInterface -m multiport --dports 1025: -j ACCEPT
```

A list of game (and other) ports can be found here:

http://www.practicallynetworked.com/sharing/app_port_list.htm#Games

Otherwise check the developers website.

 *Proteus wrote:*   

> If i use MASQUERADE it works perfectly.  
> 
> Unfortunately it s not usable for me with MASQUERADE...
> 
> I can't explain why it does not work without MASQUERADE. I thought about it all day and it should... Did I overlook something?

 

MASQUERADE is SNAT for dynamic address's. It will only help your internal address's map to the external address('s) i.e. many to 1, and is generally only recommended for use by dialup. If you have a static IP, you should use SNAT. 

If your not running any servers where internet requests need to initiate a connection to your internal machines you could use

```
iptables -t nat -A POSTROUTING -o $externalInterface -j SNAT --to-source 217.76.40.0/24
```

. You could map this to one address but you've got a heap to use (and nothing to use them for), so you may as well utilise them.

This won't map the external address to the internal, but you don't need to.Last edited by spudicus on Wed Jun 30, 2004 2:11 am; edited 1 time in total

----------

## splooge

Ahh ok, if I leave the -i out I can get it working on my system.  Duh.  Ok then.

iptables -t nat -A POSTROUTING -s 192.168.0.198 -j SNAT --to 24.55.66.17

iptables -t nat -A PREROUTING -d 24.55.66.17 -j DNAT --to 192.168.0.198

Works for me for 1-to-1 NAT.  You'll obviously need to do that for every IP you want NATted.

Make sure that works on your end, once it does, then we can start locking down the FORWARD chain.

 *Quote:*   

> I can't explain why it does not work without MASQUERADE. I thought about it all day and it should... Did I overlook something?

 

Maybe -i and -o don't apply to the nat table?  Looks like I got some homework to do.

----------

## spudicus

 *splooge wrote:*   

> iptables -t nat -A POSTROUTING -s 192.168.0.198 -j SNAT --to 24.55.66.17

 

For this to do what it's supposed to, it needs to be:

```
iptables -t nat -A POSTROUTING -d $internalServerAddress -j SNAT --to 24.55.66.17
```

 *splooge wrote:*   

> Maybe -i and -o don't apply to the nat table?

 

```
man iptables

 -i, --in-interface [!] name

              Name  of an interface via which a packet is going to be received

              (only for packets entering the  INPUT,  FORWARD  and  PREROUTING

              chains).   When  the  "!"  argument is used before the interface

              name, the sense is inverted.  If the interface name  ends  in  a

              "+",  then any interface which begins with this name will match.

              If this option is omitted, any interface name will match.

       -o, --out-interface [!] name

              Name of an interface via which a packet is going to be sent (for

              packets  entering  the  FORWARD, OUTPUT and POSTROUTING chains).

              When the "!" argument is used before  the  interface  name,  the

              sense  is  inverted.   If the interface name ends in a "+", then

              any interface which begins with this name will match.   If  this

              option is omitted, any interface name will match.
```

----------

## splooge

 *splooge wrote:*   

> iptables -t nat -A POSTROUTING -s 192.168.0.198 -j SNAT --to 24.55.66.17 
> 
> iptables -t nat -A PREROUTING -d 24.55.66.17 -j DNAT --to 192.168.0.198

 

 *spudicus wrote:*   

> For this to do what it's supposed to, it needs to be:
> 
> ```
> iptables -t nat -A POSTROUTING -d $internalServerAddress -j SNAT --to 24.55.66.17
> ```
> ...

 

First of all, I disagree, primarily on the basis that my system is working fine doing 1-to-1 NAT with the lines I used.

You use -s to match the source address, and -d to match the destination address.  In this case, we're matching source address for SNAT because we look at where these packets are coming from, not going to.  Let's speak a little "iptables english", and then you tell me why I am wrong:

Hey, iptables!  [iptables]  Look at every packet going out your postrouting chain [-t nat -A POSTROUTING] and see if it has a source address of 192.168.0.198 [-s 192.168.0.198].  If it does, your job is to change the source address [-j SNAT] to make it look like it came from 24.55.66.17 [--to 24.55.66.17]

Let's try some DNAT "iptables english" and tell me if you disagree with this:

Hey, iptables!  [iptables]  Look at all incoming packets to the prerouting chain.  [-t nat -A PREROUTING]  If you see any with a destination address of 24.55.66.17 [-d 24.55.66.17] then you need to change the destination address[-j DNAT] to 192.168.0.198 [--to 192.168.0.198]

Secondly, thanks for that quick iptables -i / -o lesson.  Saved me from having to do some homework!    :Cool:   I guess it makes sense that you can't match for the input device [-i] when it's already hit the postrouting chain!

----------

## Proteus

First, I'd like to thank everybody for participating in this thread and helping me out with my problem.

In the meantime I managed to get the router to do its job.

It's routing fine now.

Currently all I am using is a SNAT rule 

```
iptables -t nat -A POSTROUTING -s 192.168.0.198 -j SNAT --to 24.55.66.17
```

for every ip and it is working fine.

Seems SNAT manages incoming packets automagically somehow - I did not yet implement a DNAT rule. If anyone knows more about this magic - I'd like to learn about it   :Cool: 

From a previous attempt to bring up this very router (a year or so ago) I know that I will insert a DNAT line.

Reason is that we still have the problem that we cannot host a game (i.e. C&C Generals) and letting people from inside the café join that server. This fails in every game but Counterstrike (don't ask me why...). When I brought up this router a year ago I had both a SNAT and DNAT rule for every ip. That managed the trick and everybody was happy.

Unfortunately, that router stopped routing after 3 days. At that time no one knew why that happened and I somehow thought it was my fault but I could not explain it.

Therefore I stopped working on it for a long time. This was my second chance - it really has to work. 

When we recently came up with a possible explanation - a faulty DNS server I had "hardcoded" into the router - I started to work on it again.

Again, thank you all for your input and help. I've never seen better explanations for iptables anywhere else. The community support for Gentoo is just marvelous!   :Very Happy: 

----------

