diff --git a/modules/nixos/login-text.nix b/modules/nixos/login-text.nix index 625e593..7c27a52 100644 --- a/modules/nixos/login-text.nix +++ b/modules/nixos/login-text.nix @@ -23,6 +23,7 @@ service_status = { SSH = "sshd.socket"; + "SSH Certs" = "step-ssh-host-renew.timer"; Docker = "docker"; }; diff --git a/modules/programs/step-client.nix b/modules/programs/step-client.nix index 8648fae..548ceac 100644 --- a/modules/programs/step-client.nix +++ b/modules/programs/step-client.nix @@ -65,6 +65,52 @@ in '') (writeShellScriptBin "ssh-host-cert-check" "${lib.getExe' pkgs.openssh "ssh-keygen"} -Lf ${sshCertPath}") ]; + + systemd.services.step-ssh-host-renew = { + description = "Renew Step SSH host certificate if needed"; + wantedBy = [ ]; + after = [ "network-online.target" ]; + wants = [ "network-online.target" ]; + path = [ pkgs.step-cli pkgs.openssh pkgs.coreutils pkgs.systemd ]; + serviceConfig = { + Type = "oneshot"; + User = "root"; + Group = "root"; + }; + script = '' + set -euo pipefail + if ${stepBin} ssh needs-renewal "${sshCertPath}" --expires-in "4h"; then + echo "Renewing SSH host certificate" + else + rc=$? + if [ "$rc" -eq 1 ]; then + echo "SSH host cert does not need renewal" + exit 0 + fi + + if [ "$rc" -eq 2 ]; then + echo "SSH host cert missing: ${sshCertPath}" >&2 + exit 1 + fi + + echo "step ssh needs-renewal failed with rc=$rc" >&2 + exit "$rc" + fi + ''; + }; + + systemd.timers.step-ssh-host-renew = { + description = "Periodic Step SSH host certificate renewal"; + wantedBy = [ "timers.target" ]; + + timerConfig = { + OnBootSec = "5m"; + OnUnitActiveSec = "4h"; + RandomizedDelaySec = "15m"; + Persistent = true; + Unit = "step-ssh-host-renew.service"; + }; + }; }; };