Hi all,

I still run a plan9 server attached to the net. I have always
had attacks from bots, viruses, script kiddies etc. and decided
to do something to reduce the load on my system - some attacks can be
quite persistant.

I have taken the idea from the linux log2ban script but I implemented it
a rather differently. 

I added two functions to libsec (for want of a better place), nuisance()
and banished(). the former allows you to log a failed authentication attempt,
dropped TLS connection etc. the latter tests for too many failures and drops
connections from repeat offenders.

nuisance() adds a single character (indicating the type of failure, 't' for TLS 
drop,
'a' for authentication failure etc), to an append only file in /lib/ndb/banished
named with the source IP address that is connecting. if that file gets too long
the address is becomes persona non-grata.

I have a cron jonb that deletes banishment files that have not been modified 
for a month
on the basis that hackers and bots get rounded up eventually.

I added these calls to dnstcp, listen, tlssrv, imap4d, httpd, smtpd, and 
secstored.
This is enough to cover all the network listners I have, and it works well, but 
feels
a little crude. I would be interested if anyone has a more elegant solution.

-Steve
------------------------------------------
9fans: 9fans
Permalink: 
https://9fans.topicbox.com/groups/9fans/Tdfbfcf822b637ab5-M4e4c1663200a71a70be33a38
Delivery options: https://9fans.topicbox.com/groups/9fans/subscription
#include <u.h>
#include <libc.h>

static char *bandir = "/lib/ndb/banished";

/* Log that this ipaddr, (or ipaddr!port) may be causing a nuisance */
int
nuisance(char *addr, char c)
{
        int fd, len;
        char *p, *path;

        if(!addr || !*addr)
                return -1;

        len = strlen(addr);
        if((p = strchr(addr, '!')) != nil)
                len = p - addr;

        path = smprint("%s/%.*s", bandir, len, addr);
        if((fd = open(path, OWRITE)) == -1)
                fd = create(path, OWRITE, 0666|DMAPPEND);
        free(path);

        if(fd == -1){
                return -1;
        }

        write(fd, &c, 1);
        close(fd);
        return 0;
}

/* Has this ipaddr, (or ipaddr!port) caused too much of a nuisance */
int
banished(char *addr, int thresh)
{
        Dir *d;
        int n, len;
        char *p, *path;

        if(!addr || !*addr)
                return 0;

        len = strlen(addr);
        if((p = strchr(addr, '!')) != nil)
                len = p - addr;

        path = smprint("%s/%.*s", bandir, len, addr);
        d = dirstat(path);
        free(path);

        if(d == nil)
                return 0;
        n = d->length;
        free(d);

        if(n < thresh)
                return 0;
        return 1;
}

Reply via email to