Build Housecarl 0.1.0: the nftables firewall manager
Zones, address sets (IPv4 and IPv6 mixed, dynamic sets with timeouts) and services, ordered rules in the early, input, forward and output chains, port forwards with hairpin NAT and IPv6 pinholes, source NAT, redirects, and switchable built-ins (loopback, conntrack, ICMPv6, antispoofing, MSS clamping, DHCPv6 client, flowtable). Every change is validated, checked with nft -c and applied in one transaction to Housecarl's own table, inet housecarl; changes made over the network roll back unless confirmed, and the confirmed ruleset is loaded at boot by housecarl-ruleset.service. An empty configuration applies nothing. Also: hit counters and the drop log (nflog), 'hc import' of an existing nftables ruleset and 'hc takeover', the hc CLI, the REST API and the web UI, users, scoped tokens (sets:write:NAME), the audit log, the web UI's certificate through Jarl, Debian packages, docs, unit tests with real nft 1.1.3, and an e2e test with real traffic (71 checks). Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
1 parent
54beb0bba3
commit
34292eeebb
118 files changed
+22165
-114
No files matched your search
Executable
+120
@@ -0,0 +1,120 @@
|
||||
#!/bin/sh
|
||||
# Builds Housecarl's two Debian packages:
|
||||
#
|
||||
# dist/housecarl-cli_<version>_<arch>.deb the CLI, to install anywhere:
|
||||
# /usr/bin/hc, its bash completion, and /usr/share/doc/housecarl-cli/
|
||||
# (README, CHANGELOG, the CLI and permissions docs). No scripts:
|
||||
# installing it changes nothing else on the machine.
|
||||
# dist/housecarl_<version>_<arch>.deb the server, which depends on
|
||||
# housecarl-cli of the same version:
|
||||
# /usr/bin/housecarld and its bash completion
|
||||
# /usr/lib/systemd/system/{housecarl.service,housecarl-ruleset.service,
|
||||
# housecarl-backup.service,housecarl-backup.timer}
|
||||
# /usr/lib/sysusers.d/housecarl.conf, /usr/lib/tmpfiles.d/housecarl.conf
|
||||
# /usr/share/doc/housecarl/ (README, CHANGELOG, docs)
|
||||
# Its scripts (deploy/debian) create the housecarl user and directories and
|
||||
# /etc/housecarl/housecarl.yaml on the first install, enable the boot
|
||||
# ruleset unit and the daily backup timer, restart a running housecarld on
|
||||
# upgrades, and stop it on removal (the ruleset in force stays until the
|
||||
# next boot).
|
||||
# No file in /etc belongs to the package, so an upgrade never asks
|
||||
# about configuration files.
|
||||
#
|
||||
# Run through 'make deb' (which sets the variables below); needs only
|
||||
# dpkg-deb, no root and no debhelper.
|
||||
#
|
||||
# Variables: DEB_ARCH (Debian architecture, e.g. amd64, arm64, armhf),
|
||||
# DEB_VERSION, VERSION, LDFLAGS, GOFLAGS, and DEB_MAINTAINER (default: your
|
||||
# git name and email).
|
||||
set -eu
|
||||
|
||||
: "${DEB_ARCH:?}" "${DEB_VERSION:?}" "${VERSION:?}" "${LDFLAGS:?}"
|
||||
GOFLAGS=${GOFLAGS:-}
|
||||
|
||||
# Debian architecture -> Go architecture.
|
||||
goarm=
|
||||
case "$DEB_ARCH" in
|
||||
amd64) goarch=amd64 ;;
|
||||
arm64) goarch=arm64 ;;
|
||||
armhf) goarch=arm goarm=7 ;;
|
||||
i386) goarch=386 ;;
|
||||
ppc64el) goarch=ppc64le ;;
|
||||
riscv64) goarch=riscv64 ;;
|
||||
s390x) goarch=s390x ;;
|
||||
*) echo "mkdeb: unsupported architecture $DEB_ARCH" >&2; exit 1 ;;
|
||||
esac
|
||||
|
||||
if [ -z "${DEB_MAINTAINER:-}" ]; then
|
||||
name=$(git config user.name 2>/dev/null || true)
|
||||
email=$(git config user.email 2>/dev/null || true)
|
||||
DEB_MAINTAINER="${name:-Housecarl packager} <${email:-root@localhost}>"
|
||||
fi
|
||||
|
||||
work=dist/deb/${DEB_VERSION}_${DEB_ARCH}
|
||||
stage=$work/stage
|
||||
rm -rf "$work"
|
||||
# Older packages of this architecture (every development build has its
|
||||
# own version), so 'apt install ./dist/housecarl_*_amd64.deb' finds just one.
|
||||
rm -f dist/housecarl_*_"$DEB_ARCH".deb dist/housecarl-cli_*_"$DEB_ARCH".deb
|
||||
mkdir -p "$stage"
|
||||
|
||||
# Binaries for the package's architecture (bin/ holds the host's, which
|
||||
# also generated the completion scripts).
|
||||
echo "mkdeb: building for linux/$goarch"
|
||||
# go reads GOFLAGS (-trimpath) from the environment.
|
||||
export GOFLAGS
|
||||
GOOS=linux GOARCH=$goarch GOARM=$goarm CGO_ENABLED=0 go build -ldflags "$LDFLAGS" -o "$work/bin/housecarld" ./cmd/housecarld
|
||||
GOOS=linux GOARCH=$goarch GOARM=$goarm CGO_ENABLED=0 go build -ldflags "$LDFLAGS" -o "$work/bin/hc" ./cmd/hc
|
||||
|
||||
# Everything 'make install' would install, then split in two.
|
||||
make --no-print-directory install-files DESTDIR="$stage" PREFIX=/usr \
|
||||
UNITDIR=/usr/lib/systemd/system HOUSECARLD_BIN="$work/bin/housecarld" HC_BIN="$work/bin/hc" >/dev/null
|
||||
|
||||
cli=$work/housecarl-cli
|
||||
srv=$work/housecarl
|
||||
mkdir -p "$cli/DEBIAN" "$cli/usr/bin" "$cli/usr/share/bash-completion/completions" "$cli/usr/share/doc/housecarl-cli/docs"
|
||||
mv "$stage/usr/bin/hc" "$cli/usr/bin/"
|
||||
mv "$stage/usr/share/bash-completion/completions/hc" "$cli/usr/share/bash-completion/completions/"
|
||||
cp "$stage/usr/share/doc/housecarl/README.md" "$stage/usr/share/doc/housecarl/CHANGELOG.md" "$cli/usr/share/doc/housecarl-cli/"
|
||||
for d in cli permissions; do
|
||||
cp "$stage/usr/share/doc/housecarl/docs/$d.md" "$cli/usr/share/doc/housecarl-cli/docs/"
|
||||
done
|
||||
mv "$stage" "$srv"
|
||||
mkdir -p "$srv/DEBIAN"
|
||||
for f in postinst prerm postrm; do
|
||||
install -m 0755 "deploy/debian/$f" "$srv/DEBIAN/$f"
|
||||
done
|
||||
|
||||
# Debian's machine-readable copyright file, from LICENSE.
|
||||
indent() { sed -e 's/^$/./' -e 's/^/ /' "$1"; }
|
||||
copyright() {
|
||||
echo "Format: https://www.debian.org/doc/packaging-manuals/copyright-format/1.0/"
|
||||
echo "Upstream-Name: housecarl"
|
||||
echo
|
||||
echo "Files: *"
|
||||
echo "Copyright: $(sed -n 's/^Copyright (c) //p' LICENSE)"
|
||||
echo "License: Expat"
|
||||
indent LICENSE
|
||||
}
|
||||
|
||||
# build PACKAGE ROOT: writes the control file and md5sums and builds the .deb.
|
||||
build() {
|
||||
pkg=$1 root=$2 out=dist/${1}_${DEB_VERSION}_${DEB_ARCH}.deb
|
||||
copyright > "$root/usr/share/doc/$pkg/copyright"
|
||||
rm -f "$root/usr/share/doc/$pkg/LICENSE"
|
||||
# Directories 0755 and no group/other write, whatever the build's umask.
|
||||
find "$root" -type d -exec chmod 0755 {} +
|
||||
chmod -R go-w "$root"
|
||||
size=$(du -sk --exclude=DEBIAN "$root" | cut -f1)
|
||||
sed -e "s/@VERSION@/$DEB_VERSION/g" -e "s/@ARCH@/$DEB_ARCH/" -e "s/@SIZE@/$size/" \
|
||||
-e "s|@MAINTAINER@|$DEB_MAINTAINER|" "deploy/debian/control-$pkg.in" > "$root/DEBIAN/control"
|
||||
(cd "$root" && find . -path ./DEBIAN -prune -o -type f -print | sed 's|^\./||' | sort | xargs md5sum) > "$root/DEBIAN/md5sums"
|
||||
chmod 0644 "$root/DEBIAN/control" "$root/DEBIAN/md5sums"
|
||||
# Files belong to root in the package, whoever builds it.
|
||||
dpkg-deb --root-owner-group -Zxz --build "$root" "$out" >/dev/null
|
||||
echo "mkdeb: wrote $out"
|
||||
dpkg-deb --info "$out" | sed -n 's/^ \(Package\|Version\|Architecture\|Installed-Size\|Depends\):/ \1:/p'
|
||||
}
|
||||
build housecarl-cli "$cli"
|
||||
build housecarl "$srv"
|
||||
rm -rf dist/deb
|
||||
Reference in new issue
Block a user