Hairpin NAT not working

I have a public IP of 1.1.1.1 which has various port forwards on it.

For example, 1.1.1.1:80<>192.168.1.1:80 (same for 443, etc…).
When I try access my domain internally (domain.com = 1.1.1.1) I get connection refused. External → in - works fine.

jack@apollo:~ » curl 1.1.1.1. 80                                                                                                                                                                                               7 ↵
curl: (7) Failed to connect to 1.1.1.1 port 80: Connection refused

I have tried to implement hairpin NAT to overcome this situation. Below are my NAT rules (eth1 is WAN interface):


     0    ;;; HAIRPIN
          chain=srcnat action=masquerade src-address=192.168.1.0/24 dst-address=192.168.1.0/24 log=yes log-prefix="HAIRPIN!!"
    
     1    ;;; masquerade internal to eth1
          chain=srcnat action=masquerade out-interface=ether1 log=no log-prefix=""
    
     2    ;;; 443 to proxy
          chain=dstnat action=dst-nat to-addresses=192.168.1.1 to-ports=443 protocol=tcp in-interface=ether1 dst-port=443 log=no log-prefix=""
    
     3    ;;; 80 to proxy
          chain=dstnat action=dst-nat to-addresses=192.168.1.1 to-ports=80 protocol=tcp in-interface=ether1 dst-port=80 log=no log-prefix="NATTTT"

The above does not seem to be working. When trying to access ‘domain.com’ my hairpin nat counter is not increasing. I have also tried telnet, wget and curl to the domain on port 80 to see if I can get the counter to increase with no luck.

Below are my firewall rules, which are not blocking this:

     0  D ;;; special dummy rule to show fasttrack counters
          chain=forward action=passthrough
    
     1    ;;; Allow established
          chain=input action=accept connection-state=established log=no log-prefix=""
    
     2    ;;; Allow related
          chain=input action=accept connection-state=related log=no log-prefix=""
    
     3    ;;; Permit web to web.homelab
          chain=forward action=accept connection-nat-state=dstnat protocol=tcp dst-address=192.168.1.1 in-interface=ether1 dst-port=80,443,5000 log=no log-prefix=""
    
     4    ;;; DST NAT ALLOWED
          chain=forward action=accept connection-state="" connection-nat-state=dstnat log=no log-prefix=""
    
     5    ;;; defconf: fasttrack
          chain=forward action=fasttrack-connection connection-state=established,related log=no log-prefix=""
    
     6    ;;; Deny all from WAN
          chain=input action=drop connection-state="" in-interface=ether1 log=no log-prefix=""
    
     7    ;;;  Drop  invalid  connections
          chain=input action=drop connection-state=invalid log=no log-prefix=""
    
     8    ;;; Drop all from WAN not DSTNATed
          chain=forward action=drop connection-state=new connection-nat-state=!dstnat in-interface-list=WAN log=no log-prefix=""
    
     9    ;;; Matching no rules
          chain=forward action=passthrough log=no log-prefix=""

Even when disabling all deny rules I get no hairpin nat counter increase. Any help would be appreciated as I am out of ideas.

What doesn’t work for you is the dstnat part. You have dstnat rules with in-interface=ether1, but when connecting from inside, in-interface is , so rules don’t match. You need to remove in-interface=ether1 and instead use dst-address=1.1.1.1.

As per @Sobhas replied.

Your in interface is not matching as your packets are not coming up your WAN interface when you try to reach the hairpinned host from your LAN.
Using your WAN IP as the DST address will fix that completely.

If you have dynamic WAN IP then let us know as there is a very simple work around for that also.

Hello!
I’m having a similar problem, I’ve been trying for ages to sort this hairpin NAT, my mail server is sitting behind a DMZ switch and I can access it externally from another ISP, but can’t see it from inside our network.

For this example:
Vlan 205 is my WAN access
1.1.1.1 is my WAN IP for this question
192.168.20.65 is my mail server IP

add action=masquerade chain=srcnat comment=“Natting Incoming” out-interface=“Vlan 205”

add action=masquerade chain=srcnat comment=“Hairpin NAT” dst-address= 192.168.0.0/16 src-address=192.168.0.0/16

add action=dst-nat chain=dstnat comment=“HTTP/SSL” dst-address=1.1.1.1 dst-address-type=“local” dst-port=443 protocol=tcp to-addresses=192.168.20.65 to-ports=443

Any help appreciated, thank you!

Masquarde traffic that comes from you local subnet back to your local subnet on the local interface.

thanks for your help, but I’ve added my LAN port to the Hairpin NAT and it’s still not working

Have a watch of this. My very simple way of hair-pinning your NAT.
https://www.youtube.com/watch?v=_kw_bQyX-3U

Hi Steveo

I did watch your video a few times over the weekend, configured it exactly like your setup with the addition of having a static WAN IP. Still won’t work.

Any ideas?

Make a new thread on this forum (so you don’t spam this one) and post your config. Lets go through it and we’ll sort it.