Files
housecarl/docs/install.md
T
abrown38andClaude Opus 5.5 de075edd5d Shadow mode: Housecarl beside the firewall in force, changing nothing
shadow.enabled in housecarl.yaml loads Housecarl's ruleset so that it
blocks, rejects and translates nothing: drops and rejects count and
accept (an accept only ends Housecarl's chain), policies accept and log
what they would drop, NAT only counts, MSS clamping and the flowtable
are left out, and raw rules that do more than accept, drop or reject are
left out with a warning. Comments mark what would happen ([would drop]).
Filter chains run after the other firewall's (+10) or before (-10); NAT
chains always first. Every change is checked by nftables in both forms.
No probation; takeovers and closing connections are refused. The boot
fallback filters nothing. internal/tablewatch puts the table back after
a flush ruleset. Mode in status, healthz, whoami, the web UI, the log
and the tracer; hc ruleset --enforcing. docs/shadow.md.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-20 18:11:01 +01:00

5.4 KiB

Installing Housecarl

Housecarl runs on Linux with nftables 1.0 or newer. It is made for and tested on Debian 13 (nftables 1.1.3). The CLI also runs on macOS and Windows.

From the package registry

The release workflow publishes Debian packages to the Gitea registry, stable for releases and testing for release candidates. Jarl's and Steward's packages come from the same registry. If apt already has it, sudo apt install housecarl is all it takes. Otherwise add it:

sudo install -d /etc/apt/keyrings
sudo curl -fsSL https://gitea.adbraun.lol/api/packages/adam/debian/repository.key -o /etc/apt/keyrings/gitea-adam.asc
echo "deb [signed-by=/etc/apt/keyrings/gitea-adam.asc] https://gitea.adbraun.lol/api/packages/adam/debian stable main" \
  | sudo tee /etc/apt/sources.list.d/gitea-adam.list
sudo apt update
sudo apt install housecarl

For release candidates too, add the testing distribution: the same deb line with testing instead of stable.

There are two packages:

  • housecarl is the server: /usr/bin/housecarld, the systemd units housecarl.service, housecarl-ruleset.service (the ruleset at boot), housecarl-backup.service and housecarl-backup.timer, and the housecarl user and directories. It creates /etc/housecarl/housecarl.yaml on the first install and never touches it again. It depends on housecarl-cli and nftables.
  • housecarl-cli is the CLI, /usr/bin/hc. It can be installed alone on any machine to manage Housecarl remotely.

Installing changes nothing in the firewall: housecarld applies a ruleset only once it has a configuration.

The release page also has .deb files, tarballs and the CLI for Linux, macOS and Windows.

From source

make                        # bin/housecarld, bin/hc (Go, as in go.mod)
sudo make install           # /usr/local/bin, units in /etc/systemd/system
sudo systemd-sysusers housecarl.conf && sudo systemd-tmpfiles --create housecarl.conf
sudo chgrp housecarl /etc/housecarl /etc/housecarl/housecarl.yaml && sudo systemctl daemon-reload

make deb builds the packages (DEB_ARCH=arm64 for another architecture).

First steps

Do this from a console, or over SSH with a way back in if it goes wrong: you are changing the firewall you are connected through.

  1. Settings are in /etc/housecarl/housecarl.yaml (configuration.md). By default the web UI and API listen on 127.0.0.1:8070. To reach them from your network, add an address there, ideally with TLS or behind a TLS reverse proxy.

  2. Create the database and the first administrator:

    sudo -u housecarl housecarld init
    

    It asks for the administrator's name (admin if you just press Enter; your own name is better) and password.

  3. Start Housecarl:

    sudo systemctl enable --now housecarl
    

    Until it has a configuration, housecarld applies nothing: the machine stays as open (or as closed) as it was.

  4. Import your ruleset, if you have one (import.md):

    sudo hc import --defines /etc/nftables.conf -n      # look
    sudo hc import --defines /etc/nftables.conf         # import
    sudo hc takeover "inet main"
    sudo systemctl disable nftables.service
    

    To try Housecarl beside your firewall first, turn on shadow mode before the import: it loads Housecarl's ruleset but blocks nothing, and shows what it would do (shadow.md).

    Or start from scratch, through the local socket (no probation). The first change puts the ruleset in force, and the input and forward policies drop what no rule accepts, so let yourself in first:

    sudo hc set add admins 192.168.1.0/24
    sudo hc rule add input --from admins --service ssh
    sudo hc rule add input --from admins --service tcp/8070 --comment "Housecarl"
    sudo hc zone add wan --interface ppp0 --external
    sudo hc zone add lan --interface eth1
    sudo hc rule add input --in lan --service dns --service dhcp
    sudo hc rule add forward --in lan --out wan
    sudo hc snat add --out wan
    sudo hc settings set --builtin mss_clamp=on --own-prefix 2001:db8::/48
    sudo hc status
    

    Housecarl doesn't add a rule that keeps SSH or the web UI open: you write it. Connections already open (your SSH session) carry on, since established connections are accepted.

  5. Open the web UI on an address in listen, and log in.

From another machine

Install housecarl-cli, make a token, and set the server:

sudo hc token create laptop               # on the firewall; prints the token once
hc config set server https://fw.example.com:8070
hc config set token                       # paste it
hc status

Changes from there are on probation: hc confirm keeps them.

Upgrading

apt upgrade restarts a running housecarld, which applies the ruleset again (counters keep counting) and upgrades its database when it starts. The firewall stays up during the upgrade: the ruleset belongs to the kernel, not to housecarld. Take a backup first if you like (sudo -u housecarl housecarld backup); the daily timer keeps 30 days of them.

Removing

apt remove housecarl stops housecarld and disables the boot unit. The ruleset stays in force until the next boot, or until you delete it: sudo nft delete table inet housecarl. A purge keeps the database and the backups; remove /var/lib/housecarl and /var/backups/housecarl by hand if you no longer need them.