# Ban lists A **ban list** is where a program bans addresses: Guard (Housecarl's companion, which reads logs), fail2ban with Housecarl's action, or you with `hc ban`. The program says only *which address*, and perhaps a protocol and ports. The ban list says what that address is kept from. So a web server that sees password guessing in its own logs can ban the guesser at the router without knowing anything about the router. ## Ban lists ```sh hc banlist add router --scope firewall # the firewall itself hc banlist add web --scope hosts --host 10.0.10.57 --host 2001:db8:10::57 hc banlist add edge --scope everything --never trusted ``` | Scope | Banned addresses are kept from | Where the drops are | |---|---|---| | `firewall` | the firewall itself: its SSH, DNS, web UI | `input` | | `hosts` | the list's hosts (addresses or sets), behind the firewall | `forward`, to those addresses | | `everything` | the firewall and everything behind it | `input` and `forward` | A `hosts` list covers port forwards to its hosts as well: the forward chain sees a forwarded connection's translated address and port, the host's own. A web server's Guard bans `tcp/22`, and that is right even when the router forwards its port 2222 to it. Other settings, with their defaults: | Setting | Default | | |---|---|---| | `never` | none | addresses, prefixes or sets this list never bans | | `default_time` (`--time`) | 1h | a ban's length when the program asks for none | | `max_time` (`--max-time`) | 7d | the longest ban; longer ones are cut to it. `-1` (`none`): no limit, so bans may be permanent | | `max_entries` | 10000 | the most bans the list holds; more are refused (`list_full`) | | `group_v6` | 64 | the IPv6 prefix length banned for an address. One customer usually has a whole /64 and can move around in it; 128 bans the one address. IPv4 addresses are banned alone | | `disabled` | no | the list's bans aren't in force (they are kept) | A ban list can't be renamed: the tokens and programs that ban into it know it by its name. Make a new one instead. ## Bans ```sh hc ban edge 203.0.113.9 --time 1d --reason "port scan" hc ban web 203.0.113.9 --tcp ssh --tcp 8443 hc bans # every list's hc bans web hc unban web 203.0.113.9 # all of the address's bans in web hc unban web 17 # one, by ID ``` A ban is of **every port**, or of **a protocol's ports** (numbers or service names, built-in or yours). A port without a protocol is banned for TCP and UDP; a service name takes the service's protocols. Banning an address again renews the ban: its new time counts from now. Bans are dropped **ahead of every rule** in their chains, and ahead of the built-in that lets established connections through, so a ban cuts a connection that is already open. Housecarl also closes the banned address's tracked connections the ban covers when it bans it, because connections offloaded to the flowtable no longer pass the rules at all. Replies to connections the inside opened to a banned address are dropped too. Bans are kept in the database, apart from the configuration (like a dynamic set's entries): they aren't in the history, can't be undone, aren't on probation, and don't go through changesets. They end by themselves; every change, restart and reboot puts the active ones back with the time they have left. Each ban and unban is in the audit log (`ban.add`, `ban.remove`), with the program's source and reason. ### What is never banned Whatever a list's `never` says, Housecarl refuses (`422 never_ban`) to ban: * the inside: addresses in networks of inside zones' interfaces, and private addresses outside the external zones' networks; * the firewall's own addresses, and its own prefixes (settings); * the address of whoever asks (a program can't lock itself out); * loopback, link-local, multicast and unspecified addresses. A ban grouped to a prefix (IPv6) is refused when the prefix overlaps any of these. ## Programs and tokens Give each program a token for its list alone. A `bans` grant can name ban lists, as a `sets` grant names sets: ```sh hc user add guard-web --no-password --grant bans:write:web hc token create web --user guard-web # as root on the firewall ``` With it, the program may ban into `web` and lift its bans, list them, and read the list itself (`GET /banlists/web`: its grouping and times), and nothing else. `viewer` has `bans:read`, `operator` `bans:write`. ## Guard Guard reads log files and the systemd journal on any machine, and bans the addresses that misbehave into a ban list (its own documentation). Run it on the web server with a token for `web`, and on the router with one for `router` (or the local socket). ## fail2ban Housecarl ships an action for fail2ban, `/usr/share/doc/housecarl/contrib/fail2ban/action.d/housecarl.conf` (`contrib/` in the source). Copy it to `/etc/fail2ban/action.d/`, put the token in `/etc/fail2ban/housecarl.token` (mode 0600), and use it in a jail: ```ini [sshd] enabled = true action = housecarl[list=web, url="https://router.lan:8070"] ``` The jail's `port` and `protocol` go with each ban: `port = ssh` bans only `tcp/22`, fail2ban's default `0:65535` bans every port. A `bantime` of `-1` is the list's longest ban. When fail2ban unbans an address Housecarl already let go (its own time ran out first), nothing happens. Add `curlopts = --cacert /etc/fail2ban/housecarl-ca.pem` for a private CA. ## Shadow mode In shadow mode the ban rules count what they would drop (`[would drop]`) and let it through, like every other rule, and banning closes no connections. ## The ruleset Each list has four sets, `ban__v4`, `ban__v6` (every port) and `ban__v4_svc`, `ban__v6_svc` (address, protocol and port), all with timeouts: ``` ip saddr @ban_3_v4 counter drop comment "hc:ban3" ip saddr . meta l4proto . th dport @ban_3_v4_svc counter drop comment "hc:ban3" ip6 saddr and ffff:ffff:ffff:ffff:: @ban_3_v6 counter drop comment "hc:ban3" ``` Set names starting with `ban_` are therefore Housecarl's own (`set_name_reserved`).