This is a simplified version of my reaction config. Refer to the `ipv6mask` option in the docs for more info.
local banFor(time) = {
ban4: {
cmd: ['nft', 'add element inet reaction ipv4bans { <ip> }'],
ipv4only: true,
},
ban6: {
cmd: ['nft', 'add element inet reaction ipv6bans { <ip> }'],
ipv6only: true,
},
unban4: {
cmd: ['nft', 'delete element inet reaction ipv4bans { <ip> }'],
after: time,
ipv4only: true,
},
unban6: {
cmd: ['nft', 'delete element inet reaction ipv6bans { <ip> }'],
after: time,
ipv6only: true,
},
};
{
patterns: {
ip: {
type: 'ip',
ignore: ['::1'],
ignorecidr: ['127.0.0.0/8', '10.0.0.0/8', '172.16.0.0/12', '192.168.0.0/16', 'fc00::/7', 'fe80::/10'],
ipv6mask: 64,
},
},
start: [
['nft', |||
table inet reaction {
set ipv4bans {
type ipv4_addr
flags interval
auto-merge
}
set ipv6bans {
type ipv6_addr
flags interval
auto-merge
}
chain prerouting {
type filter hook prerouting priority filter
policy accept
ip saddr @ipv4bans limit rate 10/minute log prefix "reaction/drop: "
ip saddr @ipv4bans counter drop
ip6 saddr @ipv6bans limit rate 10/minute log prefix "reaction/drop: "
ip6 saddr @ipv6bans counter drop
}
}
|||],
],
stop: [
['nft', 'delete table inet reaction'],
],
streams: {
vaultwarden: {
cmd: ['journalctl', '-fn0', '-o', 'cat', '-u', 'vaultwarden.service'],
filters: {
failedlogin: {
regex: [
@'^.*?Username or password is incorrect\. Try again\. IP: <ip>\. Username:.*$',
@'^.*Invalid admin token\. IP: <ip>.*$',
@'^.*\[ERROR\] Invalid TOTP code! Server time: (.*) UTC IP: <ip>$',
],
retry: 3,
retryperiod: '2h',
actions: banFor('24h'),
},
},
},
},
}