Closed baccenfutter closed 1 year ago
The limit of what keepalived does in respect of IPVS is it adds and removes IPVS configuration just as ipvsadm
does. What IPVS does, how it works, and how to configure it is outside the scope of keepalived. Generally if someone is having difficulty getting IPVS to work, I advise configuring it with ipvsadm
without using keepalived, getting that working, and then updating the keepalived configuration so that it sets up the same IPVS configuration as has been got working with ipvsadm
. However, I can provide some pointers for you to explore.
You state:
The documentation in several sources (here is one) clearly states that the NAT forwarding technique is a combination of SNAT and DNAT, where packets are forwarded to the backends via address translation in a way that the return packets will find their way back through the keepalive host (masquerading, a.k.a. SNAT).
I cannot see any statement there that IPVS masquerading does SNAT, nor even any suggestion that it might. My understanding is that masquerading does NOT do SNAT, and that therefore the default route from the real servers has to be via the keepalived host (or more specifically via the host on which the IPVS configuration is set up) [there are ways around using the default route which I will explain below]. The best place for descriptions of how IPVS works (albeit extremely old) is on the Linux Virtual Server web site; here the examples clearly show that there is no SNAT performed. The best starting point is IPVS documentation.
There are ways of applying SNAT to the packets, but it is a bit convoluted - see below.
If the IP addresses of the real servers are only used for those services, in other words all packets from the real server hosts with the source address being the address configured in the keepalived real server entries), then it is possible to use source based routing to return packets sent from the real server addresses via the keepalived server(s). It would require a keepalived virtual router to be configured on the private side of the keepalived host, so that the real servicice packets are returned via the VIP.
Suppose a real service is on address 10.0.0.1 TCP port 80, and the private address of your keepalived host is 192.168.0.1. You could specify the following:
ip rule add from 10.0.0.1 ipproto TCP sport 80 table 30000
ip route add default via 192.168.0.1 table 30000
In order to apply SNAT as well, it is necessary to forward the packets to the real server via a separate network namespace. The SNAT can then either be done in the added network namespace or in the default network namespace. I can't remember if packets returned need to be routed via the added network namespace or not (they certainly do if the SNAT is done in the added network namespace). The reason for forwarding incoming packets via the added network namespace is so that when they are forwarded from the added network namespace back to the default network namespace, the packets pass through the protocol stack is if they are new packets, and pass though the relevant tables if nftables/iptables to be able to apply the SNAT. If the packets do not go via the added network namespace, then IPVS makes the packets skip the NAT tables in nftables/iptables.
If you want to use the above approach for applying SNAT, then please update this issue, and I will look at providing some more detailed configuration examples (there was an issue reported a few years ago where I provided the details of how to do this).
It is in fact called masquerading:
# ipvsadm -l -n
IP Virtual Server version 1.2.1 (size=4096)
Prot LocalAddress:Port Scheduler Flags
-> RemoteAddress:Port Forward Weight ActiveConn InActConn
TCP <virtual_server>:80 wlc persistent 50
-> <real_server>:80 Masq 1 0 0
-> <real_server>:80 Masq 1 0 0
The stated documentation also clearly speaks about SNAT if you read the first paragraph all the way through:
The replies are also translated in the reverse direction, when the real servers reply to the users’ requests.
It shouldn't be called masquerading, if it is in fact not masquerading. Masquerading is a well-defined term and it means SNAT. See:
It should instead be called: Forwarding
or Port-Forwarding
, or at least simply NAT
. But Masquerading
explicitly refers to SNAT.
I interpret
The replies are also translated in the reverse direction, when the real servers reply to the users’ requests.
to mean that the source address of the reply is translated (i.e. the reverse direction action for DNAT).
I agree calling it NAT would be more descriptive of what happens, but it has been called masquerading in IPVS for nearly 20 years now.
bug description
(tbh, I am not even sure if this is not rather a Linux/IPVS bug)
The documentation in several sources (here is one) clearly states that the NAT forwarding technique is a combination of SNAT and DNAT, where packets are forwarded to the backends via address translation in a way that the return packets will find their way back through the keepalive host (masquerading, a.k.a. SNAT).
The
ipvsadm
tool also clearly lists the backends as forward type ("Masq").However,
tcpdump
on my backends unmistakably shows that the packets are NOT masqueraded and in in fact are originating from the original src-ip. Since my backends are LXC containers on remote hosts, the return packets take the default route through the lxdbr0 and are black-holed.To Reproduce
tcpdump -n -i eth1 port 80
in the CTcurl http://<public-ip>/
on your laptoptcpdump
shows the requests originating from your laptop, NOT from the NAT gatewayExpected behavior The traffic from the virtual_server to the real_server should be masqueraded and hence all return packets should route back through the keepalived host and not via some random default route.
Keepalived version
Distro
Details of any containerisation or hosted service
images:debian/11
container imageConfiguration file:
System Log entries
Did keepalived coredump?
Am I completely missing something? I couldn't find any hints in
man keepalived.conf
, nor on big G.