mirror of
https://github.com/jrbrtsn/ban2fail
synced 2024-06-16 11:58:01 +00:00
Added CIDR & ipv6 support
This commit is contained in:
parent
eb9105fc4b
commit
8a1536c160
1
TODO.txt
1
TODO.txt
@ -1,2 +1,3 @@
|
|||||||
|
Add ipv6 GeoIP support
|
||||||
Implement CIDR notation for IP
|
Implement CIDR notation for IP
|
||||||
|
|
||||||
|
@ -86,7 +86,7 @@ struct Global G= {
|
|||||||
.version= {
|
.version= {
|
||||||
.major= 0,
|
.major= 0,
|
||||||
.minor= 9,
|
.minor= 9,
|
||||||
.patch= 5
|
.patch= 6
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
49
ban2fail.cfg
49
ban2fail.cfg
@ -11,33 +11,53 @@ MAX_OFFENSES 3 {
|
|||||||
IP= 46.20.2.158
|
IP= 46.20.2.158
|
||||||
}
|
}
|
||||||
|
|
||||||
# This is your whitelist
|
# This is effectively your whitelist
|
||||||
MAX_OFFENSES -1 {
|
MAX_OFFENSES 1000 {
|
||||||
|
|
||||||
# me from home
|
# me from home, CIDR notation
|
||||||
IP= 205.144.171.37
|
IP= 35.133.139.132/20
|
||||||
|
|
||||||
# Some user
|
# Some user
|
||||||
IP= 173.236.196.36
|
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 {
|
LOGTYPE auth {
|
||||||
DIR= /var/log
|
DIR= /var/log
|
||||||
PREFIX= auth.log
|
PREFIX= auth.log
|
||||||
|
|
||||||
# imapd[20193]= Login failed user=hollingsworth@robertsonoptical.com auth=hollingsworth@robertsonoptical.com host=[186.179.170.12]
|
# 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
|
# 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 ...
|
# 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
|
# 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.]+)
|
REGEX= in\.qpopper.*authentication failure.*tty=([0-9.]+)
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
LOGTYPE exim4 {
|
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 ([78.128.113.121]) [78.128.113.121]
|
||||||
# cram_md5_server authenticator failed for (swim.diverseenvironment.com.) [185.211.245.198]
|
# 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
|
# 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 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
|
# 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 */
|
/* Where to find stuff */
|
||||||
#define CONFIGFILE "/etc/ban2fail/ban2fail.cfg"
|
#define CONFIGFILE "/etc/ban2fail/ban2fail.cfg"
|
||||||
#define LOCKPATH "/var/run/lock/ban2fail"
|
#define LOCKPATH "/run/lock/ban2fail"
|
||||||
#define CACHEDIR "/var/cache/ban2fail"
|
#define CACHEDIR "/var/cache/ban2fail"
|
||||||
#define IPTABLES "/usr/sbin/iptables"
|
#define IPTABLES "/usr/sbin/iptables"
|
||||||
#define GEOIP_DB "/usr/share/GeoIP/GeoIP.dat"
|
#define GEOIP_DB "/usr/share/GeoIP/GeoIP.dat"
|
||||||
|
#define GEOIP6_DB "/usr/share/GeoIP/GeoIPv6.dat"
|
||||||
|
|
||||||
|
|
||||||
/* Singleton static object with global visibility */
|
/* Singleton static object with global visibility */
|
||||||
|
12
cntry.c
12
cntry.c
@ -30,7 +30,8 @@
|
|||||||
static struct {
|
static struct {
|
||||||
|
|
||||||
int is_init;
|
int is_init;
|
||||||
GeoIP *gip;
|
GeoIP *gip,
|
||||||
|
*gip6;
|
||||||
|
|
||||||
} S;
|
} S;
|
||||||
|
|
||||||
@ -49,6 +50,12 @@ init()
|
|||||||
eprintf("PANIC: GeoIP_open(\"%s\") failed!", GEOIP_DB);
|
eprintf("PANIC: GeoIP_open(\"%s\") failed!", GEOIP_DB);
|
||||||
exit(EXIT_FAILURE);
|
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*
|
const char*
|
||||||
@ -59,6 +66,9 @@ COUNTRY_get_code(const char *addr)
|
|||||||
{
|
{
|
||||||
if(!S.is_init) init();
|
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);
|
return GeoIP_country_code_by_addr(S.gip, addr);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
72
maxoff.c
72
maxoff.c
@ -16,6 +16,8 @@
|
|||||||
* Free Software Foundation, Inc., *
|
* Free Software Foundation, Inc., *
|
||||||
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
|
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
|
||||||
***************************************************************************/
|
***************************************************************************/
|
||||||
|
#include <assert.h>
|
||||||
|
|
||||||
#include "cntry.h"
|
#include "cntry.h"
|
||||||
#include "maxoff.h"
|
#include "maxoff.h"
|
||||||
|
|
||||||
@ -33,7 +35,7 @@ initialize(void)
|
|||||||
{
|
{
|
||||||
S.is_init= 1;
|
S.is_init= 1;
|
||||||
MAP_constructor(&S.cntry_map, 10, 10);
|
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 */
|
// Compiler doesn't like that we use integers in place of item pointers */
|
||||||
@ -73,7 +75,7 @@ MAXOFF_allowed(const char *addr)
|
|||||||
}
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
MAXOFF_init(CFGMAP *h_map, char *pfix)
|
MAXOFF_init(CFGMAP *h_cfgmap, char *pfix)
|
||||||
/**************************************************************
|
/**************************************************************
|
||||||
* Initialize objects from configuration map.
|
* Initialize objects from configuration map.
|
||||||
*/
|
*/
|
||||||
@ -85,7 +87,7 @@ MAXOFF_init(CFGMAP *h_map, char *pfix)
|
|||||||
|
|
||||||
size_t len= strlen(pfix)+1024;
|
size_t len= strlen(pfix)+1024;
|
||||||
char symBuf[len];
|
char symBuf[len];
|
||||||
unsigned arr_sz= CFGMAP_numTuples(h_map);
|
unsigned arr_sz= CFGMAP_numTuples(h_cfgmap);
|
||||||
struct CFGMAP_tuple rtn_arr[arr_sz];
|
struct CFGMAP_tuple rtn_arr[arr_sz];
|
||||||
int nAllowed;
|
int nAllowed;
|
||||||
|
|
||||||
@ -100,20 +102,72 @@ MAXOFF_init(CFGMAP *h_map, char *pfix)
|
|||||||
{ /*--- Register IP entries ---*/
|
{ /*--- Register IP entries ---*/
|
||||||
snprintf(symBuf, len, "%s\\IP", pfix);
|
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) {
|
for(unsigned i= 0; i < nFound; ++i) {
|
||||||
const struct CFGMAP_tuple *tpl= rtn_arr + i;
|
const struct CFGMAP_tuple *tpl= rtn_arr + i;
|
||||||
|
|
||||||
/* Place in the map the number allowed as if it were
|
/* Break the address into prefix & subnet bits */
|
||||||
* a pointer to an object (superflous in this case).
|
static char addr[43];
|
||||||
*/
|
unsigned bits;
|
||||||
MAP_addStrKey(&S.addr_map, tpl->value, (void*)nAllowed);
|
|
||||||
|
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 ---*/
|
{ /*--- Register COUNTRY entries ---*/
|
||||||
snprintf(symBuf, len, "%s\\COUNTRY", pfix);
|
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) {
|
for(unsigned i= 0; i < nFound; ++i) {
|
||||||
const struct CFGMAP_tuple *tpl= rtn_arr + i;
|
const struct CFGMAP_tuple *tpl= rtn_arr + i;
|
||||||
|
2
util.c
2
util.c
@ -358,7 +358,7 @@ strbits(int64_t bits, unsigned nBytes)
|
|||||||
*/
|
*/
|
||||||
{
|
{
|
||||||
/* Rotating buffers so this can be used multiple times as arg to printf() */
|
/* 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
|
#define BUF_SZ 65
|
||||||
static _Thread_local char bufArr[N_BUFS][BUF_SZ];
|
static _Thread_local char bufArr[N_BUFS][BUF_SZ];
|
||||||
static _Thread_local unsigned count;
|
static _Thread_local unsigned count;
|
||||||
|
Loading…
Reference in New Issue
Block a user