A program bans an address (every port, or a protocol's ports) for a time; the ban list says what it is kept from: the firewall, some hosts behind it, or everything. Bans drop ahead of every rule, close the address's connections, group IPv6 by /64, are kept in the database across restarts and audited. Never banned: the inside, the firewall's own addresses, the caller, the list's never. bans grant (bans:write:LIST), hc banlist/bans/ban/unban, Traffic -> Bans, a fail2ban action in contrib/, and failed logins and refused tokens logged for Guard and fail2ban. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
53 lines
2.0 KiB
Plaintext
53 lines
2.0 KiB
Plaintext
# Housecarl's action for fail2ban: a ban goes into a Housecarl ban list,
|
|
# and the list says what the banned address is kept from (the firewall
|
|
# itself, some hosts behind it, or everything). See docs/bans.md.
|
|
#
|
|
# Copy this file to /etc/fail2ban/action.d/housecarl.conf, make a ban
|
|
# list and a token for it alone on the firewall:
|
|
#
|
|
# hc banlist add web --scope hosts --host 10.0.10.57
|
|
# hc user add f2b-web --no-password --grant bans:write:web
|
|
# hc token create web --user f2b-web # as root on the firewall
|
|
#
|
|
# put the token in /etc/fail2ban/housecarl.token (mode 0600), and use it
|
|
# in a jail:
|
|
#
|
|
# [sshd]
|
|
# enabled = true
|
|
# action = housecarl[list=web, url="https://router.lan:8070"]
|
|
#
|
|
# The jail's port and protocol go along: port = ssh bans only tcp/22;
|
|
# fail2ban's default (0:65535) bans every port. IPv6 addresses are banned
|
|
# with the list's grouping (a /64 unless set otherwise). Housecarl never
|
|
# bans inside networks, its own addresses or the list's "never".
|
|
#
|
|
# On the firewall itself, the local socket works too, still with the
|
|
# token: url = http://localhost, curlopts = --unix-socket
|
|
# /run/housecarl/housecarl.sock.
|
|
|
|
[Definition]
|
|
|
|
actionstart =
|
|
actionstop =
|
|
actioncheck =
|
|
|
|
# A ban renews one already there; a bantime of -1 is the list's longest.
|
|
actionban = <_curl> -f -X POST -H "Content-Type: application/json" "<url>/api/v1/banlists/<list>/bans"
|
|
-d '{"address": "<ip>", "protocol": "<protocol>", "ports": "<port>", "time": <bantime>, "source": "fail2ban/<name>"}'
|
|
|
|
# A ban Housecarl already ended (its own time ran out) is no error.
|
|
actionunban = <_curl> -X DELETE "<url>/api/v1/banlists/<list>/bans?address=<ip>"
|
|
|
|
[Init]
|
|
|
|
# The ban list, and Housecarl's URL (its listen address).
|
|
list =
|
|
url = https://127.0.0.1:8070
|
|
# The API token, in a file only root reads.
|
|
tokenfile = /etc/fail2ban/housecarl.token
|
|
# More curl options: --cacert /etc/fail2ban/housecarl-ca.pem for a
|
|
# private CA, --unix-socket for the local socket.
|
|
curlopts =
|
|
|
|
_curl = curl -sS --max-time 10 <curlopts> -o /dev/null -H "Authorization: Bearer $(cat <tokenfile>)"
|