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?