10 Commits
v2 ... v4

Author SHA1 Message Date
Auke Kok 9042a01eab v4 2017-05-11 08:56:56 -07:00
Auke Kok 2225ee029d Revert "also catch port probers that try ssl level evils"
This reverts commit dc8f37e41f.

This message can print on a normal and legitimate user when they
disconnect, and therefore would be a false positive. We should
100% never get close to blocking legitimate users, ever.
2017-05-10 21:49:16 -07:00
Auke Kok dee23b8275 Lazy initialization.
At start, only initialize the journal, but wait until we actually
need to block anything before initializing ipset and iptables.
2017-05-10 21:14:07 -07:00
Auke Kok 34bd8d55bd Remove SIGUSR1 handler - dumping lists is obsolete with ipset. 2017-05-10 21:07:18 -07:00
Auke Kok 2a33768293 Don't break our LL on block.
We will prune regularly anyway, so this is entirely unneeded.
2017-05-10 20:59:36 -07:00
Auke Kok ea958fd2b5 v3 2017-05-08 08:49:15 -07:00
Auke Kok 4547892d56 Attempt to build against old systemd versions as well.
In case libsystemd isn't found, try libsystemd-journal as well.
2017-05-07 21:09:58 -07:00
Auke Kok c661a20e33 Revert removal of prune().
We can't just delete an entry only when it is blocked, this
would forever leave all entries lingering in the list until
they hit the limit, and it would likely consume lots of memory.

Instead, we'll prune only based on timestamp values. This removes
old entries automatically regularly, but leaves new hits that
haven't hit the expiry time. If IPs get blocked, they're not
removed, but the expiry time will remove them. This will
assure that hosts that try in large intervals actually get
blocked again right away.
2017-05-07 20:36:32 -07:00
Arjan van de Ven 9f37520c72 ip can be NULL (output of strtok) 2017-05-07 20:23:37 -07:00
Arjan van de Ven dc8f37e41f also catch port probers that try ssl level evils 2017-05-07 20:23:31 -07:00
3 changed files with 86 additions and 64 deletions
+2 -2
View File
@@ -1,12 +1,12 @@
AM_CFLAGS = -g $(LIBSYSTEMD_CFLAGS) -Wall -Wno-uninitialized -W -D_FORTIFY_SOURCE=2
AM_CFLAGS = -g $(LIBSYSTEMD_CFLAGS) $(LIBSYSTEMD_JOURNAL_CFLAGS) -Wall -Wno-uninitialized -W -D_FORTIFY_SOURCE=2
systemdsystemunitdir = @SYSTEMD_SYSTEMUNITDIR@
systemdsystemunit_DATA = tallow.service
sbin_PROGRAMS = tallow
tallow_SOURCES = tallow.c
tallow_LDADD = $(LIBSYSTEMD_LIBS)
tallow_LDADD = $(LIBSYSTEMD_LIBS) $(LIBSYSTEMD_JOURNAL_LIBS)
EXTRA_DIST = AUTHORS COPYING INSTALL tallow.service.in tallow.1.md
+4 -2
View File
@@ -2,7 +2,7 @@
# Process this file with autoconf to produce a configure script.
AC_PREREQ([2.64])
AC_INIT([tallow], [2], [auke-jan.h.kok@intel.com])
AC_INIT([tallow], [4], [auke-jan.h.kok@intel.com])
AM_INIT_AUTOMAKE([])
AC_CONFIG_FILES([Makefile])
@@ -10,9 +10,11 @@ AC_CONFIG_FILES([Makefile])
AC_PROG_CC
AC_PROG_INSTALL
PKG_CHECK_MODULES([LIBSYSTEMD], [libsystemd])
PKG_CHECK_MODULES(LIBSYSTEMD, libsystemd,, [PKG_CHECK_MODULES(LIBSYSTEMD_JOURNAL, libsystemd-journal)])
AC_SUBST(LIBSYSTEMD_CFLAGS)
AC_SUBST(LIBSYSTEMD_LIBS)
AC_SUBST(LIBSYSTEMD_JOURNAL_CFLAGS)
AC_SUBST(LIBSYSTEMD_JOURNAL_LIBS)
AC_ARG_WITH([systemdsystemunitdir], AC_HELP_STRING([--with-systemdsystemunitdir=DIR],
[path to systemd system service directory]), [path_systemdsystemunit=${withval}],
+80 -60
View File
@@ -15,6 +15,7 @@
#include <stdio.h>
#include <string.h>
#include <stdarg.h>
#include <stdbool.h>
#include <signal.h>
#include <unistd.h>
#include <limits.h>
@@ -69,11 +70,47 @@ static void ext_ignore(char *fmt, ...)
__attribute__((unused)) int ret = system(cmd);
}
static void setup(void)
{
static bool done = false;
if (done)
return;
done = true;
/* init ipset and iptables */
/* delete iptables ref to set before the ipset! */
ext_ignore("%s/iptables -t filter -D INPUT -m set --match-set tallow src -j DROP 2> /dev/null", ipt_path);
ext_ignore("%s/ipset destroy tallow 2> /dev/null", ipt_path);
if (ext("%s/ipset create tallow hash:ip family inet timeout %d", ipt_path, expires)) {
fprintf(stderr, "Unable to create ipv4 ipset.\n");
exit(EXIT_FAILURE);
}
if (ext("%s/iptables -t filter -A INPUT -m set --match-set tallow src -j DROP", ipt_path)) {
fprintf(stderr, "Unable to create iptables rule.\n");
exit(EXIT_FAILURE);
}
if (has_ipv6) {
ext_ignore("%s/ip6tables -t filter -D INPUT -m set --match-set tallow6 src -j DROP 2> /dev/null", ipt_path);
ext_ignore("%s/ipset destroy tallow6 2> /dev/null", ipt_path);
if (ext("%s/ipset create tallow6 hash:ip family inet6 timeout %d", ipt_path, expires)) {
fprintf(stderr, "Unable to create ipv6 ipset.\n");
exit(EXIT_FAILURE);
}
if (ext("%s/ip6tables -t filter -A INPUT -m set --match-set tallow6 src -j DROP", ipt_path)) {
fprintf(stderr, "Unable to create ipt6ables rule.\n");
exit(EXIT_FAILURE);
}
}
}
static void block(struct tallow_struct *s)
{
if (s->count != threshold)
return;
setup();
if (strchr(s->ip, ':')) {
if (has_ipv6)
(void) ext("%s/ipset -A tallow6 %s", ipt_path, s->ip);
@@ -82,18 +119,6 @@ static void block(struct tallow_struct *s)
}
fprintf(stderr, "Blocked %s\n", s->ip);
/* remove entry from the list */
if (head == s) {
head = s->next;
free(s->ip);
free(s);
} else {
struct tallow_struct *p = s;
s = s->next;
free(p->ip);
free(p);
}
}
static void whitelist_add(char *ip)
@@ -107,7 +132,7 @@ static void whitelist_add(char *ip)
n = malloc(sizeof(struct tallow_struct));
if (!n) {
fprintf(stderr, "Out of memory.\n");
exit(1);
exit(EXIT_FAILURE);
}
memset(n, 0, sizeof(struct tallow_struct));
n->ip = strdup(ip);
@@ -125,6 +150,9 @@ static void find(char *ip)
struct tallow_struct *n;
struct tallow_struct *w = whitelist;
if (!ip)
return;
/*
* not validating the IP address format here, just
* making sure we're not passing special characters
@@ -160,7 +188,7 @@ static void find(char *ip)
n = malloc(sizeof(struct tallow_struct));
if (!n) {
fprintf(stderr, "Out of memory.\n");
exit(1);
exit(EXIT_FAILURE);
}
memset(n, 0, sizeof(struct tallow_struct));
@@ -178,35 +206,51 @@ static void find(char *ip)
return;
}
static void dump(void)
static void sig(int u __attribute__ ((unused)))
{
struct tallow_struct *s = head;
fprintf(stderr, "Received SIGUSR1 - dumping address table: address: count, time\n");
fprintf(stderr, "Exiting on request.\n");
sd_journal_close(j);
struct tallow_struct *s = head;
while (s) {
fprintf(stderr, "%s: %d, %lu.%lu\n", s->ip, s->count, s->time.tv_sec, s->time.tv_usec);
struct tallow_struct *n = NULL;
free(s->ip);
n = s;
s = s->next;
free(n);
}
exit(EXIT_SUCCESS);
}
static void sig(int s)
static void prune(void)
{
if (s == SIGUSR1) {
dump();
} else {
fprintf(stderr, "Exiting on request.\n");
sd_journal_close(j);
struct tallow_struct *s = head;
struct tallow_struct *p;
struct timeval tv;
struct tallow_struct *s = head;
while (s) {
struct tallow_struct *n = NULL;
(void) gettimeofday(&tv, NULL);
p = NULL;
free(s->ip);
n = s;
s = s->next;
free(n);
while (s) {
if ((tv.tv_sec - s->time.tv_sec) > expires) {
if (p) {
p->next = s->next;
free(s->ip);
free(s);
s = p->next;
continue;
} else {
head = s->next;
free(s->ip);
free(s);
s = head;
p = NULL;
continue;
}
}
exit(0);
p = s;
s = s->next;
}
}
@@ -221,7 +265,6 @@ int main(void)
memset(&s, 0, sizeof(struct sigaction));
s.sa_handler = sig;
sigaction(SIGUSR1, &s, NULL);
sigaction(SIGHUP, &s, NULL);
sigaction(SIGTERM, &s, NULL);
sigaction(SIGINT, &s, NULL);
@@ -276,34 +319,9 @@ int main(void)
r = sd_journal_open(&j, SD_JOURNAL_LOCAL_ONLY);
if (r < 0) {
fprintf(stderr, "Failed to open journal: %s\n", strerror(-r));
exit(1);
exit(EXIT_FAILURE);
}
/* init ipset and iptables */
/* delete iptables ref to set before the ipset! */
ext_ignore("%s/iptables -t filter -D INPUT -m set --match-set tallow src -j DROP 2> /dev/null", ipt_path);
ext_ignore("%s/ipset destroy tallow 2> /dev/null", ipt_path);
if (ext("%s/ipset create tallow hash:ip family inet timeout %d", ipt_path, expires)) {
fprintf(stderr, "Unable to create ipv4 ipset.\n");
exit(1);
}
if (ext("%s/iptables -t filter -A INPUT -m set --match-set tallow src -j DROP", ipt_path)) {
fprintf(stderr, "Unable to create iptables rule.\n");
exit(1);
}
if (has_ipv6) {
ext_ignore("%s/ip6tables -t filter -D INPUT -m set --match-set tallow6 src -j DROP 2> /dev/null", ipt_path);
ext_ignore("%s/ipset destroy tallow6 2> /dev/null", ipt_path);
if (ext("%s/ipset create tallow6 hash:ip family inet6 timeout %d", ipt_path, expires)) {
fprintf(stderr, "Unable to create ipv6 ipset.\n");
exit(1);
}
if (ext("%s/ip6tables -t filter -A INPUT -m set --match-set tallow6 src -j DROP", ipt_path)) {
fprintf(stderr, "Unable to create ipt6ables rule.\n");
exit(1);
}
}
/* ffwd journal */
sd_journal_add_match(j, FILTER_STRING, 0);
@@ -355,9 +373,11 @@ int main(void)
free(m);
}
prune();
}
sd_journal_close(j);
exit(0);
exit(EXIT_SUCCESS);
}