From 35fec024e08cfa9b1eff06dfce2e9ea56342f04a Mon Sep 17 00:00:00 2001 From: John Lancaster <32917998+jsl12@users.noreply.github.com> Date: Fri, 3 Jul 2026 23:06:06 -0500 Subject: [PATCH] created config options for step-ca --- modules/hosts/janus/default.nix | 15 ++ modules/services/step-ca/step-ca.nix | 267 +++++++++++++++------------ 2 files changed, 166 insertions(+), 116 deletions(-) diff --git a/modules/hosts/janus/default.nix b/modules/hosts/janus/default.nix index e2a7a0f..64dff35 100644 --- a/modules/hosts/janus/default.nix +++ b/modules/hosts/janus/default.nix @@ -26,6 +26,21 @@ in "fded:fb16:653e:25da:be24:11ff:fea0:753f" ]; }; + step-ca = { + rootCertPath = ./root_ca.crt; + dnsNames = [ + "${hostname}.john-stream.com" + "192.168.1.244" + ]; + secrets = { + sopsFile = ./secrets.yaml; + caPassword = "janus/ca_password"; + intermediateCrt = "janus/intermediate_ca_crt"; + intermediateKey = "janus/intermediate_ca_key"; + sshHostCaKey = "janus/ssh_host_ca_key"; + sshUserCaKey = "janus/ssh_user_ca_key"; + }; + }; mtls = { enable = true; subject = hostname; diff --git a/modules/services/step-ca/step-ca.nix b/modules/services/step-ca/step-ca.nix index 931a361..8a0eb4a 100644 --- a/modules/services/step-ca/step-ca.nix +++ b/modules/services/step-ca/step-ca.nix @@ -1,130 +1,165 @@ { inputs, ... }: { - flake.modules.nixos.step-ca = { config, pkgs, ... }: + flake.modules.nixos.step-ca = { config, pkgs, lib, ... }: let - # Keep host-specific trust anchor in repo; secret/private keys come from sops. - rootCertPath = ../../hosts/janus/root_ca.crt; - caPasswordPath = config.sops.secrets."janus/ca_password".path; - intermediateCrtPath = config.sops.secrets."janus/intermediate_ca_crt".path; - intermediateKeyPath = config.sops.secrets."janus/intermediate_ca_key".path; - sshHostCaKeyPath = config.sops.secrets."janus/ssh_host_ca_key".path; - sshUserCaKeyPath = config.sops.secrets."janus/ssh_user_ca_key".path; + cfg = config.step-ca; + caPasswordPath = (lib.getAttr cfg.secrets.caPassword config.sops.secrets).path; + intermediateCrtPath = (lib.getAttr cfg.secrets.intermediateCrt config.sops.secrets).path; + intermediateKeyPath = (lib.getAttr cfg.secrets.intermediateKey config.sops.secrets).path; + sshHostCaKeyPath = (lib.getAttr cfg.secrets.sshHostCaKey config.sops.secrets).path; + sshUserCaKeyPath = (lib.getAttr cfg.secrets.sshUserCaKey config.sops.secrets).path; in { - # Placeholders are expected initially until real material is inserted into sops. - sops.secrets."janus/ca_password" = { - sopsFile = ../../hosts/janus/secrets.yaml; - owner = "step-ca"; - group = "step-ca"; - mode = "0400"; - }; - sops.secrets."janus/intermediate_ca_crt" = { - sopsFile = ../../hosts/janus/secrets.yaml; - owner = "step-ca"; - group = "step-ca"; - mode = "0400"; - }; - sops.secrets."janus/intermediate_ca_key" = { - sopsFile = ../../hosts/janus/secrets.yaml; - owner = "step-ca"; - group = "step-ca"; - mode = "0400"; - }; - sops.secrets."janus/ssh_host_ca_key" = { - sopsFile = ../../hosts/janus/secrets.yaml; - owner = "step-ca"; - group = "step-ca"; - mode = "0400"; - }; - sops.secrets."janus/ssh_user_ca_key" = { - sopsFile = ../../hosts/janus/secrets.yaml; - owner = "step-ca"; - group = "step-ca"; - mode = "0400"; - }; - - # https://github.com/NixOS/nixpkgs/blob/nixos-23.05/nixos/modules/services/security/step-ca.nix - services.step-ca = { - enable = true; - openFirewall = true; - address = "0.0.0.0"; - port = 443; - intermediatePasswordFile = caPasswordPath; - - # https://smallstep.com/docs/step-ca/configuration/#configuration-options - settings = { - root = rootCertPath; - crt = intermediateCrtPath; - key = intermediateKeyPath; - dnsNames = [ - "janus.john-stream.com" - "192.168.1.244" - ]; - - ssh = { - hostKey = sshHostCaKeyPath; - userKey = sshUserCaKeyPath; + options.step-ca = { + rootCertPath = lib.mkOption { + description = "Path to the Step CA root certificate served by this host."; + type = lib.types.path; + }; + dnsNames = lib.mkOption { + description = "DNS names and IP SANs advertised by this Step CA instance."; + type = with lib.types; listOf str; + }; + secrets = { + sopsFile = lib.mkOption { + description = "Host-local SOPS file that stores Step CA secret material."; + type = lib.types.path; }; - - db = { - type = "badgerv2"; - dataSource = "/var/lib/step-ca/db"; + caPassword = lib.mkOption { + description = "SOPS key for the Step CA intermediate password."; + type = lib.types.str; }; - - authority = { - backdate = "1m0s"; - provisioners = [ - { - type = "ACME"; - name = "acme"; - } - { - type = "SSHPOP"; - name = "sshpop"; - claims.enableSSHCA = true; - } - { - type = "JWK"; - name = "admin"; - key = { - use = "sig"; - kty = "EC"; - kid = "xoxgOJFbveSLIL2gm1Yu5ZiRb9v8Jxe44F56i3v-Nf8"; - crv = "P-256"; - alg = "ES256"; - x = "zFO8hPx_eH0Iyz7UJI-w8ODMusEKCZ28M76sGWmWYxA"; - y = "XIWLLyKDzqxV9UH-2KeAkKPDrgLoPrxxW9-PzkXggME"; - }; - encryptedKey = "eyJhbGciOiJQQkVTMi1IUzI1NitBMTI4S1ciLCJjdHkiOiJqd2sranNvbiIsImVuYyI6IkEyNTZHQ00iLCJwMmMiOjYwMDAwMCwicDJzIjoiUVJnTnJVTF9KcmxJYkJMVTlGNVRPZyJ9.DMu7xBNCq5pr-_--YTxNr5Hrcqy6ZmSVHsWurfVXL7Hk0Q3vyYRxiw.h-CnFiYc-DhxThI3.plx3_Qa_0kU-2TwnqFNfAfGnCpfQ2e0iiCMLruNHbLMnHeXQ1BysHBqps45_02zZXIRdHoDgYGtXRSfcdUYYoS0pLoPzC6m301ZFNSAFdRVlSZ3Q6VmWdixPXXnEB4EgSKTT_wxR33L8t9OpFzD85KfY-b_Un1l99ufjCnfg-EYkcICTn_G4-8bcW3eFIvJ6setzu-l0jHMhLQdIweqncn9on9xBXBD-ANhZfP95P2BJt-APqCi8eqiAvn_vClovdg0PxzRwOVDvWREz66FDw-HTU7xDtGO9hACopT5tfZOXDoykgZw1mJsq9NEq9ZzvKG2hvyk1UXtExxrNtFo.5q1OfGU4Amo4Si-vpeI42g"; - claims = { - enableSSHCA = true; - disableRenewal = false; - allowRenewalAfterExpiry = false; - disableSmallstepExtensions = false; - }; - options = { - x509 = { }; - ssh = { }; - }; - } - ]; + intermediateCrt = lib.mkOption { + description = "SOPS key for the Step CA intermediate certificate."; + type = lib.types.str; }; - - tls = { - cipherSuites = [ - "TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256" - "TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256" - ]; - minVersion = 1.2; - maxVersion = 1.3; - renegotiation = false; + intermediateKey = lib.mkOption { + description = "SOPS key for the Step CA intermediate private key."; + type = lib.types.str; + }; + sshHostCaKey = lib.mkOption { + description = "SOPS key for the Step SSH host CA private key."; + type = lib.types.str; + }; + sshUserCaKey = lib.mkOption { + description = "SOPS key for the Step SSH user CA private key."; + type = lib.types.str; }; }; }; - environment.systemPackages = with pkgs; [ - step-ca - step-cli - ]; + config = { + # Placeholders are expected initially until real material is inserted into sops. + sops.secrets."${cfg.secrets.caPassword}" = { + sopsFile = cfg.secrets.sopsFile; + owner = "step-ca"; + group = "step-ca"; + mode = "0400"; + }; + sops.secrets."${cfg.secrets.intermediateCrt}" = { + sopsFile = cfg.secrets.sopsFile; + owner = "step-ca"; + group = "step-ca"; + mode = "0400"; + }; + sops.secrets."${cfg.secrets.intermediateKey}" = { + sopsFile = cfg.secrets.sopsFile; + owner = "step-ca"; + group = "step-ca"; + mode = "0400"; + }; + sops.secrets."${cfg.secrets.sshHostCaKey}" = { + sopsFile = cfg.secrets.sopsFile; + owner = "step-ca"; + group = "step-ca"; + mode = "0400"; + }; + sops.secrets."${cfg.secrets.sshUserCaKey}" = { + sopsFile = cfg.secrets.sopsFile; + owner = "step-ca"; + group = "step-ca"; + mode = "0400"; + }; + + # https://github.com/NixOS/nixpkgs/blob/nixos-23.05/nixos/modules/services/security/step-ca.nix + services.step-ca = { + enable = true; + openFirewall = true; + address = "0.0.0.0"; + port = 443; + intermediatePasswordFile = caPasswordPath; + + # https://smallstep.com/docs/step-ca/configuration/#configuration-options + settings = { + root = cfg.rootCertPath; + crt = intermediateCrtPath; + key = intermediateKeyPath; + dnsNames = cfg.dnsNames; + + ssh = { + hostKey = sshHostCaKeyPath; + userKey = sshUserCaKeyPath; + }; + + db = { + type = "badgerv2"; + dataSource = "/var/lib/step-ca/db"; + }; + + authority = { + backdate = "1m0s"; + provisioners = [ + { + type = "ACME"; + name = "acme"; + } + { + type = "SSHPOP"; + name = "sshpop"; + claims.enableSSHCA = true; + } + { + type = "JWK"; + name = "admin"; + key = { + use = "sig"; + kty = "EC"; + kid = "xoxgOJFbveSLIL2gm1Yu5ZiRb9v8Jxe44F56i3v-Nf8"; + crv = "P-256"; + alg = "ES256"; + x = "zFO8hPx_eH0Iyz7UJI-w8ODMusEKCZ28M76sGWmWYxA"; + y = "XIWLLyKDzqxV9UH-2KeAkKPDrgLoPrxxW9-PzkXggME"; + }; + encryptedKey = "eyJhbGciOiJQQkVTMi1IUzI1NitBMTI4S1ciLCJjdHkiOiJqd2sranNvbiIsImVuYyI6IkEyNTZHQ00iLCJwMmMiOjYwMDAwMCwicDJzIjoiUVJnTnJVTF9KcmxJYkJMVTlGNVRPZyJ9.DMu7xBNCq5pr-_--YTxNr5Hrcqy6ZmSVHsWurfVXL7Hk0Q3vyYRxiw.h-CnFiYc-DhxThI3.plx3_Qa_0kU-2TwnqFNfAfGnCpfQ2e0iiCMLruNHbLMnHeXQ1BysHBqps45_02zZXIRdHoDgYGtXRSfcdUYYoS0pLoPzC6m301ZFNSAFdRVlSZ3Q6VmWdixPXXnEB4EgSKTT_wxR33L8t9OpFzD85KfY-b_Un1l99ufjCnfg-EYkcICTn_G4-8bcW3eFIvJ6setzu-l0jHMhLQdIweqncn9on9xBXBD-ANhZfP95P2BJt-APqCi8eqiAvn_vClovdg0PxzRwOVDvWREz66FDw-HTU7xDtGO9hACopT5tfZOXDoykgZw1mJsq9NEq9ZzvKG2hvyk1UXtExxrNtFo.5q1OfGU4Amo4Si-vpeI42g"; + claims = { + enableSSHCA = true; + disableRenewal = false; + allowRenewalAfterExpiry = false; + disableSmallstepExtensions = false; + }; + options = { + x509 = { }; + ssh = { }; + }; + } + ]; + }; + + tls = { + cipherSuites = [ + "TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256" + "TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256" + ]; + minVersion = 1.2; + maxVersion = 1.3; + renegotiation = false; + }; + }; + }; + + environment.systemPackages = with pkgs; [ + step-ca + step-cli + ]; + }; }; } \ No newline at end of file