mirror of
https://github.com/clearlinux/tallow.git
synced 2026-08-19 11:05:48 +00:00
Compare commits
19 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 5dfb9821e3 | |||
| 348fd7d744 | |||
| 83201e8b32 | |||
| 32fc0ecdaa | |||
| 79f89d8b79 | |||
| ab57cc5dd7 | |||
| 96fa692bf6 | |||
| 71e0fc6cca | |||
| 31205d7f16 | |||
| 43998632aa | |||
| e4b3977704 | |||
| feee1a2556 | |||
| 35182b8447 | |||
| d29132144c | |||
| 0a0a912c70 | |||
| 6545cb0d33 | |||
| fdaa8ed34c | |||
| ea34b5b78c | |||
| 33191b04bf |
+1
-1
@@ -10,7 +10,7 @@ depcomp
|
|||||||
install-sh
|
install-sh
|
||||||
missing
|
missing
|
||||||
tallow
|
tallow
|
||||||
tallow-*.tar.gz
|
tallow-*.tar.*
|
||||||
tallow-*/
|
tallow-*/
|
||||||
*.o
|
*.o
|
||||||
tallow.service
|
tallow.service
|
||||||
|
|||||||
@@ -16,6 +16,7 @@ addons:
|
|||||||
- valgrind
|
- valgrind
|
||||||
- autoconf
|
- autoconf
|
||||||
- automake
|
- automake
|
||||||
|
- libjson-c-dev
|
||||||
|
|
||||||
script:
|
script:
|
||||||
- ./configure && make && make distcheck
|
- ./configure && make && make distcheck
|
||||||
|
|||||||
+14
-9
@@ -10,7 +10,12 @@ systemdsystemunitdir = @SYSTEMD_SYSTEMUNITDIR@
|
|||||||
systemdsystemunit_DATA = data/tallow.service
|
systemdsystemunit_DATA = data/tallow.service
|
||||||
|
|
||||||
sbin_PROGRAMS = tallow
|
sbin_PROGRAMS = tallow
|
||||||
tallow_SOURCES = tallow.c json.c json.h data.c data.h
|
tallow_SOURCES = \
|
||||||
|
src/tallow.c \
|
||||||
|
src/json.c \
|
||||||
|
src/json.h \
|
||||||
|
src/data.c \
|
||||||
|
src/data.h
|
||||||
tallow_LDADD = $(JSON_C_LIBS) $(PCRE_LIBS) $(LIBSYSTEMD_LIBS)
|
tallow_LDADD = $(JSON_C_LIBS) $(PCRE_LIBS) $(LIBSYSTEMD_LIBS)
|
||||||
|
|
||||||
pkgdata_DATA = data/sshd.json
|
pkgdata_DATA = data/sshd.json
|
||||||
@@ -19,19 +24,19 @@ EXTRA_DIST = \
|
|||||||
AUTHORS COPYING INSTALL README.md \
|
AUTHORS COPYING INSTALL README.md \
|
||||||
data/tallow.service.in \
|
data/tallow.service.in \
|
||||||
data/sshd.json \
|
data/sshd.json \
|
||||||
tallow.conf.5.md \
|
man/tallow.conf.5.md \
|
||||||
tallow.1.md
|
man/tallow.1.md
|
||||||
|
|
||||||
dist_man_MANS = tallow.1 tallow.conf.5
|
dist_man_MANS = man/tallow.1 man/tallow.conf.5
|
||||||
|
|
||||||
dist_doc_DATA = tallow.conf
|
dist_doc_DATA = tallow.conf
|
||||||
|
|
||||||
DISTCHECK_CONFIGURE_FLAGS = \
|
DISTCHECK_CONFIGURE_FLAGS = \
|
||||||
--with-systemdsystemunitdir=$(DESTDIR)$(SYSTEMDSYSTEMUNITDIR)
|
--with-systemdsystemunitdir=$(DESTDIR)$(SYSTEMDSYSTEMUNITDIR)
|
||||||
|
|
||||||
docs: tallow.1 tallow.conf.5
|
docs: $(dist_man_MANS)
|
||||||
tallow.conf.5: tallow.conf.5.md
|
man/%.5: man/%.5.md
|
||||||
ronn -r tallow.conf.5.md --pipe > tallow.conf.5
|
ronn -r $< --pipe > $@
|
||||||
|
|
||||||
tallow.1: tallow.1.md
|
man/%.1: man/%.1.md
|
||||||
ronn -r tallow.1.md --pipe > tallow.1
|
ronn -r $< --pipe > $@
|
||||||
|
|||||||
@@ -16,7 +16,9 @@ Tallow attaches to the journal and subscribes to messages from
|
|||||||
/usr/sbin/sshd. The messages are matched against rules and the IP
|
/usr/sbin/sshd. The messages are matched against rules and the IP
|
||||||
address is extracted from the message. For each IP address that is
|
address is extracted from the message. For each IP address that is
|
||||||
extracted, the last timestamp and count is kept. Once the count exceeds
|
extracted, the last timestamp and count is kept. Once the count exceeds
|
||||||
a threshold, iptables is executed to set a IP-based blocking rule.
|
a threshold, the offending IP address is added to an ipset and blocked
|
||||||
|
with a corresponding firewall rule. It will use firewalld or
|
||||||
|
iptables / ip6tables.
|
||||||
|
|
||||||
The timestamp is kept for pruning. Records are pruned from the list
|
The timestamp is kept for pruning. Records are pruned from the list
|
||||||
if the IP address hasn't been seen by tallow for longer than the
|
if the IP address hasn't been seen by tallow for longer than the
|
||||||
@@ -66,4 +68,4 @@ tallow.
|
|||||||
|
|
||||||
Be very careful if you deploy tallow on systems that expect valid
|
Be very careful if you deploy tallow on systems that expect valid
|
||||||
users to log on from many random source addresses. If your user
|
users to log on from many random source addresses. If your user
|
||||||
mistypes their username, they could find themselves denied access.
|
mistypes their username, they could find themselves denied access.
|
||||||
+3
-2
@@ -2,8 +2,9 @@
|
|||||||
# Process this file with autoconf to produce a configure script.
|
# Process this file with autoconf to produce a configure script.
|
||||||
|
|
||||||
AC_PREREQ([2.64])
|
AC_PREREQ([2.64])
|
||||||
AC_INIT([tallow], [15], [auke-jan.h.kok@intel.com])
|
AC_INIT([tallow], [19], [auke-jan.h.kok@intel.com])
|
||||||
AM_INIT_AUTOMAKE([foreign])
|
AM_INIT_AUTOMAKE([foreign -Wall -Werror -Wno-portability silent-rules subdir-objects color-tests
|
||||||
|
no-dist-gzip dist-xz])
|
||||||
AC_CONFIG_FILES([Makefile])
|
AC_CONFIG_FILES([Makefile])
|
||||||
|
|
||||||
# Checks for programs.
|
# Checks for programs.
|
||||||
|
|||||||
@@ -0,0 +1,12 @@
|
|||||||
|
[
|
||||||
|
{
|
||||||
|
"filter": "SYSLOG_IDENTIFIER=auth",
|
||||||
|
"items": [
|
||||||
|
{
|
||||||
|
"ban": 50,
|
||||||
|
"score": 0.6,
|
||||||
|
"pattern": "MESSAGE=pam_unix[(]dovecot:auth[)]: authentication failure; logname= uid=0 euid=0 tty=dovecot ruser=.*@.* rhost=([0-9a-z:.]+)"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
]
|
||||||
@@ -6,6 +6,7 @@ Description=Tallow Service
|
|||||||
ExecStart=@prefix@/sbin/tallow
|
ExecStart=@prefix@/sbin/tallow
|
||||||
Restart=always
|
Restart=always
|
||||||
RestartSec=3
|
RestartSec=3
|
||||||
|
Nice=10
|
||||||
|
|
||||||
[Install]
|
[Install]
|
||||||
WantedBy=network.target
|
WantedBy=network.target
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
.\" generated with Ronn/v0.7.3
|
.\" generated with Ronn/v0.7.3
|
||||||
.\" http://github.com/rtomayko/ronn/tree/0.7.3
|
.\" http://github.com/rtomayko/ronn/tree/0.7.3
|
||||||
.
|
.
|
||||||
.TH "TALLOW" "5" "October 2018" "" ""
|
.TH "TALLOW" "5" "October 2019" "" ""
|
||||||
.
|
.
|
||||||
.SH "NAME"
|
.SH "NAME"
|
||||||
\fBtallow\fR
|
\fBtallow\fR
|
||||||
@@ -19,7 +19,7 @@ tallow\.conf \- Tallow daemon configuration file
|
|||||||
This file is read on startup by the tallow(1) daemon, and can be used to provide options to the tallow daemon\. If not present, tallow will operate with built\-in defaults\.
|
This file is read on startup by the tallow(1) daemon, and can be used to provide options to the tallow daemon\. If not present, tallow will operate with built\-in defaults\.
|
||||||
.
|
.
|
||||||
.SH "OPTIONS"
|
.SH "OPTIONS"
|
||||||
\fBipt_path\fR=\fB<string>\fR Specifies the location of the ipset(1), iptables(1) or ip6tables(1) program\. By default, tallow will look in "/usr/sbin" for them\.
|
\fBipt_path\fR=\fB<string>\fR Specifies the location of the ipset(1) program and iptables(1), ip6tables(1), or firewall\-cmd(1) programs\. By default, tallow will look in "/usr/sbin" for them\.
|
||||||
.
|
.
|
||||||
.P
|
.P
|
||||||
\fBexpires\fR=\fB<int>\fR The number of seconds that IP addresses are blocked for\. Note that due to the implementation, IP addresses may be blocked for much longer than this period\. If IP addresses are seen, but not blocked within this period, they are also removed from the watch list\. Defaults to 3600s\.
|
\fBexpires\fR=\fB<int>\fR The number of seconds that IP addresses are blocked for\. Note that due to the implementation, IP addresses may be blocked for much longer than this period\. If IP addresses are seen, but not blocked within this period, they are also removed from the watch list\. Defaults to 3600s\.
|
||||||
@@ -34,17 +34,37 @@ If the last character of the listed ip adress is a \fB\.\fR or a \fB:\fR, then t
|
|||||||
\fBipv6\fR=\fB<0|1>\fR Enable or disable ipv6 (ip6tables) support\. Ipv6 is disabled automatically on systems that do not appear to have ipv6 support and enabled when ipv6 is present\. Use this option to explicitly disable ipv6 support if your system does not have ipv6 or is missing ip6tables\. Even with ipv6 disabled, tallow will track and log ipv6 addresses\.
|
\fBipv6\fR=\fB<0|1>\fR Enable or disable ipv6 (ip6tables) support\. Ipv6 is disabled automatically on systems that do not appear to have ipv6 support and enabled when ipv6 is present\. Use this option to explicitly disable ipv6 support if your system does not have ipv6 or is missing ip6tables\. Even with ipv6 disabled, tallow will track and log ipv6 addresses\.
|
||||||
.
|
.
|
||||||
.P
|
.P
|
||||||
\fBnocreate\fR=\fB<0|1>\fR Disable the creation of iptables rules and ipset sets\. By default, tallow will create new iptables(1) and ip6tables(1) rules when needed automatically\. If set to \fB1\fR, \fBtallow(1)\fR will not create any new iptables rules or ipset sets to work\. You should create them manually before tallow starts up and remove them afterwards\. To create them manually, you can use the following commands:
|
\fBnocreate\fR=\fB<0|1>\fR Disable the creation of firewall rules and ipset sets\. By default, tallow will create new firewall\-cmd(1) or iptables(1) and ip6tables(1) rules when needed automatically\. If set to \fB1\fR, \fBtallow(1)\fR will not create any new firewall DROP rules or ipset sets that are needed work\. You should create them manually before tallow starts up and remove them afterwards using the sets of commands below\.
|
||||||
|
.
|
||||||
|
.P
|
||||||
|
Use the following commands if you\'re using iptables(1):
|
||||||
.
|
.
|
||||||
.IP "" 4
|
.IP "" 4
|
||||||
.
|
.
|
||||||
.nf
|
.nf
|
||||||
|
|
||||||
iptables \-t filter \-I INPUT \-m set \-\-match\-set tallow src \-j DROP
|
|
||||||
ipset create tallow hash:ip family inet timeout 3600
|
ipset create tallow hash:ip family inet timeout 3600
|
||||||
|
iptables \-t filter \-I INPUT 1 \-m set \-\-match\-set tallow src \-j DROP
|
||||||
|
|
||||||
ip6tables \-t filter \-I INPUT \-m set \-\-match\-set tallow6 src \-j DROP
|
|
||||||
ipset create tallow6 hash:ip family inet6 timeout 3600
|
ipset create tallow6 hash:ip family inet6 timeout 3600
|
||||||
|
ip6tables \-t filter \-I INPUT 1 \-m set \-\-match\-set tallow6 src \-j DROP
|
||||||
|
.
|
||||||
|
.fi
|
||||||
|
.
|
||||||
|
.IP "" 0
|
||||||
|
.
|
||||||
|
.P
|
||||||
|
Use the following commands if you\'re using firewalld(1):
|
||||||
|
.
|
||||||
|
.IP "" 4
|
||||||
|
.
|
||||||
|
.nf
|
||||||
|
|
||||||
|
firewall\-cmd \-\-permanent \-\-new\-ipset=tallow \-\-type=hash:ip \-\-family=inet \-\-option=timeout=3600
|
||||||
|
firewall\-cmd \-\-permanent \-\-direct \-\-add\-rule ipv4 filter INPUT 1 \-m set \-\-match\-set tallow src \-j DROP
|
||||||
|
|
||||||
|
firewall\-cmd \-\-permanent \-\-new\-ipset=tallow6 \-\-type=hash:ip \-\-family=inet6 \-\-option=timeout=3600
|
||||||
|
firewall\-cmd \-\-permanent \-\-direct \-\-add\-rule ipv6 filter INPUT 1 \-m set \-\-match\-set tallow6 src \-j DROP
|
||||||
.
|
.
|
||||||
.fi
|
.fi
|
||||||
.
|
.
|
||||||
@@ -20,8 +20,9 @@ tallow will operate with built-in defaults.
|
|||||||
## OPTIONS
|
## OPTIONS
|
||||||
|
|
||||||
`ipt_path`=`<string>`
|
`ipt_path`=`<string>`
|
||||||
Specifies the location of the ipset(1), iptables(1) or ip6tables(1)
|
Specifies the location of the ipset(1) program and iptables(1),
|
||||||
program. By default, tallow will look in "/usr/sbin" for them.
|
ip6tables(1), or firewall-cmd(1) programs. By default, tallow will
|
||||||
|
look in "/usr/sbin" for them.
|
||||||
|
|
||||||
`expires`=`<int>`
|
`expires`=`<int>`
|
||||||
The number of seconds that IP addresses are blocked for. Note that
|
The number of seconds that IP addresses are blocked for. Note that
|
||||||
@@ -52,20 +53,32 @@ disable ipv6 support if your system does not have ipv6 or is
|
|||||||
missing ip6tables. Even with ipv6 disabled, tallow will track
|
missing ip6tables. Even with ipv6 disabled, tallow will track
|
||||||
and log ipv6 addresses.
|
and log ipv6 addresses.
|
||||||
|
|
||||||
`nocreate`=`<0|1>`
|
`nocreate`=`<0|1>` Disable the creation of firewall rules and ipset sets. By
|
||||||
Disable the creation of iptables rules and ipset sets. By default,
|
default, tallow will create new firewall-cmd(1) or iptables(1) and ip6tables(1)
|
||||||
tallow will create new iptables(1) and ip6tables(1) rules when needed
|
rules when needed automatically. If set to `1`, `tallow(1)` will not create any
|
||||||
automatically. If set to `1`, `tallow(1)` will not create any new
|
new firewall DROP rules or ipset sets that are needed work. You should create
|
||||||
iptables rules or ipset sets to work. You should create them manually
|
them manually before tallow starts up and remove them afterwards using the sets
|
||||||
before tallow starts up and remove them afterwards. To create them
|
of commands below.
|
||||||
manually, you can use the following commands:
|
|
||||||
|
Use the following commands if you're using iptables(1):
|
||||||
|
|
||||||
```
|
```
|
||||||
iptables -t filter -I INPUT -m set --match-set tallow src -j DROP
|
|
||||||
ipset create tallow hash:ip family inet timeout 3600
|
ipset create tallow hash:ip family inet timeout 3600
|
||||||
|
iptables -t filter -I INPUT 1 -m set --match-set tallow src -j DROP
|
||||||
|
|
||||||
ip6tables -t filter -I INPUT -m set --match-set tallow6 src -j DROP
|
|
||||||
ipset create tallow6 hash:ip family inet6 timeout 3600
|
ipset create tallow6 hash:ip family inet6 timeout 3600
|
||||||
|
ip6tables -t filter -I INPUT 1 -m set --match-set tallow6 src -j DROP
|
||||||
|
```
|
||||||
|
|
||||||
|
Use the following commands if you're using firewalld(1):
|
||||||
|
|
||||||
|
```
|
||||||
|
firewall-cmd --permanent --new-ipset=tallow --type=hash:ip --family=inet --option=timeout=3600
|
||||||
|
firewall-cmd --permanent --direct --add-rule ipv4 filter INPUT 1 -m set --match-set tallow src -j DROP
|
||||||
|
|
||||||
|
firewall-cmd --permanent --new-ipset=tallow6 --type=hash:ip --family=inet6 --option=timeout=3600
|
||||||
|
firewall-cmd --permanent --direct --add-rule ipv6 filter INPUT 1 -m set --match-set tallow6 src -j DROP
|
||||||
|
|
||||||
```
|
```
|
||||||
|
|
||||||
## SEE ALSO
|
## SEE ALSO
|
||||||
@@ -75,4 +88,3 @@ tallow(1)
|
|||||||
## AUTHOR
|
## AUTHOR
|
||||||
|
|
||||||
Auke Kok <auke-jan.h.kok@intel.com>
|
Auke Kok <auke-jan.h.kok@intel.com>
|
||||||
|
|
||||||
@@ -16,6 +16,7 @@
|
|||||||
#include <stdbool.h>
|
#include <stdbool.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <sys/time.h>
|
#include <sys/time.h>
|
||||||
|
#include <malloc.h>
|
||||||
|
|
||||||
#include <pcre.h>
|
#include <pcre.h>
|
||||||
|
|
||||||
@@ -168,4 +169,7 @@ void prune(int expires)
|
|||||||
p = s;
|
p = s;
|
||||||
s = s->next;
|
s = s->next;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* return some memory */
|
||||||
|
malloc_trim(0);
|
||||||
}
|
}
|
||||||
+5
-5
@@ -36,7 +36,7 @@ static bool g_filter, g_ban, g_score, g_pattern = false;
|
|||||||
|
|
||||||
static int json_parse(json_object *ob)
|
static int json_parse(json_object *ob)
|
||||||
{
|
{
|
||||||
int count = 0;
|
int i, count = 0;
|
||||||
bool l_filter, l_ban, l_score, l_pattern = false;
|
bool l_filter, l_ban, l_score, l_pattern = false;
|
||||||
|
|
||||||
json_object_object_foreach(ob, key, val) {
|
json_object_object_foreach(ob, key, val) {
|
||||||
@@ -81,7 +81,7 @@ static int json_parse(json_object *ob)
|
|||||||
ob = json_object_object_get(ob, key);
|
ob = json_object_object_get(ob, key);
|
||||||
int len = json_object_array_length(ob);
|
int len = json_object_array_length(ob);
|
||||||
json_object *val;
|
json_object *val;
|
||||||
for (int i = 0; i < len; i++) {
|
for (i = 0; i < len; i++) {
|
||||||
val = json_object_array_get_idx(ob, i);
|
val = json_object_array_get_idx(ob, i);
|
||||||
count += json_parse(val);
|
count += json_parse(val);
|
||||||
}
|
}
|
||||||
@@ -119,7 +119,7 @@ static int json_parse(json_object *ob)
|
|||||||
|
|
||||||
static int json_load_file(const char* file)
|
static int json_load_file(const char* file)
|
||||||
{
|
{
|
||||||
int count = 0;
|
int i, count = 0;
|
||||||
char *json;
|
char *json;
|
||||||
int fd;
|
int fd;
|
||||||
struct stat st;
|
struct stat st;
|
||||||
@@ -134,7 +134,7 @@ static int json_load_file(const char* file)
|
|||||||
if (json_object_is_type(obj,json_type_array)) {
|
if (json_object_is_type(obj,json_type_array)) {
|
||||||
int len = json_object_array_length(obj);
|
int len = json_object_array_length(obj);
|
||||||
json_object *val;
|
json_object *val;
|
||||||
for (int i = 0; i < len; i++) {
|
for (i = 0; i < len; i++) {
|
||||||
val = json_object_array_get_idx(obj, i);
|
val = json_object_array_get_idx(obj, i);
|
||||||
count += json_parse(val);
|
count += json_parse(val);
|
||||||
}
|
}
|
||||||
@@ -185,7 +185,7 @@ static int json_load_dir(const char *dir)
|
|||||||
|
|
||||||
struct stat st;
|
struct stat st;
|
||||||
if (stat(sp, &st) == 0) {
|
if (stat(sp, &st) == 0) {
|
||||||
dbg("Skipped %s\n", sp);
|
dbg("Skipped " SYSCONFDIR "/" PACKAGE_NAME "/%s\n", entry->d_name);
|
||||||
free(sp);
|
free(sp);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
+97
-19
@@ -11,6 +11,8 @@
|
|||||||
* of the License.
|
* of the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#define _GNU_SOURCE
|
||||||
|
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
@@ -66,6 +68,26 @@ static void ext_ignore(char *fmt, ...)
|
|||||||
__attribute__((unused)) int ret = system(cmd);
|
__attribute__((unused)) int ret = system(cmd);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void reset_rules(void)
|
||||||
|
{
|
||||||
|
/* reset all rules in case the running fw changes */
|
||||||
|
ext_ignore("%s/firewall-cmd --permanent --direct --remove-rule ipv4 filter INPUT 1 -m set --match-set tallow src -j DROP 2> /dev/null", ipt_path);
|
||||||
|
ext_ignore("%s/firewall-cmd --permanent --delete-ipset=tallow 2> /dev/null", ipt_path);
|
||||||
|
|
||||||
|
/* 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 (has_ipv6) {
|
||||||
|
ext_ignore("%s/firewall-cmd --permanent --direct --remove-rule ipv6 filter INPUT 1 -m set --match-set tallow6 src -j DROP 2> /dev/null", ipt_path);
|
||||||
|
ext_ignore("%s/firewall-cmd --permanent --delete-ipset=tallow6 2> /dev/null", ipt_path);
|
||||||
|
|
||||||
|
/* delete iptables ref to set before the ipset! */
|
||||||
|
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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
static void setup(void)
|
static void setup(void)
|
||||||
{
|
{
|
||||||
static bool done = false;
|
static bool done = false;
|
||||||
@@ -76,31 +98,72 @@ static void setup(void)
|
|||||||
if (nocreate)
|
if (nocreate)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
/* init ipset and iptables */
|
/* firewalld */
|
||||||
/* delete iptables ref to set before the ipset! */
|
char *fwd_path;
|
||||||
ext_ignore("%s/iptables -t filter -D INPUT -m set --match-set tallow src -j DROP 2> /dev/null", ipt_path);
|
if (asprintf(&fwd_path, "%s/firewall-cmd", ipt_path) < 0) {
|
||||||
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);
|
exit(EXIT_FAILURE);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (has_ipv6) {
|
if ((access(fwd_path, X_OK) == 0) && ext("%s/firewall-cmd --state --quiet", ipt_path) == 0) {
|
||||||
ext_ignore("%s/ip6tables -t filter -D INPUT -m set --match-set tallow6 src -j DROP 2> /dev/null", ipt_path);
|
fprintf(stdout, "firewalld is running and will be used by tallow.\n");
|
||||||
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)) {
|
reset_rules();
|
||||||
fprintf(stderr, "Unable to create ipv6 ipset.\n");
|
|
||||||
|
/* create ipv4 rule and ipset */
|
||||||
|
if (ext("%s/firewall-cmd --permanent --quiet --new-ipset=tallow --type=hash:ip --family=inet --option=timeout=%d", ipt_path, expires)) {
|
||||||
|
fprintf(stderr, "Unable to create ipv4 ipset with firewall-cmd.\n");
|
||||||
exit(EXIT_FAILURE);
|
exit(EXIT_FAILURE);
|
||||||
}
|
}
|
||||||
if (ext("%s/ip6tables -t filter -A INPUT -m set --match-set tallow6 src -j DROP", ipt_path)) {
|
if (ext("%s/firewall-cmd --permanent --direct --quiet --add-rule ipv4 filter INPUT 1 -m set --match-set tallow src -j DROP", ipt_path)) {
|
||||||
fprintf(stderr, "Unable to create ipt6ables rule.\n");
|
fprintf(stderr, "Unable to create ipv4 firewalld rule.\n");
|
||||||
exit(EXIT_FAILURE);
|
exit(EXIT_FAILURE);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* create ipv6 rule and ipset */
|
||||||
|
if (has_ipv6) {
|
||||||
|
if (ext("%s/firewall-cmd --permanent --quiet --new-ipset=tallow6 --type=hash:ip --family=inet6 --option=timeout=%d", ipt_path, expires)) {
|
||||||
|
fprintf(stderr, "Unable to create ipv6 ipset with firewall-cmd.\n");
|
||||||
|
exit(EXIT_FAILURE);
|
||||||
|
}
|
||||||
|
if (ext("%s/firewall-cmd --permanent --direct --quiet --add-rule ipv6 filter INPUT 1 -m set --match-set tallow6 src -j DROP ", ipt_path)) {
|
||||||
|
fprintf(stderr, "Unable to create ipv6 firewalld rule.\n");
|
||||||
|
exit(EXIT_FAILURE);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* reload firewalld for ipsets to load */
|
||||||
|
if (ext("%s/firewall-cmd --reload --quiet", ipt_path, expires)) {
|
||||||
|
fprintf(stderr, "Unable to reload firewalld rules.\n");
|
||||||
|
exit(EXIT_FAILURE);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
/* iptables */
|
||||||
|
reset_rules();
|
||||||
|
|
||||||
|
/* create ipv4 rule and ipset */
|
||||||
|
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);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* create ipv6 rule and ipset */
|
||||||
|
if (has_ipv6) {
|
||||||
|
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);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
free(fwd_path);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void block(struct block_struct *s, int instant_block)
|
static void block(struct block_struct *s, int instant_block)
|
||||||
@@ -224,6 +287,7 @@ int main(void)
|
|||||||
int r;
|
int r;
|
||||||
FILE *f;
|
FILE *f;
|
||||||
int timeout = 60;
|
int timeout = 60;
|
||||||
|
long long unsigned int last_timestamp = 0;
|
||||||
|
|
||||||
json_load_patterns();
|
json_load_patterns();
|
||||||
|
|
||||||
@@ -312,8 +376,8 @@ int main(void)
|
|||||||
fprintf(stderr, PACKAGE_STRING " Started\n");
|
fprintf(stderr, PACKAGE_STRING " Started\n");
|
||||||
|
|
||||||
for (;;) {
|
for (;;) {
|
||||||
const void *d;
|
const void *d, *dt;
|
||||||
size_t l;
|
size_t l, dl;
|
||||||
|
|
||||||
r = sd_journal_wait(j, (uint64_t) timeout * 1000000);
|
r = sd_journal_wait(j, (uint64_t) timeout * 1000000);
|
||||||
if (r == SD_JOURNAL_INVALIDATE) {
|
if (r == SD_JOURNAL_INVALIDATE) {
|
||||||
@@ -327,6 +391,20 @@ int main(void)
|
|||||||
while (sd_journal_next(j) != 0) {
|
while (sd_journal_next(j) != 0) {
|
||||||
char *m;
|
char *m;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* discard messages older than ones we've already seen before
|
||||||
|
* this happens when the journal rotates - we get replayed events
|
||||||
|
*/
|
||||||
|
if (sd_journal_get_data(j, "_SOURCE_REALTIME_TIMESTAMP", &dt, &dl) == 0) {
|
||||||
|
long long unsigned int lt = atoll(dt + strlen("_SOURCE_REALTIME_TIMESTAMP="));
|
||||||
|
if (lt > last_timestamp)
|
||||||
|
last_timestamp = lt;
|
||||||
|
else if (lt < last_timestamp) {
|
||||||
|
dbg("Discarding old entry: %llu - %llu\n", lt, last_timestamp);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (sd_journal_get_data(j, "MESSAGE", &d, &l) < 0) {
|
if (sd_journal_get_data(j, "MESSAGE", &d, &l) < 0) {
|
||||||
fprintf(stderr, "Failed to read message field: %s\n", strerror(-r));
|
fprintf(stderr, "Failed to read message field: %s\n", strerror(-r));
|
||||||
break;
|
break;
|
||||||
@@ -4,4 +4,6 @@
|
|||||||
#ipt_path=/usr/sbin
|
#ipt_path=/usr/sbin
|
||||||
#expires=3600
|
#expires=3600
|
||||||
#whitelist=127.0.0.1
|
#whitelist=127.0.0.1
|
||||||
|
#whitelist=192.168.
|
||||||
|
#whitelist=10.
|
||||||
#ipv6=0
|
#ipv6=0
|
||||||
|
|||||||
Reference in New Issue
Block a user