I have a machine (running openSUSE Leap 15.3) with multiple public IP addresses which serves as a gateway for a few additional hosts. I need to make one of the public IPs on the gateway act as though it belongs to one of the machines connected to it (traffic is transparently forwarded).
My iptables-save
output currently is as follows (some irrelevant Docker rules are included but sensitive parts are redacted):
# Generated by iptables-save v1.8.7
*filter
:INPUT ACCEPT [9747976:4527721149]
:FORWARD ACCEPT [12638879:4423560060]
:OUTPUT ACCEPT [8913992:2531503118]
:DOCKER - [0:0]
:DOCKER-ISOLATION-STAGE-1 - [0:0]
:DOCKER-ISOLATION-STAGE-2 - [0:0]
:DOCKER-USER - [0:0]
-A FORWARD -j DOCKER-USER
-A FORWARD -j DOCKER-ISOLATION-STAGE-1
-A FORWARD -o docker0 -m conntrack --ctstate RELATED,ESTABLISHED -j ACCEPT
-A FORWARD -o docker0 -j DOCKER
-A FORWARD -i docker0 ! -o docker0 -j ACCEPT
-A FORWARD -i docker0 -o docker0 -j ACCEPT
-A DOCKER-ISOLATION-STAGE-1 -i docker0 ! -o docker0 -j DOCKER-ISOLATION-STAGE-2
-A DOCKER-ISOLATION-STAGE-1 -j RETURN
-A DOCKER-ISOLATION-STAGE-2 -o docker0 -j DROP
-A DOCKER-ISOLATION-STAGE-2 -j RETURN
-A DOCKER-USER -j RETURN
COMMIT
# Completed
# Generated by iptables-save v1.8.7
*nat
:PREROUTING ACCEPT [480085:188100350]
:INPUT ACCEPT [62951:4107383]
:OUTPUT ACCEPT [150:9857]
:POSTROUTING ACCEPT [0:0]
:DOCKER - [0:0]
-A PREROUTING -d <REDACTED_FORWARDING_IP>/32 -i eth0 -j DNAT --to-destination 10.125.0.2
-A PREROUTING -m addrtype --dst-type LOCAL -j DOCKER
-A OUTPUT ! -d 127.0.0.0/8 -m addrtype --dst-type LOCAL -j DOCKER
-A POSTROUTING -s 172.17.0.0/16 ! -o docker0 -j MASQUERADE
-A POSTROUTING -j MASQUERADE
-A DOCKER -i docker0 -j RETURN
COMMIT
# Completed
The only relevant parts of that, as far as I know, are:
-A PREROUTING -d <REDACTED_FORWARDING_IP>/32 -i eth0 -j DNAT --to-destination 10.125.0.2
-A POSTROUTING -j MASQUERADE
This still has a number of issues:
- When the internal machine initiates an outbound connection, its IP is NATed as the gateway's main address, not the address I'm trying to give it.
- When receiving connections, they appear to be coming from the gateway's local IP, not the original IP (there should be a way around that as this is the default gateway).
- If a service is listening on
0.0.0.0
on the gateway, connections on that port do not get redirected, they go to that service.
I tried to stitch together the answers to some other questions like:
- https://superuser.com/q/1130250
- https://superuser.com/q/1513820
- Iptables forward all traffic to a specified port, to another device
- Redirect all incoming traffic from a secondary public IP to an internal IP address using iptables
- Redirect all incoming traffic from a secondary public IP to an internal IP address using iptables
- https://superuser.com/q/681705
- https://unix.stackexchange.com/q/395008/381510
But due to my lack of significant iptables experience, I couldn't solve my problems, or solved some only for others to pop up.
Can anyone suggest some rules to achieve this effect? Or perhaps there's a way to do this without iptables?
iptables-save
output into the quesiton. All issues could have something to do with your SNAT rules set up. Also describe how you are making connections that display issues 2 and 3 (what is source address, what is inbound interface). I suspect you are SNATing too much, while DNAT rule matches could be made less restrictive.iptables-save
output as requested. All connections going though the gateway display issues 2 and 3. They reach the gateway oneth0:0
, the interface with the IP I'm trying to forward. In any case, my solution is likely very flawed due to my aforementioned lack of experience so it's probably best to not base answers on it. I mostly attached it to show that I have tried to do this myself.