Browser based port knocker

I would like to setup a sort of port knocking to get temporary access to a particular box on my LAN (webcams streaming video and audio) from outside.
The basic assumption is that I won’t have any telnet/ssh or portknocker.exe client out there - only browser.

I imagine a flow to be like that:

  • open browser
  • type my_url:port1 (first port of port-knocker sequence)
  • wait for 404 response or whatever it can throw
  • type my_url:port2 (second port of port-knocker sequence, this would open the required firewall hole for my IP for 15 minutes)
  • wait for 404 response or whatever it can throw
  • type my_url:actual_webcam_port (to connect to web interface of the camera)

How can I setup such a thing with RouterOS?

That will “just work”. It doesn’t matter what client you use to knock on the ports - the router just notices a traffic pattern and adds addresses to address lists. Then you port forward to the internal machine as you normally would and filter that forwarded traffic and only allow access from a specific address list. That’s the address list IPs get added to by the port knocking sequence. Whether a browser, a telnet client, or a dedicated executable sends those knocking packets is irrelevant. The router wouldn’t be able to tell. TCP handshakes are TCP handshakes.

http://mum.mikrotik.com/presentations/US10/discher.pdf

Great, thanks!
But how do I do conditional port forwarding?

The presentation above and wiki page describe getting access to the router itself, not something behind it - so the decision happens in input chain.
Port forwarding is a part of NAT settings, which happens before Filter where I can accept/reject packets…
Can I enable / disable NAT record based on address lists?

While it is true that destination NAT happens before filtering (except for prerouting filters), they still get evaluated.

/ip firewall nat
add chain=dstnat action=dst-nat to-address=192.168.1.2 protocol=tcp dst-address-type=local in-interface=WAN dst-port=500 to-port=80
/ip firewall filter
add chain=forward dst-address=192.168.1.2 protocol=tcp dst-port=80 src-address-list=port-knockers action=accept 
add chain=forward dst-address=192.168.1.2 protocol=tcp dst-port=80 action=drop 

That forwards traffic to tcp/500 with a destination address of the router WAN interface to tcp/80 on 192.168.1.2 behind the router. The firewall filters then permit that tcp/80 traffic to 192.168.1.2 for all hosts on the port-knockers address list. All other packets are dropped.

The basic idea is to always NAT, but drop the packets unless the source has completed the port knock sequence.

Yep, that’s what I thought :slight_smile:

I was hesitating to permanently NAT this - it’s kinda error prone - you open a permanent hole in firewall and put a temporary plug

Why? What’s the difference between this and using a firewall with public IPs on both sides and having the exact same filter rule, but without NAT?

The security comes from stateful packet filters, not NAT.

Yep, you’re right - my misunderstanding

Thanks!!

If you are still paranoid about this, you many add the source address matcher to the NAT rule.

Instead of

/ip firewall nat
add chain=dstnat action=dst-nat to-address=192.168.1.2 protocol=tcp dst-address-type=local in-interface=WAN dst-port=500 to-port=80

You now have

/ip firewall nat
add chain=dstnat action=dst-nat to-address=192.168.1.2 protocol=tcp dst-address-type=local in-interface=WAN dst-port=500 to-port=80 src-address-list=port-knockers

This prevent the processing of the NAT rule unless the source has completed the port knock sequence.

Continuing on a paranoid note…

Is it possible to catch a scanning attempt - after X unsuccessful attempts block that IP for some time?

This assumes that you are going to port knock in the input chain (on a non-NAT’d router IP/port).
The port knock sequence will be 90, 91, and 92. Anyone with 3 bad attempts no further than 2 minutes apart each will get blocked for 24 hours. Make sure you adjust the rule that grants administrative access via the LAN port, and permit anything else you need to, and that it fits with the rest of your firewall rules. It also does not contain any NAT rules you might need, those of course stay the same.

Might contain errors. Written in a text editor only.

/ip firewall filter
add chain=input src-address-list=blocked action=drop 
add chain=input connection-state=established action=accept 
add chain=input connection-state=related action=accept 
add chain=input connection-state=invalid action=drop 
add chain=input protocol=tcp dst-port=90 action=add-src-to-address-list address-list=portKnockStage1 address-list-timeout=00:00:10
add chain=input protocol=tcp dst-port=91 src-address-list=portKnockStage1 action=add-src-to-address-list address-list=portKnockStage2 address-list-timeout=00:00:10
add chain=input protocol=tcp dst-port=92 src-address-list=portKnockStage2 action=add-src-to-address-list address-list=portKnocker address-list-timeout=00:30:00
add chain=input in-interface=LAN action=accept 
add chain=input src-address-list=scannerStage2 action=add-src-to-address-list address-list=blocked address-list-timeout=24:00:00
add chain=input src-address-list=scannerStage1 action=add-src-to-address-list address-list=scannerStage2 address-list-timeout=00:02:00
add chain=input action=add-src-to-address-list address-list=scannerStage1 address-list-timeout=00:02:00
add chain=input action=drop 
add chain=forward connection-state=established action=accept 
add chain=forward connection-state=related action=accept 
add chain=forward connection-state=invalid action=drop 
add chain=forward in-interface=LAN action=accept 
add chain=forward src-address-list=portKnocker action=accept 
add chain=forward action=drop

The basics behind this are listed in the wiki articles on how to blacklist brute force SSH or FTP attackers. You’re just watching every port in the same fashion.

Thanks!

Now when I’m connecting from outside everything is good.

But when PC is connected via local WiFi, the applications setup to work via forwarded ports obviously can’t connect, so I have to change settings to local URLs and ports.
Is there any way to setup internal port forwarding from behind NAT - just to emulate how it works from outside so I don’t have to change app settings and URLs every time?

http://wiki.mikrotik.com/wiki/Hairpin_NAT