variable in address list name (port number in add src to address list)

I have created a couple of firewall chains to combat port scans (single IP to single port on IP-range).
The flow is like this (port 22 as example)

tcp 22 in wan, matching src address list block22 → DROP (or drop all traffic from that IP maybe)
jump to chain “in22” when tcp port 22 in WAN-interface)

in chain “in22”
add dst to block22 when matching dst address list "from22_level4) and src address NOT in list to22 (timeout 2d)
add dst to from22_level4 when matching dst address list "from22_level3) and src address NOT in list to22 (timeout 10s)
add src to to22 when matching dst address list "from22_level3) and src address NOT in list to22 (timeout 10s)
add dst to from22_level3 when matching dst address list "from22_level2) and src address NOT in list to22 (timeout 10s)
add src to to22 when matching dst address list "from22_level2) and src address NOT in list to22 (timeout 10s)
add dst to from22_level2 when matching dst address list "from22_level1) and src address NOT in list to22 (timeout 10s)
add src to to22 when matching dst address list "from22_level1) and src address NOT in list to22 (timeout 10s)
add dst to from22_level1 (timeout 10s)
add src to to22 (timeout 10s)
return

If the destination port could be added to the address list name as a variable, this could be a portscanrange-chain used for many ports, not only one (or a few) ports per chain.
We would never jump too many ports to this chain, as that would create too many address lists.

Is this possible? dst-port as a part of the address list name, automatically.

If telnet traffic was sent to this chain, all the names would have 23 in it.
The name would need to be different for different types of traffic. If not there could be a lot of false positives.

bump..

I’d say just use a single list for any detected port scan sources, regardless of what ports they got caught scanning.

A simpler way to drop all sources that hammer on your router would be to modify the default drop rule at the end of the input chain by adding a rate limit criteria to something sensible (10/second?) for any given source IP. Then add a new rule after this which adds src to the “scanners” address-list with a log action so that you can track who gets blacklisted by this rule, and of course a final drop all rule after the add-to-blacklist+log rule.

This has the added benefit of catching scan sources which only peck each port once - if they hit more than 10 ports in a second, regardless of which ones, or on which protocol, they’ll get blacklisted. You may want to have a “non-blacklistable” list as well and put a criteria on the blacklisting rule which requires src-address-list=!non-blacklistable

(a clever attacker could send spoofed-source packets to intentionally trick your router into blacklisting something you normally need to talk to out on the Internet, like your DNS resolver, and thus DOS you that way)

Now the next question is this - does your router allow connections from the Internet on any port at all, either to itself or to any device behind it with a dstnat pinhole? If the answer is no, then this entire operation (auto-blacklisting) is mostly academic because the router’s going to drop all new connections anyway, right? Why make a complicated set of rules that doesn’t add anything? The only application I can think of in this scenario would be if you want to also block this list in outbound connections. In general though, the boxes doing the scanning are often different from the boxes that host the C&C / sandbox sites, so this wouldn’t be as effective as you might think.

It is a public ip range with customer VPS, dedicated servers etc. We have whitelisted all Norwegian IP-blocks (90% of the “good” traffic), and a lot of trusted sources. The limits is also rather high for number of packets, but not so high for port scans.
It is a work in progress, and we might have to monitor the address lists regulary. Blocking all incoming traffic “non-established/related” is not possible, as there are hosted servers.

Well, you could do some interesting things in a non-blocking firewall.

One thing to consider is that the input chain only refers to traffic talking to one of the Mikrotik’s interface addresses directly - any traffic going THROUGH the router wouldn’t be a candidate. It’s a decent assumption to make that if your customers’ ranges are being scanned, then your router’s going to get hit by the same scan at a similar time.

You could put some honeypot servers out there that you never publish them in DNS, or anywhere - thus any packet reaching them is a scan just by the fact that it got there. Let this box have a very sensitive set of rules and launch a port-knock type of packet stream to the router, or maybe use iBGP to distribute a “naughty list” - once Mikrotik implements the “add prefix to address list” action in /routing filters - this will be an extremely effective way to centralize and automate such efforts using BGP. (I can’t wait!) In the meantime, you could blackhole the targets advertised by the scan sensor host.

You could even redirect a few unused ports of production servers with dstnat rules in your router - for instance you probably don’t have telnet available on the servers (I’d hope) - so just make a dstnat rule matching inbound telnet requests from the Internet that redirects them to your tripwire host.

At the end of the day, though, It’s probably most efficient to have a single dynamic blacklist regardless of origin. If you have multiple dynamic blacklists, then you must have multiple rules to check against them, and therefore are spending more CPU time checking every packet because surely your blacklist rules come before any rules that allow/fasttrack any established connections, right?

Have you ever considered subscribing to some RBL feeds from places like SpamHaus? They’re going to have a much higher scan surface than your network (catching more bad actors) and have lots of experience at maintaining such a list in realtime.

Thanks for the replies.
The plan is to use a single blocklist, but I use multiple ones now to get some more insight in the beginning.
I might also group many services together, as I’m only monitoring new connections, and not related. So there should not be many new connections to many different ports from a single IP I guess.

I would not want to run all traffic through the “filtering”, as this is only the “frontend” router. The specific IP-ranges have other firewalls (Cisco ASA’s). My telnet and ssh-blocklist has about 20k entries after 3 days running now.

I have changed some of my rules, and traffic that can easily be spoofed (udp and syn-floods) have more “slack”, and only limited.

I use some dynamic address lists that blocks known crypto-virus CNC-servers, openbl, spamhaus drop-list, TOR-network for customers that agree on this and so on.

I have a jump-rule that matches WAN-input on both input AND forward-chain, and from there it jumps to different chains for “checking”.

Chains are wonderful tools - If you want to define a specific policy, and then apply it in multiple places, this is the best way to do it.
I also like to use chains to improve firewall efficiency.
For instance in classifying/marking traffic with mangle, I make a chain that does the classification (checking ports, addresses, protocols, interfaces, etc) which is going to be the more complicated part. Then in prerouting, the first rule is just “if connection-mark=no-mark then jump to classify”
This skips lots of rules being checked on every packet, since the majority of packets are going to be “subsequent” packets in established flows.