root@sudosecurity:~/hardline/security $ cat security .md

Hardline security

How Hardline protects your server and itself: lockout guards, no shell, memory-safe Rust, checksummed releases and private vulnerability reporting.

Hardline runs as root and edits SSH and the firewall, so it has to be the most careful program on your server. This is how it earns that.

It can't lock you out

  1. Preflight. Phase 1 refuses to turn off passwords unless your user has a working SSH key, and won't turn off root login from a root session.
  2. Snapshot. Every file is copied to /var/lib/hardline/snapshots/ with its SHA-256, mode and owner before it changes. Writes are atomic.
  3. Validate. sshd -t and sshd -T for every login user, nft -c, firewall-offline-cmd --check-config or dockerd --validate must pass before anything reloads. A failure restores the snapshot.
  4. Countdown. A systemd timer reverts SSH and firewall changes unless you confirm. It keeps running if your connection drops.
  5. New-session proof. confirm from the session that made the change is refused, because that only proves an existing connection survived, not that a new login works.
  6. Boot guard. If the server reboots before you confirm, the change reverts before SSH and the firewall start.

Every one of these paths is tested on real Ubuntu, Debian, Rocky and Alma VMs before a release, including never confirming, confirming from the same session, rebooting before confirming, and a cloud-init file that turns passwords back on.

The code

hardlineone binaryfixed allowlist/usr/sbin/sshd/usr/sbin/ufw/usr/sbin/nft/usr/bin/systemctl/usr/sbin/sysctl/usr/bin/openssl…35 absolute pathsargvno shell/bin/sh -cnever
No shell, no $PATH lookup: a fixed list of absolute paths, each called with plain arguments.
  • No shell, ever. Controls are declarative TOML compiled into the binary. They can describe a check and a file to write, never a command to run.
  • A fixed list of programs. Every process starts from one module with an absolute path (/usr/sbin/sshd), no shell, an empty environment and LC_ALL=C.
  • Memory-safe Rust with #![forbid(unsafe_code)].
  • Config can only skip. /etc/hardline/config.toml can skip a control with a reason that's printed in every report. It can't change what a control checks.
  • Protects its own binary. Before arming the root revert timer, Hardline checks that its executable and every parent directory are root-owned and not writable by anyone else.
  • Owns only its own things. A drop-in instead of editing sshd_config; its own inet hardline nftables table; Docker's daemon.json merged, never replaced.

Privacy

Hardline makes no network requests of its own unless you give watch a webhook (then it posts regressions there, and nothing else), collects no telemetry, and runs no daemon. Reports stay on your server, are created root-only (0600), and contain no scripts or external resources; their Content-Security-Policy is default-src 'none'.

Releases

-----BEGIN PUBLIC KEY-----
MCowBQYDK2VwAyEAPD8oWSZySVfdT2iWIXtGhZ81gxiRJ9SK3OWReFUf25A=
-----END PUBLIC KEY-----
  • Built by GitHub Actions from a tagged commit, with a locked dependency tree and dependency vulnerability and license checks on every change.
  • Signed. The release workflow signs SHA256SUMS (which also covers VERSION) with SudoSecurity's Ed25519 key, then verifies the signature against the public key in the repo before publishing. The workflow fails rather than ship an unsigned release. The private key exists only as an encrypted GitHub Actions secret and is written to a 0600 temp file only for the length of one openssl call.
  • The public key is built into the binary (release.pub, via include_str!), so self-update trusts that key and nothing the download server says. Verify by hand: see Install.
  • Downloads are served from https://sudosecurity.org/hardline/releases/latest/. The server is just a mirror: a compromised mirror or CDN can withhold updates, but can't make Hardline install anything.
  • Release binaries are tested on fresh VMs of every supported OS before the release is published. When a test fails, the release stays unpublished.

What it doesn't claim

  • It isn't a compliance certification. STIG IDs are references, not an audit.
  • No CIS Benchmarks content; that needs a paid license for commercial use.
  • No SSH port changes, no web server edits (TLS is audit-only), and no package patching or CVE scanning. Pair it with your update process.
  • Unsupported systems are refused, not guessed at.

Report a vulnerability

Don't open a public issue. Report privately through the SudoSecurity security page with the Hardline version (hardline --version), profile, phase, and steps to reproduce on a fresh install if you can.

We aim to acknowledge reports within 3 business days and to ship a fix or mitigation within 30 days, and we credit reporters unless you ask us not to. In scope: any path to a lockout, privilege escalation through Hardline's files or units, a control that passes while the setting is insecure, and undetected tampering with snapshots or pending state.