fix(harden): keep hardening and the ntfy notifier alive when sshguard can't install

On a fresh AlmaLinux 9.8 box, install_bruteforce_protection ran unguarded under
'set -euo pipefail'. When sshguard (from EPEL) wasn't installable at that moment,
the single failed dnf aborted the ENTIRE harden run before it wrote sshd_config
or installed the pam_exec login notifier -- leaving a stock, unhardened box and a
silently-missing ntfy hook.

- oslib: install the iptables backend best-effort first, then sshguard, and
  return sshguard's status so callers can treat it as non-fatal.
- harden-ssh/harden-jumphost: install_openssh now dies with a clear message on
  failure; sshguard is '|| warn' so sshd hardening and the notifier still apply.
- install_login_notifier verifies the script + pam hook landed and logs
  'Login notifier ACTIVE' (or a loud warning) instead of failing silently.
- ntfy-ssh-login.sh: NTFY_DEBUG=1 logs delivery attempts + curl errors to
  /var/log/ssh-notify.log so the next silent failure leaves a trace.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-06-14 16:53:39 -05:00
co-authored by Claude Opus 4.8
parent 3c02574dd0
commit 60433e4c8d
4 changed files with 53 additions and 11 deletions
+5 -2
View File
@@ -57,8 +57,11 @@ log "Detected OS: ${OS_ID} (family ${OS_FAMILY}, init ${INIT_SYSTEM})"
# 1. Packages
# ----------------------------------------------------------------------------
log "Installing OpenSSH + sshguard + iptables..."
install_openssh
install_bruteforce_protection
install_openssh || die "OpenSSH packages failed to install; cannot harden. Fix the package error above, then re-run."
# sshguard is best-effort (see harden-ssh.sh): never let a missing brute-force
# package abort the whole bastion hardening.
install_bruteforce_protection \
|| warn "sshguard not installed; brute-force protection is OFF. Add it later with: dnf install -y epel-release sshguard. Continuing with the rest of the hardening."
ensure_gum || warn "gum not installed; sshuser will use its CLI mode."
SFTP_PATH="$(sftp_server_path)"