From: Martin Mares Date: Fri, 4 Nov 2016 21:12:59 +0000 (+0100) Subject: Options and config X-Git-Tag: v1.0~16 X-Git-Url: http://mj.ucw.cz/gitweb/?a=commitdiff_plain;h=fa5cd2dfdda0d515daad046e766b705bff5bf3ed;p=bouncer.git Options and config --- diff --git a/Makefile b/Makefile index bfd6263..7743cf8 100644 --- a/Makefile +++ b/Makefile @@ -1,7 +1,7 @@ PKG_CFLAGS := $(shell pkg-config --cflags libucw libipset) PKG_LIBS := $(shell pkg-config --libs libucw libipset) -CFLAGS=-O2 -Wall -W -Wno-parentheses -Wstrict-prototypes -Wmissing-prototypes -Wundef -Wredundant-decls -std=gnu99 $(PKG_CFLAGS) +CFLAGS=-O2 -Wall -Wextra -Wno-parentheses -Wstrict-prototypes -Wmissing-prototypes -Wundef -Wredundant-decls -Wno-missing-field-initializers -std=gnu99 $(PKG_CFLAGS) LDLIBS=$(PKG_LIBS) all: bouncer diff --git a/bouncer.c b/bouncer.c index 595be73..d747a3a 100644 --- a/bouncer.c +++ b/bouncer.c @@ -14,6 +14,7 @@ #include #include #include +#include #include #include @@ -86,10 +87,30 @@ static bool addr_parse(struct addr *addr, const char *src) /*** Configuration ***/ -static uns max_culprits = 3; // FIXME -static uns max_failures = 3; // FIXME -static uns max_idle_time = 600; // FIXME -static uns max_banned_time = 600; // FIXME +static uns max_failures = ~0U; +static uns max_suspect_time = 86400; +static uns max_banned_time = 86400; +static uns max_suspects = ~0U; +static uns max_banned = ~0U; + +/* + * FIXME: + * - names of ipsets + * - name of socket + * - logging + * - PAM module name(s) to match + */ + +static struct cf_section bouncer_cf = { + CF_ITEMS { + CF_UNS("MaxSuspects", &max_suspects), + CF_UNS("MaxBanned", &max_banned), + CF_UNS("MaxSuspectTime", &max_suspect_time), + CF_UNS("MaxBannedTime", &max_banned_time), + CF_UNS("MaxFailures", &max_failures), + CF_END + } +}; /*** An interface to IP sets ***/ @@ -190,14 +211,14 @@ static void is_modify(bool add, struct addr addr) /*** Handling of login failures ***/ struct culprit_node { - cnode n; + cnode n; // In either suspect_list or banned_list union { struct addr addr; byte addr_bytes[16]; }; - timestamp_t last_fail; uns fail_count; bool banned; + timestamp_t last_fail; // Not updated when banned }; #define HASH_NODE struct culprit_node @@ -211,11 +232,11 @@ struct culprit_node { #define HASH_LOOKUP_DETECT_NEW #include -static uns num_culprits; -static clist culprit_lru, culprit_bans; +static clist suspect_list, banned_list; +static uns num_suspects, num_banned; static struct main_timer cleanup_timer; -static void cleanup_list(clist *list, timestamp_t max_time, timestamp_t *next) +static void cleanup_list(clist *list, uns *counter, timestamp_t max_time, uns max_count, timestamp_t *next) { timestamp_t now = main_get_now(); @@ -226,8 +247,11 @@ static void cleanup_list(clist *list, timestamp_t max_time, timestamp_t *next) break; timestamp_t expire_in = c->last_fail + max_time - now; - if (num_culprits > max_culprits) - expire_in = 0; + if (*counter > max_count) + { + // FIXME: Warn with rate limit + expire_in = 0; + } if (expire_in > now) { @@ -247,15 +271,15 @@ static void cleanup_list(clist *list, timestamp_t max_time, timestamp_t *next) clist_remove(&c->n); culprit_remove(c); - num_culprits--; + (*counter)--; } } static void culprit_cleanup(void) { timestamp_t next_cleanup = main_get_now() + (timestamp_t)3600 * 1000; - cleanup_list(&culprit_bans, (timestamp_t)max_banned_time * 1000, &next_cleanup); - cleanup_list(&culprit_lru, (timestamp_t)max_idle_time * 1000, &next_cleanup); + cleanup_list(&suspect_list, &num_suspects, (timestamp_t)max_suspect_time * 1000, max_suspects, &next_cleanup); + cleanup_list(&banned_list, &num_banned, (timestamp_t)max_banned_time * 1000, max_banned, &next_cleanup); timer_add(&cleanup_timer, next_cleanup); } @@ -267,30 +291,34 @@ static void handle_failed_login(struct addr addr) struct culprit_node *c = culprit_lookup((byte *) &addr, &is_new); if (is_new) { + c->last_fail = now; c->fail_count = 1; c->banned = 0; - clist_add_tail(&culprit_lru, &c->n); - num_culprits++; - // FIXME: Warn on overflow, but not too frequently + clist_add_tail(&suspect_list, &c->n); + num_suspects++; DBG("%s: first fail", AFMT(addr)); } else if (!c->banned) { + c->last_fail = now; c->fail_count++; clist_remove(&c->n); - clist_add_tail(&culprit_lru, &c->n); + clist_add_tail(&suspect_list, &c->n); DBG("%s: next fail, cnt=%u", AFMT(addr), c->fail_count); } - c->last_fail = now; if (!c->banned && c->fail_count >= max_failures) { DBG("%s: banned", AFMT(addr)); c->banned = 1; clist_remove(&c->n); - clist_add_tail(&culprit_bans, &c->n); + num_suspects--; + clist_add_tail(&banned_list, &c->n); + num_banned++; is_modify(1, c->addr); } + + culprit_cleanup(); } static void culprit_timer(struct main_timer *tm UNUSED) @@ -301,8 +329,8 @@ static void culprit_timer(struct main_timer *tm UNUSED) static void fail_init(void) { culprit_init(); - clist_init(&culprit_lru); - clist_init(&culprit_bans); + clist_init(&suspect_list); + clist_init(&banned_list); cleanup_timer.handler = culprit_timer; } @@ -457,13 +485,28 @@ static void sk_init(void) /*** Main ***/ -int main(void) +static struct opt_section options = { + OPT_ITEMS { + OPT_HELP("Bouncer -- A Daemon for Turning Away Mischievous Guests"), + OPT_HELP(""), + OPT_HELP("Options:"), + OPT_HELP_OPTION, + OPT_CONF_OPTIONS, + OPT_END + } +}; + +int main(int argc UNUSED, char **argv) { + cf_def_file = "config"; // FIXME + cf_declare_section("Bouncer", &bouncer_cf, 0); + opt_parse(&options, argv+1); + main_init(); is_init(); fail_init(); - msg(L_INFO, "Clearing previous state"); + // FIXME msg(L_INFO, "Clearing previous state"); is_flush(IS_IPV4); is_flush(IS_IPV6);