diff --git a/keys/root_ca.crt b/keys/root_ca.crt new file mode 100644 index 0000000..b289fb1 --- /dev/null +++ b/keys/root_ca.crt @@ -0,0 +1,11 @@ +-----BEGIN CERTIFICATE----- +MIIBlDCCATqgAwIBAgIRAKDvqOX8WVhJ/ev02Y1gXKQwCgYIKoZIzj0EAwIwKDEO +MAwGA1UEChMFSmFudXMxFjAUBgNVBAMTDUphbnVzIFJvb3QgQ0EwHhcNMjUxMjE4 +MDYwMjI4WhcNMzUxMjE2MDYwMjI4WjAoMQ4wDAYDVQQKEwVKYW51czEWMBQGA1UE +AxMNSmFudXMgUm9vdCBDQTBZMBMGByqGSM49AgEGCCqGSM49AwEHA0IABMt6kNpx +Q9vySc1N6F9jJObeQXZI+9f33E1cN4zbEuNpmtpRl0WaPa1AGNbSi5sIbiH7wDv2 +llXfCqYWkeoCE5mjRTBDMA4GA1UdDwEB/wQEAwIBBjASBgNVHRMBAf8ECDAGAQH/ +AgEBMB0GA1UdDgQWBBRo55byyyo2sePP+8zz+uM4mXNV+zAKBggqhkjOPQQDAgNI +ADBFAiB6zxTbvWMZWgDQhKGh+MnGQQ7f8UGhzinOfRG7a/HdOAIhAIVWt6MLl6QU +FOvl/qIFGd7YJeWU5aahPABVttxjSMn/ +-----END CERTIFICATE----- diff --git a/keys/secrets.yaml b/keys/secrets.yaml index b802784..3343e71 100644 --- a/keys/secrets.yaml +++ b/keys/secrets.yaml @@ -1,5 +1,6 @@ janus: fingerprint: ENC[AES256_GCM,data:A0eNE3nX8hVq8m4bNFvkTGR15Xh9QV44JpOJFyhZojPOTirRGEq/MCSNIqpKfoFUB4TXdRZIN95pAoNlO7Z2dQ==,iv:3TQ9ZcjRmnQzkNA5Cv/cpEIT8gTJ1w3cTjTVtxtuzq4=,tag:hIwcjdZ6R8UzUgh/VoDz3A==,type:str] + admin_jwk: ENC[AES256_GCM,data:HhsnsCsR87ItjEKP3MsHpxb/WZHvxRrMIhbBgW7qq/0=,iv:b5MKd5TFkxFjd1zY0Lfi2QDv4sLmyKn7riW8s/EfDeA=,tag:GkGfyAM2RtKzuo567bAjiA==,type:str] test-nix: ssh_host_key: ENC[AES256_GCM,data:04CRKNCycc8Dre44ERtytmX6NHdZOIds95ckYzmi/i74qEYyN/L5XsuKKmjH2WCn3brvK4pZLLIZWzxC5VJ85q+O8Tfd3qdFROTG5qYRvmK5huxphPaIWSUI2ZEdLqecpRtmq7Zeq+Xa2+JKC0ehg2sqavotkPM5vIeVsaStD5rMVSgnuGaTS3WuPPfEjJPfsCyGPup4ysgxKxfc3JXOR+T8t6w4ccG0Si6tGz6io0Sl9tgPzrYqwqTaMtWLUA50luJg+D8ZxpMjpqFNbIry2tKwettzwXtGz7xGYnjvuk+1sCdYl8PXOMRT2KwAy5usCJsWFRTXJzZ5kxzwAYLwmhlsfPuxwTrR5fRETJPglRP/1muq8piIZn6yHtq9dCSrNcDCZnjnjG+cby28yPLYKhDgVNF5DObob8e6Fp/nP00sdi4Bt1aHRR5pjK/9mpsWE6ikO83SUi4xSoL1LKZM2kC5DL8XBJP7nWQTwijp84m3htMKvrKfFo68G9xP4v/DhVcHLsoNGLytH5omAuGL,iv:0cAtrXlPBis8nYw1XT4kSPRuwVkq0XSh6jjY9mpewIA=,tag:WFsiOe/l8cVicOqX2C94xA==,type:str] restic_password: @@ -35,7 +36,7 @@ sops: Z1orRCtkTDVXSktuck5pTmV4K05qZHMKZlHHu07q+GnyDDgdwW2Ic3P23PmoSPwn WuNLZdlZQleROaRb+zpD+9P1HGGJ3mWAlNlnmjGrRk453k1PbBQ5Og== -----END AGE ENCRYPTED FILE----- - lastmodified: "2026-03-14T17:37:49Z" - mac: ENC[AES256_GCM,data:wONHhXL78AnuoH8SMxTbkFTaStiHvJsNHU6srp6OvqG5zVfHu3nYrJjPEZj3QJweZ4xP9KuYtQS5WX/vqFX6bhMB4NUSkvI+jzDESZoEt/Ulto3yoFwovqxSZqB4deSPCQDDmDetSXBQEcVAc4Rf8Om/uKbn2iIdEWP89BPCNTs=,iv:n4sSiWICXLyWJSoB7eG73Xpa2ClCg8kQrBtpF6QGJwQ=,tag:4aOjzbl4iIqG/0aXlCbhUQ==,type:str] + lastmodified: "2026-03-15T15:06:29Z" + mac: ENC[AES256_GCM,data:cF/TJ8VkzrHRUrO5iGdRdlFtqV/5EQ15JwQKIywJvsh0NERK67T21czSP7923MiL0u5QTVPn/rO8R5E/8gBu3r8+fLq+CFl9PDQHEX2JhnYOD5WZR412WMZq3MVR94IMTOrQANMVpS4uhMyvnrqOe4AenxLDyzrYhkwf1KQh4w0=,iv:Qwy8z4uXGMlf+kTMNiE42M9l8LtSJ+O7diknRrsSeYI=,tag:qlCY9r8HnEDmq/jw59C/sg==,type:str] unencrypted_suffix: _unencrypted version: 3.12.1 diff --git a/modules/hosts/janus.nix b/modules/hosts/janus.nix index c63fdb4..f9ac553 100644 --- a/modules/hosts/janus.nix +++ b/modules/hosts/janus.nix @@ -14,7 +14,7 @@ in nixos.zsh nixos.docker { - + step-client.hostname = hostname; home-manager.users."${username}" = { imports = with inputs.self.modules.homeManager; [ diff --git a/modules/programs/step-client.nix b/modules/programs/step-client.nix index b073830..1cb83c3 100644 --- a/modules/programs/step-client.nix +++ b/modules/programs/step-client.nix @@ -12,13 +12,29 @@ in cfg = config.step-client; stepBin = lib.getExe pkgs.step-cli; rootCertPath = "/etc/step/certs/root_ca.crt"; - provisionerPasswordPath = config.sops.secrets."step/provisioner_password".path; + provisionerPasswordPath = config.sops.secrets."janus/admin_jwk".path; sshKeyPath = "/etc/ssh/ssh_host_ed25519_key"; - sshCertPath = "/etc/ssh/ssh_host_ed25519_key-cert.pub"; + sshCertPath = "${sshKeyPath}-cert.pub"; in { # NixOS Options options.step-client = { + 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"; + }; + hostname = lib.mkOption { + type = lib.types.str; + }; }; imports = with inputs.self.modules.nixos; [ ssh ]; @@ -28,15 +44,32 @@ in home-manager.sharedModules = with inputs.self.modules; [ homeManager.step-client ]; - sops.secrets."janus/fingerprint" = { }; + + sops.secrets."janus/admin_jwk" = { + owner = "root"; + group = "root"; + mode = "0400"; + }; + + environment.etc."step/certs/root_ca.crt".source = cfg.rootCertFile; + environment.systemPackages = with pkgs; [ - (writeShellScriptBin "step-bootstrap" '' - set -euo pipefail - step ca bootstrap --ca-url ${caURL} --fingerprint ${stepFingerprint} + 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" '') ]; networking.nameservers = [ "192.168.1.150" ]; networking.dhcpcd.extraConfig = "nohook resolv.conf"; + }; }; @@ -49,8 +82,8 @@ in in { options.step-client = { - enable = lib.mkEnableOption "opionated step client config"; - caUrl = lib.mkOption { + enable = lib.mkEnableOption "opionated step client config for SSH certs"; + caURL = lib.mkOption { type = lib.types.str; default = "${caURL}"; }; @@ -58,12 +91,25 @@ in type = lib.types.str; default = "${stepFingerprint}"; }; + rootCertFile = { + path = lib.mkOption { + type = lib.types.str; + description = "Path to where the root_ca.crt file will be stored for the user"; + default = "${config.home.homeDirectory}/.step/certs/root_ca.crt"; + }; + source = lib.mkOption { + type = lib.types.path; + description = "Nix path to the root cert file within the repo"; + default = ../../keys/root_ca.crt; + }; + }; }; - config = { + config = lib.mkIf cfg.enable { + home.file.".step/certs/root_ca.crt".source = cfg.rootCertFile; home.file.".step/config/defaults.json".text = builtins.toJSON { - "ca-url" = cfg.caUrl; + "ca-url" = cfg.caURL; fingerprint = cfg.fingerprint; - root = "${config.home.homeDirectory}/.step/certs/root_ca.crt"; + root = "${cfg.rootCertFile.path}"; }; }; };