Rules against scanners

One useful feature can be to block scanners that try annoying things on ports that you want to have opened.

E.g. you run a web server but you do not want to serve those endless attempts to break the CMS or the forms, and they come from systems that also try telnet, ssh etc which you do not have opened. Then, locking a system that is trying a broad variety of portocols could be helpful.

But always be aware: there are scans where the source address is spoofed. You will see telnet attempts "from 8.8.8.8", for example. When you put the offender in a list for the "raw" table, you will lock yourself out of using Google DNS. You have been warned.

In my case such address list doesn’t permanently store IPs, scanner detected are with 24h timeout and script added 1w, even it is refreshed daily, just to avoid auto-removal if script fails to fetch at some point, so there is no boot issue because address list is always empty until startup scheduler triggers fetching and adding entries.

Regarding scanners detected records, daily added are approx. 0-5 IPs, so its low, never noticed 10 or more per day, most records are added by script.

So such list never grows very large and doesn’t cause performance issues, when scheduled script refreshes records in such list it removes all previously script added (by checking record comment) and adds new ones (can be same records, not performing delta).

Sure, that's why something like AbuseIPDB, ipinfo or other similar services exist.
One can check before banning blindly.

I use port knocking detection firewall rules (ahead of the scanner detection rules) to identify a correct knock and temporarily add that source IP to the whitelist.

0 ;;; Port knocking to enable direct outside administrative access
chain=input action=add-src-to-address-list protocol=tcp address-list=KnockKnock:${MYKNOCKPORT#1} address-list-timeout=1m dst-port=${MYKNOCKPORT#1} log=no log-prefix=""

1 ;;; Port knocking to enable direct outside administrative access, part 2
chain=input action=add-src-to-address-list protocol=tcp src-address-list=KnockKnock:${MYKNOCKPORT#1} address-list=KnockedSuccessfully address-list-timeout=1m
dst-port=${MYKNOCKPORT#2} log=yes log-prefix="KnockedSuccessfully"

2 ;;; Accept connections from those who have knocked successfully in the past 60 seconds
chain=input action=accept src-address-list=KnockedSuccessfully log=yes log-prefix="Connect After Knocking"

Never had so far such case. Also response packet will never reach source with spoofed IP so it will never work for scanning, only thing where is useful is to have many parallel scan instances from same attacking host and one instance uses non-spoofed address for scanning which will actually work so that in victim logs is less clear which IP is actually attacker’s IP.

For ROS services, in some cases, makes sense to allow connections only on demand so that service is not permanently exposed, I use similar technique with SMS commands to control ROS services (some VPNs) input port rules since I use LTE router.

Should we create a rule for this in the RAW table?

The problem with similar port knocking method is that the attacker can quickly send 2×65K SYN packets towards your router (with destination port from 1-65535), without having to wait for the responses, and they are added to your KnockedSuccessfully list.

I hope that my firewall filter psd= rule would catch that:

0 ;;; Block scanners from accidentally triggering port knocking
chain=input action=add-src-to-address-list connection-state=!established
protocol=tcp src-address=!${certain_of_my_known_internal_only_addresses}
address-list="Suspected_port_scanners" address-list-timeout=5m
psd=4,60,1,1 log=yes in-interface=bridge

No?

:face_with_spiral_eyes:

You can add some content check for port knocking rules (L7 or content property on rule for UDP) to be more secure against port brute forcing. Example of modified MT help port knocking rules that does that:

/ip firewall filter
add action=add-src-to-address-list address-list=pn-888 address-list-timeout=30s chain=input content=<some_secret> dst-port=888 in-interface-list=WAN protocol=udp
add action=add-src-to-address-list address-list=pn-555 address-list-timeout=30s chain=input content=<some_secret> dst-port=555 in-interface-list=WAN protocol=udp src-address-list=pn-888
add action=add-src-to-address-list address-list=secured address-list-timeout=30m chain=input content=<some_secret> dst-port=222 in-interface-list=WAN protocol=udp src-address-list=pn-555

And shell cmd to add IP to whitelist (secured address list):

for x in 888 555 222; do nc -cu <router_ip> $x <<< <some_secret>; done

Replace <some_secret> with some passphrase/secret.

Yes, directly on RAW, if one want.

:grin: This router is not directly exposed to the Internet. There's an ISP router in front of it, filtering most ports :slight_smile:

Indeed, were this MikroTik THE firewall, it wouldn't be that way.

... which actually makes things even more interesting in terms of identifying port scans. To detect port scans, I have to let some signal not-actually-open ports in through the front-end ISP router/firewall's filters/NAT. Complicateder and complicateder, said Alice ...

( also for @libove )

I don't think so,
it should send each packet with an appropriate delay to knok all 6 "ports" in the correct order,
and with the correct protocol...

Two packets arriving almost simultaneously can't activate anything,
and then, no matter what happens,
they would also have to guess which service to connect to,
and even which port, which obviously isn't the standard one...

And the opening window is a few seconds.
So, if everything happens by chance, nothing is impossible, but it's extremely unlikely...

There is a port knocking method that is very simple and effective that requires no particular tool to initiate (a standard computer without additional programs suffices, or a phone with one of the hundreds available apps) that is to use ping with packet size :slight_smile:

Here is an example that you can try for yourself:

/ip firewall filter
add action=log chain=input icmp-options=8:0 in-interface-list=WAN packet-size=1925 protocol=icmp

/ipv6 firewall filter
add action=log chain=input icmp-options=128:0 in-interface-list=WAN packet-size=1925 protocol=icmpv6

(the rules are to be placed after the accept established/related and before the accept ICMP rules to be effective)

Now from outside, ping your router's external IP / IPv6 address, under Windows use:

ping -l 1897 IPv4-address
ping -l 1877 IPv6-address

Linux

ping -4 -c 4 -s 1897 IPv4-address
ping -6 -c 4 -s 1877 IPv6-address

(subtract 28 bytes for IPv4 and 48 bytes for IPv6)

For android, use apps like Ping & Net for example.

So instead of checking sequence of ports numbers, check the sequence of different ping packet sizes. The great thing is that ICMP / ICMPv6 is by default rate-limited. You can not fire thousands of packets per seconds at your router, they will be dropped. But also, RouterOS Firewall tracks ICMP like connection, with a 10-second timeout for ICMP and 30-second timeout for ICMPv6. After you issue a ping / ping6 command towards your router, the next rule matching will only happen after the conntrack entry expired. So when you issue the ping sequence, you'll have to wait 10 seconds between two sizes for IPv4, and 30 for IPv6. Perfect when you issue the ping manually. Bot that tries to fire tens of ICMP Echo requests per seconds to your router will only get the 1st packet counted.

And the packet size is not limited to the MTU. As you can see the example use 1925. Fragmentation is automatic, even for IPv6 because it's done at the source (your ping program).

As a result brute-forcing is very difficult.

And did I say that you don't need special port knocking program? just open your PC's Terminal app.

I am using this method for my inbound SSTP emergency VPN.

Yea, if one doesn’t prefer ICMP silent router from WAN like me :slight_smile:

You don't have to answer that echo request, you can still have a rule that drops ICMP right below. The rules with the packet sizes only need to update the address lists.

IPv6? What is IPv6? :laughing:

(Yeah, topic for a new thread, and a lot of alcohol ... so far, I've managed to avoid needing to ever enable that whole new can of headaches :sweat_smile: )

Ah true, such rule will not answer echo…