Compare commits

...

2 commits

Author SHA1 Message Date
9fb72e762b
docs(age): improve readability with structured comments
Add section headers and explanatory comments to clarify the purpose of each configuration block, with emphasis on the critical persistent path requirement for early boot secret decryption.
2025-10-12 10:19:42 +08:00
4389500ccc
fix(borgbackup): add network dependencies to onsite services
Fixes DNS resolution failures when persistent timers trigger backups
after system wake.

The NixOS borgbackup module adds network-online.target dependencies
to the timer when persistentTimer=true, but systemd timers don't pass
their dependencies to the services they trigger. This caused onsite
backups to start before the network was ready, resulting in "Could not
resolve hostname" errors.

Adding after/wants network-online.target directly to the service
ensures the backup waits for network availability regardless of how
it's triggered (timer or offsite's Wants= dependency).

Example failure (Oct 11, 07:43):
- Backup started at 07:43:43 (persistent timer caught up)
- DNS lookup failed: "Could not resolve hostname viridian.home.arpa"
- WiFi connected at 07:43:47 (4 seconds too late)

Applied to both fuchsia and viridian onsite backups.
2025-10-11 08:06:00 +08:00
3 changed files with 18 additions and 3 deletions

View file

@ -1,3 +1,5 @@
# Agenix secret management with YubiKey rekeying
# Handles encrypted secrets for services requiring credentials
{
config,
pkgs,
@ -6,25 +8,34 @@
}: let
hostname = config.networking.hostName;
in {
# Module imports
imports = [
inputs.agenix.nixosModules.default
inputs.agenix-rekey.nixosModules.default
];
# Overlay provides agenix-rekey package and extensions
nixpkgs.overlays = [
inputs.agenix-rekey.overlays.default
];
# CLI tool for manual secret rekeying operations
environment.systemPackages = with pkgs; [
agenix-rekey
];
# Secret decryption configuration
# Use persistent paths to ensure SSH keys are available during early boot
# activation, before impermanence bind mounts /etc/ssh/
age.identityPaths = [
"/persist/etc/ssh/ssh_host_rsa_key"
"/persist/etc/ssh/ssh_host_ed25519_key"
];
# YubiKey-based secret rekeying
age.rekey = {
# Pubkey for rekeying
hostPubkey = ../../${hostname}/ssh_host_ed25519_key.pub;
# Master identity used for decryption
masterIdentities = [../users/sajenim/agenix-rekey.pub];
# Where we store the rekeyed secrets
storageMode = "local";
localStorageDir = ./. + "/secrets/rekeyed/${config.networking.hostName}";
};

View file

@ -13,6 +13,8 @@ in {
# Configure service to wait for completion before marking as active
systemd.services."borgbackup-job-onsite" = {
after = [ "network-online.target" ];
wants = [ "network-online.target" ];
serviceConfig = {
Type = "oneshot";
};

View file

@ -22,6 +22,8 @@ in {
# Configure service to wait for completion before marking as active
systemd.services."borgbackup-job-onsite" = {
after = [ "network-online.target" ];
wants = [ "network-online.target" ];
serviceConfig = {
Type = "oneshot";
};