diff --git a/flake.lock b/flake.lock index 2ec9ec8..1c0b5ac 100644 --- a/flake.lock +++ b/flake.lock @@ -2,11 +2,11 @@ "nodes": { "flake-file": { "locked": { - "lastModified": 1772999280, - "narHash": "sha256-XX60YlqSKa/QNIJVnLeEXNDQPwrQucMuITef6rEJqIs=", + "lastModified": 1773554778, + "narHash": "sha256-keH0VNsci9e0Uwt3Msp/N+pltaP8Lb6lt09Q3WvDPw4=", "owner": "vic", "repo": "flake-file", - "rev": "e2a19eb539fa7be4537f6e73e7556edf031eed7f", + "rev": "f4780a86bd4c756475d839b286f8a40aabdbc802", "type": "github" }, "original": { @@ -76,11 +76,11 @@ "nixpkgs": "nixpkgs" }, "locked": { - "lastModified": 1772985285, - "narHash": "sha256-wEEmvfqJcl9J0wyMgMrj1TixOgInBW/6tLPhWGoZE3s=", + "lastModified": 1773597207, + "narHash": "sha256-ZHoQqj+prlvfMItkQ/xTZbPguEcRlNPyRzh2j/51z8E=", "owner": "nix-community", "repo": "home-manager", - "rev": "5be5d8245cbc7bc0c09fbb5f38f23f223c543f85", + "rev": "585a161ea6d1ec78e0daee9f1b40f8539d53d4a3", "type": "github" }, "original": { @@ -91,11 +91,11 @@ }, "import-tree": { "locked": { - "lastModified": 1772999353, - "narHash": "sha256-dPb0WxUhFaz6wuR3B6ysqFJpsu8txKDPZvS47AT2XLI=", + "lastModified": 1773554199, + "narHash": "sha256-6apV5N1F5tTD8JY9AUGnkWmy56HqDPn4MNFRsq4Rg+s=", "owner": "vic", "repo": "import-tree", - "rev": "545a4df146fce44d155573e47f5a777985acf912", + "rev": "c6ebc59c85ee54cfb68163d06d1a3149ce0fe431", "type": "github" }, "original": { @@ -127,11 +127,11 @@ }, "nixpkgs": { "locked": { - "lastModified": 1772773019, - "narHash": "sha256-E1bxHxNKfDoQUuvriG71+f+s/NT0qWkImXsYZNFFfCs=", + "lastModified": 1773389992, + "narHash": "sha256-wvfdLLWJ2I9oEpDd9PfMA8osfIZicoQ5MT1jIwNs9Tk=", "owner": "NixOS", "repo": "nixpkgs", - "rev": "aca4d95fce4914b3892661bcb80b8087293536c6", + "rev": "c06b4ae3d6599a672a6210b7021d699c351eebda", "type": "github" }, "original": { @@ -143,11 +143,11 @@ }, "nixpkgs_2": { "locked": { - "lastModified": 1772771118, - "narHash": "sha256-SDEGkbscgwFhxzfvNdDNcvsA82gAQcyOh0/BZOb6fWg=", - "rev": "e38213b91d3786389a446dfce4ff5a8aaf6012f2", + "lastModified": 1773507054, + "narHash": "sha256-yzDBkI1CpeZrAt4l1nGvTOs3OFtXCS7a7Gi5Y1h878w=", + "rev": "e80236013dc8b77aa49ca90e7a12d86f5d8d64c9", "type": "tarball", - "url": "https://releases.nixos.org/nixpkgs/nixpkgs-26.05pre958959.e38213b91d37/nixexprs.tar.xz" + "url": "https://releases.nixos.org/nixpkgs/nixpkgs-26.05pre963414.e80236013dc8/nixexprs.tar.xz" }, "original": { "type": "tarball", @@ -190,11 +190,11 @@ ] }, "locked": { - "lastModified": 1772944399, - "narHash": "sha256-xTzsSd3r5HBeufSZ3fszAn0ldfKctvsYG7tT2YJg5gY=", + "lastModified": 1773550941, + "narHash": "sha256-wa/++bL2QeMUreNFBZEWluQfOYB0MnQIeGNMuaX9sfs=", "owner": "Mic92", "repo": "sops-nix", - "rev": "c8e69670b316d6788e435a3aa0bda74eb1b82cc0", + "rev": "c469b6885f0dcd5c7c56bd935a0f08dbcd9e79e1", "type": "github" }, "original": { diff --git a/modules/programs/step-client.nix b/modules/programs/step-client.nix index 548ceac..c28f3b6 100644 --- a/modules/programs/step-client.nix +++ b/modules/programs/step-client.nix @@ -4,116 +4,6 @@ let stepFingerprint = "2036c44f7b5901566ff7611ea6c927291ecc6d2dd00779c0eead70ec77fa10d6"; in { - # - # NixOS Module - # - flake.modules.nixos.step-ssh-host = { config, pkgs, lib, ... }: - let - cfg = config.step-ssh-host; - stepBin = lib.getExe pkgs.step-cli; - 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 { - type = lib.types.str; - }; - caURL = lib.mkOption { - type = lib.types.str; - default = "${caURL}"; - }; - rootCertFile = lib.mkOption { - type = lib.types.path; - description = "Public Step root CA certificate file from the repo."; - default = ../../keys/root_ca.crt; - }; - sshHostProvisioner = lib.mkOption { - 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."step/certs/root_ca.crt".source = cfg.rootCertFile; - 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.sshHostProvisioner}" \ - --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 ${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"; - }; - }; - }; - }; - # # Home Manager Module # diff --git a/modules/services/step-ca/ssh-host.nix b/modules/services/step-ca/ssh-host.nix new file mode 100644 index 0000000..a29ee37 --- /dev/null +++ b/modules/services/step-ca/ssh-host.nix @@ -0,0 +1,112 @@ +{ 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 { + type = lib.types.str; + }; + caURL = lib.mkOption { + type = lib.types.str; + default = "${caURL}"; + }; + rootCertFile = lib.mkOption { + type = lib.types.path; + description = "Public Step root CA certificate file from the repo."; + default = ../../../keys/root_ca.crt; + }; + sshHostProvisioner = lib.mkOption { + 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."step/certs/root_ca.crt".source = cfg.rootCertFile; + 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.sshHostProvisioner}" \ + --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"; + }; + }; + }; + }; +} \ No newline at end of file