Files
os-build/docs/hardening.md
Blake Ridgway 87fc370541 docs: add architecture, hardening, and building documentation
Document the design and how to operate it: architecture, building
(including toolchain-free/minimal builds), hardening guide, editions,
observability, and the toolchain. README ties it together.
2026-08-21 13:15:43 -05:00

3.2 KiB

Hardening guide

Every edition ships the same hardening baseline (the overlays/base layer). This page explains what each piece does and how to tune it. Everything is documented in the config files too — read them, they are the source of truth.

Kernel

  • Boot cmdline (editions/*/kernel.cmdline) — applied to both the live ISO and (via configure-system.sh/etc/default/grub) any installed system:
    • init_on_alloc=1 init_on_free=1 — zero freshly allocated and freed memory
    • slab_nomerge — prevent slab object merging
    • page_poison=1 — fill freed pages to catch use-after-free
    • pti=on — kernel page-table isolation
    • spectre_v2=on spec_store_bypass=on tsx=off — mitigations forced on
    • lockdown=integrity — kernel refuses unsigned in-memory modification
    • oops=panic panic=-1 — halt (and stay down) on kernel oops
  • sysctl (overlays/base/etc/sysctl.d/10-arcline-hardening.conf):
    • memory: sane dirty ratios, no overcommit
    • network: strict rp_filter, no ICMP redirects, syncookies, TCP hardening
    • visibility: dmesg_restrict=1, kptr_restrict=2, perf_event_paranoid=3, ptrace_scope=1, unprivileged_bpf_disabled=1
    • filesystem: protected hardlinks/symlinks/fifos, suid_dumpable=0
  • Module blacklist (overlays/base/etc/modprobe.d/arcline-hardening.conf):
    • exotic network protocols (sctp, dccp, rds, tipc) and legacy filesystems (cramfs, hfs, hfsplus, jffs2, udf, …).

The workstation edition relaxes a few of these for developer ergonomics (perf, tracing, rootless containers) via overlays/workstation/etc/sysctl.d/90-arcline-desktop.conf.

Firewall — nftables, default-deny

overlays/base/etc/nftables.conf ships a drop-by-default policy:

  • allow: loopback, established/related, ICMP (for PMTU discovery)
  • allow: tcp/22 (ssh — key auth only)
  • everything else inbound: dropped
  • forward chain: dropped (container bridges manage their own rules)

Open a port by editing the file and systemctl reload nftables, e.g.:

sudo nft add rule inet filter input tcp dport 443 accept

You opt in to exposure; nothing is open unless you say so.

ssh

overlays/base/etc/ssh/sshd_config.d/10-arcline-hardening.conf:

  • PermitRootLogin prohibit-password — root only via key
  • PasswordAuthentication no — keys only (this is the secure default; change deliberately)
  • MaxAuthTries 3, LoginGraceTime 30, ClientAliveInterval 300
  • no X11Forwarding, UseDNS no

Logging

journald.conf.d/10-arcline.conf — persistent, bounded (500M), compressed, 14-day retention. Logs live on the @log subvolume so they survive rollbacks.

AppArmor

Arcline uses Debian's AppArmor profiles (loaded at boot) plus the kernel hardening above. Extra profiles can be dropped into /etc/apparmor.d/local/ — the enforcement is on by default.

systemd hardening

system.conf.d/10-arcline.conf — no core dumps on disk, sane default limits (NOFILE=65535, NPROC=4096).

Verifying a build

tests/smoke/verify-rootfs.sh build/rootfs/server

The smoke test asserts the guarantees above (kptr_restrict, policy drop, ssh keys-only, no telemetry, no snapd, btrfs tooling present). The build fails if any are missing.