I have forwarded a few ports to the internal local IP addresses and I can access the services on those ports from the internet.
But when I try to access these services from inside local network using the public IP address it’s not working. (This seems to be called Hairpin NAT https://wiki.mikrotik.com/wiki/Hairpin_NAT)
I added 3 Hairpin rules in /ip firewall nat, one for each port that I have forwarded but that did not help. Here is my configuration:
[admin@MikroTik] > /ip firewall raw print all
Flags: X - disabled, I - invalid, D - dynamic
0 D ;;; special dummy rule to show fasttrack counters
chain=prerouting action=passthrough
[admin@MikroTik] > /ip firewall nat print all
Flags: X - disabled, I - invalid, D - dynamic
0 ;;; defconf: masquerade
chain=srcnat action=masquerade out-interface-list=WAN ipsec-policy=out,none
1 ;;; masq. vpn traffic
chain=srcnat action=masquerade src-address=192.168.89.0/24 log=no log-prefix=""
2 ;;; OpenVPN
chain=dstnat action=dst-nat to-addresses=192.168.1.110 to-ports=1194 protocol=udp in-interface=ether1 dst-port=1194 log=no log-prefix=""
3 ;;; Gitlab ssh
chain=dstnat action=dst-nat to-addresses=192.168.1.110 to-ports=5522 protocol=tcp in-interface-list=WAN dst-port=5522 log=no log-prefix=""
4 ;;; Hairpin 3
chain=srcnat action=masquerade protocol=tcp src-address=192.168.1.0/24 dst-address=192.168.1.110 out-interface-list=LAN dst-port=5522 log=no log-prefix=""
5 ;;; nginx Rev Proxy http
chain=dstnat action=dst-nat to-addresses=192.168.1.110 to-ports=81 protocol=tcp in-interface=ether1 dst-port=80 log=no log-prefix=""
6 ;;; Hairpin 1
chain=srcnat action=masquerade to-ports=80 protocol=tcp src-address=192.168.1.0/24 dst-address=192.168.1.110 out-interface-list=LAN dst-port=81 log=yes log-prefix=""
7 ;;; nginx Rev Proxy https
chain=dstnat action=dst-nat to-addresses=192.168.1.110 to-ports=444 protocol=tcp in-interface=ether1 dst-port=443 log=no log-prefix=""
8 ;;; Hairpin 2
chain=srcnat action=masquerade to-ports=443 protocol=tcp src-address=192.168.1.0/24 dst-address=192.168.1.110 out-interface-list=LAN dst-port=444 log=yes log-prefix=""
[admin@MikroTik] > /ip firewall mangle print all
Flags: X - disabled, I - invalid, D - dynamic
0 D ;;; special dummy rule to show fasttrack counters
chain=prerouting action=passthrough
1 D ;;; special dummy rule to show fasttrack counters
chain=forward action=passthrough
2 D ;;; special dummy rule to show fasttrack counters
chain=postrouting action=passthrough
[admin@MikroTik] > /ip firewall filter print all
Flags: X - disabled, I - invalid, D - dynamic
0 D ;;; special dummy rule to show fasttrack counters
chain=forward action=passthrough
1 ;;; defconf: accept established,related,untracked
chain=input action=accept connection-state=established,related,untracked
2 ;;; allow IPsec NAT
chain=input action=accept protocol=udp dst-port=4500
3 ;;; allow IKE
chain=input action=accept protocol=udp dst-port=500
4 ;;; allow l2tp
chain=input action=accept protocol=udp dst-port=1701
5 ;;; allow pptp
chain=input action=accept protocol=tcp dst-port=1723
6 ;;; allow sstp
chain=input action=accept protocol=tcp dst-port=443
7 ;;; defconf: drop invalid
chain=input action=drop connection-state=invalid
8 ;;; defconf: accept ICMP
chain=input action=accept protocol=icmp
9 ;;; defconf: drop all not coming from LAN
chain=input action=drop in-interface-list=!LAN
10 ;;; defconf: accept in ipsec policy
chain=forward action=accept ipsec-policy=in,ipsec
11 ;;; defconf: accept out ipsec policy
chain=forward action=accept ipsec-policy=out,ipsec
12 ;;; defconf: fasttrack
chain=forward action=fasttrack-connection connection-state=established,related
13 ;;; defconf: accept established,related, untracked
chain=forward action=accept connection-state=established,related,untracked
14 ;;; defconf: drop invalid
chain=forward action=drop connection-state=invalid
15 ;;; defconf: drop all from WAN not DSTNATed
chain=forward action=drop connection-state=new connection-nat-state=!dstnat in-interface-list=WAN
Can you please help me resolve this issue? Thanks.
Doing a HairPinNat I never use any interface like out-interface-list=LAN and my action was always action=src-nat to-addresses=192.168.1.1 where 192.168.1.1
is a MikroTik interface. Example:
HairPinNat is used when Client and Server are in the same subnet and Client try reach Server via PublicIP (DNAT).
When C and S are in different subnets base vlans then this just work without HairPinNat.
In HairPinNat rule is from LOCAL IP to LOCAL IP via Router LOCAL IP.
from 192.168.1.123 to 192.168.1.2 SNAT via 192.168.1.1 ← one host to host
from 192.168.1.0/24 to 192.168.1.2 SNAT via 192.168.1.1 ← full subnet to host
from 192.168.1.0/24 to 192.168.1.0/24 SNAT via 192.168.1.1 ← full subnet to subnet
The gold key to solve your problem is to not use in DNAT the in-interface=ether1 because the LAN to LAN network not go by ether1 interface (the WAN interface).
This means all your testing HairPinNat just cannot work in that DNAT rule.
This is ok. Masq action use interface from routing means a proper one and check his IP address and use it to hide your all 192.168.1.0/24 before 192.168.1.110 as Router itself IP - the 192.168.1.110 thinking he speak only with router and for him a router is like PC in the same subnet and he not use a default gateway to this conversation.
.
I not checking them but you try log and any analize of situation. Very good. Remember that biggest help you can reach by /tool sniffer and he in this scenario show you more then other tools.
Now I hope it’s be easy as easy to correct the DNAT. I not know what you have a WAN interface, static IP or receive dynamic etc. then I not do anythink know about this matter. Write me if you not understand any stuff.
HairPinNat is tricky and very fun. When someone have full understanding what do DNAT and SNAT then many many situation was fix by that like change flow from one IPSec to other one by not existing third adressing… but it’s btw.
Small correction, to-addresses=192.168.50.1 in hairpin/srcnat rule is ok, and to-addresses=2.2.2.2 was ok too. It may be less common, but it will work. It’s just the fake address used as new source for connections from LAN client back to LAN server via public address. Anything except addresses from same LAN subnet will work.
The problem here, as was already written, is in-interface=ether1 in dstnat rules. If your public address is static, replace it with dst-address=. If it’s dynamic, use dst-address-type=local. If it’s for ports not used by router itself, it’s enough. If the same port is used also by router (e.g. 80 for WebFig), you need to add extra dst-address=!<router’s LAN address> to exclude it from dstnat, otherwise you wouldn’t be able to connect, because everything would be forwarded to internal server.
Thank you for your help guys. In dstnat rules, I replaced in-interface=ether1 with dst-address=2.2.2.2 and the problem is solved! Woot woot!
I don’t officially have a static IP address but my experience says that once my ISP assigns an IP to my router, it never changes it. So I should be good.
But you never know when it might change. If you use dst-address-type method, it will always work. Or, if you’d be feeling up for some advanced stuff, you can keep using dst-address and use lease script to update it. Cool stuff, everyone would envy you. Or you can go with DDNS and address list. RouterOS offers different ways.