1
1
Fork 1
mirror of https://github.com/oddlama/nix-config.git synced 2025-10-10 23:00:39 +02:00

chore: update to new agenix-rekey format

This commit is contained in:
oddlama 2023-06-07 19:48:15 +02:00
parent 972b0456da
commit dec790c589
No known key found for this signature in database
GPG key ID: 14EFE510775FE39A
21 changed files with 195 additions and 100 deletions

36
flake.lock generated
View file

@ -31,12 +31,10 @@
] ]
}, },
"locked": { "locked": {
"lastModified": 1684539260, "lastModified": 1686159246,
"narHash": "sha256-lF3+vp2UZwBjzF4pnOKYZrQOCFdnOdtvGmaFIzsaMN4=", "narHash": "sha256-6+u3Ed6rsYKJ1gnjt1DoEnxgF6Xmi4qPFUy7OBEiN5E=",
"owner": "oddlama", "type": "git",
"repo": "agenix-rekey", "url": "file:///root/projects/agenix-rekey"
"rev": "e9a2bad33b7b1634af65cbc809fc31776df41fe5",
"type": "github"
}, },
"original": { "original": {
"owner": "oddlama", "owner": "oddlama",
@ -119,11 +117,11 @@
] ]
}, },
"locked": { "locked": {
"lastModified": 1685970051, "lastModified": 1686150639,
"narHash": "sha256-F5ZxBD2DeNd+Q0dDKYBhv76kfjVG/X0ccXjSKpa8KdI=", "narHash": "sha256-QHorMn3tgvCE0BM4QlNb/7vuquz11cS2ke1GSfmgiPo=",
"owner": "nix-community", "owner": "nix-community",
"repo": "disko", "repo": "disko",
"rev": "29d632d7e8fa86f937153ecdfd7d768411001d2d", "rev": "f1178c6e72b7d8ab2b55990397969324822275eb",
"type": "github" "type": "github"
}, },
"original": { "original": {
@ -210,11 +208,11 @@
] ]
}, },
"locked": { "locked": {
"lastModified": 1685885003, "lastModified": 1686142265,
"narHash": "sha256-+OB0EvZBfGvnlTGg6mtyUCqkMnUp9DkmRUU4d7BZBVE=", "narHash": "sha256-IP0xPa0VYqxCzpqZsg3iYGXarUF+4r2zpkhwdHy9WsM=",
"owner": "nix-community", "owner": "nix-community",
"repo": "home-manager", "repo": "home-manager",
"rev": "607d8fad96436b134424b9935166a7cd0884003e", "rev": "39c7d0a97a77d3f31953941767a0822c94dc01f5",
"type": "github" "type": "github"
}, },
"original": { "original": {
@ -260,11 +258,11 @@
] ]
}, },
"locked": { "locked": {
"lastModified": 1685384827, "lastModified": 1686092477,
"narHash": "sha256-lEEMXGKQY5cUWO9vS08a5VLPbVAJm6xGBTd3Cnfg99c=", "narHash": "sha256-ewXevzxR3FGhI5ip1QX+jCAQW2En9BTwBI9+kGip9DA=",
"owner": "astro", "owner": "astro",
"repo": "microvm.nix", "repo": "microvm.nix",
"rev": "3683f43a37568fbc14bdc1c952acb41b0bb09a01", "rev": "c6416c6b9fed22b71f526720cb120b0218c51b62",
"type": "github" "type": "github"
}, },
"original": { "original": {
@ -348,7 +346,7 @@
"nixpkgs": { "nixpkgs": {
"locked": { "locked": {
"lastModified": 1685290091, "lastModified": 1685290091,
"narHash": "sha256-eJ4hOd5fA8i9uhpPFrpjLAb09wqfB+NH9utHh0PGD4k=", "narHash": "sha256-Shhg4EstYivzF10RuNDUKw3KGQOS5e7S7yHFnWuJQSI=",
"type": "git", "type": "git",
"url": "file:///root/projects/nixpkgs-test" "url": "file:///root/projects/nixpkgs-test"
}, },
@ -388,11 +386,11 @@
"nixpkgs-stable": "nixpkgs-stable" "nixpkgs-stable": "nixpkgs-stable"
}, },
"locked": { "locked": {
"lastModified": 1685970613, "lastModified": 1686050334,
"narHash": "sha256-sMbR4zPciUfQ6YHt6GNVxT/yhWJKngvZo8qHzYkaU6E=", "narHash": "sha256-R0mczWjDzBpIvM3XXhO908X5e2CQqjyh/gFbwZk/7/Q=",
"owner": "cachix", "owner": "cachix",
"repo": "pre-commit-hooks.nix", "repo": "pre-commit-hooks.nix",
"rev": "a117a1cd2c280bf8d499f26370fddfe1923e75e6", "rev": "6881eb2ae5d8a3516e34714e7a90d9d95914c4dc",
"type": "github" "type": "github"
}, },
"original": { "original": {

View file

@ -15,7 +15,16 @@
; ;
in { in {
# TODO needed until https://github.com/NixOS/nixpkgs/issues/236146 is resolved # TODO needed until https://github.com/NixOS/nixpkgs/issues/236146 is resolved
boot.initrd.network.flushBeforeStage2 = true; boot.initrd.systemd = {
services.systemd-networkd = {
before = ["initrd-switch-root.target"];
conflicts = ["initrd-switch-root.target"];
};
sockets.systemd-networkd = {
before = ["initrd-switch-root.target"];
conflicts = ["initrd-switch-root.target"];
};
};
networking = { networking = {
hostName = nodeName; hostName = nodeName;

View file

@ -343,7 +343,7 @@
// lib.optionalAttrs (nodePath != null && lib.pathExists local) {inherit local;}; // lib.optionalAttrs (nodePath != null && lib.pathExists local) {inherit local;};
# Setup secret rekeying parameters # Setup secret rekeying parameters
rekey = { age.rekey = {
inherit inherit
(inputs.self.secretsConfig) (inputs.self.secretsConfig)
masterIdentities masterIdentities

View file

@ -4,13 +4,14 @@
nodePath, nodePath,
... ...
}: { }: {
rekey.secrets.initrd_host_ed25519_key.file = nodePath + "/secrets/initrd_host_ed25519_key.age"; # TODO generate script
age.secrets.initrd_host_ed25519_key.file = nodePath + "/secrets/initrd_host_ed25519_key.age";
boot.initrd.network.enable = true; boot.initrd.network.enable = true;
boot.initrd.network.ssh = { boot.initrd.network.ssh = {
enable = true; enable = true;
port = 4; port = 4;
hostKeys = [config.rekey.secrets.initrd_host_ed25519_key.path]; hostKeys = [config.age.secrets.initrd_host_ed25519_key.path];
}; };
# Make sure that there is always a valid initrd hostkey available that can be installed into # Make sure that there is always a valid initrd hostkey available that can be installed into
@ -21,8 +22,8 @@
# for the first time, and the secrets were rekeyed for the the new host identity. # for the first time, and the secrets were rekeyed for the the new host identity.
system.activationScripts.agenixEnsureInitrdHostkey = { system.activationScripts.agenixEnsureInitrdHostkey = {
text = '' text = ''
[[ -e ${config.rekey.secrets.initrd_host_ed25519_key.path} ]] \ [[ -e ${config.age.secrets.initrd_host_ed25519_key.path} ]] \
|| ${pkgs.openssh}/bin/ssh-keygen -t ed25519 -N "" -f ${config.rekey.secrets.initrd_host_ed25519_key.path} || ${pkgs.openssh}/bin/ssh-keygen -t ed25519 -N "" -f ${config.age.secrets.initrd_host_ed25519_key.path}
''; '';
deps = ["agenixInstall"]; deps = ["agenixInstall"];
}; };

View file

@ -1,8 +1,8 @@
{config, ...}: let {config, ...}: let
inherit (config.repo.secrets.local) acme; inherit (config.repo.secrets.local) acme;
in { in {
rekey.secrets.acme-credentials = { age.secrets.acme-credentials = {
file = ./secrets/acme-credentials.age; rekeyFile = ./secrets/acme-credentials.age;
mode = "440"; mode = "440";
group = "acme"; group = "acme";
}; };
@ -11,7 +11,7 @@ in {
acceptTerms = true; acceptTerms = true;
defaults = { defaults = {
inherit (acme) email; inherit (acme) email;
credentialsFile = config.rekey.secrets.acme-credentials.path; credentialsFile = config.age.secrets.acme-credentials.path;
dnsProvider = "cloudflare"; dnsProvider = "cloudflare";
dnsPropagationCheck = true; dnsPropagationCheck = true;
reloadServices = ["nginx"]; reloadServices = ["nginx"];

View file

@ -15,8 +15,8 @@ in {
# TODO message = "non-deterministic uid detected for: ${name}"; # TODO message = "non-deterministic uid detected for: ${name}";
# TODO }); # TODO });
rekey.secrets.loki-basic-auth = { age.secrets.loki-basic-auth = {
file = ./secrets/loki-basic-auth.age; rekeyFile = ./secrets/loki-basic-auth.age;
mode = "440"; mode = "440";
group = "caddy"; group = "caddy";
}; };
@ -125,7 +125,7 @@ in {
encode zstd gzip encode zstd gzip
skip_log skip_log
basicauth { basicauth {
import ${config.rekey.secrets.loki-basic-auth.path} import ${config.age.secrets.loki-basic-auth.path}
} }
reverse_proxy { reverse_proxy {
to http://${nodes.ward-loki.config.extra.wireguard.proxy-sentinel.ipv4}:${lokiPort} to http://${nodes.ward-loki.config.extra.wireguard.proxy-sentinel.ipv4}:${lokiPort}

View file

@ -24,6 +24,7 @@ in {
./fs.nix ./fs.nix
./net.nix ./net.nix
./promtail.nix
]; ];
boot.initrd.availableKernelModules = ["xhci_pci" "ahci" "nvme" "usbhid" "usb_storage" "sd_mod" "sdhci_pci" "r8169"]; boot.initrd.availableKernelModules = ["xhci_pci" "ahci" "nvme" "usbhid" "usb_storage" "sd_mod" "sdhci_pci" "r8169"];
@ -68,7 +69,7 @@ in {
parentNodeName, parentNodeName,
... ...
}: { }: {
rekey.hostPubkey = "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIBXXjI6uB26xOF0DPy/QyLladoGIKfAtofyqPgIkCH/g"; age.rekey.hostPubkey = "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIBXXjI6uB26xOF0DPy/QyLladoGIKfAtofyqPgIkCH/g";
extra.wireguard.proxy-sentinel.client.via = "sentinel"; extra.wireguard.proxy-sentinel.client.via = "sentinel";
@ -91,14 +92,14 @@ in {
}; };
}; };
rekey.secrets.grafana-secret-key = { age.secrets.grafana-secret-key = {
file = ./secrets/grafana-secret-key.age; rekeyFile = ./secrets/grafana-secret-key.age;
mode = "440"; mode = "440";
group = "grafana"; group = "grafana";
}; };
rekey.secrets.loki-basic-auth-password-grafana = { age.secrets.loki-basic-auth-password = {
file = ./secrets/loki-basic-auth-password-grafana.age; rekeyFile = ./secrets/loki-basic-auth-password.age;
mode = "440"; mode = "440";
group = "grafana"; group = "grafana";
}; };
@ -116,14 +117,11 @@ in {
enable_gzip = true; enable_gzip = true;
http_addr = config.extra.wireguard.proxy-sentinel.ipv4; http_addr = config.extra.wireguard.proxy-sentinel.ipv4;
http_port = 3001; http_port = 3001;
# cert_key = /etc/grafana/grafana.key;
# cert_file = /etc/grafana/grafana.crt;
# protocol = "https"
}; };
security = { security = {
disable_initial_admin_creation = true; disable_initial_admin_creation = true;
secret_key = "$__file{${config.rekey.secrets.grafana-secret-key.path}}"; secret_key = "$__file{${config.age.secrets.grafana-secret-key.path}}";
cookie_secure = true; cookie_secure = true;
disable_gravatar = true; disable_gravatar = true;
hide_version = true; hide_version = true;
@ -137,7 +135,7 @@ in {
allow_sign_up = true; allow_sign_up = true;
auto_login = true; auto_login = true;
client_id = "grafana"; client_id = "grafana";
#client_secret = "$__file{${config.rekey.secrets.grafana-oauth-client-secret.path}}"; #client_secret = "$__file{${config.age.secrets.grafana-oauth-client-secret.path}}";
client_secret = "r6Yk5PPSXFfYDPpK6TRCzXK8y1rTrfcb8F7wvNC5rZpyHTMF"; # TODO temporary test not a real secret client_secret = "r6Yk5PPSXFfYDPpK6TRCzXK8y1rTrfcb8F7wvNC5rZpyHTMF"; # TODO temporary test not a real secret
scopes = "openid email profile"; scopes = "openid email profile";
login_attribute_path = "prefered_username"; login_attribute_path = "prefered_username";
@ -167,8 +165,8 @@ in {
url = "https://${lokiDomain}"; url = "https://${lokiDomain}";
orgId = 1; orgId = 1;
basicAuth = true; basicAuth = true;
basicAuthUser = "grafana"; basicAuthUser = "iB6UEjt4so4xWqei";
secureJsonData.basicAuthPassword = "$__file{${config.rekey.secrets.loki-basic-auth-password-grafana.path}}"; secureJsonData.basicAuthPassword = "$__file{${config.age.secrets.loki-basic-auth-password.path}}";
} }
]; ];
}; };
@ -180,13 +178,12 @@ in {
config, config,
... ...
}: { }: {
rekey.hostPubkey = "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIN2TxWynLb8V9SP45kFqsoCWhe/dG8N1xWNuJG5VQndq"; age.rekey.hostPubkey = "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIN2TxWynLb8V9SP45kFqsoCWhe/dG8N1xWNuJG5VQndq";
extra.wireguard.proxy-sentinel.client.via = "sentinel"; extra.wireguard.proxy-sentinel.client.via = "sentinel";
networking.nftables.firewall = { networking.nftables.firewall = {
zones = lib.mkForce { zones = lib.mkForce {
#local-vms.interfaces = ["local-vms"];
proxy-sentinel.interfaces = ["proxy-sentinel"]; proxy-sentinel.interfaces = ["proxy-sentinel"];
sentinel = { sentinel = {
parent = "proxy-sentinel"; parent = "proxy-sentinel";
@ -204,13 +201,13 @@ in {
}; };
}; };
rekey.secrets."kanidm-self-signed.crt" = { age.secrets."kanidm-self-signed.crt" = {
file = ./secrets/kanidm-self-signed.crt.age; rekeyFile = ./secrets/kanidm-self-signed.crt.age;
mode = "440"; mode = "440";
group = "kanidm"; group = "kanidm";
}; };
rekey.secrets."kanidm-self-signed.key" = { age.secrets."kanidm-self-signed.key" = {
file = ./secrets/kanidm-self-signed.key.age; rekeyFile = ./secrets/kanidm-self-signed.key.age;
mode = "440"; mode = "440";
group = "kanidm"; group = "kanidm";
}; };
@ -221,8 +218,8 @@ in {
serverSettings = { serverSettings = {
domain = authDomain; domain = authDomain;
origin = "https://${config.services.kanidm.serverSettings.domain}"; origin = "https://${config.services.kanidm.serverSettings.domain}";
tls_chain = config.rekey.secrets."kanidm-self-signed.crt".path; tls_chain = config.age.secrets."kanidm-self-signed.crt".path;
tls_key = config.rekey.secrets."kanidm-self-signed.key".path; tls_key = config.age.secrets."kanidm-self-signed.key".path;
bindaddress = "${config.extra.wireguard.proxy-sentinel.ipv4}:8300"; bindaddress = "${config.extra.wireguard.proxy-sentinel.ipv4}:8300";
trust_x_forward_for = true; trust_x_forward_for = true;
}; };
@ -247,7 +244,7 @@ in {
utils, utils,
... ...
}: { }: {
rekey.hostPubkey = "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAICDDvvF3+KwfoZrPAUAt2HS7y5FM9S5Mr1iRkBUqoXno"; age.rekey.hostPubkey = "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAICDDvvF3+KwfoZrPAUAt2HS7y5FM9S5Mr1iRkBUqoXno";
extra.wireguard.proxy-sentinel.client.via = "sentinel"; extra.wireguard.proxy-sentinel.client.via = "sentinel";

View file

@ -1,20 +1,45 @@
{ {
lib,
config, config,
lib,
nodeName,
nodes,
parentNodeName, parentNodeName,
... ...
}: { }: let
inherit (nodes.sentinel.config.repo.secrets.local) personalDomain;
lokiDomain = "loki.${personalDomain}";
in {
age.secrets.loki-basic-auth-password = {
rekeyFile = ./secrets/loki-basic-auth-password.age;
file = ./aaa;
#file = ./aaa;
#generate = "alnum48";
mode = "440";
group = "promtail";
};
#age.secrets.loki-basic-auth-password = {
# generate = "alnum48";
# mode = "440";
# group = "promtail";
#};
services.promtail = { services.promtail = {
enable = true; enable = true;
configuration = { configuration = {
server.http_listen_port = 9080; server = {
server.grpc_listen_port = 0; http_listen_port = 9080;
grpc_listen_port = 0;
log_level = "warn";
};
clients = [ clients = [
{ {
basic_auth.username = "promtail@thalheim.io"; #basic_auth.username = nodeName;
basic_auth.password_file = config.sops.secrets.promtail-password.path; #basic_auth.password_file = config.age.random-secrets.loki-basic-auth-password.path;
url = "http://loki.r/loki/api/v1/push"; basic_auth.username = "iB6UEjt4so4xWqei";
basic_auth.password_file = config.age.secrets.loki-basic-auth-password.path;
url = "https://${lokiDomain}/loki/api/v1/push";
} }
]; ];
@ -23,7 +48,7 @@
job_name = "journal"; job_name = "journal";
journal = { journal = {
json = true; json = true;
max_age = "12h"; max_age = "24h";
labels.job = "systemd-journal"; labels.job = "systemd-journal";
}; };
pipeline_stages = [ pipeline_stages = [
@ -55,7 +80,6 @@
{ {
template = { template = {
source = "msg"; source = "msg";
# FIXME would be cleaner to have this in a match block, but could not get it to work
template = "{{if .coredump_exe}}{{.coredump_exe}} core dumped (user: {{.coredump_uid}}/{{.coredump_gid}}, command: {{.coredump_cmdline}}){{else}}{{.msg}}{{end}}"; template = "{{if .coredump_exe}}{{.coredump_exe}} core dumped (user: {{.coredump_uid}}/{{.coredump_gid}}, command: {{.coredump_cmdline}}){{else}}{{.msg}}{{end}}";
}; };
} }
@ -83,6 +107,30 @@
source_labels = ["__journal__hostname"]; source_labels = ["__journal__hostname"];
target_label = "host"; target_label = "host";
} }
{
source_labels = ["__journal_priority"];
target_label = "priority";
}
{
source_labels = ["__journal_priority_keyword"];
target_label = "level";
}
#{
# source_labels = ["__journal__systemd_unit"];
# target_label = "unit";
#}
{
source_labels = ["__journal__systemd_user_unit"];
target_label = "user_unit";
}
{
source_labels = ["__journal__boot_id"];
target_label = "boot_id";
}
{
source_labels = ["__journal__comm"];
target_label = "command";
}
]; ];
} }
]; ];

View file

@ -33,7 +33,7 @@
#SMTP_SECURITY = "force_tls"; #SMTP_SECURITY = "force_tls";
#SMTP_USERNAME={{ vaultwarden_smtp_username }}; #SMTP_USERNAME={{ vaultwarden_smtp_username }};
#SMTP_PASSWORD={{ vaultwarden_smtp_password }}; #SMTP_PASSWORD={{ vaultwarden_smtp_password }};
#environmentFile = config.rekey.secrets.vaultwarden-env.path; #environmentFile = config.age.secrets.vaultwarden-env.path;
}; };
# Replace uses of old name # Replace uses of old name
@ -58,8 +58,8 @@
virtualHosts."${config.repo.secrets.local.vaultwarden.domain}" = { virtualHosts."${config.repo.secrets.local.vaultwarden.domain}" = {
forceSSL = true; forceSSL = true;
#enableACME = true; #enableACME = true;
sslCertificate = config.rekey.secrets."selfcert.crt".path; sslCertificate = config.age.secrets."selfcert.crt".path;
sslCertificateKey = config.rekey.secrets."selfcert.key".path; sslCertificateKey = config.age.secrets."selfcert.key".path;
locations."/" = { locations."/" = {
proxyPass = "http://vaultwarden"; proxyPass = "http://vaultwarden";
proxyWebsockets = true; proxyWebsockets = true;

View file

@ -26,8 +26,8 @@
virtualHosts."${config.repo.secrets.local.esphome.domain}" = { virtualHosts."${config.repo.secrets.local.esphome.domain}" = {
forceSSL = true; forceSSL = true;
#enableACME = true; #enableACME = true;
sslCertificate = config.rekey.secrets."selfcert.crt".path; sslCertificate = config.age.secrets."selfcert.crt".path;
sslCertificateKey = config.rekey.secrets."selfcert.key".path; sslCertificateKey = config.age.secrets."selfcert.key".path;
locations."/" = { locations."/" = {
proxyPass = "http://esphome"; proxyPass = "http://esphome";
proxyWebsockets = true; proxyWebsockets = true;

View file

@ -89,14 +89,14 @@ in {
extraPackages = python3Packages: with python3Packages; [psycopg2]; extraPackages = python3Packages: with python3Packages; [psycopg2];
}; };
rekey.secrets."home-assistant-secrets.yaml" = { age.secrets."home-assistant-secrets.yaml" = {
file = ./secrets/home-assistant-secrets.yaml.age; rekeyFile = ./secrets/home-assistant-secrets.yaml.age;
owner = "hass"; owner = "hass";
}; };
systemd.services.home-assistant = { systemd.services.home-assistant = {
preStart = lib.mkBefore '' preStart = lib.mkBefore ''
ln -sf ${config.rekey.secrets."home-assistant-secrets.yaml".path} ${config.services.home-assistant.configDir}/secrets.yaml ln -sf ${config.age.secrets."home-assistant-secrets.yaml".path} ${config.services.home-assistant.configDir}/secrets.yaml
touch -a ${config.services.home-assistant.configDir}/{automations,scenes,scripts,manual}.yaml touch -a ${config.services.home-assistant.configDir}/{automations,scenes,scripts,manual}.yaml
''; '';
}; };
@ -118,8 +118,8 @@ in {
serverAliases = ["192.168.1.21"]; # TODO remove later serverAliases = ["192.168.1.21"]; # TODO remove later
forceSSL = true; forceSSL = true;
#enableACME = true; #enableACME = true;
sslCertificate = config.rekey.secrets."selfcert.crt".path; sslCertificate = config.age.secrets."selfcert.crt".path;
sslCertificateKey = config.rekey.secrets."selfcert.key".path; sslCertificateKey = config.age.secrets."selfcert.key".path;
locations."/" = { locations."/" = {
proxyPass = "http://homeassistant"; proxyPass = "http://homeassistant";
proxyWebsockets = true; proxyWebsockets = true;

View file

@ -8,7 +8,7 @@
disabledModules = ["services/networking/hostapd.nix"]; disabledModules = ["services/networking/hostapd.nix"];
# Associates each known client to a unique password # Associates each known client to a unique password
rekey.secrets.wifi-clients.file = ./secrets/wifi-clients.age; age.secrets.wifi-clients.rekeyFile = ./secrets/wifi-clients.age;
services.hostapd = { services.hostapd = {
enable = true; enable = true;
@ -22,7 +22,7 @@
macAcl = "allow"; macAcl = "allow";
apIsolate = true; apIsolate = true;
authentication = { authentication = {
saePasswordsFile = config.rekey.secrets.wifi-clients.path; saePasswordsFile = config.age.secrets.wifi-clients.path;
saeAddToMacAllow = true; saeAddToMacAllow = true;
enableRecommendedPairwiseCiphers = true; enableRecommendedPairwiseCiphers = true;
}; };

View file

@ -3,14 +3,14 @@
config, config,
... ...
}: { }: {
rekey.secrets.mosquitto-pw-zigbee2mqtt = { age.secrets.mosquitto-pw-zigbee2mqtt = {
file = ./secrets/mosquitto-pw-zigbee2mqtt.age; rekeyFile = ./secrets/mosquitto-pw-zigbee2mqtt.age;
mode = "440"; mode = "440";
owner = "zigbee2mqtt"; owner = "zigbee2mqtt";
group = "mosquitto"; group = "mosquitto";
}; };
rekey.secrets.mosquitto-pw-home_assistant = { age.secrets.mosquitto-pw-home_assistant = {
file = ./secrets/mosquitto-pw-home_assistant.age; rekeyFile = ./secrets/mosquitto-pw-home_assistant.age;
mode = "440"; mode = "440";
owner = "hass"; owner = "hass";
group = "mosquitto"; group = "mosquitto";
@ -24,11 +24,11 @@
acl = ["pattern readwrite #"]; acl = ["pattern readwrite #"];
users = { users = {
zigbee2mqtt = { zigbee2mqtt = {
passwordFile = config.rekey.secrets.mosquitto-pw-zigbee2mqtt.path; passwordFile = config.age.secrets.mosquitto-pw-zigbee2mqtt.path;
acl = ["readwrite #"]; acl = ["readwrite #"];
}; };
home_assistant = { home_assistant = {
passwordFile = config.rekey.secrets.mosquitto-pw-home_assistant.path; passwordFile = config.age.secrets.mosquitto-pw-home_assistant.path;
acl = ["readwrite #"]; acl = ["readwrite #"];
}; };
}; };

View file

@ -3,18 +3,18 @@
config, config,
... ...
}: { }: {
rekey.secrets."selfcert.crt" = { age.secrets."selfcert.crt" = {
file = ./secrets/selfcert.crt.age; rekeyFile = ./secrets/selfcert.crt.age;
mode = "440"; mode = "440";
group = "nginx"; group = "nginx";
}; };
rekey.secrets."selfcert.key" = { age.secrets."selfcert.key" = {
file = ./secrets/selfcert.key.age; rekeyFile = ./secrets/selfcert.key.age;
mode = "440"; mode = "440";
group = "nginx"; group = "nginx";
}; };
rekey.secrets."dhparams.pem" = { age.secrets."dhparams.pem" = {
file = ./secrets/dhparams.pem.age; rekeyFile = ./secrets/dhparams.pem.age;
mode = "440"; mode = "440";
group = "nginx"; group = "nginx";
}; };

View file

@ -3,8 +3,8 @@
config, config,
... ...
}: { }: {
rekey.secrets."mosquitto-pw-zigbee2mqtt.yaml" = { age.secrets."mosquitto-pw-zigbee2mqtt.yaml" = {
file = ./secrets/mosquitto-pw-zigbee2mqtt.yaml.age; rekeyFile = ./secrets/mosquitto-pw-zigbee2mqtt.yaml.age;
mode = "440"; mode = "440";
owner = "zigbee2mqtt"; owner = "zigbee2mqtt";
group = "mosquitto"; group = "mosquitto";
@ -22,7 +22,7 @@
mqtt = { mqtt = {
server = "mqtt://localhost:1883"; server = "mqtt://localhost:1883";
user = "zigbee2mqtt"; user = "zigbee2mqtt";
password = "!${config.rekey.secrets."mosquitto-pw-zigbee2mqtt.yaml".path} password"; password = "!${config.age.secrets."mosquitto-pw-zigbee2mqtt.yaml".path} password";
}; };
# TODO once 1.30.3 is out # TODO once 1.30.3 is out
# frontend.host = "/run/zigbee2mqtt/zigbee2mqtt.sock"; # frontend.host = "/run/zigbee2mqtt/zigbee2mqtt.sock";
@ -41,8 +41,8 @@
virtualHosts."${config.repo.secrets.local.zigbee2mqtt.domain}" = { virtualHosts."${config.repo.secrets.local.zigbee2mqtt.domain}" = {
forceSSL = true; forceSSL = true;
#enableACME = true; #enableACME = true;
sslCertificate = config.rekey.secrets."selfcert.crt".path; sslCertificate = config.age.secrets."selfcert.crt".path;
sslCertificateKey = config.rekey.secrets."selfcert.key".path; sslCertificateKey = config.age.secrets."selfcert.key".path;
locations."/".proxyPass = "http://zigbee2mqtt"; locations."/".proxyPass = "http://zigbee2mqtt";
# TODO dynamic definitions for the "local" network, IPv6 # TODO dynamic definitions for the "local" network, IPv6
extraConfig = '' extraConfig = ''

View file

@ -58,7 +58,7 @@ in {
# SSL config # SSL config
sslCiphers = "EECDH+AESGCM:EDH+AESGCM:!aNULL"; sslCiphers = "EECDH+AESGCM:EDH+AESGCM:!aNULL";
sslDhparam = config.rekey.secrets."dhparams.pem".path; sslDhparam = config.age.secrets."dhparams.pem".path;
commonHttpConfig = '' commonHttpConfig = ''
error_log syslog:server=unix:/dev/log; error_log syslog:server=unix:/dev/log;
access_log syslog:server=unix:/dev/log; access_log syslog:server=unix:/dev/log;

View file

@ -152,19 +152,21 @@
(genAttrs wgCfg.server.openFirewallRules (_: {allowedUDPPorts = [wgCfg.server.port];})) (genAttrs wgCfg.server.openFirewallRules (_: {allowedUDPPorts = [wgCfg.server.port];}))
); );
rekey.secrets = age.secrets =
concatAttrs (map concatAttrs (map
(other: { (other: {
${peerPresharedKeySecret nodeName other} = { ${peerPresharedKeySecret nodeName other} = {
file = peerPresharedKeyPath nodeName other; rekeyFile = peerPresharedKeyPath nodeName other;
owner = "systemd-network"; owner = "systemd-network";
# TODO gen func
}; };
}) })
neededPeers) neededPeers)
// { // {
${peerPrivateKeySecret nodeName} = { ${peerPrivateKeySecret nodeName} = {
file = peerPrivateKeyPath nodeName; rekeyFile = peerPrivateKeyPath nodeName;
owner = "systemd-network"; owner = "systemd-network";
# TODO gen func
}; };
}; };
@ -176,7 +178,7 @@
}; };
wireguardConfig = wireguardConfig =
{ {
PrivateKeyFile = config.rekey.secrets.${peerPrivateKeySecret nodeName}.path; PrivateKeyFile = config.age.secrets.${peerPrivateKeySecret nodeName}.path;
} }
// optionalAttrs isServer { // optionalAttrs isServer {
ListenPort = wgCfg.server.port; ListenPort = wgCfg.server.port;
@ -190,7 +192,7 @@
in { in {
wireguardPeerConfig = { wireguardPeerConfig = {
PublicKey = builtins.readFile (peerPublicKeyPath serverNode); PublicKey = builtins.readFile (peerPublicKeyPath serverNode);
PresharedKeyFile = config.rekey.secrets.${peerPresharedKeySecret nodeName serverNode}.path; PresharedKeyFile = config.age.secrets.${peerPresharedKeySecret nodeName serverNode}.path;
AllowedIPs = serverAllowedIPs serverNode; AllowedIPs = serverAllowedIPs serverNode;
Endpoint = "${snCfg.server.host}:${toString snCfg.server.port}"; Endpoint = "${snCfg.server.host}:${toString snCfg.server.port}";
}; };
@ -202,7 +204,7 @@
in { in {
wireguardPeerConfig = { wireguardPeerConfig = {
PublicKey = builtins.readFile (peerPublicKeyPath peerName); PublicKey = builtins.readFile (peerPublicKeyPath peerName);
PresharedKeyFile = config.rekey.secrets.${peerPresharedKeySecret nodeName peerName}.path; PresharedKeyFile = config.age.secrets.${peerPresharedKeySecret nodeName peerName}.path;
AllowedIPs = map (net.cidr.make 128) ips; AllowedIPs = map (net.cidr.make 128) ips;
# Connections to external peers should always be kept alive # Connections to external peers should always be kept alive
PersistentKeepalive = 25; PersistentKeepalive = 25;
@ -215,7 +217,7 @@
in { in {
wireguardPeerConfig = { wireguardPeerConfig = {
PublicKey = builtins.readFile (peerPublicKeyPath clientNode); PublicKey = builtins.readFile (peerPublicKeyPath clientNode);
PresharedKeyFile = config.rekey.secrets.${peerPresharedKeySecret nodeName clientNode}.path; PresharedKeyFile = config.age.secrets.${peerPresharedKeySecret nodeName clientNode}.path;
AllowedIPs = map (net.cidr.make 128) clientCfg.addresses; AllowedIPs = map (net.cidr.make 128) clientCfg.addresses;
}; };
}) })
@ -229,7 +231,7 @@
in in
{ {
PublicKey = builtins.readFile (peerPublicKeyPath wgCfg.client.via); PublicKey = builtins.readFile (peerPublicKeyPath wgCfg.client.via);
PresharedKeyFile = config.rekey.secrets.${peerPresharedKeySecret nodeName wgCfg.client.via}.path; PresharedKeyFile = config.age.secrets.${peerPresharedKeySecret nodeName wgCfg.client.via}.path;
Endpoint = "${snCfg.server.host}:${toString snCfg.server.port}"; Endpoint = "${snCfg.server.host}:${toString snCfg.server.port}";
# Access to the whole network is routed through our entry node. # Access to the whole network is routed through our entry node.
# TODO this should add any routedAddresses on ANY server in the network, right? # TODO this should add any routedAddresses on ANY server in the network, right?
@ -414,6 +416,6 @@ in {
}; };
config = mkIf (cfg != {}) (mergeToplevelConfigs config = mkIf (cfg != {}) (mergeToplevelConfigs
["assertions" "rekey" "networking" "systemd"] ["assertions" "age" "networking" "systemd"]
(mapAttrsToList configForNetwork cfg)); (mapAttrsToList configForNetwork cfg));
} }

View file

@ -13,6 +13,7 @@
apps = [ apps = [
./draw-graph.nix ./draw-graph.nix
./format-secrets.nix ./format-secrets.nix
./generate-secrets.nix
./generate-wireguard-keys.nix ./generate-wireguard-keys.nix
./show-wireguard-qr.nix ./show-wireguard-qr.nix
]; ];

View file

@ -0,0 +1,39 @@
{
self,
pkgs,
...
} @ inputs: let
inherit
(pkgs.lib)
assertMsg
removePrefix
hasPrefix
concatStringsSep
filterAttrs
escapeShellArg
flatten
mapAttrsToList
;
inherit (self.extraLib) rageEncryptArgs;
flakeDir = toString self.sourceInfo.outPath;
relativeToFlake = x: let
xFile = toString x;
in
assert assertMsg (hasPrefix flakeDir xFile) "${xFile} must be a subpath of ${flakeDir}";
"." + removePrefix flakeDir xFile;
x = nodeName: nodeCfg:
mapAttrsToList (_: s: ''
echo ${escapeShellArg (relativeToFlake s.file)}
'') (filterAttrs (_: s: s.generate != null) nodeCfg.config.rekey.secrets);
in
pkgs.writeShellScript "generate-secrets" ''
set -euo pipefail
if [[ ! -e flake.nix ]] ; then
echo "this script must be executed from your flake's root directory." >&2;
exit 1
fi
${concatStringsSep "\n" (flatten (mapAttrsToList x self.nodes))}
''