mirror of https://github.com/jrbrtsn/ban2fail
Added CIDR & ipv6 support
This commit is contained in:
parent
eb9105fc4b
commit
8a1536c160
|
@ -86,7 +86,7 @@ struct Global G= {
|
|||
.version= {
|
||||
.major= 0,
|
||||
.minor= 9,
|
||||
.patch= 5
|
||||
.patch= 6
|
||||
}
|
||||
};
|
||||
|
||||
|
|
49
ban2fail.cfg
49
ban2fail.cfg
|
@ -11,33 +11,53 @@ MAX_OFFENSES 3 {
|
|||
IP= 46.20.2.158
|
||||
}
|
||||
|
||||
# This is your whitelist
|
||||
MAX_OFFENSES -1 {
|
||||
# This is effectively your whitelist
|
||||
MAX_OFFENSES 1000 {
|
||||
|
||||
# me from home
|
||||
IP= 205.144.171.37
|
||||
# me from home, CIDR notation
|
||||
IP= 35.133.139.132/20
|
||||
|
||||
# Some user
|
||||
IP= 173.236.196.36
|
||||
}
|
||||
|
||||
LOGTYPE syslog {
|
||||
|
||||
DIR= /var/log
|
||||
PREFIX= syslog
|
||||
|
||||
#Nov 23 10:08:03 srv auth: pam_unix(dovecot:auth): authentication failure; logname= uid=0 euid=0 tty=dovecot ruser=john rhost=35.133.128.47 user=john
|
||||
# REGEX= pam_unix\(dovecot:auth\): authentication failure;.*rhost=([0-9.]+)
|
||||
REGEX= pam_unix\(dovecot:auth\): authentication failure;.*rhost=([0-9.a-f:]+)
|
||||
|
||||
# Nov 23 16:16:12 srv dovecot: pop3-login: Aborted login (auth failed, 1 attempts in 0 secs): user=<dfloyd>, rip=69.64.58.110, lip=50.116.38.131, session=<5nY6CgqYFdVFQDpu>
|
||||
# REGEX= pop3-login: Aborted.*, rip=([0-9.]+)
|
||||
REGEX= pop3-login: Aborted.*, rip=([0-9.a-f:]+)
|
||||
|
||||
# Nov 23 16:33:53 srv dovecot: pop3-login: Disconnected (no auth attempts in 1 secs): user=<>, rip=71.6.135.131, lip=50.116.38.131, session=<DXWCSQqYjopHBoeD>
|
||||
# REGEX= pop3-login: Disconnected.*, rip=([0-9.]+)
|
||||
REGEX= pop3-login: Disconnected.*, rip=([0-9.a-f:]+)
|
||||
}
|
||||
|
||||
LOGTYPE auth {
|
||||
DIR= /var/log
|
||||
PREFIX= auth.log
|
||||
|
||||
# imapd[20193]= Login failed user=hollingsworth@robertsonoptical.com auth=hollingsworth@robertsonoptical.com host=[186.179.170.12]
|
||||
REGEX= imapd.*Login failed.*\[([0-9.]+)\]$
|
||||
# REGEX= imapd.*Login failed.*\[([0-9.]+)\]$
|
||||
REGEX= imapd.*Login failed.*\[([0-9.a-f:]+)\]$
|
||||
|
||||
# sshd[6165]= Failed password for invalid user user from 185.224.137.201 port 44865 ssh2
|
||||
REGEX= sshd.*Failed password.*from ([0-9.]+) port [0-9]+ ssh2$
|
||||
# REGEX= sshd.*Failed password.*from ([0-9.]+) port [0-9]+ ssh2$
|
||||
REGEX= sshd.*Failed password.*from ([0-9.a-f:]+) port [0-9]+ ssh2$
|
||||
|
||||
# Unable to negotiate with 193.188.22.188 port ...
|
||||
REGEX= Unable to negotiate with ([0-9.]+) port
|
||||
# REGEX= Unable to negotiate with ([0-9.]+) port
|
||||
REGEX= Unable to negotiate with ([0-9.a-f:]+) port
|
||||
|
||||
# in.qpopper[14962]= pam_unix(qpopper=auth)= authentication failure; logname= uid=0 euid=0 tty=96.89.83.1
|
||||
# TODO: this can be retired around 2019-12-10
|
||||
REGEX= in\.qpopper.*authentication failure.*tty=([0-9.]+)
|
||||
|
||||
}
|
||||
|
||||
LOGTYPE exim4 {
|
||||
|
@ -47,14 +67,21 @@ LOGTYPE exim4 {
|
|||
|
||||
# cram_md5_server authenticator failed for ([78.128.113.121]) [78.128.113.121]
|
||||
# cram_md5_server authenticator failed for (swim.diverseenvironment.com.) [185.211.245.198]
|
||||
REGEX= [[:alnum:]_]+ authenticator failed for .*\[([0-9.]+)\]
|
||||
# REGEX= [[:alnum:]_]+ authenticator failed for .*\[([0-9.]+)\]
|
||||
REGEX= [[:alnum:]_]+ authenticator failed for .*\[([0-9.a-f:]+)\]
|
||||
|
||||
# 2019-11-15 00:08:25 SMTP protocol error in "AUTH LOGIN" H=(User) [193.56.28.176] LOGIN authentication mechanism not supported
|
||||
REGEX= \[([0-9.]+)\] [[:alnum:]_]+ authentication mechanism not supported
|
||||
# REGEX= \[([0-9.]+)\] [[:alnum:]_]+ authentication mechanism not supported
|
||||
REGEX= \[([0-9.a-f:]+)\] [[:alnum:]_]+ authentication mechanism not supported
|
||||
|
||||
# 2019-11-20 03:44:51 1iXLbX-0000ZX-F8 <= kirsten@rrci.com H=(rrci.com) [171.244.140.160] P=esmtpa A=cram_md5_server:kirsten S=2742 id=9857581066.20191120084450@rrci.com
|
||||
# 2019-11-20 18:21:15 1iXZHe-0002fZ-W8 <= kirsten@rrci.com H=035-133-139-132.res.spectrum.com ([192.168.1.29]) [35.133.139.132] P=esmtpsa X=TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128 CV=no A=plain_server:kirsten S=703 id=e8478681-4fc5-75d8-7328-52f534956d65@rrci.com
|
||||
REGEX= \[([0-9.]+)\].*A=[[:alnum:]_]+_server:
|
||||
# REGEX= \[([0-9.]+)\].*A=[[:alnum:]_]+_server:
|
||||
REGEX= \[([0-9.a-f:]+)\].*A=[[:alnum:]_]+_server:
|
||||
|
||||
# [185.234.217.241] (gnutls_handshake): No supported cipher suites have been found.
|
||||
# REGEX= \[([0-9.]+)\].*No supported cipher suites have been found
|
||||
REGEX= \[([0-9.a-f:]+)\].*No supported cipher suites have been found
|
||||
|
||||
}
|
||||
|
||||
|
|
|
@ -37,10 +37,11 @@
|
|||
|
||||
/* Where to find stuff */
|
||||
#define CONFIGFILE "/etc/ban2fail/ban2fail.cfg"
|
||||
#define LOCKPATH "/var/run/lock/ban2fail"
|
||||
#define LOCKPATH "/run/lock/ban2fail"
|
||||
#define CACHEDIR "/var/cache/ban2fail"
|
||||
#define IPTABLES "/usr/sbin/iptables"
|
||||
#define GEOIP_DB "/usr/share/GeoIP/GeoIP.dat"
|
||||
#define GEOIP6_DB "/usr/share/GeoIP/GeoIPv6.dat"
|
||||
|
||||
|
||||
/* Singleton static object with global visibility */
|
||||
|
|
12
cntry.c
12
cntry.c
|
@ -30,7 +30,8 @@
|
|||
static struct {
|
||||
|
||||
int is_init;
|
||||
GeoIP *gip;
|
||||
GeoIP *gip,
|
||||
*gip6;
|
||||
|
||||
} S;
|
||||
|
||||
|
@ -49,6 +50,12 @@ init()
|
|||
eprintf("PANIC: GeoIP_open(\"%s\") failed!", GEOIP_DB);
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
S.gip6= GeoIP_open(GEOIP6_DB, 0);
|
||||
if(!S.gip6) {
|
||||
eprintf("PANIC: GeoIP_open(\"%s\") failed!", GEOIP6_DB);
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
}
|
||||
|
||||
const char*
|
||||
|
@ -59,6 +66,9 @@ COUNTRY_get_code(const char *addr)
|
|||
{
|
||||
if(!S.is_init) init();
|
||||
|
||||
if(strchr(addr, ':'))
|
||||
return GeoIP_country_code_by_addr_v6(S.gip6, addr);
|
||||
|
||||
return GeoIP_country_code_by_addr(S.gip, addr);
|
||||
}
|
||||
|
||||
|
|
72
maxoff.c
72
maxoff.c
|
@ -16,6 +16,8 @@
|
|||
* Free Software Foundation, Inc., *
|
||||
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
|
||||
***************************************************************************/
|
||||
#include <assert.h>
|
||||
|
||||
#include "cntry.h"
|
||||
#include "maxoff.h"
|
||||
|
||||
|
@ -33,7 +35,7 @@ initialize(void)
|
|||
{
|
||||
S.is_init= 1;
|
||||
MAP_constructor(&S.cntry_map, 10, 10);
|
||||
MAP_constructor(&S.addr_map, 10, 10);
|
||||
MAP_constructor(&S.addr_map, 1000, 200);
|
||||
}
|
||||
|
||||
// Compiler doesn't like that we use integers in place of item pointers */
|
||||
|
@ -73,7 +75,7 @@ MAXOFF_allowed(const char *addr)
|
|||
}
|
||||
|
||||
int
|
||||
MAXOFF_init(CFGMAP *h_map, char *pfix)
|
||||
MAXOFF_init(CFGMAP *h_cfgmap, char *pfix)
|
||||
/**************************************************************
|
||||
* Initialize objects from configuration map.
|
||||
*/
|
||||
|
@ -85,7 +87,7 @@ MAXOFF_init(CFGMAP *h_map, char *pfix)
|
|||
|
||||
size_t len= strlen(pfix)+1024;
|
||||
char symBuf[len];
|
||||
unsigned arr_sz= CFGMAP_numTuples(h_map);
|
||||
unsigned arr_sz= CFGMAP_numTuples(h_cfgmap);
|
||||
struct CFGMAP_tuple rtn_arr[arr_sz];
|
||||
int nAllowed;
|
||||
|
||||
|
@ -100,20 +102,72 @@ MAXOFF_init(CFGMAP *h_map, char *pfix)
|
|||
{ /*--- Register IP entries ---*/
|
||||
snprintf(symBuf, len, "%s\\IP", pfix);
|
||||
|
||||
unsigned nFound= CFGMAP_find_tuples(h_map, rtn_arr, symBuf);
|
||||
unsigned nFound= CFGMAP_find_tuples(h_cfgmap, rtn_arr, symBuf);
|
||||
for(unsigned i= 0; i < nFound; ++i) {
|
||||
const struct CFGMAP_tuple *tpl= rtn_arr + i;
|
||||
|
||||
/* Place in the map the number allowed as if it were
|
||||
* a pointer to an object (superflous in this case).
|
||||
*/
|
||||
MAP_addStrKey(&S.addr_map, tpl->value, (void*)nAllowed);
|
||||
/* Break the address into prefix & subnet bits */
|
||||
static char addr[43];
|
||||
unsigned bits;
|
||||
|
||||
int rc= sscanf(tpl->value, "%42[0-9a-zA-Z:.]/%u", addr, &bits);
|
||||
|
||||
if(1 != rc && 2 != rc) {
|
||||
eprintf("ERROR: \"%s\" is neither IP address or CIDR.", tpl->value);
|
||||
goto abort;
|
||||
}
|
||||
|
||||
/* If it's simply an IP address, place in map & keep going */
|
||||
if(1 == rc) {
|
||||
/* Place in the map the number allowed as if it were
|
||||
* a pointer to an object (there is no object in this case).
|
||||
*/
|
||||
MAP_addStrKey(&S.addr_map, addr, (void*)nAllowed);
|
||||
continue;
|
||||
}
|
||||
|
||||
/* Avoid stupidity right off the hop */
|
||||
if(strchr(addr, ':')) {
|
||||
eprintf("ERROR: CIDR not implemented for ipv6 \"%s\"", tpl->value);
|
||||
goto abort;
|
||||
} else if(16 > bits) {
|
||||
eprintf("ERROR: Subnet is too large! \"%s\"", tpl->value);
|
||||
goto abort;
|
||||
}
|
||||
|
||||
/*--- Expand the CIDR notation to addresses ---*/
|
||||
unsigned q1, q2, q3, q4;
|
||||
|
||||
/* Convert quad values from text to binary */
|
||||
rc= sscanf(addr, "%u.%u.%u.%u", &q1, &q2, &q3, &q4);
|
||||
|
||||
/* Convert quads into useful parameters */
|
||||
uint32_t baddr= (q1 << 24) | (q2 << 16) | (q3 << 8) | q4,
|
||||
mask= 0xffffffff << (32-bits),
|
||||
net= baddr & mask,
|
||||
nAddr= 0xffffffff >> bits;
|
||||
|
||||
assert(4 == rc);
|
||||
|
||||
/* Generate individual addresses, and place them in the map */
|
||||
for(unsigned i= 0; i < nAddr; ++i) {
|
||||
baddr= net | i;
|
||||
q1= (baddr & 0xff000000) >> 24;
|
||||
q2= (baddr & 0x00ff0000) >> 16;
|
||||
q3= (baddr & 0x0000ff00) >> 8;
|
||||
q4= baddr & 0x000000ff;
|
||||
|
||||
/* Convert back to text form */
|
||||
snprintf(addr, sizeof(addr), "%u.%u.%u.%u", q1, q2, q3, q4);
|
||||
/* Add to the map */
|
||||
MAP_addStrKey(&S.addr_map, addr, (void*)nAllowed);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
{ /*--- Register COUNTRY entries ---*/
|
||||
snprintf(symBuf, len, "%s\\COUNTRY", pfix);
|
||||
unsigned nFound= CFGMAP_find_tuples(h_map, rtn_arr, symBuf);
|
||||
unsigned nFound= CFGMAP_find_tuples(h_cfgmap, rtn_arr, symBuf);
|
||||
|
||||
for(unsigned i= 0; i < nFound; ++i) {
|
||||
const struct CFGMAP_tuple *tpl= rtn_arr + i;
|
||||
|
|
Loading…
Reference in New Issue