how to route 2 Nics with 2 public IP on same subnet running with same gateway - linux

I'm newbie in networking field. I have trouble with my web server Network configuration (OS is Centos).
I have 2 NICs (eth0 + eth2 - physically) running 2 public IP which have the same subnet, same gateway.
When I configure nginx to listen on these 2 NICs, everything works just fine. But when I monitor the traffic, all traffic is on the eth0 only, nothing on eth2.
My question is: How can I configure so that traffic goes in a NIC, go out on that NIC, too?
This is my ethernet card config:
DEVICE="eth0"
ONBOOT=yes
BOOTPROTO=static
IPADDR=x.x.x.38
PREFIX=27
GATEWAY=x.x.x.x.33
DNS1=8.8.8.8
DNS2=8.8.4.4
NAME="System eth0"
DEVICE="eth2"
ONBOOT=yes
BOOTPROTO=static
IPADDR=x.x.x.39
PREFIX=27
GATEWAY=x.x.x.33
DNS1=8.8.8.8
DNS2=8.8.4.4
NAME="System eth2"
This is my route -n result
Kernel IP routing table
Destination Gateway Genmask Flags Metric Ref Use Iface
10.14.8.0 0.0.0.0 255.255.255.0 U 0 0 0 eth1
y.z.0.0 0.0.0.0 255.255.0.0 U 1002 0 0 eth0
y.z.0.0 0.0.0.0 255.255.0.0 U 1003 0 0 eth1
y.z.0.0 0.0.0.0 255.255.0.0 U 1004 0 0 eth2
0.0.0.0 x.x.x.33 0.0.0.0 UG 0 0 0 eth0
Hope you can help, thanks in advanced!

In Linux, routing is performed by looking at the destination address only, so a packet will follow whichever route can be used to reach the packet's destination, with no regard to the source address.
The behaviour you want requires choosing a route depending not only on the destination address, but also on the source address — this is sometimes called source-sensitive routing or SADR (source-address dependent routing). The most portable way of implementing source-sensitive routing under Linux is to define routing rules across multiple routing tables using the ip rule and ip route ... table ... commands.
This is described in detail in Section 4 of the Linux Advanced Routing and Traffic Control HOWTO

Probably, the problem can be solved even with NAT.
ip tuntap add dev tap0 mode tap
ip tuntap add dev tap1 mode tap
Then you can assign separate ip addresses to these devices:
ifconfig tap0 10.10.10.1 netmask 255.255.255.255
ifconfig tap1 10.10.10.2 netmask 255.255.255.255
And finally - redirect incoming traffic to specific virtual device
iptables -t nat -A PREROUTING -i eth0 -j DNAT --to-destination 10.10.10.1
iptables -t nat -A PREROUTING -i eth2 -j DNAT --to-destination 10.10.10.2
In this case, all traffic will be routed definetely to the interface it came from.

Related

Odroidh2 Debian - Unable to ping network gateway / no network connectivity

I have an OdroidH2 with docker setup.
It was working fine for a few months and suddenly, out of nowhere it stopped having any internet/intranet connectivity.
It's connectivity is going through an Ethernet cable, not WiFi and the interface that is supposed to have the connection is enp3s0 with an ip address of 192.168.1.100.
I have performed the following troubleshooting steps:
Restart (of course, always the first step)
Checked interface settings via ifconfig and also in /etc/network/interfaces
Checked the routing via route -n
Checked iptables (iptables was populated with the docker configuration, I've flushed the iptables including nat and mangle and set the default policy to ACCEPT for input, forward and output. Restarted the networking service afterwards)
Checked if it was able to ping itself and the default gateway (it is able to ping itself but not the gateway, or any other devices)
Checked if another device was able to ping the OdroidH2 (host unreachable)
Checked dmesg and for some reason, I had 2 firmwares that were not able to be loaded (already installed and rebooted after installation):
rtl_nic/rtl8168g-2.fw (after checking, this is the firmware for the network interfaces)
i915/glk_dmc_ver1_04.bin (didn't research much about this one, something to do with runtime power management??)
After all of these steps, I still am unable to get the network connectivity going.
Below you can find information regarding my current configuration:
dmesg output
Stackoverflow does not allow me to put all the information from my dmesg output so I had to put it on google drive: dmesg_output
/etc/hosts
127.0.0.1 localhost
192.168.1.100 dc1 dc1.samdom.andrewoliverhome.local samdom.andrewoliverhome.local
# The following lines are desirable for IPv6 capable hosts
::1 localhost ip6-localhost ip6-loopback
ff02::1 ip6-allnodes
ff02::2 ip6-allrouters
iptables -nvL output (after clearing and reloading the networking service)
Chain INPUT (policy ACCEPT 0 packets, 0 bytes)
pkts bytes target prot opt in out source destination
Chain FORWARD (policy ACCEPT 0 packets, 0 bytes)
pkts bytes target prot opt in out source destination
Chain OUTPUT (policy ACCEPT 0 packets, 0 bytes)
pkts bytes target prot opt in out source destination
/etc/resolv.conf
#nameserver 127.0.0.1
#nameserver 8.8.8.8
#nameserver 8.8.4.4
search samdom.andrewoliverhome.local
#domain samdom.andrewoliverhome.local
nameserver 192.168.1.100
nameserver 8.8.8.8
route -n output
Kernel IP routing table
Destination Gateway Genmask Flags Metric Ref Use Iface
0.0.0.0 192.168.1.254 0.0.0.0 UG 0 0 0 enp3s0
172.17.0.0 0.0.0.0 255.255.0.0 U 0 0 0 docker0
172.18.0.0 0.0.0.0 255.255.0.0 U 0 0 0 docker_gwbridge
172.19.0.0 0.0.0.0 255.255.0.0 U 0 0 0 br-debc10cb5b21
192.168.1.0 0.0.0.0 255.255.255.0 U 0 0 0 enp3s0
/etc/network/interfaces
# This file describes the network interfaces available on your system
# and how to activate them. For more information, see interfaces(5).
source /etc/network/interfaces.d/*
# The loopback network interface
auto lo enp2s0 enp3s0
#auto lo br0
iface lo inet loopback
# The primary network interface
iface enp2s0 inet dhcp
allow-hotplug enp2s0 enp3s0
#iface enp2s0 inet manual
# post-up iptables-restore < /etc/iptables.up.rules
# This is an autoconfigured IPv6 interface
#iface enp2s0 inet dhcp
iface enp3s0 inet static
address 192.168.1.100
netmask 255.255.255.0
# broadcast 169.254.99.255
network 192.168.1.0
gateway 192.168.1.254
#iface enp2s0 inet manual
#iface enp3s0 inet manual
#iface br0 inet static
# bridge_ports enp2s0 enp3s0
# address 192.168.1.100
# broadcast 192.168.1.255
# netmask 255.255.255.0
# gateway 192.168.1.254
#
In /etc/resolv.conf, the reason I have the primary nameserver to be itself is because I am running a docker container that is serving as a samba-ad-dc.
In order for OdroidH2 to find all of my devices in the domain, it needs to make dns queries to the samba dc, if samba is not able to find a dns record, it will autoforward it to 8.8.8.8.
Any help would be greatly appreciated (:
After all the troubleshooting done, the issue is not within the OdroidH2 itself, it was with my router.
The LAN port that I'm using malfunctioned. I switched the Ethernet cable to a different LAN port and it worked.

Fail to bind to specific network interface on Linux

=== Background stuff ===
I have two wired ethernet interface on my Debian 9 server, both of them have internet access but through different ISP.
enp11s0 192.168.0.9
eth0 192.168.2.2
iptables -L and iptables -L -t nat is empty and accepts all incoming and outgoing. Here is my route:
Kernel IP routing table
Destination Gateway Genmask Flags Metric Ref Use Iface
default 192.168.0.1 0.0.0.0 UG 0 0 0 enp11s0
116.xxx.xxx.0 192.168.2.1 255.255.255.0 UG 0 0 0 eth0
192.168.0.0 0.0.0.0 255.255.255.0 U 0 0 0 enp11s0
192.168.2.0 0.0.0.0 255.255.255.0 U 0 0 0 eth0
=== End of Background ===
I would like to let most traffic go through enp11s0 since the eth0 is metered, but few connection go through eth0 (e.g. 116.xxx.xxx.xxx). This works, but when I try to let a program bind to a specific interface, it becomes weird.
curl icanhazip.com --interface enp11s0 gives my ip address which is expected, however curl icanhazip.com --interface eth0 does not work. With -v flag here is the output:
* Rebuilt URL to: icanhazip.com/
* Trying 144.202.71.30...
* TCP_NODELAY set
* Local Interface eth0 is ip 192.168.2.2 using address family 2
* Local port: 0
* Trying 2001:19f0:6401:18fc:2709:e14e:21cd:4e41...
* TCP_NODELAY set
* Trying 2001:19f0:5c01:1aed:dcdf:7e47:e74b:1197...
* TCP_NODELAY set
And it just keeps repeating forever. I added -4 flag and Trying 2001:19f0:6401:18fc:2709:e14e:21cd:4e41 disappears, but it still doesn't work. How do I fix eth0? Thanks in advance!
see this question and answer here for a good explanation about how what you are attempting with curl is not what is happenning with curl.
You are curling an external address from eth0 via the server default gateway which is on the link enp11s0 . check that forwarding is enabled on the server.
You need to set up policy based routing. depending on what traffic you wan't to send out eth0, look into iproute2, ip rule, and
/etc/iproute2/rt_tables

Linux : I programatically changed my default route to eth0 but now I can't ping, any suggestions?

I'm writing a program for my embedded Debian Linux system. It has a cell modem that is brought up as ppp0 and also has eth0 that may or may not be plugged in. How I want the system to work is for it to use ppp0 as the default route, unless it can establish a connection to the outside world over eth0, in that case eth0 should be made the default route. The eth0 cable could be unplugged at any time. To do this I've written a C++ program that uses curl to try and establish a connection to a public web server over eth0. If successful it then tries to go and make the default route eth0. I've borrowed some code from the Linux pppd project to manipulate the routing information. The system boots up with ppp0 active. I then run my program, and it detects it can make a connection via eth0 (as the cable is plugged in), and it then changes the default route to eth0. After that networking somehow stops working, I can no longer ping and public servers. Somehow my changing the route has killed networking. Before I run my program, the output of "route" is:
Kernel IP routing table
Destination Gateway Genmask Flags Metric Ref Use Iface
80.sub-66-174-2 * 255.255.255.255 UH 0 0 0 ppp0
192.168.98.0 * 255.255.255.0 U 0 0 0 eth0
loopback * 255.0.0.0 U 0 0 0 lo
default * 0.0.0.0 U 0 0 0 ppp0
After I run my program, the output of "route" is:
Kernel IP routing table
Destination Gateway Genmask Flags Metric Ref Use Iface
66.174.217.80 * 255.255.255.255 UH 0 0 0 ppp0
192.168.98.0 * 255.255.255.0 U 0 0 0 eth0
loopback * 255.0.0.0 U 0 0 0 lo
default * 0.0.0.0 U 0 0 0 eth0
So I can't see any obvious signs of what's wrong. The code is posted at http://pastebin.com/AwKdvSf1
Thanks for any help or insights on how to fix this.
your default gateway ip address is not defined.
type route add default gw <gateway ip> as root (or sudo)
NOTE: using dhcp to assign ip settings would be best way I think to solve your problem otherwise you'll have to define the default route statically.
You'll have to add DEFROUTE=no in your ppp0 configuration.

connman: Auto-Connecting to multiple Ethernet interfaces at a time

Quite easy use-case: I have two Ethernet interfaces which should both be connected using DHCP. It does not matter which one the default route is, since it is just a dedicated proof-of-concept setup. However, hot-plugging must work for both interfaces (one of them is a CDC-NCM connection).
connman 1.17 seems only to try to establish a connection to one of the interfaces. If I unplug this connection, DHCP is started on the second interface and everything continues to work. I can connect the second interface always by using “connmanctl connect” manually. But…
… is there any way to configure connman to connect AUTOMATICALLY to both networks via DHCP?
is there any way to configure connman to connect AUTOMATICALLY to both networks via DHCP?
By default most DHCP servers are configured to issue a default route to the client. If you get two default routes, it's impossible for the linux networking stack to function properly.
Since you would want DHCP clients on both networks to be able to function properly, perhaps the best thing you can do is scan the system routing table and remove one of the default routes.
Typically you'd use netstat -rn to find the duplicate default...
[mpenning#tsunami micro]$ netstat -rn
Kernel IP routing table
Destination Gateway Genmask Flags MSS Window irtt Iface
172.16.1.0 0.0.0.0 255.255.255.0 U 0 0 0 eth0
172.16.2.0 0.0.0.0 255.255.255.0 U 0 0 0 eth1
239.0.0.0 0.0.0.0 255.0.0.0 U 0 0 0 eth0
0.0.0.0 172.16.1.1 0.0.0.0 UG 0 0 0 eth0 <--
0.0.0.0 172.16.2.1 0.0.0.0 UG 0 0 0 eth1 <--
[mpenning#tsunami micro]$
Then remove one of them...
[mpenning#tsunami micro]$ sudo route del default dev eth1
[mpenning#tsunami micro]$ netstat -rn
Kernel IP routing table
Destination Gateway Genmask Flags MSS Window irtt Iface
172.16.1.0 0.0.0.0 255.255.255.0 U 0 0 0 eth0
172.16.2.0 0.0.0.0 255.255.255.0 U 0 0 0 eth1
239.0.0.0 0.0.0.0 255.0.0.0 U 0 0 0 eth0
0.0.0.0 172.16.1.1 0.0.0.0 UG 0 0 0 eth0
[mpenning#tsunami micro]$
It's not so hard to write a shell script to check for this issue. However, a better solution is just to get a static address on one of the networks so you don't have to manage around the DHCP issue.

How do I route a packet to use localhost as a gateway?

I'm trying to test a gateway I wrote(see What's the easiest way to test a gateway? for context). Due to an issue I'd rather not get into, the gateway and "sender" have to be on the same machine. I have a receiver(let's say 9.9.9.9) which the gateway is able to reach.
So I'll run an application ./sendStuff 9.9.9.9 which will send some packets to that IP address.
The problem is: how do I get the packets destined for 9.9.9.9 to go to the gateway on localhost? I've tried:
sudo route add -host 9.9.9.9 gw 127.0.0.1 lo
sudo route add -host 9.9.9.9 gw <machine's external IP address> eth0
but neither of those pass packets through the gateway. I've verified that the correct IPs are present in sudo route. What can I do?
Per request, here is the route table, after running the second command(IP addresses changed to match the question. x.y.z.t is the IP of the machine I'm running this on):
Destination Gateway Genmask Flags Metric Ref Use Iface
9.9.9.9 x.y.z.t 255.255.255.255 UGH 0 0 0 eth0
x.y.z.0 0.0.0.0 255.255.254.0 U 0 0 0 eth0
0.0.0.0 <gateway addr> 0.0.0.0 UG 100 0 0 eth0
127.0.0.1 is probably picking up the packets, then forwarding them on their merry way if ipv4 packet forwarding is enabled. If it's not enabled, it will drop them.
If you are trying to forward packets destined to 9.9.9.9 to 127.0.0.1, look into iptables.
Edit: try this:
iptables -t nat -A OUTPUT -d 9.9.9.9 -j DNAT --to-destination 127.0.0.1
That should redirect all traffic to 9.9.9.9 to localhost instead.

Resources