9

First, I know this is not how IP is intended. But as usual, this is how I need to have it working.

I work for a security company. There are at least 2 network interfaces. Both interfaces should have a default gateway. One interface is a default Ethernet interface, the second is a 3g interface. Both connect to the internet. Different configurations are possible as in one interface is the main and the other is the backup. Or the Ethernet interface is local LAN (with different subnets, gateway) and the 3G modem is the internet connection.

My main question is, how can I get the Linux TCP/IP stack to answer back on the same interface as a request came from.

The second question how can I start a connection through the interface of my choice, without playing with different subnets on different interfaces.

sysadmin1138
  • 133,124
  • 18
  • 176
  • 300
Malic
  • 93
  • 1
  • 1
  • 6

2 Answers2

12

You can set routes in Linux based on the source IP address. While it's possible in Linux to bind to a specific interface, it's very uncommon. Routing based on source IP will allow you to create a default gateway per outgoing interface. Since the socket for the server fielding the requests can be bound to an IP, this will make sure the responses are sent out from the same interface that they came in on. (If the server is listening on the wildcard address (0.0.0.0), and not bound to a specific interface, you won't be able to use this method. It's still should be possible using the conntrack module, and iptables marks, but I won't go into that here).

You can accomplish this by creating another routing table using the ip command. The '10' here is arbitrary.

# 10.0.0.1 = gateway for the secondary interface
# 10.0.0.10 = ip address for the secondary interface eth1

ip route add default via 10.0.0.1 dev eth1 table 10
ip rule add from 10.0.0.10 table 10

If you're binding to multiple addresses, or have dhcp, you can create a rule base on subnet

ip route add default via 10.0.0.1 dev eth1 table 10
ip rule add from 10.0.0.0/8 table 10

If you are certain that the server is binding to a device, another default gateway with a higher metric will suffice.

ip route add default via 10.0.0.1 dev eth1 metric 2
JimB
  • 1,924
  • 12
  • 15
  • In this device it is possible that both have a dynamic ip address. So if I understand it right i could make it work with the following: ip route add default via iif eth0 table 10 ip rule add oif eth0 table 10 ip route add default via iif ppp0 table 20 ip rule add oif ppp0 table 20 – Malic Jan 31 '11 at 08:57
  • It works! But with the ip address not with the interface name – Malic Jan 31 '11 at 09:31
  • @Malic - yes, the gateway (default via ...) needs to be an IP address. – JimB Jan 31 '11 at 15:27
  • Everything is working using your first part of the example (specify source ip address). Since the ip address is obtained through dhcp, I'm trying your second part of the example, using the interface. "ip rule add oif eth1 table 10". oif is not accepted, using iif is wel accepted. But the functionality breaks, the packets are not send through "eth1" interface. Do you have an idea? For me it seems that everything is correct. (ip rule add iif eth1 table 10) – Malic Apr 18 '11 at 09:17
  • @Malic - oif and iif (outbound and inbound) are not the same, so I don't understand why you would think that would work. What do you mean that "oif is not accepted"? Please check the `ip` man-page for a complete reference. – JimB Apr 20 '11 at 15:30
  • @JimB Clarification: "ip rule add oif eth1 table 10" --> "Error: argument "oif" is wrong: Failed to parse rule type". Looking in the man page, ip rule add, only iif is a possible entry. I'm no expert in ip, but it would be very helpfull to be able to use the interface name. Could you hint me a way? Thank you for the help you allready gave. – Malic Apr 21 '11 at 13:34
  • @Malic - Ahh, it seems oif was added for ip rules somewhat recently. updated with another solution. – JimB Apr 21 '11 at 16:11
  • @JimB your updated solution doesn't work for me. Everything is set but no packets gets through. It probably is not important but I'm working with a backup 3g interface, using ppp3 name as network interface. Thank you – Malic Apr 27 '11 at 14:06
  • what if I need to answer the same question to windows? – jasmines Dec 21 '17 at 15:24
1

I'm not sure if this is possible in the general sense you desire. You certainly can control which network interface a program running on your machine uses by binding it to a particular address.

However, in general I don't think there's a way to connect incoming network packets to outgoing packets. The best you can do is provide instructions to the system along the lines of 'if you are trying to connect to this network, always use this interface'. This can be done in various ways via the system routing table (iproute) or with iptables firewall rules.

If this is for security purposes, have you thought about using virtual machines running on your physical server? You could configure one VM to only have access to one interface, and other VM to have access only to the other. Since the VM can't see the other interface at all, there's no way it could ever respond to packets from the incorrect network.

You should probably also look at this serverfault question which covers how to control which interface arp requests go out on. You should also look at the rp_filter sysctl, which can be set to ignore packets which appear on the incorrect interface.

Phil Hollenback
  • 14,947
  • 4
  • 35
  • 52