{ inputs, ... }: let caURL = "https://janus.john-stream.com/"; stepFingerprint = "2036c44f7b5901566ff7611ea6c927291ecc6d2dd00779c0eead70ec77fa10d6"; in { flake.modules.nixos.step-ssh-host = { config, pkgs, lib, ... }: let cfg = config.step-ssh-host; rootCertPath = "/etc/step/certs/root_ca.crt"; provisionerPasswordPath = config.sops.secrets."janus/admin_jwk".path; sshKeyPath = "/etc/ssh/ssh_host_ed25519_key"; sshCertPath = "${sshKeyPath}-cert.pub"; in { # NixOS Options options.step-ssh-host = { hostname = lib.mkOption { description = "Networking host name"; type = lib.types.str; }; caURL = lib.mkOption { description = "URL for the certificate authority"; type = lib.types.str; }; rootCertFile = { path = lib.mkOption { description = "String path to where the root_ca.crt file will be stored for the user"; type = lib.types.str; default = "step/certs/root_ca.crt"; }; source = lib.mkOption { description = "Nix path to the root cert file within the repo"; type = lib.types.path; default = ../../../keys/root_ca.crt; }; }; provisioner = lib.mkOption { description = "Provisioner inside Step CA to use for the SSH certificates"; type = lib.types.str; default = "admin"; }; }; imports = with inputs.self.modules.nixos; [ ssh ]; # NixOS Config config = { ssh.certificates.enable = true; sops.secrets."janus/admin_jwk" = { owner = "root"; group = "root"; mode = "0400"; }; networking.nameservers = [ "192.168.1.150" ]; networking.dhcpcd.extraConfig = "nohook resolv.conf"; environment.etc."${cfg.rootCertFile.path}".source = cfg.rootCertFile.source; environment.systemPackages = with pkgs; [ step-cli (writeShellScriptBin "ssh-host-cert-renew" '' ${lib.getExe pkgs.step-cli} ssh certificate \ --host --sign \ --root "${rootCertPath}" \ --ca-url ${cfg.caURL} \ --provisioner "${cfg.provisioner}" \ --provisioner-password-file "${provisionerPasswordPath}" \ --principal "${cfg.hostname}" \ --principal "${cfg.hostname}.john-stream.com" \ "${cfg.hostname}" "${sshKeyPath}.pub" '') (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 ${lib.getExe pkgs.step-cli} 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"; }; }; }; }; }