It is worthwhile to point out possible unintended consequences of using ufw's LIMIT feature.
Suppose one placed a blanket limit on port 22/tcp as the first ufw rule:
To Action From
-- ------ ----
[ 1] 22/tcp LIMIT IN Anywhere
...
with the assumption that any connections operating under the limit could still be filtered by following ufw rules and finally the default policy of "deny(incoming)".
At least for ufw 0.35, that assumption would be wrong. In fact the LIMIT IN logic immediately accepts any input not rejected by the limit criterion.
In psuedocode, the LIMIT logic is
if CONDITION then DENY else ACCEPT
whereas other ufw rules seem to have logic:
if CONDITION then (DENY|ACCEPT) else continue to next rule
.
I personally found that to be unexpected behavior for ufw LIMIT, which I only discovered by unexpectedly finding many port 22 login attempts in the system log file which should have never happened due to filtered by other ufw rules.
Details of behavior confirmation
The relevant lines of iptables code inserted by ufw are as follows:
-A ufw-user-input -p tcp -m tcp --dport 22 -m conntrack --ctstate NEW -m recent --update --seconds 30 --hitcount 6 --name DEFAULT --mask 255.255.255.255 --rsource -j ufw-user-limit
-A ufw-user-input -p tcp -m tcp --dport 22 -j ufw-user-limit-accept
-A ufw-user-limit -m limit --limit 3/min -j LOG --log-prefix "[UFW LIMIT BLOCK] "
-A ufw-user-limit -j REJECT --reject-with icmp-port-unreachable
-A ufw-user-limit-accept -j ACCEPT
The above listing can be created with
iptables -S | grep ufw-user-limit
The first two lines are consecutive in ufw-user-input
which can be confirmed with
iptables -S | grep ufw-user-input