1

I have a network gateway (Debian) with two interfaces: eth0 and tun0. In general all traffic from all clients is routed through tun0.

I would like to change that in the following way:

  • client a‘s traffic is routed only through eth0
  • client b‘s traffic is routed only through tun0
  • all other clients are routed through tun0 if existent and through eth0 is tun0 is not available

I am currently using iptables to route specific traffic originating from the gateway itself and have no clue how I can change it to „client based“-routing.

--- Update ---

  • Client A will have a static IP address
  • Client B will have a static IP address
  • eth0 has a dynamic IP address
  • tun0 has a dynamic IP address
  • 4
    If you want to route based on source IP address (is that what you mean by "client based"?) then you need policy routing; start with man ip rule. – Ferenc Wágner Jan 6 at 11:30
2

As already mentioned by user Ferenc, policy routing is probably the best solution.

Take a look at ip rule, it will typically look like this:

# ip rule
0:      from all lookup local 
32766:  from all lookup main 
32767:  from all lookup default

This is a sorted list of rule priorities followed by the rule specification. local, main and default are the routing tables to look at. To see a specific routing table run ip route show table <table> or in short ip r s t <table>.

In order to route different source IPs to different targets or over different devices we will need separate routing tables and routing rules for jumping into these tables.

Lets assume we want to have a special route for IP 10.0.0.42 and a special route for net 10.0.0.128/25. We have to create two additional rules and two additional tables, the order doesn't matter. Let's create the rules. Example:

# ip rule add from 10.0.0.42 lookup 300 prio 5
# ip rule add from 10.0.0.128/25 lookup 301 prio 6

Let's take a look at them:

# ip rule
0:  from all lookup local 
5:  from 10.0.0.42 lookup 300 
6:  from 10.0.0.128/25 lookup 301
32766:  from all lookup main 
32767:  from all lookup default

300 and 301 are our table names (tables usually are just numbers but can be given names, too, by adding them to /etc/iproute2/rt_tables). The rest should be self-explanatory.

Now we need to fill these tables. Example:

# ip route add default via 10.0.0.1 dev eth1 table 300
# ip route add 192.168.178.0/24 dev eth2 table 301

Let's take a look at them:

# ip route show table 300
default via 10.0.0.1 dev eth1 scope link 
# ip route show table 301
192.168.178.0/24 dev eth2 scope link

As you can see it is possible to add any route you like. The system from address 10.0.0.42 will now get routed via 10.0.0.1 over eth1. Systems from network 10.0.0.128/25 will now get routed via eth2 if their destination address is inside network 192.168.178.0/24.

If no route matches from your special routing tables the next routing rule gets evaluated. For example if systems from network 10.0.0.128/25 don't want to route to 192.168.178.0/24 then they fall back to the main table.

If you want to remove any rule then just replace add with del. The routing tables will exist until you have removed all of their routes, e.g. by running ip route flush table <table>. If you want to see all routing rules then simply run ip route show table all.

Routing rules are very flexible, you can use various other selectors such as incoming/outgoing interfaces, source/dest ports and protocols. See man ip rule for details.

Take care to not lock yourself out when editing routes and rules via SSH.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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