WIP with placeholder secrets
This commit is contained in:
+12
@@ -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
@@ -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
|
||||
|
||||
@@ -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;
|
||||
};
|
||||
home.packages = [
|
||||
inputs.self.packages.${pkgs.stdenv.hostPlatform.system}.step-bootstrap
|
||||
];
|
||||
# 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";
|
||||
# };
|
||||
{ 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;
|
||||
};
|
||||
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;
|
||||
})
|
||||
];
|
||||
|
||||
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, ... }: {
|
||||
|
||||
@@ -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,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;
|
||||
};
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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
|
||||
]);
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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]
|
||||
|
||||
@@ -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";
|
||||
|
||||
@@ -1,22 +1,127 @@
|
||||
{ inputs, ... }:
|
||||
let
|
||||
ipAddress = "0.0.0.0";
|
||||
in
|
||||
{
|
||||
flake.modules.nixos.step-ca = { pkgs, ... }: {
|
||||
flake.modules.nixos.step-ca = { config, pkgs, ... }:
|
||||
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;
|
||||
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 = 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
|
||||
|
||||
Reference in New Issue
Block a user