Port forwarding to router itself doesn't work

Hello,

I did a lot of port forwarding and they worked, but when I’m trying to forward to router itself, I have Connection Timed Out.

My network map is: a LAN cable comes from modem and goes to PPPoE In to the MT device (modem is not bridged), and MT creates a WiFi interface and I connect to MT.
Modem’s IP is 192.168.1.1, MT’s IP is both 192.168.1.242 and 192.168.88.1.

In my modem’s port forwarding page, I created a rule to forward all requests to port 1194 to forward to 192.168.1.242:1194. In the MT’s firewall I created a dstnat like this:

ip/firewall/nat/add chain=dstnat action=dst-nat to-addresses=192.168.88.1 to-ports=1194 protocol=tcp port=1194

I have a static public IP and I can forward other ports to other devices with no problem.

I have this error when I run curl -v my_public_ip:1194:

connect to my_public_ip port 1194 failed: Connection timed out

Is there anything I’m not doing or doing it wrong?

Try hairpin NAT https://help.mikrotik.com/docs/display/ROS/NAT#NAT-HairpinNAT

Thanks a lot. I tried but that didn’t work.

This is my NAT export:

[admin@MikroTik] > /ip/firewall/nat export 
/ip firewall nat
add action=accept chain=input disabled=yes dst-port=1194 protocol=tcp
add action=masquerade chain=srcnat comment="defconf: masquerade" ipsec-policy=out,none
add action=dst-nat chain=dstnat dst-port=14000-15000 protocol=udp to-addresses=192.168.88.1 to-ports=14000-15000
add action=dst-nat chain=dstnat dst-address=my_public_ip dst-port=1194 log=yes log-prefix=mynatishere protocol=tcp to-addresses=192.168.88.1 to-ports=1194
add action=dst-nat chain=dstnat dst-port=81 log=yes log-prefix=nginx protocol=tcp to-addresses=192.168.88.250 to-ports=80
add action=masquerade chain=srcnat dst-address=192.168.88.1 out-interface=ether1 protocol=tcp src-address=192.168.88.0/24

I tried moving up and down the rules but I still have Connection Timed Out error.

Try action redirect instead of dst-nst

Thanks, you mean like this?

add action=redirect chain=dstnat dst-port=1194 log=yes log-prefix=mynatishere protocol=tcp to-addresses=192.168.88.1 to-ports=1194

I tried even with dst-address=my_public_ip, but still not working.

First, given your location, I would not be surprised if incoming connections to port 1194 were blocked by your ISP by government order.

Your dst-nat rule does not match on in-interface, so try to connect from the LAN side of your Mikrotik (a device in the 192.168.88.x/24 subnet) using telnet or curl and see whether the packet counter of the dst-nat rule increments as you do so. If it does, try the same from the internet towards the public IP address. If it still increments, the issue is not the dst-nat (or redirect) rule but the OpenVPN server process that does not respond.
If it does not increment, you can run /tool sniffer quick port=1194 in a terminal window - if you can see the TCP SYN packets to arrive from the modem as you try to connect from the outside to the public IP, something else (IPsec policy, a drop rule in raw, or another dst-nat rule in nat) must prevent the packet from reaching your dst-nat rule.

Hairpin NAT is only necessary if the dst-nat forwards the incoming connections to a server in some LAN subnet and the client that connects to the “external” address is located in the same LAN subnet like the server. This is not your scenario, as the server is the router itself.

Off topic remarks to your firewall rules:

  • port matches if the value is present in the source port or in the destination port field of the packet, which is rarely what you want. Unless you really have a particular reason to use port, use src-port or dst-port, whichever is relevant in the particular case.
  • if you do not want a NAT rule to change the port or address, do not specify to-ports or to-addresses. A rule action=dst-nat dst-port=10000-15000 to-ports=10000-15000 will act if the original destination port is in the specified range, but it will change the port to a randomly chosen one from the range.

This is what I have in /log/print follow output when I have the following firewall nat rules:

[admin@MikroTik] > /ip/firewall/nat print
Flags: X - disabled, I - invalid; D - dynamic 
 0    ;;; defconf: masquerade
      chain=srcnat action=masquerade to-ports=1194 protocol=tcp dst-address=my_public_ip dst-port=1194 log=yes log-prefix="masq2" ipsec-policy=out,none 

 1    chain=dstnat action=dst-nat to-addresses=192.168.88.1 to-ports=1194 protocol=tcp dst-port=1194 log=yes log-prefix="mynatishere" 

 2    ;;; defconf: masquerade
      chain=srcnat action=masquerade log=no log-prefix="" ipsec-policy=out,none 

 3 X  chain=dstnat action=dst-nat to-addresses=192.168.88.1 to-ports=14000-15000 protocol=udp dst-port=14000-15000 log=no log-prefix="" 

 4    chain=dstnat action=dst-nat to-addresses=192.168.88.250 to-ports=80 protocol=tcp dst-port=82 log=yes log-prefix="nginx"

Firewall’s output:

22:43:53 firewall,info mynatishere dstnat: in:ether1 out:(unknown 0), connection-state:new src-mac 8c:59:73:61:90:20, proto TCP (SYN), my_server_ip:32796->192.168.1.242:1194, len 60

Oops, I’m so sorry that you know the I.R. with such thing:(
They learnt to block by protocol, not by port number only. But connecting to OpenVPN from Iran to Iran usually works with no problem. But currently I’m not trying to use OpenVPN on this port. I enabled SSH on this port and even changed it to 22 to see if it works.

My laptop is connected wireless to the Mikrotik and my private IP is in 192.168.88.0/24 subnet. I can curl 192.168.88.1:1194 and it connects to this port with no issue.
I tried this at first to see if it’s working local.

I also am seeing this rule’s counter increments when I run curl from another server. I changed the SSH port to other ports and I still see the counter increments, but still connection timed out is what I see.

This is the firewall’s output:

23:06:23 firewall,info mynatishere dstnat: in:ether1 out:(unknown 0), connection-state:new src-mac 8c:59:73:61:90:20, proto TCP (SYN), my_server_ip:41494->192.168.1.242:1194, len

This is firewall rule:

nat chain=dstnat protocol=tcp dst-port=1194 action=dst-nat to-addresses=192.168.88.1 to-ports=1194



I didn’t understand this part. You mean I shouldn’t specify the src-port and dst-port?

This rule is for a Wireguard port, but tonight I understood it’s not working. The reason for a range IP address is because WG is blocked on some ports, and I increment when old port is blocked. For example I am currently using port 10000 and it’s working. Then it’s blocked, now I change it to 10001 and it works again.

Thanks a lot for the help.

my_server_ip is a public IP somewhere in the internet?

Yes, that’s right.
And my_public_ip is my home’s static Ip.

I checked this and I see the connections there exist too:

interface: ether1
direction: rx
src address: my_server_ip
src port: 49466
dst address: 192.168.1.242 (this ip is my mikrotik's ip)
dst port: 1994 (I changed the port to 22 to see if it's really blocked by port number or not)

I figured out the issue.

I have some default rules in firewall/filter rules, and I disabled them all and I can curl now:

[admin@MikroTik] > /ip/firewall/filter/print 
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 log=no log-prefix="" 

 2    ;;; defconf: drop invalid
      chain=input action=drop connection-state=invalid log=no log-prefix="" 

 3    ;;; defconf: accept ICMP
      chain=input action=accept protocol=icmp log=no log-prefix="" 

 4    ;;; defconf: accept to local loopback (for CAPsMAN)
      chain=input action=accept dst-address=127.0.0.1 log=no log-prefix="" 

 5    ;;; defconf: drop all not coming from LAN
      chain=input action=drop in-interface-list=!LAN log=no log-prefix="" 

 6    ;;; defconf: accept in ipsec policy
      chain=forward action=accept log=no log-prefix="" ipsec-policy=in,ipsec 

 7    ;;; defconf: accept out ipsec policy
      chain=forward action=accept log=no log-prefix="" ipsec-policy=out,ipsec 

 8    ;;; defconf: fasttrack
      chain=forward action=fasttrack-connection hw-offload=yes connection-state=established,related log=no log-prefix="" 

 9    ;;; defconf: accept established,related, untracked
      chain=forward action=accept connection-state=established,related,untracked log=no log-prefix="" 

10    ;;; defconf: drop invalid
      chain=forward action=drop connection-state=invalid log=no log-prefix="" 

11    ;;; defconf: 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=""

I found rule number 5 is occurring the issue. I’m not sure what it does exactly at this moment (it’s around 01:45 in Iran), but disabling it causes to SSH to my home from another server.
I’ll figure it out soon, but I’ll be happy if you assist:)

Maybe this and this will help you understand the basic idea of how the firewall rules work and interact.