WIP janus secrets
This commit is contained in:
@@ -17,6 +17,9 @@ Insert generated runtime CA material into `modules/hosts/janus/secrets.yaml` und
|
||||
- `/tmp/janus-step-ca-bootstrap/step/secrets/intermediate_ca_key` -> `intermediate_ca_key`
|
||||
- `/tmp/janus-step-ca-bootstrap/step/secrets/ssh_host_ca_key` -> `ssh_host_ca_key`
|
||||
- `/tmp/janus-step-ca-bootstrap/step/secrets/ssh_user_ca_key` -> `ssh_user_ca_key`
|
||||
- `/tmp/janus-step-ca-bootstrap/step/config/ca.json` -> `admin_provisioner_encrypted_key` (copy `authority.provisioners[].encryptedKey` for the `admin` JWK provisioner)
|
||||
|
||||
If you are only validating wiring first, `admin_provisioner_encrypted_key` can be an encrypted placeholder and replaced later.
|
||||
|
||||
If rotating provisioner password, also set:
|
||||
|
||||
@@ -24,7 +27,7 @@ If rotating provisioner password, also set:
|
||||
|
||||
Secret source-of-truth after this split:
|
||||
|
||||
- `modules/hosts/janus/secrets.yaml`: Janus runtime CA secrets only (`ca_password`, `intermediate_ca_crt`, `intermediate_ca_key`, `ssh_host_ca_key`, `ssh_user_ca_key`)
|
||||
- `modules/hosts/janus/secrets.yaml`: Janus runtime CA secrets (`ca_password`, `intermediate_ca_crt`, `intermediate_ca_key`, `ssh_host_ca_key`, `ssh_user_ca_key`, `admin_provisioner_encrypted_key`)
|
||||
- `keys/secrets.yaml`: shared Janus provisioner secret (`janus.admin_jwk`) consumed by `step-ssh-host` across hosts
|
||||
|
||||
Then update public artifacts in repo from generated output:
|
||||
|
||||
@@ -39,6 +39,7 @@ in
|
||||
intermediateKey = "janus/intermediate_ca_key";
|
||||
sshHostCaKey = "janus/ssh_host_ca_key";
|
||||
sshUserCaKey = "janus/ssh_user_ca_key";
|
||||
adminProvisionerEncryptedKey = "janus/admin_provisioner_encrypted_key";
|
||||
};
|
||||
};
|
||||
mtls = {
|
||||
|
||||
@@ -4,6 +4,7 @@ janus:
|
||||
intermediate_ca_key: ENC[AES256_GCM,data:wrzE8pgSZrtMA2jyLuVhMFxr47ICDBUkqOFyFJex9h3g,iv:I3Sz07e+cFDOUunCu7ZGcAjckRJDy3NmTXoB0vtA0HI=,tag:inANSVzyAzWlX4J5pheY8A==,type:str]
|
||||
ssh_host_ca_key: ENC[AES256_GCM,data:IT3PcnbrexRDvxoVEyyxYBx7+Brm3SzVP3Yr2UGkFjeH,iv:edfMiRR+EVx9veTH+mEAFtEdC/rlW8uU5jMD8UX2Ylo=,tag:KKS/2GQE8V6obbjfMLspug==,type:str]
|
||||
ssh_user_ca_key: ENC[AES256_GCM,data:w3gc97CYUODNxk0gIyghd9PCksDVvrdvl8j/NQe/tCtw,iv:WbWlVCPV7niVHEJ9sVcO9SAcLSfquE/bvcR5KClxszk=,tag:08uj+lv9MflYOtQh28K6pw==,type:str]
|
||||
admin_provisioner_encrypted_key: ENC[AES256_GCM,data:/EdlRiPn/LHpQk5sA9VVYTz/U4i6Ag==,iv:r6Rm38L1R4xsnyR97e3J2FdH4KWYewZdADosv9WLAXw=,tag:MnWq9lI7GAXN0FmGTa9zmQ==,type:str]
|
||||
sops:
|
||||
age:
|
||||
- enc: |
|
||||
@@ -24,7 +25,7 @@ sops:
|
||||
ZT3ScL4PAYhH+lxciJK4tit53taevbp5o0jFibaup4ByDvgj7HPclw==
|
||||
-----END AGE ENCRYPTED FILE-----
|
||||
recipient: age1gvplss0ddmyf6vpjy363wu3n057vhm0j6n7tc94cxd8kadapypws5mtaj0
|
||||
lastmodified: "2026-07-04T03:42:39Z"
|
||||
mac: ENC[AES256_GCM,data:qBuVJo9F5IiQGDqji0ZfNH6MYYLgaVuEoHGsvejw1ffFjYeqGI5LrZmez8xTx8dymQADCDYINZNYlKxgXaXdGqrlKaU8GzuWeF7M0Ad43+S/8DbP2OGPXERHAH+IWVjvzlurXs4tWE4ULw4PbsVpWqOBaSk603N7cuy7Ztwfk8M=,iv:lceVJAeZi8FwKo8DAET1hgUi54Bu+0kjWcGEZxs5wCA=,tag:mFkqan9BHtI6NkxqbjkIcQ==,type:str]
|
||||
lastmodified: "2026-07-04T04:20:22Z"
|
||||
mac: ENC[AES256_GCM,data:N0+lAFghaas9fg9PMcsaMPKJbYmnSrgPIFPsEuC749nzMX1IfQVaTLYm6ziZiq8TpscGR1tBqzw2eXiSZG4XfI44naEzO8CvY87aaZAL19/c/j4XE8eBqv1RLsLMbBIYYs8h6aZXCwhWUa3bwFukjueD0iu2X3md6V4T+4RnYSE=,iv:Xd/DCSDymp+KURHjM3Cht8oqbyN/k5+eybdi3pK5eww=,tag:tmDJoo5RKXQTnVjqkXsZ1w==,type:str]
|
||||
unencrypted_suffix: _unencrypted
|
||||
version: 3.13.1
|
||||
|
||||
@@ -1,129 +0,0 @@
|
||||
{
|
||||
"root": "/etc/step-ca/certs/root_ca.crt",
|
||||
"federatedRoots": null,
|
||||
"crt": "/etc/step-ca/certs/intermediate_ca.crt",
|
||||
"key": "/etc/step-ca/secrets/intermediate_ca_key",
|
||||
"address": ":443",
|
||||
"insecureAddress": "",
|
||||
"dnsNames": [
|
||||
"janus.john-stream.com",
|
||||
"192.168.1.113"
|
||||
],
|
||||
"ssh": {
|
||||
"hostKey": "/etc/step-ca/secrets/ssh_host_ca_key",
|
||||
"userKey": "/etc/step-ca/secrets/ssh_user_ca_key"
|
||||
},
|
||||
"logger": {
|
||||
"format": "text"
|
||||
},
|
||||
"db": {
|
||||
"type": "badgerv2",
|
||||
"dataSource": "/var/lib/step-ca/db",
|
||||
"badgerFileLoadingMode": ""
|
||||
},
|
||||
"authority": {
|
||||
"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": {}
|
||||
}
|
||||
}
|
||||
],
|
||||
"template": {},
|
||||
"backdate": "1m0s"
|
||||
},
|
||||
"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
|
||||
},
|
||||
"templates": {
|
||||
"ssh": {
|
||||
"user": [
|
||||
{
|
||||
"name": "config.tpl",
|
||||
"type": "snippet",
|
||||
"template": "templates/ssh/config.tpl",
|
||||
"path": "~/.ssh/config",
|
||||
"comment": "#"
|
||||
},
|
||||
{
|
||||
"name": "step_includes.tpl",
|
||||
"type": "prepend-line",
|
||||
"template": "templates/ssh/step_includes.tpl",
|
||||
"path": "${STEPPATH}/ssh/includes",
|
||||
"comment": "#"
|
||||
},
|
||||
{
|
||||
"name": "step_config.tpl",
|
||||
"type": "file",
|
||||
"template": "templates/ssh/step_config.tpl",
|
||||
"path": "ssh/config",
|
||||
"comment": "#"
|
||||
},
|
||||
{
|
||||
"name": "known_hosts.tpl",
|
||||
"type": "file",
|
||||
"template": "templates/ssh/known_hosts.tpl",
|
||||
"path": "ssh/known_hosts",
|
||||
"comment": "#"
|
||||
}
|
||||
],
|
||||
"host": [
|
||||
{
|
||||
"name": "sshd_config.tpl",
|
||||
"type": "snippet",
|
||||
"template": "templates/ssh/sshd_config.tpl",
|
||||
"path": "/etc/ssh/sshd_config",
|
||||
"comment": "#",
|
||||
"requires": [
|
||||
"Certificate",
|
||||
"Key"
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "ca.tpl",
|
||||
"type": "snippet",
|
||||
"template": "templates/ssh/ca.tpl",
|
||||
"path": "/etc/ssh/ca.pub",
|
||||
"comment": "#"
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
"commonName": "Step Online CA"
|
||||
}
|
||||
@@ -3,11 +3,83 @@
|
||||
flake.modules.nixos.step-ca = { config, pkgs, lib, ... }:
|
||||
let
|
||||
cfg = config.step-ca;
|
||||
caAddress = "0.0.0.0";
|
||||
caPort = 443;
|
||||
|
||||
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;
|
||||
adminProvisionerEncryptedKeyValue =
|
||||
(lib.getAttr cfg.secrets.adminProvisionerEncryptedKey config.sops.placeholder);
|
||||
|
||||
renderedStepCaConfig = builtins.toJSON {
|
||||
root = cfg.rootCertPath;
|
||||
crt = intermediateCrtPath;
|
||||
key = intermediateKeyPath;
|
||||
address = "${caAddress}:${toString caPort}";
|
||||
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 = adminProvisionerEncryptedKeyValue;
|
||||
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;
|
||||
};
|
||||
};
|
||||
in
|
||||
{
|
||||
options.step-ca = {
|
||||
@@ -44,6 +116,10 @@
|
||||
description = "SOPS key for the Step SSH user CA private key.";
|
||||
type = lib.types.str;
|
||||
};
|
||||
adminProvisionerEncryptedKey = lib.mkOption {
|
||||
description = "SOPS key for the Step CA admin provisioner encrypted key.";
|
||||
type = lib.types.str;
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
@@ -54,108 +130,66 @@
|
||||
owner = "step-ca";
|
||||
group = "step-ca";
|
||||
mode = "0400";
|
||||
restartUnits = [ "step-ca.service" ];
|
||||
};
|
||||
sops.secrets."${cfg.secrets.intermediateCrt}" = {
|
||||
sopsFile = cfg.secrets.sopsFile;
|
||||
owner = "step-ca";
|
||||
group = "step-ca";
|
||||
mode = "0400";
|
||||
restartUnits = [ "step-ca.service" ];
|
||||
};
|
||||
sops.secrets."${cfg.secrets.intermediateKey}" = {
|
||||
sopsFile = cfg.secrets.sopsFile;
|
||||
owner = "step-ca";
|
||||
group = "step-ca";
|
||||
mode = "0400";
|
||||
restartUnits = [ "step-ca.service" ];
|
||||
};
|
||||
sops.secrets."${cfg.secrets.sshHostCaKey}" = {
|
||||
sopsFile = cfg.secrets.sopsFile;
|
||||
owner = "step-ca";
|
||||
group = "step-ca";
|
||||
mode = "0400";
|
||||
restartUnits = [ "step-ca.service" ];
|
||||
};
|
||||
sops.secrets."${cfg.secrets.sshUserCaKey}" = {
|
||||
sopsFile = cfg.secrets.sopsFile;
|
||||
owner = "step-ca";
|
||||
group = "step-ca";
|
||||
mode = "0400";
|
||||
restartUnits = [ "step-ca.service" ];
|
||||
};
|
||||
sops.secrets."${cfg.secrets.adminProvisionerEncryptedKey}" = {
|
||||
sopsFile = cfg.secrets.sopsFile;
|
||||
owner = "step-ca";
|
||||
group = "step-ca";
|
||||
mode = "0400";
|
||||
restartUnits = [ "step-ca.service" ];
|
||||
};
|
||||
|
||||
sops.templates."step-ca-config" = {
|
||||
owner = "step-ca";
|
||||
group = "step-ca";
|
||||
mode = "0400";
|
||||
content = renderedStepCaConfig;
|
||||
};
|
||||
|
||||
# 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;
|
||||
address = caAddress;
|
||||
port = caPort;
|
||||
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;
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
# Keep modules/services/step-ca/ca.json as reference-only; runtime config comes from SOPS template.
|
||||
environment.etc."smallstep/ca.json".source =
|
||||
lib.mkForce config.sops.templates."step-ca-config".path;
|
||||
systemd.services.step-ca.restartTriggers =
|
||||
lib.mkAfter [ config.sops.templates."step-ca-config".path ];
|
||||
|
||||
environment.systemPackages = with pkgs; [
|
||||
step-ca
|
||||
step-cli
|
||||
|
||||
Reference in New Issue
Block a user