janus deployment

This commit is contained in:
John Lancaster
2026-07-04 23:19:35 -05:00
parent f2ba5d914c
commit b1f4b6ad41
5 changed files with 54 additions and 77 deletions
+2 -18
View File
@@ -5,8 +5,8 @@ Generate passwords:
mkdir -p /tmp/janus-step-ca-bootstrap && chmod 700 /tmp/janus-step-ca-bootstrap && cd /tmp/janus-step-ca-bootstrap && umask 077 && openssl rand -base64 48 > ca_password.txt && openssl rand -base64 48 > admin_jwk_password.txt
```
Generate the Janus OpenSSH host key that Nix will materialize from SOPS at
`/etc/ssh/ssh_host_ed25519_key`:
Generate the Janus OpenSSH host key for reference (Janus now uses whatever key
already exists on the target at `/etc/ssh/ssh_host_ed25519_key`):
```shell
ssh-keygen -t ed25519 -N '' -C [email protected] -f /tmp/janus-step-ca-bootstrap/ssh_host_ed25519_key
@@ -24,24 +24,9 @@ Insert generated runtime CA material into `modules/hosts/janus/secrets.yaml` und
- `/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)
- `/tmp/janus-step-ca-bootstrap/ssh_host_ed25519_key` -> `ssh_host_ed25519_key`
If you are only validating wiring first, `admin_provisioner_encrypted_key` can be an encrypted placeholder and replaced later.
The checked-in `ssh_host_ed25519_key` value is also only an encrypted placeholder.
Replace it before deploying Janus, otherwise OpenSSH and SSH host certificate
issuance will fail because the materialized host key is not a valid private key.
For multiline secret values, avoid putting private key contents in shell history.
One safe non-interactive pattern is to JSON-encode the file content and pass that
temporary JSON file to `sops set --value-file`:
```shell
jq -Rs . /tmp/janus-step-ca-bootstrap/ssh_host_ed25519_key > /tmp/janus-step-ca-bootstrap/ssh_host_ed25519_key.json
sops --config .sops.yaml set --value-file modules/hosts/janus/secrets.yaml '["janus"]["ssh_host_ed25519_key"]' /tmp/janus-step-ca-bootstrap/ssh_host_ed25519_key.json
rm -f /tmp/janus-step-ca-bootstrap/ssh_host_ed25519_key.json
```
If rotating provisioner password, also set:
- `/tmp/janus-step-ca-bootstrap/admin_jwk_password.txt` -> `janus.admin_jwk` in `keys/secrets.yaml`
@@ -49,7 +34,6 @@ If rotating provisioner password, also set:
Secret source-of-truth after this split:
- `modules/hosts/janus/secrets.yaml`: Janus runtime CA secrets (`ca_password`, `intermediate_ca_key`, `ssh_host_ca_key`, `ssh_user_ca_key`, `admin_provisioner_encrypted_key`)
- `modules/hosts/janus/secrets.yaml`: Janus OpenSSH host private key (`ssh_host_ed25519_key`) materialized to `/etc/ssh/ssh_host_ed25519_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:
+9 -16
View File
@@ -2,6 +2,8 @@
let
username = "john";
hostname = "janus";
ipv4 = "192.168.1.32";
ipv6 = "fded:fb16:653e:25da:be24:11ff:fe6b:4d57";
in
{
flake.nixosConfigurations."${hostname}" = inputs.nixpkgs.lib.nixosSystem {
@@ -22,27 +24,17 @@ in
"Step-CA" = "step-ca";
};
sops.defaultSopsFile = ./secrets.yaml;
sops.secrets."janus/ssh_host_ed25519_key" = {
sopsFile = ./secrets.yaml;
owner = "root";
group = "root";
mode = "0600";
path = "/etc/ssh/ssh_host_ed25519_key";
restartUnits = [ "sshd.socket" "step-ssh-host-renew.service" ];
};
step-ssh-host = {
hostname = hostname;
extraPrincipals = [
"192.168.1.244"
"fded:fb16:653e:25da:be24:11ff:fea0:753f"
];
extraPrincipals = [ ipv4 ipv6 ];
};
step-ca = {
rootCertPath = ./root_ca.crt;
intermediateCertPath = ./intermediate_ca.crt;
dnsNames = [
"${hostname}.john-stream.com"
"192.168.1.244"
ipv4
ipv6
];
secrets = {
sopsFile = ./secrets.yaml;
@@ -53,17 +45,18 @@ in
adminProvisionerEncryptedKey = "janus/admin_provisioner_encrypted_key";
};
};
step-client.caUrl = "https://${ipv4}/";
mtls = {
enable = true;
subject = hostname;
san = [
"${hostname}.john-stream.com"
"192.168.1.244"
ipv4
];
bootstrap = {
enable = true;
after = [ "network-online.target" "sops-nix.service" "step-ca.service" ];
wants = [ "network-online.target" "step-ca.service" ];
after = [ "sops-nix.service" "step-ca.service" ];
wants = [ "step-ca.service" ];
provisionerPasswordFile = config.sops.secrets."janus/admin_jwk".path;
};
};
+16 -16
View File
@@ -9,29 +9,29 @@ sops:
age:
- enc: |
-----BEGIN AGE ENCRYPTED FILE-----
YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBCdFNwM2JQSVlFZXpJZ0VQ
eDFYek1TMnNTM3lLbjh4SG56VDl6MGsvb1drCnpLbGZ1N2FwSmRacitFVDJxaFlD
Vk5XeCtxRGM0OGV2UFNwQmlFV1pLS1EKLS0tIHB5bm1iRG9WWmpjTlBKcWkwWktz
SWVQOVlJU3RBejdpaGpyTTAzVmh0MFkK6nLey1QwSw5J8WeDdUIjJo62pylqOKmP
+GANs3OQkRuwW2+nwG+LJR2pfUS6O6PDOz7ZWGKih90/Bk7EMtjOIQ==
YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBRZ1pQQW1rekYzUDFGcXBW
M2RHSXUvbCtvemtHYUljNmxXOCt4dEczYUU0CkdFWDRBYWRhQStYb1RtbEFmZVk4
bWxMTnhKVXlZWDRlcWZHWWhaSC9KMW8KLS0tIER6VWJGY28ramk2NDhZa0x5RU1s
YmU5S1FCVkJyNTNIVXhJSkdQVHYxMVkKEkbFmD4a7FWC8cKpZu2ZVot5ibheTQ1h
H6uqwAYT/UIXqnceyZyoT9JRcZyQy7xAUAJzQMe+TxUr+8iHAm7aBg==
-----END AGE ENCRYPTED FILE-----
recipient: age1n94nkvmzezdj08t4dpwukd7s5k4cx2rldwvx9x5qhx3xhqm48yhq6ejldt
recipient: age1qahhlzeanprtykym9jymk2t95uedr7cwx9sdshx46q2m6u66fucsqua8l3
- enc: |
-----BEGIN AGE ENCRYPTED FILE-----
YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSAyeE04L0RvYmlnaWpxUWhm
M01vQVc2bFdNZ2k4TjJBOWZDTlV1V2VkVGd3CnhseTlOZWtqbmpldXUrWnRxSWdR
dFFPTFZtSlZjZVdKMDdYQkVJeG5wZUUKLS0tIGxRbEE3ZjNrUTlLSDMrVVIzbnJ5
cEFnNmErTlhQMEtZM282STVRUGl0dVkKDyyTGVFDm6u+cdGu/PzFUFgj6ewCf0fi
vFhmYA8bTGNg6loThbYxm4uN1u+mJgwOKJ3FRR+u9yYEF6xvqrIbdw==
YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBqWjBiVDJSZFRQYis3dSt5
OFFMbGhyaHgxSDBjdnVMSlZ5d3B0eEhVM0VVCmw4TXk2a0s3ZDRCeHhEVFpGRkpl
b1lSQUJPL0hNRk50UEhHejNkL2VRd1EKLS0tICtXaWVMN0FSejNsNGNTOGh1WG13
aFJINlNKOVNhc3VBOU00VXYyMTRFdVkKV251o5CegRdDxvhpOJjK5ITp/+DVBE9o
R3eAsTXG5SSN50rcZYjwoEgYUeiRB4dQ/NYw6lVDUFrOf/a7sAr32g==
-----END AGE ENCRYPTED FILE-----
recipient: age1ykcs39e62pz3xu6cedg8ea685kv5d5qsrhgkndygzm8rx30xd5ys5t3qxt
- enc: |
-----BEGIN AGE ENCRYPTED FILE-----
YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBjeHQ4aDlSU2M2bzE1ODFY
Ym1NNEFFaVhrVlR0WUs1ZUVwTFVGN3QwMFZJCmdJWWFaeHByUlB2U3FLbEpwRkJI
ckRTNWx2dVl3Mi9ZNjhwUFNTdjZIaTAKLS0tIDZ0dFpCa2F3aFRCYmh2N3Nwb2dF
ZUJxakM3Wnc3U3JwTklPcllydXZBUXcKlf9C2/Gb9H9PdEKHdAd48dsalm43vYIz
ODYoLItstmJvT/rZ+XijZFALNsRrIj5435CW6V34OsfCkFkjeHz17w==
YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBYYjlQRGVmRnRGbjNNT3dC
cWJCWmtrM1BnbE80QnpTWXdHMytqSmFHOVhjCm9LYzd4R2s1TENIVkFYK3g4STRk
cGIxMS9RQ2Y1dmR6RjZYeVF5LzRoelkKLS0tIEdjaGk2WnNCRVA0S1dxRzJyWFc3
Yzh0MlFSZTR0Z0RhUnhHQzRSbFRXaUEK+5jadT4PMWPrljNcXVW3S1yJ1nI0iei8
htf09S2S5jraIFkl2x6Rv8IqOnKVPPgTZkvZqPMQoM4zcs+o1/lnug==
-----END AGE ENCRYPTED FILE-----
recipient: age1gvplss0ddmyf6vpjy363wu3n057vhm0j6n7tc94cxd8kadapypws5mtaj0
lastmodified: "2026-07-05T01:59:20Z"