From e8d7d8df5c22d7805ee9cb1ae687de03b9e2c9da Mon Sep 17 00:00:00 2001 From: Y Date: Mon, 12 Mar 2018 18:18:28 +0100 Subject: [PATCH] fix in action_nftBan documentation --- doc/intro_func.md | 1 + doc/logandban.md | 34 ++++++++++++++++++++++---- extra/examples/full_pyruse.json | 10 ++++---- tests/action_nftBan.py | 42 ++++++++++++++++----------------- tests/nftBan.cmd.test_ref | 2 +- tests/pyruse.json | 2 +- 6 files changed, 58 insertions(+), 33 deletions(-) diff --git a/doc/intro_func.md b/doc/intro_func.md index f0e5c57..f973975 100644 --- a/doc/intro_func.md +++ b/doc/intro_func.md @@ -38,6 +38,7 @@ The most interesting [filtering or informational entries](https://www.freedeskto * `PRIORITY`: see [Syslog at Wikipedia](https://en.wikipedia.org/wiki/Syslog#Severity_level) for the definitions * `SYSLOG_FACILITY`: see [Syslog at Wikipedia](https://en.wikipedia.org/wiki/Syslog#Facility) for the definitions +* `SYSLOG_IDENTIFIER`: short name for the program that produced the log entry (better accuracy than `_SYSTEMD_UNIT`) * `_HOSTNAME`: short hostname of the machine where the log entry occurred * `_UID`: user ID of the systemd service that produced the log entry * `_GID`: group ID of the systemd service that produced the log entry diff --git a/doc/logandban.md b/doc/logandban.md index 729b2f6..5ef2f62 100644 --- a/doc/logandban.md +++ b/doc/logandban.md @@ -69,7 +69,7 @@ table ip6 Inet6 { } ``` -Then the values for `nftSetIPv4` and `nftSetIPv6` will be respectively “`Inet4 mail_ban`” and “`Inet6 mail_ban`”. +Then the values for `nftSetIPv4` and `nftSetIPv6` will be respectively “`ip Inet4 mail_ban`” and “`ip6 Inet6 mail_ban`”. Optionally, a number may be specified with `banSeconds` to limit the time this ban will last. The nice thing with nftables, is that it handles the timeouts itself: no need to keep track of the active bans and remove them using a Python program; the only reason why bans are recorded in a file, is to be able to restore them on reboot. @@ -79,12 +79,12 @@ Here are examples: ```json { "action": "action_nftBan", - "args": { "IP": "thatIP", "banSeconds": 86400, "nftSetIPv4": "Inet4 mail_ban", "nftSetIPv6": "Inet6 mail_ban" } + "args": { "IP": "thatIP", "banSeconds": 86400, "nftSetIPv4": "ip Inet4 mail_ban", "nftSetIPv6": "ip6 Inet6 mail_ban" } } { "action": "action_nftBan", - "args": { "IP": "thatIP", "nftSetIPv4": "Inet4 sshd_ban", "nftSetIPv6": "Inet6 sshd_ban" } + "args": { "IP": "thatIP", "nftSetIPv4": "ip Inet4 sshd_ban", "nftSetIPv6": "ip6 Inet6 sshd_ban" } } ``` @@ -93,7 +93,7 @@ Here are examples: To see what IP addresses are currently banned, here is the `nft` command: ```bash -$ sudo nft 'list set Inet4 mail_ban' +$ sudo nft 'list set ip Inet4 mail_ban' table ip Inet4 { set mail_ban { type ipv4_addr @@ -121,10 +121,34 @@ It is bound to happen some day: you will want to un-ban a banned IP address. Since `action_nftBan` does not keep the current bans in memory, it is enough to remove the ban using the `nft` command: ```bash -$ sudo nft 'delete element Inet4 mail_ban {10.0.0.10}' +$ sudo nft 'delete element ip Inet4 mail_ban {10.0.0.10}' ``` However, the ban may be restored when restarting Pyruse. To avoid that, also delete the corresponding record from the `action_nftBan.py.json` file in Pyruse’s [storage directory](conffile.md). To go further, you could tweak your configuration, so that your trusted IP addresses never reach `action_nftBan`. + +### Manual ban of an IP address + +To add a ban yourself, run a command like this: + +```bash +$ sudo nft 'add element ip Inet4 ssh_ban {192.168.1.1 timeout 5d} +``` + +The `timeout …` part can be omitted to add a permanent ban. The timeout can be any combination of days (`d`), hours (`h`), minutes (`m`), and seconds (`s`), eg. “`3d31m16s`”. + +In order to make the ban persistent across reboots, a corresponding record should also be appended to the `action_nftBan.py.json` file in Pyruse’s [storage directory](conffile.md) (the IP address, nft Set, days, hours, minutes, seconds, and actual path to the file should be adapted to your needs): + +* either a time-limited ban: + +```bash +$ sudo sed -i "\$s/.\$/$(date +', {"IP": "192.168.1.1", "nftSet": "ip Inet4 ssh_ban", "timestamp": %s.000000}' -d 'now +3day +31minute +16second')]/" /var/lib/pyruse/action_nftBan.py.json +``` + +* or an unlimited ban: + +```bash +$ sudo sed -i '$s/.$/, {"IP": "192.168.1.1", "nftSet": "ip Inet4 ssh_ban", "timestamp": 0}]/' /var/lib/pyruse/action_nftBan.py.json +``` diff --git a/extra/examples/full_pyruse.json b/extra/examples/full_pyruse.json index a292f03..89a37c2 100644 --- a/extra/examples/full_pyruse.json +++ b/extra/examples/full_pyruse.json @@ -120,7 +120,7 @@ }, { "action": "action_nftBan", - "args": { "IP": "thatIP", "banSeconds": 900, "nftSetIPv4": "Inet4 https_ban", "nftSetIPv6": "Inet6 https_ban" } + "args": { "IP": "thatIP", "banSeconds": 900, "nftSetIPv4": "ip Inet4 https_ban", "nftSetIPv6": "ip6 Inet6 https_ban" } } ], "… Let Nextcloud core messages pass-through": [ @@ -297,7 +297,7 @@ }, { "action": "action_nftBan", - "args": { "IP": "thatIP", "banSeconds": 7200, "nftSetIPv4": "Inet4 https_ban", "nftSetIPv6": "Inet6 https_ban" } + "args": { "IP": "thatIP", "banSeconds": 7200, "nftSetIPv4": "ip Inet4 https_ban", "nftSetIPv6": "ip6 Inet6 https_ban" } } ], "… Immediate warning for connectivity errors": [ @@ -438,7 +438,7 @@ }, { "action": "action_nftBan", - "args": { "IP": "thatIP", "banSeconds": 432000, "nftSetIPv4": "Inet4 mail_ban", "nftSetIPv6": "Inet6 mail_ban" } + "args": { "IP": "thatIP", "banSeconds": 432000, "nftSetIPv4": "ip Inet4 mail_ban", "nftSetIPv6": "ip6 Inet6 mail_ban" } } ], "… Discard Dovecot debug entries": [ @@ -520,7 +520,7 @@ }, { "action": "action_nftBan", - "args": { "IP": "thatIP", "banSeconds": 432000, "nftSetIPv4": "Inet4 mail_ban", "nftSetIPv6": "Inet6 mail_ban" } + "args": { "IP": "thatIP", "banSeconds": 432000, "nftSetIPv4": "ip Inet4 mail_ban", "nftSetIPv6": "ip6 Inet6 mail_ban" } } ], "… Detect some SMTP spammers": [ @@ -799,7 +799,7 @@ }, { "action": "action_nftBan", - "args": { "IP": "thatIP", "banSeconds": 432000, "nftSetIPv4": "Inet4 sshd_ban", "nftSetIPv6": "Inet6 sshd_ban" } + "args": { "IP": "thatIP", "banSeconds": 432000, "nftSetIPv4": "ip Inet4 sshd_ban", "nftSetIPv6": "ip6 Inet6 sshd_ban" } } ], "Warn of SpamAssassin update failures": [ diff --git a/tests/action_nftBan.py b/tests/action_nftBan.py index 3ff5b2e..0e1e373 100644 --- a/tests/action_nftBan.py +++ b/tests/action_nftBan.py @@ -17,45 +17,45 @@ def _clean(): def whenBanIPv4ThenAddToIPv4Set(): _clean() - Action({"IP": "ip", "nftSetIPv4": "I4 ban", "nftSetIPv6": "I6 ban"}).act({"ip": "10.0.0.1"}) + Action({"IP": "ip", "nftSetIPv4": "ip I4 ban", "nftSetIPv6": "ip6 I6 ban"}).act({"ip": "10.0.0.1"}) assert os.path.exists(nftBanCmd) assert os.path.exists(nftBanState) nbLines = 0 with open(nftBanCmd, "rt") as c: for line in c: - assert line == "add element I4 ban {10.0.0.1}\n", line + assert line == "add element ip I4 ban {10.0.0.1}\n", line nbLines += 1 assert nbLines == 1, nbLines nbBans = 0 with open(nftBanState) as s: for ban in json.load(s): - assert ban["IP"] == "10.0.0.1" and ban["nftSet"] == "I4 ban", str(ban) + assert ban["IP"] == "10.0.0.1" and ban["nftSet"] == "ip I4 ban", str(ban) nbBans += 1 assert nbBans == 1, nbBans _clean() def whenBanIPv6ThenAddToIPv6Set(): _clean() - Action({"IP": "ip", "nftSetIPv4": "I4 ban", "nftSetIPv6": "I6 ban"}).act({"ip": "::1"}) + Action({"IP": "ip", "nftSetIPv4": "ip I4 ban", "nftSetIPv6": "ip6 I6 ban"}).act({"ip": "::1"}) assert os.path.exists(nftBanCmd) assert os.path.exists(nftBanState) nbLines = 0 with open(nftBanCmd, "rt") as c: for line in c: - assert line == "add element I6 ban {::1}\n", line + assert line == "add element ip6 I6 ban {::1}\n", line nbLines += 1 assert nbLines == 1, nbLines nbBans = 0 with open(nftBanState) as s: for ban in json.load(s): - assert ban["IP"] == "::1" and ban["nftSet"] == "I6 ban", str(ban) + assert ban["IP"] == "::1" and ban["nftSet"] == "ip6 I6 ban", str(ban) nbBans += 1 assert nbBans == 1, nbBans _clean() def whenBanTwoIPThenTwoLinesInState(): _clean() - action = Action({"IP": "ip", "nftSetIPv4": "I4 ban", "nftSetIPv6": "I6 ban"}) + action = Action({"IP": "ip", "nftSetIPv4": "ip I4 ban", "nftSetIPv6": "ip6 I6 ban"}) action.act({"ip": "10.0.0.1"}) action.act({"ip": "::1"}) action.act({"ip": "10.0.0.1"}) @@ -64,9 +64,9 @@ def whenBanTwoIPThenTwoLinesInState(): with open(nftBanState) as s: for ban in json.load(s): if ban["IP"] == "10.0.0.1": - assert ban["nftSet"] == "I4 ban", str(ban) + assert ban["nftSet"] == "ip I4 ban", str(ban) elif ban["IP"] == "::1": - assert ban["nftSet"] == "I6 ban", str(ban) + assert ban["nftSet"] == "ip6 I6 ban", str(ban) else: assert false, str(ban) nbBans += 1 @@ -75,7 +75,7 @@ def whenBanTwoIPThenTwoLinesInState(): def whenBanAnewThenNoDuplicate(): _clean() - action = Action({"IP": "ip", "nftSetIPv4": "I4 ban", "nftSetIPv6": "I6 ban"}) + action = Action({"IP": "ip", "nftSetIPv4": "ip I4 ban", "nftSetIPv6": "ip6 I6 ban"}) action.act({"ip": "10.0.0.1"}) action.act({"ip": "10.0.0.1"}) assert os.path.exists(nftBanCmd) @@ -85,24 +85,24 @@ def whenBanAnewThenNoDuplicate(): for line in c: lineCount += 1 if lineCount == 1: - assert line == "add element I4 ban {10.0.0.1}\n", line + assert line == "add element ip I4 ban {10.0.0.1}\n", line elif lineCount == 2: - assert line == "delete element I4 ban {10.0.0.1}\n", line + assert line == "delete element ip I4 ban {10.0.0.1}\n", line elif lineCount == 3: - assert line == "add element I4 ban {10.0.0.1}\n", line + assert line == "add element ip I4 ban {10.0.0.1}\n", line assert lineCount == 3, lineCount nbBans = 0 with open(nftBanState) as s: for ban in json.load(s): if ban["IP"] == "10.0.0.1": - assert ban["nftSet"] == "I4 ban", str(ban) + assert ban["nftSet"] == "ip I4 ban", str(ban) nbBans += 1 assert nbBans == 1, nbBans _clean() def whenFinishedBanThenAsIfNotThere(): _clean() - action = Action({"IP": "ip", "nftSetIPv4": "I4 ban", "nftSetIPv6": "I6 ban", "banSeconds": 1}) + action = Action({"IP": "ip", "nftSetIPv4": "ip I4 ban", "nftSetIPv6": "ip6 I6 ban", "banSeconds": 1}) action.act({"ip": "10.0.0.1"}) time.sleep(1) action.act({"ip": "10.0.0.1"}) @@ -112,15 +112,15 @@ def whenFinishedBanThenAsIfNotThere(): for line in c: lineCount += 1 if lineCount == 1: - assert line == "add element I4 ban {10.0.0.1 timeout 1s}\n", line + assert line == "add element ip I4 ban {10.0.0.1 timeout 1s}\n", line elif lineCount == 2: - assert line == "add element I4 ban {10.0.0.1 timeout 1s}\n", line + assert line == "add element ip I4 ban {10.0.0.1 timeout 1s}\n", line assert lineCount == 2, lineCount _clean() def whenUnfinishedBanThenTimeoutReset(): _clean() - action = Action({"IP": "ip", "nftSetIPv4": "I4 ban", "nftSetIPv6": "I6 ban", "banSeconds": 2}) + action = Action({"IP": "ip", "nftSetIPv4": "ip I4 ban", "nftSetIPv6": "ip6 I6 ban", "banSeconds": 2}) action.act({"ip": "10.0.0.1"}) time.sleep(1) action.act({"ip": "10.0.0.1"}) @@ -130,11 +130,11 @@ def whenUnfinishedBanThenTimeoutReset(): for line in c: lineCount += 1 if lineCount == 1: - assert line == "add element I4 ban {10.0.0.1 timeout 2s}\n", line + assert line == "add element ip I4 ban {10.0.0.1 timeout 2s}\n", line elif lineCount == 2: - assert line == "delete element I4 ban {10.0.0.1}\n", line + assert line == "delete element ip I4 ban {10.0.0.1}\n", line elif lineCount == 3: - assert line == "add element I4 ban {10.0.0.1 timeout 2s}\n", line + assert line == "add element ip I4 ban {10.0.0.1 timeout 2s}\n", line assert lineCount == 3, lineCount _clean() diff --git a/tests/nftBan.cmd.test_ref b/tests/nftBan.cmd.test_ref index 711db94..5321a80 100644 --- a/tests/nftBan.cmd.test_ref +++ b/tests/nftBan.cmd.test_ref @@ -1 +1 @@ -add element I4 bans {1.2.3.4 timeout 100s} +add element ip I4 bans {1.2.3.4 timeout 100s} diff --git a/tests/pyruse.json b/tests/pyruse.json index d5a0129..2c62b56 100644 --- a/tests/pyruse.json +++ b/tests/pyruse.json @@ -58,7 +58,7 @@ }, { "action": "action_nftBan", - "args": { "IP": "ip", "banSeconds": 100, "nftSetIPv4": "I4 bans", "nftSetIPv6": "I6 bans" }, + "args": { "IP": "ip", "banSeconds": 100, "nftSetIPv4": "ip I4 bans", "nftSetIPv6": "ip6 I6 bans" }, "then": "… finalize after last action" } ],