I am trying to forward packets to a firewall without using NATting in order to preserve the original destination IP.
The scenario is the following:
- I have a physical server connected to the internet with multiple external IPs via only one physical network adapter.
- This physical server is running as a hypervisor. One of the virtual machines is running pfSense as a firewall and should take care of all the port forwarding to the other VMs (which are in a different network which only the firewall has direct access to and does NATting for).
- The idea is to forward / redirect incoming packets for the multiple external IPs to the pfSense firewall so I can set up the port forwarding rules only once in that central place.
The problem is that if I were to use NAT, I would of course replace the destination IP of the incoming packet with the firewall's IP before passing it on to the firewall. That works fine for just one external IP, but with multiple external IPs I would lose the information about which external IP was originally targeted, effectively limiting me to only one port forwarding across all external IPs.
Question: Is there a way to forward the packets to the pfSense firewall without changing the destination IP or while preserving this information somehow for use with the pfSense firewall?
I tried using the iptables mangle table and setting a mark / fwmark for the packets + using ip route and ip rule to redirect the package, but it does not seem to be working:
Hypervisor:
External IP 1 = 123.123.123.123
Firewall network IP = 10.0.0.1
pfSense firewall
Firewall network IP = 10.0.0.2
iptables -t mangle -A PREROUTING -d 123.123.123.123/32 -j MARK --set-mark 1
iptables -A FORWARD -d 123.123.123.123/32 -j ACCEPT
ip route flush table 1
ip route add table 1 default via 10.0.0.2
ip rule add fwmark 1 table 1
The ip rule does work:
# ip route get 1.1.1.1 mark 0
1.1.1.1 via 123.123.123.1 dev xenbr0 src 123.123.123.123 uid 0
cache
# ip route get 1.1.1.1 mark 1
1.1.1.1 via 10.0.0.2 dev xenbr0 table 1 src 10.0.0.1 mark 1 uid 0
cache
iptables shows me that these relevant rules do get properly executed, but when I run tcpdump on the hypervisor:
tcpdump -i any -n tcp and dst port 12345
then I only see the two entries for the incoming packet, not another set of two like I would when using DNAT.
tcpdump on pfSense does not show me anything:
tcpdump -i xn0 -n tcp and dst port 12345
At this point I am not sure if iptables or the ip route / rule part are even working, but I could not find a good way to test this.
I am open to different approaches, but I would like to keep the current network layout.
Thank you!