Commit cd19ec4
Changed files (1)
modules
services
modules/services/headscale.nix
@@ -81,6 +81,8 @@
(builtins.attrNames r.value)
)
reverseProxyTailscale;
+
+ dnsRecordsFile = "/var/lib/headscale/dns-records.json";
in {
services.headscale = {
enable = true;
@@ -121,17 +123,63 @@
"2400:3200::1" # AliDNS
"2606:4700:4700::1111" # Cloudflare
];
- extra_records = tailscaleRecords;
+ extra_records_path = dnsRecordsFile;
};
};
};
networking.firewall.allowedUDPPorts = lib.optional (cfg.derp.enable) cfg.derp.port;
- systemd.services.headscale = {
- serviceConfig.EnvironmentFile =
- lib.mkIf (hostAddr.ipv4.secret.name != null || hostAddr.ipv6.secret.name != null)
- config.vaultix.templates.headscale-env.path;
+ systemd.services.headscale = let
+ mutableConfig = "/var/lib/headscale/config.yaml";
+ nixConfig = config.services.headscale.configFile;
+ hsCfg = config.services.headscale;
+
+ nixDnsRecords =
+ pkgs.writeText "headscale-dns-records.json"
+ (builtins.toJSON tailscaleRecords);
+
+ mergeHeadscaleState = pkgs.writeShellScript "merge-headscale-state" ''
+ set -euo pipefail
+
+ # Merge main configuration
+ if [ -f "${mutableConfig}" ]; then
+ ${lib.getExe pkgs.yq-go} eval-all '. as $item ireduce ({}; . * $item)' \
+ "${mutableConfig}" \
+ "${nixConfig}" \
+ > "${mutableConfig}.tmp" \
+ && mv "${mutableConfig}.tmp" "${mutableConfig}"
+ else
+ cp "${nixConfig}" "${mutableConfig}"
+ chmod 0640 "${mutableConfig}"
+ fi
+
+ # Merge DNS extra records
+ if [ -f "${dnsRecordsFile}" ]; then
+ ${lib.getExe pkgs.yq-go} eval-all '. as $item ireduce ([]; . + $item) | unique_by(.name + "|" + .type)' \
+ "${nixDnsRecords}" \
+ "${dnsRecordsFile}" \
+ > "${dnsRecordsFile}.tmp" \
+ && mv "${dnsRecordsFile}.tmp" "${dnsRecordsFile}"
+ else
+ cp "${nixDnsRecords}" "${dnsRecordsFile}"
+ chmod 0640 "${dnsRecordsFile}"
+ fi
+ '';
+ in {
+ serviceConfig = {
+ ExecStartPre = [mergeHeadscaleState];
+ EnvironmentFile =
+ lib.mkIf (hostAddr.ipv4.secret.name != null || hostAddr.ipv6.secret.name != null)
+ config.vaultix.templates.headscale-env.path;
+ };
+
+ script = lib.mkForce ''
+ ${lib.optionalString (hsCfg.settings.database.postgres.password_file != null) ''
+ export HEADSCALE_DATABASE_POSTGRES_PASS="$(head -n1 ${lib.escapeShellArg hsCfg.settings.database.postgres.password_file})"
+ ''}
+ exec ${lib.getExe hsCfg.package} serve --config ${mutableConfig}
+ '';
};
vaultix.templates.headscale-env =
lib.mkIf (hostAddr.ipv4.secret.name != null || hostAddr.ipv6.secret.name != null)