HAIRPIN HAT not working

I’ve tried to implement a subset of your scenario. My PC is connected to the LAN interface of a RB, and the gateway to the internet is connected to the WAN interface of the same RB. There already was a srcnat masquerade rule on the WAN interface, and I’ve added a dstnat rule for ssh (proctocol=tcp,dst-port 22) for dst-address matching the WAN IP of the RB which redirects the packet to the internet gateway. This rule alone was enough to log in to the internet gateway from a PC in the LAN subnet when indicating RB’s WAN IP as destination and, noteworthy, to translate the source address of the TCP response from the internet gateway to RB’s WAN IP when forwarding the response to the PC. So the dst-nat rule automatically works as src-nat in the opposite direction for related packets. The nat configuration and the resulting connection look as follows:


/ip firewall nat
add action=masquerade chain=srcnat comment="defconf: masquerade" out-interface=ether1
add action=dst-nat chain=dstnat dst-address=192.168.5.173 dst-port=22 protocol=tcp to-addresses=192.168.5.1

/ip firewall connection print detail where src-address~":22" || dst-address~":22" || reply-src-address~":22" || reply-dst-address~":22" 
Flags: E - expected, S - seen-reply, A - assured, C - confirmed, D - dying, F - fasttrack, s - srcnat, d - dstnat 
 0  SAC Fsd protocol=tcp src-address=192.168.88.253:54434 dst-address=192.168.5.173:22 reply-src-address=192.168.5.1:22
  reply-dst-address=192.168.5.173:54434 tcp-state=established timeout=23h45m orig-packets=18 orig-bytes=2 356 orig-fasttrack-packets=0
  orig-fasttrack-bytes=0 repl-packets=19 repl-bytes=2 893 repl-fasttrack-packets=9 repl-fasttrack-bytes=1 713 orig-rate=0bps repl-rate=0bps

So “normally”, i.e. when the client and server are connected to different subnets and different physical ports, these two rules alone are sufficient to make things work properly - at TCP level, both the server and the client think they talk to the RouterBoard, and connection tracking handles that as a single connection. So the srcnat rule I’ve suggested before is redundant, and the reason why it does not work in your scenario is different. Can you please paste here the export of your “/ip firewall filter” rules? If they are not responsible, then it must be the hairpinning itself, but it does not seem logical to me.

add action=src-nat chain=srcnat out-interface=Local protocol=tcp src-address=192.168.0.52 src-port=629 to-addresses=1.1.1.10 to-ports=629
Wrong idea.

You need only 4 NAT rules:

  1. Classic masquerade for your local network in order to go to Internet;
  2. Destination NAT IN rule for your provider interface in order to get access to your web server from outside;
  3. Destination NAT IN rule for your LAN interface in order to translate IP packets from global destination to local destination;
  4. Source NAT OUT rule for your LAN interface in order to translate IP packets from local source ip to your router’s IP.

And absence of different firewall rules which can do collision of packets flow.

here are my firewall filters:
ordinary drop port rules for each in-iterface

;;; PROXY-ATAK-DROP
chain=input action=drop protocol=tcp in-interface=RADIO-LINK dst-port=8080 log=no 
log-prefix="" 

;;; PROXY-ATAK-DROP
chain=input action=drop protocol=tcp in-interface=VDSL-ETH dst-port=8080 log=no 
log-prefix="" 

;;; DNS-ATAK-DROP
chain=input action=drop protocol=tcp in-interface=VDSL-ETH dst-port=53 log=no 
log-prefix="" 

;;; DNS-ATAK-DROP
chain=input action=drop protocol=tcp in-interface=RADIO-LINK dst-port=53 log=no 
log-prefix=""

If firewall would be preventing the client on LAN from connecting to the server also on LAN redirected from the WAN IP of the Mikrotik, rules in filter chain “forward” would be responsible. So if no such rules exist, the reason must be different. I’ll rearrange my test setup a bit to fully match yours and see what happens.

Hi Anumrak, for your described 4 rules, i checked my rules again. now my rules are shown like this:

  1. Classic masquerade for your local network in order to go to Internet;
    add action=masquerade chain=srcnat out-interface=RADIO-LINK src-address=192.168.0.0/24

  2. Destination NAT IN rule for your provider interface in order to get access to your web server from outside;
    add action=dst-nat chain=dstnat dst-port=629 in-interface=RADIO-LINK protocol=tcp to-addresses=192.168.0.52 to-ports=629

  3. Destination NAT IN rule for your LAN interface in order to translate IP packets from global destination to local destination;
    add action=dst-nat chain=dstnat dst-address=1.1.1.10 dst-port=629 in-interface=Local protocol=tcp src-address=192.168.0.0/24 to-addresses=192.168.0.52 to-ports=629

  4. Source NAT OUT rule for your LAN interface in order to translate IP packets from local source ip to your router’s IP.
    add action=src-nat chain=srcnat out-interface=Local protocol=tcp src-address=192.168.0.52 src-port=629 to-addresses=1.1.1.10 to-ports=629

Still it is not working :frowning:

In torch tool only “Local” interface was catches packages. (I guess this is normal)
mikrotik-nat-problem-20180115-1.PNG
mikrotik-nat-problem-20180115-2.PNG

What is the device 192.168.0.52?

This is the server which I want to reach in local network.

i want to reach to local server (192.168.0.52) in local network (my local ip: 192.168.0.195) with external ip (1.1.1.10). (My external IP is static)
When i try reach from out network (e.g. 2.2.2.2) to (1.1.1.10) → SUCCESS
When i try reach from in network (192.168.0.195) to (192.168.0.52) → SUCCESS
When i try reach from in network (192.168.0.195) to (1.1.1.10) → FAIL : ERR_CONNECTION_REFUSED

What exactly is this server? Does it have iptables or something?

This is QNAP NAS server.
OS: QTS 4.3.4.0.4.35

In web panel, it hasn’t iptables configuration. It has only TCP/IP network configuration.
mikrotik-nat-problem-20180115-3.PNG

Instead of torch, use packet sniffing to file and Wireshark to see what the response from the server was. At this stage we need to know whether the Mikrotik rejects the TCP session establishment or the server does. @Anumrak’s question expresses a suspicion that the server may refuse requests coming from Mikrotik’s own address (which is the case when the client connects to 1.1.1.10 and Mikrotik does a dst-nat and src-nat while forwarding the request) while it accepts requests coming from another address in the same subnet (which is the case when the client connects to 192.168.0.52 which means that routing and all firewall rules on Mikrotik are bypassed).

Wireshark result with filter (port 629) from client. (192.168.0.195)
mikrotik-nat-problem-20180115-4.PNG

You have TCP Reset segments. They transmitted because of wrong or not existing connection. Try to make hairpining to something else in your LAN.

What I can see in the capture is that the initial SYN packet from the client goes to the public address, but the response SYN,ACK from the server comes from the real address of the server, which makes the client send a RST as the SYN,ACK comes from an unexpected source. So the src-nat action (not necessarily rule!) in the server->client direction fails.

@emrah, I assume the client and the server are connected directly to RouterBoard’s physical ports, or, if some other switching gear is between them and the RouterBoard, that it is possible for you to re-arrange cabling in such a way that the client is connected through one physical port of the RouterBoard and the server through another one. Once you are sure that the physical path between the cleint and server goes through the RouterBoard, sniff at both ports simultaneously. And set a display filter “tcp.port == 629 or icmp” when taking the screenshot of the result in Wireshark.

Either one of your NAT rules does not work as expected (maybe because connection tracking does not work), or the RouterBoard sends an icmp redirect to the server when it finds out that it should forward a packet to the same subnet from which it has arrived, so the server re-sends the packet directly to the client.

Anumrak can help?

I have problem with hairpin. It’s not working.
3 rules:

add action=dst-nat chain=dstnat dst-address=GLOBALIP dst-port=80 protocol=tcp src-address=!192.0.0.0/23 to-addresses=192.0.0.13 to-ports=80
add action=dst-nat chain=dstnat dst-address= GLOBALIP dst-port=80 in-interface=bridge1 protocol=tcp src-address=192.0.0.0/23 to-addresses=192.0.0.13 to-ports=80
add action=masquerade chain=srcnat dst-address=192.0.0.13 dst-port=80 out-interface=bridge1 protocol=tcp

192.0.0.13 - host with web server
it’s working from other network, locally not.
bridge1 was default defined in rb, is this problem?