hairpin NAT not working

Hi, I have a RB2011iL-RM router. ETH1 is connected to a TCom router (so there is double NAT). All the other ports are in bridge_local.
My LAN ip address range is 192.168.1.0/24.
I have an ip cam on 192.168.1.90. I would like to reach it through my dyndns domain, since I have dynamic ip from TCom.
And obviously I want to use the same domain on the LAN and outside as well, that is why I want to set up hairpin.
Before working out a solution for the changing WAN address, I tried to have it work on the actual public IP address.

Here is my NAT settings:
Flags: X - disabled, I - invalid, D - dynamic
0 ;;; srcnat rule
chain=srcnat action=masquerade to-addresses=0.0.0.0
out-interface=ether1-gateway log=no log-prefix=“”

1 chain=dstnat action=dst-nat to-addresses=192.168.1.90 to-ports=80
protocol=tcp dst-address=my_current_ip in-interface=ether1-gateway
dst-port=80 log=no log-prefix=“”

2 chain=srcnat action=masquerade protocol=tcp src-address=192.168.1.0/24
dst-address=192.168.1.90 out-interface=bridge-local dst-port=80 log=no
log-prefix=“”

Through WAN, it works. From local LAN it does not. Theoretically, it is the example config from the Hairpin NAT wiki…

What is wrong with this setting?

The public IP is not on the Mikrotik, so when you attempt to access the public IP from the LAN, the Mikrotik doesn’t realize this hairpin needs to happen. If you tried using the ether1-gateway IP from the LAN, that would work with what you have.

Add another dstnat rule:
dst-address=public_ip_address protocol=tcp dst-port=80 to-address=192.168.1.90

Thank you. Now it works. Actually this is my working scenario:
0 ;;; srcnat rule
chain=srcnat action=masquerade to-addresses=0.0.0.0
out-interface=ether1-gateway log=no log-prefix=“”

1 ;;; hairpin part starts here
chain=dstnat action=dst-nat to-addresses=192.168.1.90 to-ports=80
protocol=tcp dst-address=84.0.95.48 dst-port=80 log=no log-prefix=“”

2 chain=dstnat action=dst-nat to-addresses=192.168.1.90 to-ports=80
protocol=tcp in-interface=ether1-gateway dst-port=80 log=no log-prefix=“”

3 chain=srcnat action=masquerade protocol=tcp src-address=192.168.1.0/24
dst-address=192.168.1.90 out-interface=bridge-local dst-port=80 log=no
log-prefix=“”

Now comes the tricky part. How to make it permanent. I have dyndns account and a dyndns script is checking my public ip address every 10 minutes. Whenever it changes, dyndns records are updated.

Googling the net, I found a script:
:global hostname
:global resolvedIP [:resolve $hostname]
/ip firewall nat set [find comment~“hairpin”] dst-address=$resolvedIP

However, it was not working. I run the script manually and

  1. resolvedIP never showed up in the “environment” of tab of the script list,
  2. dst-address was not changed, I set it initially to 0.0.0.0 to check the script.

What is the problem?

probably your script has a syntax error that is preventing it from running from the scripts list, but runs okay on command line (I’ve had that happen a few times, but I can’t recall what exactly my issue was).

Put some debug outputs in your script and run it and see if it appears in the logs:

:log debug “resolved IP to $resolvedIP”

You’ll need to add a logging entry for script,debug in order to see this output, or change the facility to info or warn or something that is already being logged by default. I just did the command :put [:resolve ] and it worked, so that command seems fine. Probably you have a missing " mark or something somewhere in the script. Any error at all will keep it from running, even if the error is on the last line of the script.