WIP with placeholder secrets

This commit is contained in:
John Lancaster
2026-07-03 22:46:49 -05:00
parent cf418ca7a0
commit 6499ad7612
12 changed files with 370 additions and 102 deletions
+12
View File
@@ -4,6 +4,18 @@ keys:
- &test-nix age1gvplss0ddmyf6vpjy363wu3n057vhm0j6n7tc94cxd8kadapypws5mtaj0
- &soteria age1h0prahyukq4l564yqwgcpg3g6gdrjflk0suklussjjrjstxd9uesws8633
creation_rules:
- path_regex: modules/hosts/janus/secrets\.yaml$
key_groups:
- age:
- *john-pc
- *test-nix
- path_regex: keys/secrets\.yaml$
key_groups:
- age:
- *john-p14s
- *john-pc
- *test-nix
- *soteria
- path_regex: soteria/secrets\.yaml$
key_groups:
- age:
+30 -21
View File
@@ -9,33 +9,42 @@ api:
gmail_client_secret: ENC[AES256_GCM,data:du2gEY5TQIwpUEvJKDWKY3noLRGeiKek4IMwPUusVx8NMys=,iv:hIYi1xQYf6+hDhK0pNprBYu6wXwRH2yOTwQg6pzQa0A=,tag:sqmQ5GCkKbHpIy2R+Y5G/A==,type:str]
sops:
age:
- recipient: age1f6drjusg866yscj8029tk4yfpgecklrvezldm02ankm6h8nnwu5s2u6ahy
enc: |
- enc: |
-----BEGIN AGE ENCRYPTED FILE-----
YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSB0UEpja2kxdThZVWZhOGVP
S0NtSi84MjhnN0RORkh2NjZ4YlYvWS9kZDBNClFzYnVxWnhmQkpCRkRFVUx1RDdX
ZHFqYXRqYXM0cWJzcU5EeEtSR1BUVzAKLS0tIDdEY2pnVTJqWlNZVkZldXVYVmFH
dVNBRUVodU5sRnpVcG1GZ1RiZzhjTXMKefqBvvD/qZwcSHmFjUnleukVRLueG36Y
Q81KlwQweF2F8kHl7Bqsi+3hH1dZZbVm3vjuGpWFOoti7fowUV55Kw==
YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBhbmduOWR1ZloxWjRjTjFp
ZFpvUFA2cStzYllUa1BhSmJBYWVUSmNGblZ3Cmw3TnVBSGtwaDV4ZlRRT2h6OWw0
bGd6dUQ2eE1QVWNTTitSSG80NVhraU0KLS0tIHRVMXFFRGh5cjlwNXpIb0F4TnF3
Ykplcm1DWm04RExHYnRjQjdCOVhLaE0K/VGQ/58QWOAWPToQt22W4iBX7rrh/lxL
Via5/T25c64Eh6FXzar+z9zdHjS4s7PLsf6iJIY84xpKCpSAkcaquw==
-----END AGE ENCRYPTED FILE-----
- recipient: age1ykcs39e62pz3xu6cedg8ea685kv5d5qsrhgkndygzm8rx30xd5ys5t3qxt
enc: |
recipient: age1f6drjusg866yscj8029tk4yfpgecklrvezldm02ankm6h8nnwu5s2u6ahy
- enc: |
-----BEGIN AGE ENCRYPTED FILE-----
YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBqZFZxbDhVUWFEUGhPMlZI
SFdBYkpxSnAxTUZXbjVwQnlZQ3l1SWtuZGg0CmVBdnVHbTNUcmwvK01iMnZKZTJh
ajFla3kzYUl4ZWY3czA0WUdNM2lpVFUKLS0tIHo5Uk1pV296MXdnUTZGQ25haWZG
QWZDWGRaRDBhY1ZkZk5oTHY0ZVV2RXMKanv+WWRhf5nl+aw/T6QZFVQQmhV1DZfB
jkSzOAKOgPx7toYFmpq9E8fAH+zrMzDbxI2z2uyrOFI6v+QE0Ul/iQ==
YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBkdEVYYzR2M1hDSmR6aVZO
WCtBUTBVUU96SitsTFlBT2IzQjk2Q21LV2tvCkRxVEVESVFsWlczdU5CT2V1a0cw
MUxXNFJFa1BvRFdGbVpkdDRTYVhROUkKLS0tIHBMaGFTRmgrYnkraGt3YkRCMXhw
Rk9GMUhXcWhYL3NXdmRZN0FtQjR2bU0Kql1oAOuJDJ2jcR+WcibBiFiVcMEBbXVS
cxydfdl3/la1tqiMd6rnDh/iB5hwjeeULwrgE/5Qjc7w23hMN9AF1g==
-----END AGE ENCRYPTED FILE-----
- recipient: age1gvplss0ddmyf6vpjy363wu3n057vhm0j6n7tc94cxd8kadapypws5mtaj0
enc: |
recipient: age1ykcs39e62pz3xu6cedg8ea685kv5d5qsrhgkndygzm8rx30xd5ys5t3qxt
- enc: |
-----BEGIN AGE ENCRYPTED FILE-----
YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBZcGtMNi9RSG5aTVV5cWdT
NittUXN0Qnpld1YvOU50OUh3Z3ZiSzhHOHdNCnc4TmdYbS9QQnBLbldHSytIdkJl
R0psQWxkZTgyZTRzckkrTGpyNCsvR2sKLS0tIEdLb05aT2I2S3BKcFRrVmtvTGw5
Z1orRCtkTDVXSktuck5pTmV4K05qZHMKZlHHu07q+GnyDDgdwW2Ic3P23PmoSPwn
WuNLZdlZQleROaRb+zpD+9P1HGGJ3mWAlNlnmjGrRk453k1PbBQ5Og==
YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSArTnc1ZEorSDlZSW1qY3Zu
NExrYXgyQjRIQUNRYlFXZCt4bXcxRndzWW40CjNCM3p0VDcwbENoTGxFNGZRR3lM
R0pnSlluTUpiNk91d0hlci9sOUtBYjQKLS0tIGp2eWpReExSNTdCS0RBQ1F5dDNt
eWhuak00dTFZV0k1WEREQkRPWUFmc00KQ13ormwGmzwPxvId8WXe1PY4FG3g1Juw
KnBf20sSRkJ/oj3iEhfd8ZmXeoK1Xc44aeCcVe7NEzVtMhjIdzcNqg==
-----END AGE ENCRYPTED FILE-----
recipient: age1gvplss0ddmyf6vpjy363wu3n057vhm0j6n7tc94cxd8kadapypws5mtaj0
- enc: |
-----BEGIN AGE ENCRYPTED FILE-----
YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBWTHN6TDBHdFU1L1lEQzg4
TW1vT08vYnp3bzBzSFlxbGpDSFNycFYycFJRCnYvcjVQOC9rZTFXb0lHQWFUVVhZ
ZFVtM09zWW9GZzNMRnBHdHNFNnZHdTgKLS0tIFh1b1pnKzJQUWg4YkRIWVFnRDNz
bXRzY1piak43N0dMZFQ1WWdSZjBBT2cKujwWnuf7LFZe1TIu0R+Vc+HGCYqaeRkD
jBuPRyN7cqCZ5cK9492BVLg48toU/djCSs1w33aLeTF5Ug/Swduqkg==
-----END AGE ENCRYPTED FILE-----
recipient: age1h0prahyukq4l564yqwgcpg3g6gdrjflk0suklussjjrjstxd9uesws8633
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
+135 -19
View File
@@ -1,29 +1,145 @@
{ self, inputs, ... }: {
flake.modules.homeManager.step-client = { config, pkgs, lib, ... }: {
home.file.".step/config/defaults.json".text = builtins.toJSON {
ca-url = "https://janus.john-stream.com/";
fingerprint = "2036c44f7b5901566ff7611ea6c927291ecc6d2dd00779c0eead70ec77fa10d6";
root = ../hosts/janus/root_ca.crt;
{ self, inputs, ... }:
let
defaultCaUrl = "https://janus.john-stream.com/";
defaultFingerprint = "2036c44f7b5901566ff7611ea6c927291ecc6d2dd00779c0eead70ec77fa10d6";
defaultRoot = ../hosts/janus/root_ca.crt;
mkStepBootstrap = { pkgs, caUrl, fingerprint, install ? false }:
(inputs.self.wrappers.stepBootstrap.apply {
inherit pkgs install;
ca-url = caUrl;
inherit fingerprint;
}).wrapper;
mkDefaultsText = cfg: builtins.toJSON {
ca-url = cfg.caUrl;
fingerprint = cfg.fingerprint;
root = cfg.root;
};
home.packages = [
inputs.self.packages.${pkgs.stdenv.hostPlatform.system}.step-bootstrap
in
{
flake.modules.nixos.step-client = { config, pkgs, lib, ... }:
let
cfg = config."step-client";
in
{
options."step-client" = {
enable = lib.mkOption {
description = "Enable step-ca client bootstrap";
type = lib.types.bool;
default = true;
};
caUrl = lib.mkOption {
description = "The step-ca URL used for bootstrap and renewal.";
type = lib.types.str;
default = defaultCaUrl;
};
fingerprint = lib.mkOption {
description = "The SHA256 fingerprint of the step-ca root certificate.";
type = lib.types.str;
default = defaultFingerprint;
};
root = lib.mkOption {
description = "The step-ca root certificate used for bootstrap.";
type = lib.types.path;
default = defaultRoot;
};
certDir = lib.mkOption {
description = "Directory used to store root CA material for mTLS and step bootstrap.";
type = lib.types.str;
default = "/etc/step-ca/certs";
};
};
config = lib.mkIf cfg.enable {
environment.systemPackages = [
(mkStepBootstrap {
inherit pkgs;
caUrl = cfg.caUrl;
fingerprint = cfg.fingerprint;
})
];
# sops.secrets."step-ca-defaults" = {
# sopsFile = ../hosts/janus/defaults.json;
# format = "json";
# key = ""; # This causes it to decode the whole file
# path = "${config.home.homeDirectory}/defaults.json";
# mode = "0400";
# };
environment.etc."step-ca/defaults.json".text = mkDefaultsText cfg;
systemd.tmpfiles.rules = [
"d ${cfg.certDir} 0750 root root -"
"d /root/.step 0700 root root -"
"d /root/.step/config 0700 root root -"
"d /root/.step/certs 0700 root root -"
"L+ /root/.step/config/defaults.json - - - - /etc/step-ca/defaults.json"
"L+ /root/.step/certs/root_ca.crt - - - - ${cfg.certDir}/root_ca.crt"
];
};
};
flake.modules.homeManager.step-client = { config, pkgs, lib, ... }:
let
cfg = config."step-client";
in
{
options."step-client" = {
enable = lib.mkOption {
description = "Enable step-ca client bootstrap";
type = lib.types.bool;
default = true;
};
caUrl = lib.mkOption {
description = "The step-ca URL used for bootstrap and renewal.";
type = lib.types.str;
default = defaultCaUrl;
};
fingerprint = lib.mkOption {
description = "The SHA256 fingerprint of the step-ca root certificate.";
type = lib.types.str;
default = defaultFingerprint;
};
root = lib.mkOption {
description = "The step-ca root certificate used for bootstrap.";
type = lib.types.path;
default = defaultRoot;
};
certDir = lib.mkOption {
description = "Directory used to store root CA material for mTLS and step bootstrap.";
type = lib.types.str;
default = "${config.home.homeDirectory}/.step/certs";
};
};
config = lib.mkIf cfg.enable (
let
certDirPath = lib.removePrefix "${config.home.homeDirectory}/" cfg.certDir;
in
{
home.packages = [
(mkStepBootstrap {
inherit pkgs;
caUrl = cfg.caUrl;
fingerprint = cfg.fingerprint;
})
];
home.file.".step/config/defaults.json".text = mkDefaultsText cfg;
home.file."${certDirPath}/root_ca.crt".source = cfg.root;
}
);
};
perSystem = { system, pkgs, lib, ... }: {
packages.step-bootstrap = (inputs.self.wrappers.stepBootstrap.apply {
packages.step-bootstrap = mkStepBootstrap {
inherit pkgs;
ca-url = "https://janus.john-stream.com";
fingerprint = "2036c44f7b5901566ff7611ea6c927291ecc6d2dd00779c0eead70ec77fa10d6";
caUrl = defaultCaUrl;
fingerprint = defaultFingerprint;
install = true;
}).wrapper;
};
};
flake.wrappers.stepBootstrap = inputs.wrappers.lib.wrapModule ({config, lib, wlib, ... }: {
+37
View File
@@ -0,0 +1,37 @@
# Janus
Generate passwords:
```shell
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
```
Bootstrap CA materials with SSH enabled:
```shell
STEPPATH=/tmp/janus-step-ca-bootstrap/step step ca init --name Janus --dns janus.john-stream.com --dns 192.168.1.244 --address :443 --provisioner admin --password-file /tmp/janus-step-ca-bootstrap/ca_password.txt --provisioner-password-file /tmp/janus-step-ca-bootstrap/admin_jwk_password.txt --ssh --deployment-type standalone --with-ca-url https://janus.john-stream.com
```
Insert generated runtime CA material into `modules/hosts/janus/secrets.yaml` under `janus`:
- `/tmp/janus-step-ca-bootstrap/ca_password.txt` -> `ca_password`
- `/tmp/janus-step-ca-bootstrap/step/certs/intermediate_ca.crt` -> `intermediate_ca_crt`
- `/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`
If rotating provisioner password, also set:
- `/tmp/janus-step-ca-bootstrap/admin_jwk_password.txt` -> `janus.admin_jwk` in `keys/secrets.yaml`
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`)
- `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:
- `modules/hosts/janus/root_ca.crt` from `/tmp/janus-step-ca-bootstrap/step/certs/root_ca.crt`
- `modules/hosts/janus/fingerprint` from:
```shell
step certificate fingerprint /tmp/janus-step-ca-bootstrap/step/certs/root_ca.crt
```
- `modules/hosts/janus/ssh_user_ca.pub` from `/tmp/janus-step-ca-bootstrap/step/certs/ssh_user_ca_key.pub`
+4 -45
View File
@@ -4,55 +4,13 @@ let
hostname = "janus";
in
{
flake.modules.nixos.janus-ca =
{ config, pkgs, lib, ... }:
let
cfg = config.janus-ca;
johnHome = lib.attrByPath [ "users" "users" username "home" ] "/home/${username}" config;
johnGroup = lib.attrByPath [ "users" "users" username "group" ] username config;
cfgInEtc = lib.hasPrefix "/etc/" cfg.certDir;
certDirEtcPath =
if cfgInEtc then
lib.removePrefix "/etc/" cfg.certDir
else
cfg.certDir;
mkStepRules = home: user: group: [
"d ${home}/.step 0700 ${user} ${group} -"
"d ${home}/.step/config 0700 ${user} ${group} -"
"d ${home}/.step/certs 0700 ${user} ${group} -"
"L+ ${home}/.step/config/defaults.json - - - - /etc/step-ca/defaults.json"
"L+ ${home}/.step/certs/root_ca.crt - - - - ${cfg.certDir}/root_ca.crt"
];
in
{
options.janus-ca = {
certDir = lib.mkOption {
description = "String path to where the mtls certs will be stored.";
type = lib.types.str;
default = "/etc/step-ca/certs";
};
};
config = {
environment.etc = lib.mkIf cfgInEtc {
"step-ca/defaults.json".text = builtins.toJSON {
ca-url = "https://janus.john-stream.com/";
fingerprint = "2036c44f7b5901566ff7611ea6c927291ecc6d2dd00779c0eead70ec77fa10d6";
root = ./root_ca.crt;
};
};
systemd.tmpfiles.rules =
mkStepRules johnHome username johnGroup
++ mkStepRules "/root" "root" "root";
};
};
flake.nixosConfigurations."${hostname}" = inputs.nixpkgs.lib.nixosSystem {
modules = with inputs.self.modules; [
nixos.lxc
nixos.mysops
nixos.step-ssh-host
nixos.janus-ca
nixos.step-client
nixos.step-ca
inputs.home-manager.nixosModules.home-manager
nixos."${username}"
nixos.docker
@@ -60,7 +18,7 @@ in
nixos.mtls
({ lib, pkgs, ... }: {
networking.hostName = hostname;
sops.defaultSopsFile = ../../../keys/secrets.yaml;
sops.defaultSopsFile = ./secrets.yaml;
step-ssh-host = {
hostname = hostname;
extraPrincipals = [
@@ -90,6 +48,7 @@ in
home-manager.users."${username}" = {
imports = with inputs.self.modules.homeManager; [
mysops
step-client
];
docker.enable = true;
};
+30
View File
@@ -0,0 +1,30 @@
janus:
ca_password: ENC[AES256_GCM,data:GmuqoePDJd5Cn7+sWbvXPlGoUf3SVgYnHOoq9mnPWNWj,iv:VY/8olA+yu66wW+RbhD58GtA0YUWuAtm1HUXtNIIuLk=,tag:fCz3x6B4UPw+XpJE0F3t/g==,type:str]
intermediate_ca_crt: ENC[AES256_GCM,data:9W6QXGlcPdfas1ea6S3w1OYI/SeF6YDIdF5J7Hv4ype3,iv:H8oVfbMLBRvU0ywovVSB84g0q1wPhHEdzfpIVAY0Bkg=,tag:7/pU0N1SlfC1i8H2IgPGVA==,type:str]
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]
sops:
age:
- enc: |
-----BEGIN AGE ENCRYPTED FILE-----
YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBCTEFTSy96QTluaWo0bURH
YlpFSWx3VnYvSHpDYU1PNmZrb0FuVHVTcG00CmJnT09OZEJad01OZk8zUzlPT1Ft
bVpHeW9UMXZYN1JJQVgrTk9OamhZeXcKLS0tIFhXMVNDQjhVcUp2aHhjenlGVW9z
cTNPalJOQVJNQWxzMnVMT1lYQS9SNW8KWapdX8dwxEvcqhKI8RJmCWRrV7sRmS72
sUt6HaUGpQfUQ97MtS01DYaSZjbAvj8t//mXhLubZddDTtTuhbpjAg==
-----END AGE ENCRYPTED FILE-----
recipient: age1ykcs39e62pz3xu6cedg8ea685kv5d5qsrhgkndygzm8rx30xd5ys5t3qxt
- enc: |
-----BEGIN AGE ENCRYPTED FILE-----
YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBWcnVWS2lpMDM5VWxLWDIx
R0xWQ3ZOaEVFNTR5bXArNTc4MzFOM2xCQWhjCnBZeUtJQ3RvWDdZeVRpRzBPbTl2
M3FOTlRnTDhIaGg2VzM3MFVEc1FVUmcKLS0tIDAzeDlaZGt5Q2dJbzNWRVB4Qmwr
SWpxcytNdEFBQ2o0Q3lWSHZSNEdCUUEKgHE0j678WIhcQQsZQ5RcQNkQcP++ibvr
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]
unencrypted_suffix: _unencrypted
version: 3.13.1
@@ -56,6 +56,7 @@
gnome
desktop
mysops
step-client
rebuild
{
my-vscode.enable = true;
+1 -1
View File
@@ -12,7 +12,6 @@
"${inputs.nixos-hardware}/lenovo/thinkpad/p14s/amd/gen4"
] ++ (with self.modules.nixos; [
p14sConfiguration
janus-ca
rebuild
sudo
john
@@ -20,6 +19,7 @@
steam
wireguard
mtls
step-client
# greetd
# niri
]);
+3 -4
View File
@@ -8,19 +8,18 @@ in
flake.nixosConfigurations."${hostname}" = inputs.nixpkgs.lib.nixosSystem {
modules = with inputs.self.modules; [
nixos.lxc
nixos."${username}"
nixos.mysops
nixos."${username}"
nixos.step-ssh-host
nixos.login-text
nixos.docker
nixos.mtls
nixos.janus-ca
nixos.step-client
nixos.forgejo
nixos.restic-server
# nixos.restic-envoy
({ config, pkgs, ... }: {
networking.hostName = hostname;
time.timeZone = "America/Chicago";
# Removes password for sudo
security.sudo-rs.extraRules = lib.mkAfter [
@@ -38,7 +37,6 @@ in
users.users."${username}".extraGroups = [ "mtls" ];
mtls = {
enable = true;
certDir = config.janus-ca.certDir;
subject = hostname;
san = [
"${hostname}.john-stream.com"
@@ -98,6 +96,7 @@ in
imports = [
inputs.self.modules.homeManager.rebuild
inputs.self.modules.homeManager.mysops
inputs.self.modules.homeManager.step-client
({ config, pkgs, lib, ... }: {
homeManagerFlakeDir = "${config.xdg.configHome}/home-manager";
docker.enable = true;
-2
View File
@@ -1,5 +1,3 @@
janus:
admin_jwk: ENC[AES256_GCM,data:2XcN5X77wTQ+OUXa4C9xAErGvrwJKseHjCcgoj6jt+c=,iv:9x+M1wM0dYND1JYkJjM4N8pSOok2OF+P9vmm9NCumTI=,tag:dTCfh+KB1iRJBVoNsGqvuw==,type:str]
forgejo:
#ENC[AES256_GCM,data:/wtm0uXbiWFoGNWtlTzVuNxBR7CPm2FMB98t3AxSj5V5rltLvzF9BjgWoJCiX3ltzmU=,iv:xaZXbUIGJHxPrLRQzEQI7hgRgc0y061jIhoE3zlcMaA=,tag:fQGheCIdBKm6wE+vtj7g6A==,type:comment]
secret_key: ENC[AES256_GCM,data:/jcyeDcsryLqu9Q3VnNaENb71/Tl5JUr0zDzxt8L5UCtnJ/YHA6MKItrQ9ZHFv1XROtnSfZl9D5kKomeM8EVqA==,iv:HxMKAMVQ08gkq6SWENj0/d8i9PhcgPCp5eqbztj9bSg=,tag:nO2dFWT/vfgGc/9JIDZrGw==,type:str]
+2
View File
@@ -37,6 +37,8 @@
config = {
ssh.certificates.enable = true;
sops.secrets."janus/admin_jwk" = {
# Shared provisioner credential is intentionally centralized.
sopsFile = ../../../keys/secrets.yaml;
owner = "root";
group = "root";
mode = "0400";
+111 -6
View File
@@ -1,22 +1,127 @@
{ inputs, ... }:
{
flake.modules.nixos.step-ca = { config, pkgs, ... }:
let
ipAddress = "0.0.0.0";
# 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;
in
{
flake.modules.nixos.step-ca = { pkgs, ... }: {
# 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 = ipAddress;
port = 8443;
address = "0.0.0.0";
port = 443;
intermediatePasswordFile = caPasswordPath;
# https://smallstep.com/docs/step-ca/configuration/#configuration-options
settings = {
root = "";
crt = "";
root = rootCertPath;
crt = intermediateCrtPath;
key = intermediateKeyPath;
dnsNames = [
"janus.john-stream.com"
"192.168.1.244"
];
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