Added CIDR & ipv6 support

This commit is contained in:
john 2019-11-23 21:22:37 -05:00
parent eb9105fc4b
commit 8a1536c160
7 changed files with 117 additions and 24 deletions

View File

@ -1,2 +1,3 @@
Add ipv6 GeoIP support
Implement CIDR notation for IP

View File

@ -86,7 +86,7 @@ struct Global G= {
.version= {
.major= 0,
.minor= 9,
.patch= 5
.patch= 6
}
};

View File

@ -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
}

View File

@ -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
View File

@ -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);
}

View File

@ -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;

2
util.c
View File

@ -358,7 +358,7 @@ strbits(int64_t bits, unsigned nBytes)
*/
{
/* Rotating buffers so this can be used multiple times as arg to printf() */
#define N_BUFS 5
#define N_BUFS 8
#define BUF_SZ 65
static _Thread_local char bufArr[N_BUFS][BUF_SZ];
static _Thread_local unsigned count;