NAT Reflection on the WAN interface (packet with WAN IP as source)
-
Hey, I started using pfSense recently, after many years just using my ISP provided router (Technicolor TG789vac v2) and I noticed something weird.
When I started reading about Port Forwarding and NAT Reflection, the consensus seems to be that the only way to do it, necessitates that the target system (Server) will always see the Router as the source of the packets sent by a Client in the same network, as described by the pink path in the attached image. (When using the public address)However, in all these years, I had grown used to the Client seeing the packets as originating from the Public Address, as described by the green path in the image.
How do these consumer routers achieve this, and can this be replicated in pfSense? (or PF in general)
This is a bit of an academic scenario, but I appreciate any help or reading suggestions. Thanks!TL;DR: Can pfSense hairpin nat on the wan interface?
-
I can't get an idea what's this good for.
The NAT reflection aims that response packets are addressed back to pfSense, so it can direct them back to the origin device. It doesn't matter if the packets are addressed to the WAN or LAN IP, they will go back to pfSense.What source address the packets get is no issue of the path they are going through pfSense, but of NAT.
So if you really want to have them the WAN address as source, simply add an outbound NAT rule to translate properly. -
This post is deleted! -
@viragomann Mostly academic, my previous ISP-issued router worked that way, and I had always taken it for granted.
So it got me curious about if it is possible to replicate that behavior with pfSense or pf.
I tried the outgoing rules, I even went and changed the /etc/inc/filter.inc file (that generates the reflection rules) to force the automatic port forward reflection rules to point to the WAN IP.rdr on vtnet1 proto tcp from any to WAN_IP port 22 -> SSH_SERVER no nat on vtnet1 proto tcp from (vtnet1) to SSH_SERVER port 22 nat on vtnet1 proto tcp from PRIVATE_NET to SSH_SERVER port 22 -> LAN_IP port 1024:65535
to
rdr on vtnet1 proto tcp from any to WAN_IP port 22 -> SSH_SERVER no nat on vtnet1 proto tcp from (vtnet1) to SSH_SERVER port 22 nat on vtnet1 proto tcp from PRIVATE_NET to SSH_SERVER port 22 -> WAN_IP port 1024:65535
But it doesn't work. I'm assuming the NAT state is either not shared across interfaces or something...
-
No, it's the Outbound NAT (S-NAT or masquerading) which has to be adapted.
Firewall > NAT > OutboundNever tested this, cause as stated above, that makes no sense for me. However, you may give it a try.
If your outbound NAT is in automatic mode switch into hybrid and save that setting.
Add a rule:
interface: LAN
source: LAN net
destination: LAN net or a specific IP
translation: WAN address -
@viragomann I think that's what NAT is on pf, DNAT is rdr (change destination ip and keep source).
If I create an outbound rule, the resulting pf rule in /tmp/rules.debug is:nat on $LAN inet proto tcp from LAN_NET/16 to LAN_IP/32 port 22 -> WAN_IP/32 port 1024:65535
Which doesn't work. Interestingly, if I change the mask of the translation address to WAN_IP/24, it works, but the last octet of the public ip will be wrong (it will round robin over that /24 net).
It also works if I set the translation IP to any other IP in the WAN_NET except the actual WAN_IP.