Port forwarding doesn't work over SSH

We’ve recently replaced our Zyxel USG-20 with a new Mikrotik Cloud Core CCR1009-7G-1C-PC, and I’m having a really hard time configuring port forwarding for SSH access. I’ve already configured the DHCP server, and all machines (connected either directly or via switches) have access to the Internet. We’ve got several servers running on Ubuntu Server and I’ve given them static IP addresses. These are the firewall configurations I’ve added:

/ip firewall nat add chain=dstnat dst-address=<isp_public_ip> protocol=tcp dst-port=<port_x> action=dst-nat to-address=<server_lan_static_ip> to-ports=<port_x> in-interface=ether1
/ip firewall filter add chain=forward in-interface=ether1 protocol=tcp dst-address=<isp_public_ip> dst-port=<port_x>

Now, on my machine:

$ ssh <user>@<isp_public_ip> -p <port_x>
ssh: connect to host <isp_public_ip> port <port_x>: Connection refused

Am I doing something wrong?

P.S.

I’ve also added the following safety rules to avoid any attacks on the router itself, because someone has been trying to login as root and admin via telnet:

/ip service
set telnet disabled=yes
set ftp disabled=yes
set www disabled=yes
set ssh disabled=yes
set api disabled=yes
set api-ssl disabled=yes

Firstly, no need to set to-ports in the nat rule, only use this if you are changing the to-port

Secondly, the filter rule needs to use the IP of the internal device, eg after the NAT has happened.

Hope that helps
Nick

It seems to me that you don’t have any decent firewall (or else router’s telnet service couldn’t be accessed from outside) … which is actually default with CCR line of RouterBoards. I strongly suggest you to read a few articles on how to build a proper firewall on MT.

Other than that: your problem connecting from remote IP can either be related to

  • ISP filtering the particular port you chose to forward
  • forward rule not working as desired (I can’t see any problem apart from possibility that your WAN port is not ether1 or from possibility that you’re forwarding port <port_x> to port 22 on LAN server in which case filter rule should have to-ports=22)
  • LAN server not listening on the port <port_x>, ssh usually listen on port 22.

Coming from zyxel you would have applied a NAT rule(port forwarding) and then a firewall rule.
MT is a bit different, the NAT rule is still first in the packet flow but here is where you can delineate allowed users.
The firewall rules for destination nat anyway are more to state are these types of packets (dst nat) allowed in general.

Lets have a look at these two rules…
/ip firewall nat add chain=dstnat dst-address=<isp_public_ip> protocol=tcp dst-port=<port_x> action=dst-nat to-address=<server_lan_static_ip> to-ports=<port_x> in-interface=ether1
/ip firewall filter add chain=forward in-interface=ether1 protocol=tcp dst-address=<isp_public_ip> dst-port=<port_x>

/ip firewall nat
add action=dst-nat chain=dstnat comment=ServerX dst-port=xxxx
in-interface-list=WAN protocol=tcp src-address-list=AllowedUsers
to-addresses=192.168.u.u

Is the usual format. If you only have one wan then use in-interface=WAN, I also have a source address list here for authorized users for my server (their public WANIPs).
If you don;t have such a list, then you can remove that part, however, its crappy security not to do so.

For the firewall rule set, what is usual is the following…
/ip firewall filter
{forward chain}
add action=accept chain=forward comment=
“Allow Port Forwarding” connection-nat-state=dstnat

Basically, in the forward chain one has accepted established and related connections,
dropped invalid connections, allowed any LAN to WAN type traffic, and any other required internal traffic
and then a last drop all else rule ensures anything else is dropped. Stick this one just before the last rule.
The firewall looks at the dst nat packet flow and it doesn;t match the rules before the dst rule and then its matched and passed to the natted address.

Thanks for responding

I’m indeed using a non-standard port.

Unfortunately, that didn’t help.

Everything has been working well with the other router. Nothing has changed apart from that. The WAN is indeed on ether1.

Unfortunately, I can’t use a list of WANIPs, because people use all sorts of mobile internet connections to login.

I’ve got some progress, though. I removed the old NAT rule and added a new one:

/ip firewall nat add action=dst-nat chain=dstnat dst-port=<port_x> protocol=tcp to-addresses=<server_lan_static_ip> to-ports=<port_x> dst-address=<isp_public_ip>

Basically, I’ve removed the interface parameter. Now, whenever I try to connect to the server, I finally see incoming packets, but the ssh connection times out. This is a bit weird, because the WAN is on ether1, so I don’t get why it doesn’t work with in-interface=ether1

I can now connect to the server over LAN, but connection over the internet times out. This seems to be a firewall issue.

I’ve decided to start anew and drop all current configurations to make sure I haven’t screwed up somewhere along the way. Here is my log:

  1. Reset configurations (do not use factory configurations)
  2. Connect ISP WAN cable to ether1 (out router also has a combo1 port, but I’ve been ignoring it so far), connect a LAN switch to ether2, connect servers to ether3-5, connect an ethernet cable to ether6 to access the router
  3. Label the interfaces.
  4. Add ISP IP to ether1. Create a route, add DNS servers with local caching. Make sure internet works fine on all connected machines
  5. Create a bridge for ether2-7
  6. Setup a DHCP server
  7. Assign static LAN IPs to all servers
  8. Setup firewall rules
  9. Add a NAT rule (for one server on ether3)

Here are the configurations:

[admin@Router] /interface export
# jan/29/2019 20:21:46 by RouterOS 6.43.8
# software id = ...
#
# model = CCR1009-7G-1C
# serial number = ...
/interface bridge
add name=bridge1
/interface ethernet
set [ find default-name=ether1 ] comment=WAN
set [ find default-name=ether2 ] comment="LAN (switch point)"
/interface list
add name=WAN
add name=LAN
/interface wireless security-profiles
set [ find default=yes ] supplicant-identity=MikroTik
/interface bridge port
add bridge=bridge1 interface=ether2
add bridge=bridge1 interface=ether3
add bridge=bridge1 interface=ether4
add bridge=bridge1 interface=ether5
add bridge=bridge1 interface=ether6
add bridge=bridge1 interface=ether7
/interface list member
add interface=ether1 list=WAN
add interface=bridge1 list=LAN

[admin@Router] > /ip export
/ip pool
add name=dhcp_pool0 ranges=192.168.1.2-192.168.1.254
add name=dhcp ranges=192.168.1.2-192.168.1.254
/ip dhcp-server
add address-pool=dhcp disabled=no interface=bridge1 lease-time=1h name=dhcp1
/ip address
add address=<isp_wanip> comment="ISP WANIP" interface=ether1 network=xxx
add address=192.168.1.1/24 comment="LAN subnet" interface=ether2 network=192.168.1.0
/ip dhcp-server lease
add address=<server_address> comment="server" mac-address=xxx server=dhcp1
/ip dhcp-server network
add address=192.168.1.0/24 dns-server=192.168.1.1 gateway=192.168.1.1
/ip dns
set allow-remote-requests=yes servers=<dns1>,<dns2>
/ip firewall address-list
add address=192.168.1.0/24 list=LAN
/ip firewall filter
add action=accept chain=input comment="Allow all connections to the router from the LAN subnet" src-address-list=LAN
add action=accept chain=input comment="Accept established and related packets to the router" connection-state=established,related
add action=drop chain=input comment="Drop all unknown traffic to the router"
add action=accept chain=forward comment="Allow traffic to the server" connection-state=established,related,new dst-address=<server_address> dst-port=\
    <port_x> protocol=tcp
add action=drop chain=forward comment="Drop invalid packets targetting the LAN" connection-state=invalid,new,untracked disabled=yes
/ip firewall nat
add action=masquerade chain=srcnat out-interface-list=WAN
add action=dst-nat chain=dstnat dst-address=<isp_wanip> dst-port=<port_x> protocol=tcp to-addresses=<server_address> to-ports=<port_x>
/ip route
add distance=1 gateway=<isp_gateway>

To be clear:

  1. All machines have access to the internet
  2. I can SSH into the server on <port_x> from the local network
  3. When I try to SSH from the internet, I do see incoming packets in the NAT rule for the server, but the connection times out after a while.
  4. The ISP is not blocking traffic on <port_x>

I’m absolutely out of any ideas as to why this is happening.

You should put IP configuration related to LAN on bridge1 interface rather than ether2 interface.

I think, I’ve found the problem. All this time I’ve been trying to connect through the public IP while being on the same LAN, and it seems like you have to manually configure hairpin NAT on MT routers, because I’ve got no problems connecting from a from a disjoint network neighbourhood.

That is indeed so.

I use in-interface-list=WAN on my nat rule (not dest address=WANIP)???
Not sure if there is any difference…

In grayfall’s case it doesn’t matter … he needs hair-pin nat. Conection towards server, originating from LAN, won’t trigger in-interface-list=WAN either.

Other than that, I guess the difference between using dst-address and in-interface(-list) is mostly the same as difference between using src-nat with src-address versus masquerade with out-interface.
When one is using dynamic WAN address, the only way is to use in-interface. When one is using multiple static WAN addresses and wants to use all for dst-nat, the only way is to use dst-address. When one uses single static WAN address, then the both ways are possible and there are other mimor differences that might be decision-makers.

Yes, this was indeed the case. I’ve configured hairpin NAT, and everything works fine now. Thank you very much for the confirmation and the firewall configuration guide.

Lets dissect that one shall we…
For masquerade actionr, its typicall to use out-interface-list=WAN (for me having two wanips) as you stated… however
For src-nat action, why do you assume or imply that one will use src-address???
Wouldnt it be
add action=scr-nat chain=srcnat destination-address=staticWANIP

Where are you getting source address???
The only time I see that as viable is if you have two LANs and at least two WANIPs and you want to direct one to a and the other to b so to speak, in which case one would need two rules
add action=scr-nat chain=srcnat destination-address=staticWANIPA source-address=lansubnetX
add action=scr-nat chain=srcnat destination-address=staticWANIPB source address=lansubnetY

Of course, then how do you route these is my next question, (what would be the appropriate table commands)??

Let’s consider a simple case when one gets a subnet on WAN interface. In this case routing is not a problem, one only needs to construct a few src-nat rules so that some particular LAN hosts (with particular services?) will get mapped to particular WAN IPs (which are not the same as router’s WAN IP as a prime candidate for resulting src-address after masquerade is done with it).

I’m not going to lenghty duscuss about why you think this idea is outrageous, I’m just mentioning different options and it’s up to router’s admin to implement whichever seems viable/sensible.

Its not a matter of outrageous its a matter of over complicating in your example.
Provide the basis for correct config and then add complexity in an example…

Lets say for static IPs,
Basic rule one WAN, one LAN
add action=src-nat chain=srcnat to-address=WANIP out-interface=WAN

Basic rule one WAN two LANs
add action=src-nat chain=srcnat to-address=WANIP out-interface=WAN

Complex rule Two WANS one LAN (simple failover)
add action=src-nat chain=srcnat to-address=wan1 out-interface=wan1
add action=src-nat chain=srcnat to-address=wan2 out-interface=wan2
(regardless of routing and availability private IPs will get matched to public IP and source nat will occur)

So you can see starting with the basic requirement and then expanding is more useful for learning purposes. Simply providing a middle solution makes too many assumption.

Now lets take it to the next step…
Complex rule Two WANS two LANs (LANA to WAN1, LANB to WAN2, no failover )
add action=src-nat chain=srcnat source-address=LANA.0/24 to-address=WANIP1 out-interface=WAN1
add action=src-nat chain=srcnat source-address=LANB.0/24 to-address=WANIP2 out-interface=WAN2

In the latter case here, was the fruit of my last question in the previous post that was never responded to…
What would be the appropriate routing rules, something about tables??