Hello,
Here is my ugly script in testing which uses a postgres table to track bad guys 
in
authlog and pf to lock them forever.
---
#! /bin/ksh
MAX_RETRIES=2
function finish_serving {
       echo "Finish serving";
       exit 0;
}
function add_entry {
       psql -U ecounter -d ecounter_db -q -c "merge into entry_counter \
               as ec using (select '$1' as e) on ec.entry = \
               e when matched and ec.count < $MAX_RETRIES then \
               update set count = count + 1 when not matched then \
               insert (entry, count) values ('$1', 1);";
       RESULT=$(psql -U ecounter -d ecounter_db -t -c "select entry from \
               entry_counter where entry = '$1' and count >= $MAX_RETRIES;");
       if [[ -n $RESULT ]]; then
               echo "pfctl add to table $RESULT";
               /sbin/pfctl -vvt bad_ips -T add $RESULT;
               /sbin/pfctl -vvk $RESULT;
               NET=$(echo $RESULT  | awk -F. '{print $1 "." $2 ".0.0/16"}');
               echo "pfctl add to table $NET";
               /sbin/pfctl -vvt bad_ips -T add $NET;
               /sbin/pfctl -vvk $NET;
               RESULT="";
               NET="";
       fi
}
trap finish_serving SIGINT
echo Start serving...
while read line;
       do add_entry $line;
done
---

And an ugly oneliner to make it do the job in real time:
---
tail -fn0 /var/log/authlog | grep -E \
        --line-buffered 'Failed password' | grep -Eo \
        --line-buffered '[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}'\
        | ksh script.sh
---

On Sat Aug 24 00:38:11 2024, Joel Carnat wrote:
> 
> > 
> > Le 23 août 2024 à 17:12, Peter N. M. Hansteen <pe...@bsdly.net> a écrit :
> > 
> > On Fri, Aug 23, 2024 at 12:54:20PM +0200, Joel Carnat wrote:
> >> I have a server which gets flooded with unsolicited HTTP requests. So far, 
> >> I use relayd filters to identify those requests and block them, at relayd 
> >> level. It works as they never reach the web server but relayd is still 
> >> working to block them.
> >> 
> >> I thought of parsing relayd logs to get those IPs and add them to a pf 
> >> block table, using an automated script.
> > 
> > If the problem is that there are a lot of requests from the same hosts 
> > coming in rapid-fire, it is
> > possible that state tracking rules with overloading could be the thing to 
> > try.
> > 
> > The other thing that comes to mind is to put together something that parses 
> > the logs
> > and adds offenders to a table of addresses that PF will block.
> > 
> > Something along the lines of what is described in 
> > https://nxdomain.no/~peter/forcing_the_password_gropers_through_a_smaller_hole.html
> > (also prettified but tracked at 
> > https://bsdly.blogspot.com/2017/04/forcing-password-gropers-through.html)
> > could be what you need (some assembly required, obviously).
> > 
> > - Peter
> 
> Unfortunately, those are not single IP spamming. It looks more like infected 
> computers and/or computer farms sending individual requests at "normal" rate. 
> There are just thousands of them.
> 
> The only way to identify them is by looking at User-Agent and/ou HTTP 
> requests body. So pf only won’t be enough there.
> 
> I thought I could use some matching relayd rules that would tag the 
> connections so that pf blocks them. But it seems pftag is not made for this.
> 
> Writing a script and feed it using syslog is doable. But I hoped I could use 
> only relayd and pf.

-- 
Best regards
Maksim Rodin

С уважением,
Родин Максим

Reply via email to