Server Fault is a question and answer site for system and network administrators. Join them; it only takes a minute:

Sign up
Here's how it works:
  1. Anybody can ask a question
  2. Anybody can answer
  3. The best answers are voted up and rise to the top

I have 3 interfaces:


The default gateway is which I want to keep as it is in the changes I want to make.

I want to masquerade eth1 and enable NAT forwarding to eth2. So I have done this:

ip route add dev eth2 src table t1
ip route add default via dev eth2 table t1

ip rule add from table t1
ip rule add to table t1

Now I can receive ping replies from any internet host if I did:

ping -I eth2

To enable NAT forwarding I did this:

sudo iptables -A FORWARD -o eth2 -i eth1 -s -m conntrack --ctstate NEW -j ACCEPT
sudo iptables -A FORWARD -m conntrack --ctstate ESTABLISHED,RELATED -j ACCEPT
sudo iptables -t nat -A POSTROUTING -o eth1 -j MASQUERADE

But it isn't working. To test I used a client pc and put it on network and gateway was set as

I want to have as default gateway. And the traffic that comes in via eth1 should be forwarded to eth2

I have enabled forwarding on ubuntu also.

share|improve this question
Can you be more specific regarding "it's not working"? In what way it didn't work? – pepoluan Mar 10 '11 at 17:04
More question: are you sure the address for eth2 starts with 225? AFAIK 224-239 are multicast addresses. – pepoluan Mar 10 '11 at 17:32
@pepoluan I have not given my acutal public ip, I intentionally randomized it. When I used a client machine to access internet it didn't work. – nixnotwin Mar 11 '11 at 1:12
okay, fair enough. was typing a solution for you last night when I realized the address is strange. will type the solution again later today. (tip: next time, use ;) ) – pepoluan Mar 11 '11 at 2:42
Thanks for the tip, pepoluan. I will suerly use it in the future. – nixnotwin Mar 11 '11 at 14:06
up vote 2 down vote accepted

I believe you want to:

  • Route everyone from eth1 through eth2
  • Yet maintain the Linux box's routing via eth0

If that's the case, there are several mistakes with your iptables & iproute2 settings. Here's my suggestion:

-A FORWARD -i eth1 -o eth2 -j ACCEPT
-A FORWARD -i eth2 -o eth1 -m state --state ESTABLISHED,RELATED -j ACCEPT

For the routing, you'll need two custom tables. I'll use numbers instead of names because I don't know what's in your /etc/iproute2/rt_tables. Now, one important note: Modifying the RPDB and default routes my way will cause temporary network disturbance. So I'd suggest not typing these on the CLI, instead put it in a script, so everything happens atomically (unless you're typing the commands on the Linux box's physical console).

ip route add default via     dev eth0 table 100
ip route add default via dev eth2 table 102
ip route del default table main

ip rule add order 10 from all lookup main
ip rule add order 20 iif lo   lookup 100
ip rule add order 30 iif eth1 lookup 102

We move the lookup main as the first rule to ensure proper routing to subnets directly attached to the Linux box. But we delete the default route in that table, because we want to specify different default routes depending on where the packet enters the Linux box.

Now, here's an important question: Is the subnet represents all networks attached -- directly or indirectly -- to eth1?

If YES, then the configuration is finished.

If NO, i.e., there are other subnets indirectly attached to eth1 (let's say,,, etc.) which you can access through another router (let's say, then you have to add more routes to the main table:

ip route add via dev eth1 table main
ip route add via dev eth1 table main
... and so on ...

Note: table main is not necessary, but a good habit

share|improve this answer
I have only one subnet on eth1. I put both firwall rules and ip route rules in two different files. When I executed those scripts, the firewall script got executed but ip route script gave an error. The only thing I modfied in the ip route script was instead of using 100 and 102 as table names I used t1 and t2. In the rt_tables file I had put 200 t1 and 210 t2 in two different lines – nixnotwin Mar 11 '11 at 14:04
@nixnotwin can you try entering the ip statements one-by-one and tell me which one results in an error? and what's the error message? – pepoluan Mar 11 '11 at 14:38
@pepoluan, it worked. I carefully removed all the earlier entered rules, and executed your script, with echo function inserted between each lines to discover the failing line, but it got executed without any errors. The forwarding and masquerading works fine too. One thing remains to be done is figuring out where to place all those rules so that they get applied at boot-up. One thing more: I can't do ping -I eth2 on the server-router. It is not necessary actually. Just wanted to let you know. Well, massive thanks. – nixnotwin Mar 12 '11 at 9:05
@nixnotwin glad to hear that it works :) .. well, the router can't send packets out eth2 because of the 'iif lo' ip rule. you can test it by entering ip rule order 15 iif lo lookup <table that's used by 'iif eth1'>, then erasing the new rule ip rule del order 15 when you're done – pepoluan Mar 12 '11 at 13:31
@nixnotwin oh, and for the rules to start automatically, there are lots of ways. but the easiest is: create a script (say, /etc/${HOSTNAME} careful, do not clobber an existing script) and call it from /etc/rc.local (right before exit 0). just remember that you must use the full path to ip and iptables (use the which command to find out). – pepoluan Mar 12 '11 at 13:35

Your Answer


By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.