Safeguarding peers having successfully connected from accidental block by Brute Force rules | Script sharing

The advice in the Brute force prevention Help article is useful. But in cases where you or trusted peers may accidentally make several connections in a short period of time – like when being tired you were struggling to type correct password, or electric grid was turning off and on several types thus causing your other router with a VPN client to reconnect again and again, – this security approach creates a high risk of blocking a legitimate peer.

Making the timeout of the blacklist shorter, like 10m instead of 1d (or even 30d), doesn’t secure well from the probing third parties.

So another solution is needed. It seems the only suitable is to add to the “First attempt” rule a parameter src-address-list!=Trusted.
When the legitimate peers’ addresses are known beforehand, the Trusted address list can be filled in manually. In other cases it should be updated regularly:

  • For manual management connections, like SSH, a good idea may be to utilise the System - Note feature – to see before yourself a reminder at each login to add the address to Trusted.


  • For manual non-management (like VPN from a smartphone) or just automatic (from another router) connections, it seems this can be solved automatically only via a script – run by a tool such as Scheduler, NetWatch, etc. An example of the script (for a WireGuard tunnel peer) is shared below. AKA Dynamic whitelisting of WireGuard peers.


:do {

:global CurrentEndpointIP [/interface wireguard peers get number=[find name=peer1blabla] value-name=current-endpoint-address];

:if ($CurrentEndpointIP!="0.0.0.0" and [/interface wireguard peers get number=[find name= peer1blabla] value-name=last-handshake] < 01:00:00) do={

/ip firewall address-list

:if ([:len [find list=SuccessfulWgPeersLast7d address=$CurrentEndpointIP]] = 0) do={
add list=SuccessfulWgPeersLast7d address=$CurrentEndpointIP timeout=7d;
:log info "MyScript ADDED wg endpoint ".$CurrentEndpointIP." to the address-list Successful"
} else={
remove [find list=SuccessfulWgPeersLast7d address=$CurrentEndpointIP];
add list=SuccessfulWgPeersLast7d address=$CurrentEndpointIP timeout=7d;
:log info "MyScript casually renewed wg endpoint ".$CurrentEndpointIP." in the address-list Successful";
:if ([:len [find list=BruteforceLadderStep1 address=$CurrentEndpointIP]] != 0) do={
remove [find list=BruteforceLadderStep1 address=$CurrentEndpointIP];
:log info "MyScript deleted wg endpoint ".$CurrentEndpointIP." from the address-list BruteforceLadderStep1"
};
}

} on-error={:log info "Error - failed to apply MyScript script address list configurations!"}

If using Scheduler, set the execution frequency suitable for the expected length of a session of the WireGuard peer – like 8 hours for a peer-[another]router and 5 minutes for a peer-smartphone.
And with similar reasoning maybe set a longer or shorter value for the last-handshake check’s timer (“01:00:00” in the example).

UPD 12 Dec 2024: Fixed a typo that the opening curly bracket of “else” was detached from it into the next row.
UPD 28 May 2025: Added a check (just to be on the safe side) in the beginning that the address of the peer is not zero, which in RouterOS is suddenly returned as “0.0.0.0”.
Renamed the list into a non-peer-specific (i.e. a single list for all the having-successfully-connected peers, to check [in the first step of] the ladder of the bruteforce rules in the Firewall Filter just this list [i.e. src-address-list!=SuccessfulWgPeersLast7d], i.e. not to duplicate the rules for each peer).
Added to the logging text the address of the peer.
Renamed the address list name for the rule of the first step of the brute force ladder to a clearer name.
Fixed a typo of excessive “list=” in the last remove command.
Renamed “MyNetWatch” into “MyScript” for generality.

Starting out, it’s really wrong to leave services reachable directly,
worse if with default ports…

Hello rextended,

What exactly do you mean by reachable?
And due to what exactly you are saying it’s really wrong?