3 # This yate script will monitor authentication requests and update an
4 # nftables set with IP addresses of users who consistently fail to
5 # authenticate. The nftables set can then be used in OpenWrt's
6 # firewall configuration to block these IP addresses.
8 # The nftables set has to exist before launching yate.
10 # Here's an example configuration that creates an nftables set, where
11 # entries expire after 12 hours, and configures the OpenWrt firewall
12 # to drop packets where the source IP address is in the set. Put this
13 # in /etc/nftables.d/99-yate.nft:
21 # type filter hook input priority -1; policy accept;
22 # ip saddr @yate_denylist counter drop comment "Drop packets from bad SIP clients"
26 # To enable this script in yate, add it to the [scripts] section in
27 # /etc/yate/extmodule.conf.
29 # You can tweak how tolerant this script should be by modifying the
32 # A user's IP address will be added to the nftables set if there are
33 # more than MAX_AUTH_FAILURES consecutive authentication failures in
34 # MAX_AUTH_FAILURES_TIME_PERIOD seconds.
35 my $MAX_AUTH_FAILURES = 5;
36 my $MAX_AUTH_FAILURES_TIME_PERIOD = 3600; # seconds
38 # The name of the nftables table and set where IP addresses are added.
39 my $NFTABLES_TABLE = 'inet fw4';
40 my $NFTABLES_SET = 'yate_denylist';
45 use lib
'/usr/share/yate/scripts';
48 my %ip_auth_failures = ();
50 sub OnAuthenticationRequest
($) {
53 # Forget any expired failed authentications
54 foreach my $ip (keys(%ip_auth_failures)) {
55 my $failures = \@
{$ip_auth_failures{$ip}};
57 time() - @
$failures[0] > $MAX_AUTH_FAILURES_TIME_PERIOD) {
62 delete $ip_auth_failures{$ip};
66 my $remote_ip = $yate->param('ip_host');
67 my $remote_device = $yate->param('device') || '<unknown>';
69 if ($yate->header('processed') eq 'true') {
70 $yate->output("banbrutes: Successful authentication from $remote_ip");
71 delete $ip_auth_failures{$remote_ip};
75 $yate->output("banbrutes: Failed authentication from $remote_ip");
76 push(@
{$ip_auth_failures{$remote_ip}}, time());
77 if (scalar(@
{$ip_auth_failures{$remote_ip}}) > $MAX_AUTH_FAILURES) {
78 $yate->output("banbrutes: Adding $remote_ip to nftables set $NFTABLES_SET (remote device: $remote_device)");
79 `nft add element $NFTABLES_TABLE $NFTABLES_SET { $remote_ip }`;
80 delete $ip_auth_failures{$remote_ip};
84 my $yate = new Yate
();
85 $yate->install_watcher("user.auth", \
&OnAuthenticationRequest
);