diff --git a/ban2fail.c b/ban2fail.c index 10984a5..e404e93 100644 --- a/ban2fail.c +++ b/ban2fail.c @@ -85,8 +85,8 @@ struct Global G= { .version= { .major= 0, - .minor= 9, - .patch= 7 + .minor= 10, + .patch= 0 } }; @@ -376,7 +376,7 @@ main(int argc, char **argv) /* Print out only for list option */ if(G.flags & GLB_LIST_ADDR_FLG) { - ez_fprintf(stdout, "%-15s: %5u / %u\t offenses %s (%s)\n" + ez_fprintf(stdout, "%-15s\t%5u/%-4u offenses %s (%s)\n" , e->addr , e->count , nAllowed diff --git a/ban2fail.h b/ban2fail.h index 5349bf1..fbf1015 100644 --- a/ban2fail.h +++ b/ban2fail.h @@ -40,6 +40,7 @@ #define LOCKPATH "/run/lock/ban2fail" #define CACHEDIR "/var/cache/ban2fail" #define IPTABLES "/usr/sbin/iptables" +#define IP6TABLES "/usr/sbin/ip6tables" #define GEOIP_DB "/usr/share/GeoIP/GeoIP.dat" #define GEOIP6_DB "/usr/share/GeoIP/GeoIPv6.dat" diff --git a/iptables.c b/iptables.c index e73cc78..f38dc81 100644 --- a/iptables.c +++ b/iptables.c @@ -49,7 +49,23 @@ initialize (void) FILE *fh= ez_popen(IPTABLES " -nL INPUT 2>/dev/null", "r"); for(unsigned i= 0; ez_fgets(lbuf, sizeof(lbuf)-1, fh); ++i) { if(0 == i || 1 == i) continue; - if(1 != sscanf(lbuf, "DROP all -- %63s 0.0.0.0/0", addr)) continue; + if(1 != sscanf(lbuf, "DROP all -- %63s 0.0.0.0/0", addr)) { + eprintf("ERROR: scanning pattern"); + continue; + } + MAP_addStrKey(&S.addr_map, addr, (void*)-1); + } + ez_pclose(fh); + + fh= ez_popen(IP6TABLES " -nL INPUT 2>/dev/null", "r"); + for(unsigned i= 0; ez_fgets(lbuf, sizeof(lbuf)-1, fh); ++i) { + if(0 == i || 1 == i) continue; + +// DROP all 2607:5300:60:653b:: ::/0 + if(1 != sscanf(lbuf, "DROP all %63s ::/0", addr)) { + eprintf("ERROR: scanning pattern"); + continue; + } MAP_addStrKey(&S.addr_map, addr, (void*)-1); } ez_pclose(fh); @@ -75,6 +91,25 @@ IPTABLES_is_currently_blocked(const char *addr) return 0; } +static int +addrCmp_pvsort(const void *const* pp1, const void *const* pp2) +/************************************************************** + * PTRVEC_sort() comparison function for addresses, puts + * ipv6 at the bottom. + */ +{ + const char *addr1= *((const char*const*)pp1), + *addr2= *((const char*const*)pp2); + + if(strchr(addr2, ':')) { + if(!strchr(addr1, ':')) return -1; + } else { + if(strchr(addr1, ':')) return 1; + } + + return 0; +} + static int _control_addresses(int cmdFlag, PTRVEC *h_vec, unsigned batch_sz) /************************************************************** @@ -94,15 +129,56 @@ _control_addresses(int cmdFlag, PTRVEC *h_vec, unsigned batch_sz) const char *addr; - /* Work through addresses in the vector */ - while((addr= PTRVEC_remHead(h_vec))) { + /* Put any ipv6 addresses at end */ + PTRVEC_sort(h_vec, addrCmp_pvsort); + /* Work through ipv4 addresses in the vector */ + while((addr= PTRVEC_remHead(h_vec)) && + !strchr(addr, ':')) + { /* Initialize / reset string buffer */ STR_sinit(&cmd_sb, 256+batch_sz*42); /* Beginning of command string, with first source address */ STR_sprintf(&cmd_sb, IPTABLES " 2>&1 -%c INPUT -s %s", cmdFlag, addr); + /* Append additional source addresses */ + unsigned i= 1; + while(i < batch_sz && + (addr= PTRVEC_remHead(h_vec)) && + !strchr(addr, ':')) + { + /* employ multiple source addresses for batching */ + STR_sprintf(&cmd_sb, ",%s", addr); + ++i; + } + + /* Put the end of the command in place */ + STR_sprintf(&cmd_sb, " -j DROP"); + + /* Run iptables */ + FILE *fh= ez_popen(STR_str(&cmd_sb), "r"); + /* Display any output from iptables */ + static char lbuf[1024]; + while(ez_fgets(lbuf, sizeof(lbuf), fh)) + ez_fprintf(stderr, "NOTE: iptables output: %s", lbuf); + + /* All done */ + ez_pclose(fh); + + /* If the last address pulled was ipv6, move on */ + if(addr && strchr(addr, ':')) break; + } + + /* Work through ipv6 addresses in the vector */ + for( ; addr; (addr= PTRVEC_remHead(h_vec))) { + + /* Initialize / reset string buffer */ + STR_sinit(&cmd_sb, 256+batch_sz*42); + + /* Beginning of command string, with first source address */ + STR_sprintf(&cmd_sb, IP6TABLES " 2>&1 -%c INPUT -s %s", cmdFlag, addr); + /* Append additional source addresses */ unsigned i= 1; while(i < batch_sz && (addr= PTRVEC_remHead(h_vec))) { @@ -120,7 +196,7 @@ _control_addresses(int cmdFlag, PTRVEC *h_vec, unsigned batch_sz) /* Display any output from iptables */ static char lbuf[1024]; while(ez_fgets(lbuf, sizeof(lbuf), fh)) - ez_fprintf(stderr, "NOTE: iptables output: %s", lbuf); + ez_fprintf(stderr, "NOTE: ip6tables output: %s", lbuf); /* All done */ ez_pclose(fh);