Reverse lookups (internal/names, POST /names) put a name beside each inside address in connections, the log, quota usage, the dashboard's quotas and the statistics' devices and blocked sources, in the web UI and hc (--no-names to leave them out). Only inside addresses are looked up: an inside zone's networks, and private ones outside the external zones'. Names are cached (names.cache, 10m) and never stored; names.resolver picks the DNS server. Also: hc stats top devices listed each device twice; the dashboard's quotas named the rule's ID twice. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
5.5 KiB
Configuration file
/etc/housecarl/housecarl.yaml says how housecarld runs. The firewall's
configuration (zones, sets, rules, NAT, settings) isn't here; it is in
the database, changed with the CLI, the API or the web UI.
housecarld config --example prints a commented file with the defaults.
Every setting is optional; unknown settings are an error. housecarld
reads the file when it starts.
| Setting | Default | |
|---|---|---|
listen |
["127.0.0.1:8070"] |
addresses of the web UI and API (host:port). Keep them on localhost or a management network, and write an input rule that lets you reach them |
tls.cert_file, tls.key_file |
none | serve HTTPS with this certificate; housecarld rereads it when the file changes, or on systemctl reload housecarl |
tls.acme.* |
off | get the certificate from Let's Encrypt, with Jarl publishing the challenge (certificates.md) |
jarl.server, jarl.token_file (or jarl.token), jarl.ca_cert, jarl.insecure |
none | the Jarl server for the certificate's challenge, and its token (jarl.md) |
ruleset |
/var/lib/housecarl/ruleset.nft |
the confirmed ruleset, which housecarl-ruleset.service loads at boot; its fallback is saved beside it as ruleset-fallback.nft (operations.md). Change both paths in the unit too |
trusted_proxies |
[] |
addresses or prefixes of reverse proxies whose X-Forwarded-For and X-Forwarded-Proto are believed |
socket |
/run/housecarl/housecarl.sock |
the local API socket; "" turns it off |
database |
/var/lib/housecarl/housecarl.db |
the SQLite database: configuration, history, users, audit log |
log.level |
info |
debug (every HTTP request), info, warn or error |
log.format |
text |
text or json |
session.lifetime |
12h |
how long a web UI login lasts |
session.idle_timeout |
2h |
logged out after this long without use |
session.cookie_secure |
auto |
auto (secure over HTTPS), always or never |
backup.dir |
/var/backups/housecarl |
where housecarld backup writes |
backup.retention |
30d |
backups older than this are deleted… |
backup.keep_at_least |
7 |
…keeping at least this many |
stats.enabled |
true |
keep traffic, drops, hits, blocked sources, connections and quotas over time (stats.md) |
stats.database |
/var/lib/housecarl/stats.db |
the statistics' own database; deleting it is safe |
stats.retention.minute, .hour, .day |
7d, 90d, 730d |
how long per-minute, hourly and daily figures are kept |
stats.top_n |
100 |
entries kept per top list, per hour and per day |
shadow.enabled |
false |
shadow mode: Housecarl's ruleset is loaded beside the firewall you have, but blocks, rejects and translates nothing; its counters, log and tracer show what it would do. No change is on probation, and takeovers and closing connections are refused (shadow.md) |
shadow.position |
after |
where Housecarl's filter chains run in shadow mode: after the other firewall's (filter + 10: it sees only what that one lets through, so what it would drop is what switching would break) or before them (filter - 10: it sees every packet) |
names.enabled |
true |
show inside addresses' names beside them, found by reverse lookups (below) |
names.resolver |
"" |
the DNS server to ask, such as 10.10.0.1:53; empty: the system's (/etc/hosts, then /etc/resolv.conf) |
names.cache |
10m |
how long a name, or the lack of one, is kept |
Durations are written 15s, 12h or 30d.
Shadow mode is here, and not a firewall setting, so that no user or API token can switch enforcement off; restart housecarld to switch.
Names
The web UI and hc show a name beside each inside address in
connections, the log, quotas and traffic per device: laptop 192.168.1.20. Housecarl finds it with a reverse (PTR) lookup, so the
names are your reverse zones' (and /etc/hosts'). An address counts as
inside when it is in a network connected to an inside zone's interface,
or private (10.0.0.0/8, 172.16.0.0/12, 192.168.0.0/16, fc00::/7)
and not in an external zone's network. Outside addresses get no name:
their reverse zones belong to whoever holds the addresses, who would
choose the names, and looking up every scanner is slow.
Names are looked up when a page or hc asks, cached (a failed lookup is
tried again after a minute), and never stored: statistics stay by
address. With a split DNS (views), the server asked must answer the
firewall as an inside client; set names.resolver if the system's
resolver doesn't. IPv6 traffic per device is counted per /64, which has
no name. hc --no-names leaves them out.
The probation's length is a firewall setting, not here: hc settings set --probation 5m. So is counting traffic per device for the statistics:
hc settings set --stats-per-device on.
HTTPS
Over plain HTTP, passwords and tokens cross the network in the clear; housecarld warns when it listens on a non-loopback address without TLS. Let it get its own certificate through Jarl (certificates.md), or give it one:
listen: ["192.168.1.1:8070"]
tls:
cert_file: /etc/housecarl/tls/fullchain.pem
key_file: /etc/housecarl/tls/privkey.pem
Or keep it on 127.0.0.1 behind a reverse proxy that terminates TLS, and
list the proxy in trusted_proxies. With a certificate, the same port
answers HTTPS and redirects plain HTTP to it, except from the firewall
itself.