Hardline changelog

Every Hardline release and what changed: new controls, supported Linux distributions, safety fixes and new commands like report, explain and watch.

Every release, newest first. Release binaries and checksums are on GitHub Releases.

0.4.1 · 2026-10-19

Fixed

  • Rolling back a change that installed a package (ufw on Debian 12, firewalld on RHEL) deleted the config files that package had just created, such as /etc/ufw/ufw.conf. On Debian that made ufw disable fail, so the firewall stayed on after rollback. Files a package install creates are now recorded after the install, and rollback puts back the package's own copy.

0.4.0 · 2026-10-19

Added

  • An A–F security grade, weighted by severity, in audit output and the JSON report (grade.letter, grade.percent). A failing high-severity control caps an A at B.
  • hardline report [--out FILE]: the audit as a self-contained HTML page with the grade, a "fix first" list and a link for every finding. No scripts or external requests (strict CSP), light and dark themes, works on phones and prints cleanly. --out creates a new 0600 file and never overwrites or follows an existing path.
  • hardline watch enable|disable|run|status: a systemd timer (hourly, daily or weekly, with jitter and catch-up after downtime) that re-audits and compares with the previous run. A grade drop, a newly failing control or an outside edit to a file Hardline wrote exits 1, so hardline-watch.service shows in systemctl --failed and OnFailure= hooks fire. Skips a run while a change awaits confirm or another hardline command holds the lock. Results go to /var/lib/hardline/watch.json (0600).
  • hardline explain <id> [--json]: why a control matters, exactly what it checks, what apply writes, the preflight checks, and how to undo it. Works offline and without root; an unknown id suggests close matches. The text comes from controls/guides.toml, which also builds the website, so the CLI and https://sudosecurity.org/hardline/ never disagree.
  • RHEL 9, Rocky Linux 9 and AlmaLinux 9 support for the baseline profile: dnf/rpm package handling, sshd.service, a new selinux-enforcing check in phase 3, and SELinux labels restored on every file Hardline writes. Tested on Rocky 9.8 and AlmaLinux 9.8 VMs with SELinux enforcing.
  • Guarded firewalld support on RHEL 9, Rocky Linux 9 and AlmaLinux 9: when firewalld isn't running, apply --phase 2 installs it if needed, opens SSH and every listening port in the default zone while keeping existing zone rules, validates with firewall-offline-cmd --check-config, and starts it under the confirm/revert/boot guard. Rollback restores the zone file exactly and stops firewalld again. Tested on Rocky 9 with SELinux enforcing.
  • Controls can be limited to one distro family with os = ["debian"] or os = ["rhel"].

Fixed

  • Boot-guard reverts now also stop units the reverted change enabled; disabling alone didn't cancel a start job already queued for that boot.
  • Rollback disables units before restoring files. Before, reverting an nftables change failed with "Unit file hardline-firewall.service does not exist" because the unit file was already removed, so the boot guard reported a failed revert.
  • audit, diff, status, controls and dry-run apply exit 3 when stdout fails for a reason other than a closed pipe (for example a full disk), instead of exiting 0 with a truncated report.
  • The dpkg lock wait is one 5-minute budget for the whole package install, not 5 minutes per apt-get call.

0.3.1 · 2026-10-19

Fixed

  • Piping output into head (or any closed pipe) no longer crashes Hardline with a broken-pipe panic. Output errors can never stop an apply halfway.
  • Package installs wait up to 5 minutes for the dpkg lock (DPkg::Lock::Timeout=300) instead of failing while unattended-upgrades runs on a fresh server.

0.3.0 · 2026-10-19

Added

  • Ubuntu 22.04 LTS and Debian 12 support for the baseline profile. All phases and the SSH/firewall lockout scenarios were run on VMs of each.
  • --profile stig is refused outside Ubuntu 24.04, since its IDs come from the Ubuntu 24.04 STIG.

Changed

  • Release binaries are built on Ubuntu 22.04 so they run on glibc 2.35+ (Ubuntu 22.04, Debian 12) as well as 24.04.

0.2.0 · 2026-10-19

Added

  • Phase 7, kernel: six sysctl controls (kernel.dmesg_restrict, net.ipv4.tcp_syncookies, kernel.randomize_va_space from the STIG; kernel.kptr_restrict, fs.protected_symlinks, fs.protected_hardlinks in baseline). Fixes go in /etc/sysctl.d/99-zz-hardline.conf; rollback restores the previous running values.
  • Phase 7 blocks kernel modules: usb-storage (STIG) plus dccp, rds, tipc (baseline) via /etc/modprobe.d/hardline.conf.
  • Phase 8, accounts: empty passwords, libpam-pwquality, and in stig the DISA password rules, password ages, INACTIVE=35 and sudo NOPASSWD. Config files are edited in place, so only the managed lines change.

0.1.0 · 2026-10-19

Added

  • audit, apply (dry run by default, --commit to write), confirm, rollback, diff, status and controls commands.
  • 43 controls across SSH, firewall, AppArmor, auditd, TLS and Docker, with baseline and stig profiles and Ubuntu 24.04 STIG/CCI references.
  • Guarded SSH and firewall changes: a revert timer plus a boot guard undo anything not confirmed from a new SSH session.
  • SHA-256 snapshots with mode and ownership, drift detection, and manual rollback that refuses to overwrite later edits without --force.
  • ufw backend, and an nftables backend that only owns table inet hardline.
  • JSON report schema version 1.
  • Project page at https://sudosecurity.org/hardline/, built from the controls by site/build.py. Every finding links to its section there.
  • Release archives have stable names (hardline-<target>.tar.gz), so releases/latest/download/ links always work.