Compare commits
No commits in common. '5846157eedde59d137fea8283ff68a9fc745da09' and '2f15996b91de5cf4773ddb48f4d5d7f0c3431f76' have entirely different histories.
5846157eed
...
2f15996b91
30 changed files with 153 additions and 322 deletions
@ -1,8 +1,6 @@ |
|||||||
# -q option stops a ipfw table add or delete from failing if the entry |
|
||||||
# already exists or is not present. |
|
||||||
[backend:exec-ipfw] |
[backend:exec-ipfw] |
||||||
load = backend_exec.so |
load = backend_exec.so |
||||||
ban = /sbin/ipfw -q table <ID> add <IP> |
ban = /sbin/ipfw table <ID> add <IP> |
||||||
unban = /sbin/ipfw -q table <ID> delete <IP> |
unban = /sbin/ipfw table <ID> delete <IP> |
||||||
timeout = 2 |
timeout = 2 |
||||||
shared = yes |
shared = yes |
||||||
|
@ -1,3 +0,0 @@ |
|||||||
[jail:dovecot] |
|
||||||
source = files:/var/log/mail.log |
|
||||||
filter = preg:${CMAKE_INSTALL_FULL_DATAROOTDIR}/f2b/filters/dovecot.preg |
|
@ -1,3 +0,0 @@ |
|||||||
[jail:nginx] |
|
||||||
source = files:/var/log/nginx/*access*.log |
|
||||||
filter = pcre:${CMAKE_INSTALL_FULL_DATAROOTDIR}/f2b/filters/nginx-bots.pcre |
|
@ -1,3 +0,0 @@ |
|||||||
[jail:postfix] |
|
||||||
source = files:/var/log/mail.log |
|
||||||
filter = preg:${CMAKE_INSTALL_FULL_DATAROOTDIR}/f2b/filters/postfix.preg |
|
@ -1,3 +0,0 @@ |
|||||||
[jail:ssh] |
|
||||||
source = files:/var/log/auth.log |
|
||||||
filter = preg:${CMAKE_INSTALL_FULL_DATAROOTDIR}/f2b/filters/ssh.preg |
|
@ -1,2 +1 @@ |
|||||||
usr/share/f2b/filters |
|
||||||
var/lib/f2b |
var/lib/f2b |
||||||
|
@ -1,2 +0,0 @@ |
|||||||
- Where have all filters gone? |
|
||||||
- Now it located in their own repository, for convinient maintenance |
|
@ -0,0 +1,4 @@ |
|||||||
|
SECURITY.* SecurityEvent="FailedACL".*RemoteAddress="IPV[46]/[TU][CD]P/<HOST>/[0-9]+" |
||||||
|
SECURITY.* SecurityEvent="InvalidAccountID".*RemoteAddress="IPV[46]/[TU][CD]P/<HOST>/[0-9+]+" |
||||||
|
SECURITY.* SecurityEvent="ChallengeResponseFailed".*RemoteAddress="IPV[46]/[TU][CD]P/<HOST>/[0-9]+" |
||||||
|
SECURITY.* SecurityEvent="InvalidPassword".*RemoteAddress="IPV[46]/[TU][CD]P/<HOST>/[0-9]+" |
@ -0,0 +1,2 @@ |
|||||||
|
# set: defscore=5 |
||||||
|
closed \(2nd stage\), user <> .* remote <HOST>:[0-9]+, reason: allocation watchdog determined stale session state |
@ -0,0 +1,6 @@ |
|||||||
|
pop3-login: Aborted login \(auth failed, [0-9]+ attempts in [0-9]+ secs\): .* rip=<HOST> |
||||||
|
imap-login: Aborted login \(auth failed, [0-9]+ attempts in [0-9]+ secs\): .* rip=<HOST> |
||||||
|
pop3-login: Disconnected \(auth failed, [0-9]+ attempts in [0-9]+ secs\): .* rip=<HOST> |
||||||
|
imap-login: Disconnected \(auth failed, [0-9]+ attempts in [0-9]+ secs\): .* rip=<HOST> |
||||||
|
# set: defscore=5 |
||||||
|
submission-login: Client has quit the connection \(tried to use disallowed plaintext auth\): .* rip=<HOST> |
@ -0,0 +1,10 @@ |
|||||||
|
# set: defscore=10 |
||||||
|
SMTP protocol synchronization error \(input sent without waiting for greeting\): rejected connection from .*\[<HOST>\] |
||||||
|
SMTP protocol synchronization error \(next input sent too soon: pipelining was not advertised\): rejected .*\[<HOST>\] |
||||||
|
rejected [HE][EH]HLO from \[<HOST>\]: syntactically invalid argument |
||||||
|
\[<HOST>\] .* host is listed in .+ |
||||||
|
\[<HOST>\] .* relay not permitted |
||||||
|
\[<HOST>\] .* rejected after DATA: This message was detected as possible malware |
||||||
|
# set: defscore=5 |
||||||
|
\[<HOST>\] .* too many connections from that IP address |
||||||
|
\[<HOST>\] .* temporarily rejected RCPT \<\S+\>: lowest numbered MX record points to local host |
@ -0,0 +1,3 @@ |
|||||||
|
Failed authentication attempt for [[:print:]]+ from <HOST> |
||||||
|
Failed authentication attempt from <HOST> |
||||||
|
invalid credentials from <HOST> |
@ -0,0 +1,6 @@ |
|||||||
|
# set: defscore=10 |
||||||
|
<HOST>#[0-9]+ .* query \(cache\) '[0-9.]+.in-addr.arpa/(PTR|SOA)/IN' denied |
||||||
|
# requests to '.' or top-level domains |
||||||
|
<HOST>#[0-9]+ .* query \(cache\) '[a-z.]+/ANY/IN' denied |
||||||
|
# set: defscore=1 |
||||||
|
<HOST>#[0-9]+ .* query \(cache\) '[0-9a-z.-]+/RRSIG/IN' denied |
@ -0,0 +1,32 @@ |
|||||||
|
# set: defscore=15 |
||||||
|
# h4x0rs |
||||||
|
<HOST> .* "(GET|HEAD|POST) (https?://[0-9a-z.-]+)?(:[0-9]*)?/(shell|cmd|x)\.(php|cgi) |
||||||
|
<HOST> .* "(GET|HEAD|POST) (https?://[0-9a-z.-]+)?(:[0-9]*)?/w00tw00t |
||||||
|
<HOST> .* "(GET|HEAD|POST) (https?://[0-9a-z.-]+)?(:[0-9]*)?/+Ringing\.at\.your\.dorbell |
||||||
|
<HOST> .* "(GET|HEAD|POST) (https?://[0-9a-z.-]+)?(:[0-9]*)?/.*(wget|curl)(\\x|%)20https?:// |
||||||
|
<HOST> .* "(GET|HEAD|POST) .*/bin/(ba|c|z)?sh( |\\x20|%20)-c |
||||||
|
<HOST> .* "(\\x[0-9a-z]{2,6})+" 400 |
||||||
|
# set: defscore=10 |
||||||
|
# phpmyadmin and variations |
||||||
|
<HOST> .* "(GET|HEAD|POST) (https?://[0-9a-z.-]+)?(:[0-9]*)?/+(php|sqlite)-?(manager)? |
||||||
|
<HOST> .* "(GET|HEAD|POST) (https?://[0-9a-z.-]+)?(:[0-9]*)?/+(php|pg|sql)-?my-?admin |
||||||
|
<HOST> .* "(GET|HEAD|POST) (https?://[0-9a-z.-]+)?(:[0-9]*)?/+pma[0-9]* |
||||||
|
<HOST> .* "(GET|HEAD|POST) (https?://[0-9a-z.-]+)?(:[0-9]*)?/+((my|pg)(sql)?|db|msd?)-?(admin|dumper|dump|manager) |
||||||
|
# set: defscore=5 |
||||||
|
# open proxy search |
||||||
|
<HOST> .* "(GET|HEAD|POST) https?://[a-z-\.]+proxyradar\.com |
||||||
|
<HOST> .* "CONNECT [a-z-\.]*proxyradar\.com |
||||||
|
<HOST> .* "CONNECT [a-z-\.]*proxytest\.zmap\.io |
||||||
|
<HOST> .* "(GET|HEAD|POST) (https?://[0-9a-z.-]+)?(:[0-9]*)?/+testproxy\.php |
||||||
|
# set: defscore=2 |
||||||
|
# search bots |
||||||
|
<HOST> .* "(GET|HEAD|POST) .* "python-(requests|urllib)/[0-9\.]+ |
||||||
|
<HOST> .* "(GET|HEAD|POST) .* "AhrefsBot/[0-9a-z\.]+ |
||||||
|
<HOST> .* "(GET|HEAD|POST) .* "DotBot/[0-9a-z\.]+ |
||||||
|
<HOST> .* "(GET|HEAD|POST) .* "MauiBot |
||||||
|
<HOST> .* "(GET|HEAD|POST) .* SiteExplorer/[0-9a-z\.]+ |
||||||
|
<HOST> .* "(GET|HEAD|POST) .* MJ12bot |
||||||
|
<HOST> .* "(GET|HEAD|POST) .* WebIndex |
||||||
|
# shit-coded php cms |
||||||
|
<HOST> .* "(GET|HEAD|POST) (https?://[0-9a-z.-]+)?(:[0-9]*)?/.*/wp-login.php |
||||||
|
<HOST> .* "(GET|HEAD|POST) (https?://[0-9a-z.-]+)?(:[0-9]*)?/+(joomla|cms)/administrator |
@ -0,0 +1,11 @@ |
|||||||
|
# set: defscore=10 |
||||||
|
NOQUEUE: reject: RCPT from [[:print:]]+\[<HOST>\]: 450 4\.7\.1 Client host rejected |
||||||
|
NOQUEUE: reject: RCPT from [[:print:]]+\[<HOST>\]: 454 4\.7\.1 Service unavailable; Client host \[[[:print:]]+\] blocked |
||||||
|
NOQUEUE: reject: RCPT from [[:print:]]+\[<HOST>\]: 454 4\.7\.1 <[[:print:]]+>: Relay access denied |
||||||
|
NOQUEUE: reject: RCPT from [[:print:]]+\[<HOST>\]: 554 5\.7\.1 <[[:print:]]+>: Relay access denied |
||||||
|
NOQUEUE: reject: RCPT from [[:print:]]+\[<HOST>\]: 550 5\.1\.1 <[[:print:]]+>: Recipient address rejected: undeliverable address |
||||||
|
warning: [[:print:]]+\[<HOST>\]: SASL [A-Z0-9-]+ authentication failed |
||||||
|
# set: defscore=5 |
||||||
|
NOQUEUE: reject: RCPT from [[:print:]]+\[<HOST>\]: 450 4\.7\.1 <[[:print:]]+>: Helo command rejected: Host not found |
||||||
|
NOQUEUE: reject: RCPT from [[:print:]]+\[<HOST>\]: 504 5\.5\.2 <[[:print:]]+>: Helo command rejected: need fully-qualified hostname |
||||||
|
lost connection after AUTH from [[:print:]]+\[<HOST>\] |
@ -0,0 +1,17 @@ |
|||||||
|
# set: defscore=15 |
||||||
|
User [[:print:]]+ from <HOST> not allowed because listed in DenyUsers |
||||||
|
User [[:print:]]+ from <HOST> not allowed because a group is listed in DenyGroups |
||||||
|
# set: defscore=10 |
||||||
|
User [[:print:]]+ from <HOST> not allowed because not listed in AllowUsers |
||||||
|
User [[:print:]]+ from <HOST> not allowed because not in any group |
||||||
|
User [[:print:]]+ from <HOST> not allowed because none of user's groups are listed in AllowGroups |
||||||
|
[Aa]uthentication failure for .* from <HOST>( via [[:print:]]*)? |
||||||
|
[Aa]uthentication error for .* from <HOST>( via [[:print:]]*)? |
||||||
|
Failed password for .* from <HOST> |
||||||
|
# set: defscore=5 |
||||||
|
User not known to the underlying authentication module for .* from <HOST> |
||||||
|
Invalid user [[:print:]]+ from <HOST> |
||||||
|
# set: defscore=3 |
||||||
|
refused connect from [[:print:]]+ \(<HOST>\) |
||||||
|
Did not receive identification string from <HOST> |
||||||
|
Connection closed by <HOST>( port [0-9]+)? \[preauth\] |
@ -1,192 +0,0 @@ |
|||||||
/* Copyright 2017 Alex 'AdUser' Z (ad_user@runbox.com)
|
|
||||||
* |
|
||||||
* This program is free software; you can redistribute it and/or modify |
|
||||||
* it under the terms of the GNU General Public License version 2 as |
|
||||||
* published by the Free Software Foundation. |
|
||||||
*/ |
|
||||||
|
|
||||||
#include <assert.h> |
|
||||||
#include <stdbool.h> |
|
||||||
#include <stdint.h> |
|
||||||
#include <stdlib.h> |
|
||||||
#include <string.h> |
|
||||||
#include <unistd.h> |
|
||||||
|
|
||||||
#include <libipset/ipset.h> |
|
||||||
|
|
||||||
#include "../strlcpy.h" |
|
||||||
|
|
||||||
#include "backend.h" |
|
||||||
#define MODNAME "ipset" |
|
||||||
|
|
||||||
#define IP_LEN_MAX 46 /* ipv6 in mind */ |
|
||||||
|
|
||||||
struct _config { |
|
||||||
char name[ID_MAX + 1]; |
|
||||||
void (*logcb)(enum loglevel lvl, const char *msg); |
|
||||||
struct ipset *ipset; |
|
||||||
enum ipset_cmd last_cmd; |
|
||||||
int flags; |
|
||||||
bool shared; |
|
||||||
}; |
|
||||||
|
|
||||||
#include "backend.c" |
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief Wrapper to get last ipset error and send to log |
|
||||||
* @note Called from this module */ |
|
||||||
inline static bool |
|
||||||
my_ipset_error(cfg_t *cfg, const char *func) { |
|
||||||
struct ipset_data *data = NULL; |
|
||||||
struct ipset_session *sess = ipset_session(cfg->ipset); |
|
||||||
|
|
||||||
if (ipset_session_report_type(sess) != IPSET_NO_ERROR) { |
|
||||||
log_msg(cfg, error, "%s: %s", func, ipset_session_report_msg(sess)); |
|
||||||
ipset_session_report_reset(sess); |
|
||||||
} |
|
||||||
|
|
||||||
if ((data = ipset_session_data(sess)) != NULL) |
|
||||||
ipset_data_reset(data); |
|
||||||
|
|
||||||
return false; |
|
||||||
} |
|
||||||
|
|
||||||
/**
|
|
||||||
* @note Called from library internals |
|
||||||
*/ |
|
||||||
int |
|
||||||
my_ipset_std_error_cb(struct ipset *ipset, void *cfg) { |
|
||||||
struct ipset_session *sess = ipset_session(ipset); |
|
||||||
|
|
||||||
switch (ipset_session_report_type(sess)) { |
|
||||||
case IPSET_NOTICE : |
|
||||||
case IPSET_WARNING : |
|
||||||
if (!ipset_envopt_test(sess, IPSET_ENV_QUIET)) |
|
||||||
log_msg(cfg, error, "warning: %s", ipset_session_report_msg(sess)); |
|
||||||
break; |
|
||||||
case IPSET_ERROR : |
|
||||||
default: |
|
||||||
if (((cfg_t *) cfg)->last_cmd != IPSET_CMD_TEST) { |
|
||||||
log_msg(cfg, error, "error: %s", ipset_session_report_msg(sess)); |
|
||||||
} |
|
||||||
break; |
|
||||||
} |
|
||||||
|
|
||||||
ipset_session_report_reset(sess); |
|
||||||
return -1; |
|
||||||
} |
|
||||||
|
|
||||||
cfg_t * |
|
||||||
create(const char *id) { |
|
||||||
cfg_t *cfg = NULL; |
|
||||||
|
|
||||||
assert(id != NULL); |
|
||||||
|
|
||||||
if ((cfg = calloc(1, sizeof(cfg_t))) == NULL) |
|
||||||
return NULL; |
|
||||||
strlcpy(cfg->name, id, sizeof(cfg->name)); |
|
||||||
cfg->logcb = &logcb_stub; |
|
||||||
cfg->flags |= MOD_IS_READY; |
|
||||||
cfg->flags |= MOD_TYPE_BACKEND; |
|
||||||
cfg->last_cmd = IPSET_CMD_NONE; |
|
||||||
return cfg; |
|
||||||
} |
|
||||||
|
|
||||||
bool |
|
||||||
config(cfg_t *cfg, const char *key, const char *value) { |
|
||||||
assert(cfg != NULL); |
|
||||||
assert(key != NULL); |
|
||||||
assert(value != NULL); |
|
||||||
|
|
||||||
(void)(cfg); |
|
||||||
(void)(key); |
|
||||||
(void)(value); |
|
||||||
|
|
||||||
return false; |
|
||||||
} |
|
||||||
|
|
||||||
bool |
|
||||||
start(cfg_t *cfg) { |
|
||||||
assert(cfg != NULL); |
|
||||||
|
|
||||||
if (cfg->shared && usage_inc(cfg->name) > 1) |
|
||||||
return true; |
|
||||||
|
|
||||||
ipset_load_types(); |
|
||||||
|
|
||||||
if ((cfg->ipset = ipset_init()) == NULL) { |
|
||||||
log_msg(cfg, error, "can't init ipset library"); |
|
||||||
return false; |
|
||||||
} |
|
||||||
|
|
||||||
if (ipset_session_output(ipset_session(cfg->ipset), IPSET_LIST_NONE) < 0) |
|
||||||
return my_ipset_error(cfg, "ipset_session_output()"); |
|
||||||
|
|
||||||
if (ipset_envopt_parse(cfg->ipset, IPSET_ENV_EXIST, NULL) < 0) |
|
||||||
return my_ipset_error(cfg, "ipset_envopt_parse()"); |
|
||||||
ipset_custom_printf(cfg->ipset, NULL, &my_ipset_std_error_cb, NULL, (void *) cfg); |
|
||||||
ipset_envopt_set(ipset_session(cfg->ipset), IPSET_ENV_QUIET); |
|
||||||
|
|
||||||
return true; |
|
||||||
} |
|
||||||
|
|
||||||
bool |
|
||||||
stop(cfg_t *cfg) { |
|
||||||
assert(cfg != NULL); |
|
||||||
|
|
||||||
if (cfg->shared && usage_dec(cfg->name) > 0) |
|
||||||
return true; |
|
||||||
|
|
||||||
if (cfg->ipset) { |
|
||||||
ipset_fini(cfg->ipset); |
|
||||||
cfg->ipset = NULL; |
|
||||||
} |
|
||||||
|
|
||||||
return true; |
|
||||||
} |
|
||||||
|
|
||||||
bool |
|
||||||
ban(cfg_t *cfg, const char *ip) { |
|
||||||
char ipw[IP_LEN_MAX] = ""; |
|
||||||
char *argv[] = { "ignored", "add", cfg->name, ipw, NULL }; |
|
||||||
assert(cfg != NULL); |
|
||||||
strlcpy(ipw, ip, sizeof(ipw)); |
|
||||||
cfg->last_cmd = IPSET_CMD_ADD; |
|
||||||
return ipset_parse_argv(cfg->ipset, 4, argv) == 0; |
|
||||||
} |
|
||||||
|
|
||||||
bool |
|
||||||
unban(cfg_t *cfg, const char *ip) { |
|
||||||
char ipw[IP_LEN_MAX] = ""; |
|
||||||
char *argv[] = { "ignored", "del", cfg->name, ipw, NULL }; |
|
||||||
assert(cfg != NULL); |
|
||||||
strlcpy(ipw, ip, sizeof(ipw)); |
|
||||||
cfg->last_cmd = IPSET_CMD_DEL; |
|
||||||
return ipset_parse_argv(cfg->ipset, 4, argv) == 0; |
|
||||||
} |
|
||||||
|
|
||||||
bool |
|
||||||
check(cfg_t *cfg, const char *ip) { |
|
||||||
char ipw[IP_LEN_MAX] = ""; |
|
||||||
char *argv[] = { "ignored", "test", cfg->name, ipw, NULL }; |
|
||||||
assert(cfg != NULL); |
|
||||||
strlcpy(ipw, ip, sizeof(ipw)); |
|
||||||
cfg->last_cmd = IPSET_CMD_TEST; |
|
||||||
return ipset_parse_argv(cfg->ipset, 4, argv) == 0; |
|
||||||
} |
|
||||||
|
|
||||||
bool |
|
||||||
ping(cfg_t *cfg) { |
|
||||||
assert(cfg != NULL); |
|
||||||
|
|
||||||
(void)(cfg); /* silence warning about unused variable */ |
|
||||||
|
|
||||||
return true; |
|
||||||
} |
|
||||||
|
|
||||||
void |
|
||||||
destroy(cfg_t *cfg) { |
|
||||||
assert(cfg != NULL); |
|
||||||
|
|
||||||
free(cfg); |
|
||||||
} |
|
Loading…
Reference in new issue