Centos 7 routing doesn't keep source IP

Issues related to configuring your network
Post Reply
JeffMings
Posts: 19
Joined: 2014/01/05 02:23:14

Centos 7 routing doesn't keep source IP

Post by JeffMings » 2017/10/04 22:40:34

I know someone on this forum is clever enough to resolve this, and probably even faster than it takes to read this :)

When switching from Centos 6 to Centos 7 a long time ago, I noticed that routing and port forwarding don't behave the same way. Briefly, packets don't keep their source / "upstream" IP address over port forwarding or routing.

Here are some simple examples for servers using OpenVPN VPN tunnels, which use "intermediate" PTP interfaces to do the actual connections for the tunnels. The "local" server is the router/edge/gateway device with a public internet connection, a connection to an internal network, and some VPN tunnels with their associated tunX interfaces and their PTP connections/addresses. Let's use specific examples of NICs on the local server:
eth1 > internet NIC with public IP address, e.g. 7.7.7.7
eth0 > LAN NIC with address 192.168.1.1/24
tun0 > VPN NIC with PTP address 10.1.1.1 , connects to remote server with matching PTP address of 10.1.1.2. Remote server has LAN address of 192.168.9.1/24.
tun1, tun2, tun3 also exist on the local server as OpenVPN tunnels to other locations.

So, a local PC, on the local network, with an IP of 192.168.1.11 can easily ping a remote PC, on the remote network, with an IP of 192.168.9.99. Everything works, all traffic flows as expected.

Under Centos 6:
tcpdump on the remote PC at 192.168.9.99 will show ICMP packets from the local PC coming across tun0, with the IP of the local LAN's PTP IP of 10.1.1.1. I.e., the remote PC will receive pings with the IP address of the VPN NIC on the local server. One can see, on the remote PC, where the packets are coming from. The pings went from the local PC, through the local PC's default gateway, which is the local server's LAN NIC, at 192.168.1.1. The packets were routed through the local server's VPN tun0 at 10.1.1.1 through the VPN NIC on the remote server, at 10.1.1.2, to the remote PC at 192.168.9.99

Under Centos 7:
tcpdump on the remote PC (receiving pings from the local PC) at 192.168.9.99 will show ICMP packets coming from the remote server at 192.168.9.1. Once can't see where the pings came from. One only knows that they came from the remote server itself, or were somehow routed through it.

The same thing happens with port forwarding.
Under Centos 6, the source address of the external host sending packets to an inside host can be seen. E.g. host 8.8.8.8 can be seen sending forwarded ssh packets to an internal host at 192.168.1.11.
Under Centos 7, the internal host only sees the address of the server forwarding the packets. E.g., the packets are seen coming from the server, 192.168.1.1, instead of the external host at 8.8.8.8.

Originally, this was a minor annoyance. Now, however, it is preventing internal Asterisk VMs/boxes from making reliable IAX2 connections to a SIP trunking service.

How can I correct the loss of originating/source IP in forwarding/routing on Centos 7? I have spent a lot of time searching this forum and googling for an answer. I have seen another recent forum request with the same problem.


Some more info:
I have been in the habit of using "out of the box" firewall/routing on both Centos 6 and 7. I don't string together IPTables commands.
Under Centos 6, I would use the simple terminal based "setup" to create basic rules.
Under Centos 7, I generally use the GUI firewall-config, but I certainly know firewall-cmd well enough to use it, in conjunction with the config files in /etc/firewalld, to set up firewalls. I always turn off network-manager, since the NICs don't change, and I don't need another service trying to mess with things. SELinux is always turned off. Masquerading is set per the simple "check-box" option in firewall-config.

Thank You :)

User avatar
jlehtone
Posts: 4530
Joined: 2007/12/11 08:17:33
Location: Finland

Re: Centos 7 routing doesn't keep source IP

Post by jlehtone » 2017/10/12 09:12:10

Interesting.

Base case:

Code: Select all

# tcpdump -nn -vv -i eth0 host 8.8.8.8
tcpdump: listening on eth0, link-type EN10MB (Ethernet), capture size 262144 bytes
11:58:57.190698 IP (tos 0x0, ttl 64, id 6295, offset 0, flags [DF], proto ICMP (1), length 84)
    10.0.0.10 > 8.8.8.8: ICMP echo request, id 6067, seq 1, length 64
11:58:57.200400 IP (tos 0x0, ttl 49, id 42339, offset 0, flags [none], proto ICMP (1), length 84)
    8.8.8.8 > 10.0.0.10: ICMP echo reply, id 6067, seq 1, length 64

# traceroute 8.8.8.8
traceroute to 8.8.8.8 (8.8.8.8), 30 hops max, 60 byte packets
 1  fubar (10.0.0.1)  0.275 ms  0.226 ms  0.185 ms
 2 ISP router (public IP) ...
The fubar is a CentOS 7 and does SNAT on its public interface.
The pong is clearly from source 8.8.8.8, not from 10.0.0.1.

You say that if the fubar would route to a OpenVPN tunnel, then fubar would masquerade the replies. Is that an issue created by the OpenVPN?

You say that port forwarding adds masquerade. It would be interesting to see the actual netfilter ruleset that the configuration tools generate.

Post Reply