Redirecting ssh port

I’m trying to make SSH available on a different port on external networks.

My current NAT and filter rules:

/ip firewall nat
add action=masquerade chain=srcnat comment="default configuration" out-interface=ether1-gateway
add action=redirect chain=dstnat dst-port=2222 protocol=tcp to-ports=22

/ip firewall filter
add chain=input protocol=icmp
add chain=input dst-port=2222 protocol=tcp
add chain=input connection-state=established
add chain=input connection-state=related
add action=drop chain=input in-interface=ether1-gateway

The problem is that when packets are passing through the firewall, the destination port is still 22, so the rule for port 2222 above won’t match the packets. If I allow port 22, then ssh will answer on both port 22 and 2222.

How do I make it only accept packets on port 2222, but not 22?

Why don’t you just change the port it is running on instead?

I want it accessible on port 22 from internal networks.

Ah.. Few options then. The reason what you are doing above doesn’t work is a matter of “when” the redirect gets applied. See the packet flow diagram.

Option 1 would be to change the service port to 2222 and then put a redirect in for ONLY the internal side traffic.

Option 2 would be to place a drop in dst-nat or mangle to drop port 22 traffic from the outside… …

Option 3 would be to tag the redirected packets and then only allow “tagged” port 22 packets on the filter chain.

There are tons of ways to do it… the question is just what makes the most sense to you.

I see, any idea on how to tag the redirected packets?

I think I figured it out. This seems to be working:

/ip firewall mangle
add action=mark-connection chain=prerouting dst-port=2222 new-connection-mark=ssh-redirect protocol=tcp

/ip firewall filter
add chain=input connection-mark=ssh-redirect dst-port=22 protocol=tcp
add chain=input connection-state=established
add chain=input connection-state=related
add action=drop chain=input in-interface=ether1-gateway

Yep… thats the way.