3

I have 2 internet links using 2 ADSL routers and I need to give access to the Internet for the 192.168.0.0/24 network.

I have to route outgoing traffic based on port number, protocol, … using iproute2 and iptables on a linux router.

This is my network:

     (ISP-1)                              (ISP-2)
Dynamic public IP                    Dynamic public IP 
        |                                    |
+---------------+                    +---------------+
|ADSL Router (1)|                    |ADSL Router (2)|
+---------------+                    +---------------+
        |                                    |
   192.168.1.1                          192.168.2.1
        |                                    |
        |                                    |
        |                                    |
        |        +------------------+        |
        |        |                  |        |
   192.168.1.2 --|eth1          eth2|-- 192.168.2.2
                 |                  |
                 |   Linux Router   |
                 |                  |
                 |       eth0       |
                 +------------------+
                          |
                     192.168.0.1
                          |
                          |
                    Local Network:
                    192.168.0.0/24

I use the following script to setup the network configuration on the Linux router:

#!/bin/bash

echo 1 >| /proc/sys/net/ipv4/ip_forward
echo 0 >| /proc/sys/net/ipv4/conf/all/rp_filter

# flush all iptables entries
iptables -t filter -F
iptables -t filter -X
iptables -t nat -F
iptables -t nat -X
iptables -t mangle -F
iptables -t mangle -X
iptables -t filter -P INPUT ACCEPT
iptables -t filter -P OUTPUT ACCEPT
iptables -t filter -P FORWARD ACCEPT

# marking packets
iptables -t mangle -A PREROUTING -i eth0 -p icmp -j MARK --set-mark 1
iptables -t mangle -A PREROUTING -i eth0 -p udp  -j MARK --set-mark 1
iptables -t mangle -A PREROUTING -i eth0 -p tcp  -j MARK --set-mark 2

# create routing tables and default routes
echo '1     ISP1' >> /etc/iproute2/rt_tables
echo '2     ISP2' >> /etc/iproute2/rt_tables
ip route add default via 192.168.1.1 dev eth1 table ISP1
ip route add default via 192.168.2.1 dev eth2 table ISP2

# routing based on previous marks
ip rule add fwmark 1 table ISP1
ip rule add fwmark 2 table ISP2

ip route flush cache

# NAT
iptables -t nat -A POSTROUTING -o eth1 -j MASQUERADE
iptables -t nat -A POSTROUTING -o eth2 -j MASQUERADE

The problem is that I can't connect to the internet from the 192.168.0.0/24 network.

When I ping from this network to a remote server I can see (using Wireshark) replies returning back from the remote server to eth1 of the Linux router, but they don't reach out eth0.

Please help. And Thanks in advance.

(EDIT)

I tried troubleshooting this weird issue for a week.

Troubleshooting commands output:

ip rule
0:  from all lookup local 
32764:  from all fwmark 0x1 lookup ISP1
32765:  from all fwmark 0x2 lookup ISP2 
32766:  from all lookup main 
32767:  from all lookup default 

ip route show table ISP1
default via 192.168.1.1 dev eth1

ip route show table ISP2
default via 192.168.2.1 dev eth2

ip route show table main
192.168.2.0/24 dev eth2  proto kernel  scope link  src 192.168.2.2
192.168.1.0/24 dev eth1  proto kernel  scope link  src 192.168.1.2
192.168.0.0/24 dev eth0  proto kernel  scope link  src 192.168.0.1
169.254.0.0/16 dev eth0  scope link  metric 1000 
default via 192.168.1.1 dev eth1  metric 100

I can solve this problem partially by typing the following commands:

ip rule del fwmark 1 table ISP1
ip rule del fwmark 2 table ISP2
ip rule add from 192.168.0.0/24 table ISP1

So I get all traffic from local network routed correctly trough ISP1 link and all PCs get Internet access.

But i am interested in routing based on packets marks.

yozapho yozapho
  • 131
  • 1
  • 7

3 Answers3

10

After a lot of hard work I finally found what was the problem.

In fact it is not a routing problem, the script is correct but something is missing.

This command is not enough to disable rp_filter:

echo 0 >| /proc/sys/net/ipv4/conf/all/rp_filter

So the traffic returning back from Internet was drop at eth1 and eth2.

When I disabled rp_filter explicitly for both interfaces by adding the following commands:

echo 0 >| /proc/sys/net/ipv4/conf/eth1/rp_filter
echo 0 >| /proc/sys/net/ipv4/conf/eth2/rp_filter

The problem was solved and I get everything working perfectly.

The proof that Linux tutorials and documentation are not always completes.

yozapho yozapho
  • 131
  • 1
  • 7
  • The LARTC Howto does mention rp_filter, but it is a pretty obscure reference as a footnote. – Zoredache Aug 05 '11 at 19:34
  • it could be written as `echo 0 >| /proc/sys/net/ipv4/conf/*/rp_filter` – Sgaduuw Aug 06 '11 at 09:12
  • Can it? How can you pipe to more than one file? You can do `for f in /proc/sys/net/ipv4/conf/*/rp_filter; do echo 0 >| $f ; done` although quickest in the simplest cases is `echo 0 >/proc/sys/net/ipv4/conf/default/rp_filter` – Cedric Knight Feb 22 '15 at 17:58
0

If the traffic's getting back to the router but not going out again, then the problem's in your routing table, some iptables rule, or you're not reading the wireshark correctly. There's not a lot of options for what would be stopping packets from exiting a system.

womble
  • 96,255
  • 29
  • 175
  • 230
0

please look. seems looks like your issue. http://www.slashroot.in/linux-kernel-rpfilter-settings-reverse-path-filtering