Take the 2-minute tour ×
Server Fault is a question and answer site for professional system and network administrators. It's 100% free, no registration required.

I'm trying to configure a linux pc-router that must deal with routing and using NAT to provide connectivity to an internal network (it's also the DHCP server and firewall). In the external side the computer has 2 interfaces with 2 cablemodem connected (it gets public IP in both via DHCP).

The scenario looks like this: http://img810.imageshack.us/img810/411/filer.jpg

Considering the dynamic role of the external interfaces I'll have to add some scripts to /etc/network/if-up.d and /etc/network/if-down.d in order to establish the right values, but right now I just want to make sure that it works.

So, for the basic config I'm using this: http://pastebin.com/raw.php?i=tvSj0d5S

In the tests I've done one of the computers can connect to internet, but the other can not. By sniffing with wireshark I've seen how the non working PC sends its packets, the router redirects them after applying NAT and the responses do arrive to the router again, but the NAT is not "undone", and the PC never receives them. On the opposite the other PC works perfectly. Of course I have 2 default gateways (one per provider) that do appear by showing the route list (route -n).

Assuming that both external interfaces have well known addresses and gateways (I'm allways getting the same addresses, so for the test it should work in the same way) what is failing here? Should I use the SNAT target instead of the MASQUERADE one? should I use the "route from" feature of iproute2 instead of fwmark?

Thanks in advance and regards

share|improve this question
    
Can you include or pastebin the output of ip route show table all? –  Zoredache Aug 16 '10 at 3:53
add comment

5 Answers

If what you posted in your script is all you have done, then you are missing some steps.

To taking a look at your script my first concern is these following lines. The file /etc/iproute2/rt_tables is not usually recreated on each reboot. You are probably repeatedly adding the same thing to that file. This will cause problems in the future. Especially if you change the numbers you have used.

echo "201 $TABLE1" >> /etc/iproute2/rt_tables
echo "202 $TABLE2" >> /etc/iproute2/rt_tables

The next issue is that the routes you have added to your new tables using these commands.

ip route add default via $GW1 dev $DEV1 table $TABLE1
ip route add default via $GW2 dev $DEV2 table $TABLE2

When you create a new table it is completely empty. This means it does not even include routes for your local network.

So if you run a command like this ip route show table main scope link you should see lines like this.

192.168.1.0/24  dev eth1 proto kernel  src 192.168.1.100
192.168.2.0/24  dev eth2 proto kernel  src 192.168.2.100
192.168.3.0/24  dev eth3 proto kernel  src 192.168.3.1

These are local routes, the are required for routing to work, and you must recreate them on every table.

The generic command would look like this. You need to run this command for each interface on each table.

/sbin/ip route add table ${TABLE} scope link proto kernel dev ${IFACE} ${ROUTE}
share|improve this answer
    
If I'm not wrong by using the add table command it will create the table dinamically, but won't add anything to /etc/iproute2/rt_tables, right? Related to the basic routes those are automatically created by the ifup script. –  user51267 Aug 16 '10 at 8:33
add comment

First of all, what's the pool of the dhcp server ? (In the configuration you have 192.168.3.[2,3] hardtyped. Did you check the case that one of the PCs gets an ip out of these ?)

Also do you have logs enabled for iptables ? They could help you.

I know that it doesn't help much, but just some tips for troubleshooting :>

share|improve this answer
    
This is just an example, so don't worry about the address not matching. The goal is being able to route/NAT the packets from all the PC's in the internal network (somehow split by adding several rules with the appropiate mark, marking them in the PREROUTING table). This is just a common DHCP C-class network. I've never logged with iptables, but you're talking about the LOG target or another internal log in /var? –  user51267 Aug 15 '10 at 23:37
add comment

Try using SNAT instead of MASQUERADE, and using the --to option to change the source address to one of the gateway addresses.

Like:

iptables -t nat -o $DEV1 -A POSTROUTING -p tcp -j SNAT --to <ethX ip>
iptables -t nat -o $DEV2 -A POSTROUTING -p tcp -j SNAT --to <ethY ip>

Maybe you need to add -s too, but I can't be sure without testing.

EDIT: --to refers to interface address, not GW address.

share|improve this answer
    
If I'm not wrong the --to option should be related to the external interface IP instead of the one from the gateway, isn't it? –  user51267 Aug 15 '10 at 23:38
    
You're correct, fixed the answer. –  coredump Aug 16 '10 at 0:40
add comment

If you're using DHCP for both of your gateways, did you verify that the DHCP servers from your provider don't send you gateway information that would be taken by your stack, and would modify your routing table? By default, that's what at least dhclient does.

share|improve this answer
    
Yes, they do. 2 entries are added: one for the interface direct network (the usual 192.168.1.0/24) and also a default GW. Should I remove both default GW's? I thought the custom table definition having their own default GW should have top priority for the packets that do enter the other tables, preciselly because of that, those packets should not enter the main table (or this is the problem? maybe they do when responses do return, and one of them ignores the NAT cache?) –  user51267 Aug 16 '10 at 8:38
add comment

After getting no results with DHCP I decided to test something: I did establish a static configuration for the external interfaces using the same addresses that I'm allways getting. I've tested both from the router itself and of course worked, but again no results for the PC's. In fact it didn't work by removing the default GW in the main table, even if the secondary tables had their own GW's. And it worked again only for the default interface as long as I established again the default GW.

So my guess is that somehow the fwmark system doesn't work mixed with NAT when there are multiple interfaces (tables).

I'll try again by adding 2 global scopes for traffic balance, in the same way it appears in the LARTC guide.

Regards

share|improve this answer
add comment

Your Answer

 
discard

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.