Initial commit

This commit is contained in:
stherm 2026-03-06 08:31:13 +01:00
commit 430194beda
109 changed files with 9066 additions and 0 deletions

View file

@ -0,0 +1,105 @@
{
config,
lib,
...
}:
let
cfg = config.services.headscale;
domain = config.networking.domain;
subdomain = cfg.reverseProxy.subdomain;
fqdn = if (cfg.reverseProxy.enable && subdomain != "") then "${subdomain}.${domain}" else domain;
acl = "headscale/acl.hujson";
inherit (lib)
mkDefault
mkIf
mkOption
optional
optionals
types
;
inherit (lib.utils)
mkReverseProxyOption
mkUrl
mkVirtualHost
;
in
{
options.services.headscale = {
reverseProxy = mkReverseProxyOption "Headscale" "hs";
openFirewall = mkOption {
type = types.bool;
default = false;
description = "Whether to automatically open firewall ports. TCP: 80, 443; UDP: 3478.";
};
};
config = mkIf cfg.enable {
assertions = [
{
assertion = !cfg.settings.derp.server.enable || cfg.reverseProxy.forceSSL;
message = "cryodev/nixos/headscale: DERP requires TLS";
}
{
assertion = fqdn != cfg.settings.dns.base_domain;
message = "cryodev/nixos/headscale: `settings.server_url` must be different from `settings.dns.base_domain`";
}
{
assertion = !cfg.settings.dns.override_local_dns || cfg.settings.dns.nameservers.global != [ ];
message = "cryodev/nixos/headscale: `settings.dns.nameservers.global` must be set when `settings.dns.override_local_dns` is true";
}
];
environment.etc.${acl} = {
inherit (config.services.headscale) user group;
source = ./acl.hujson;
};
environment.shellAliases = {
hs = "${cfg.package}/bin/headscale";
};
services.headscale = {
address = mkDefault (if cfg.reverseProxy.enable then "127.0.0.1" else "0.0.0.0");
port = mkDefault 8077;
settings = {
policy.path = "/etc/${acl}";
database.type = "sqlite"; # postgres is highly discouraged as it is only supported for legacy reasons
server_url = mkUrl {
inherit fqdn;
ssl = with cfg.reverseProxy; enable && forceSSL;
};
derp.server.enable = cfg.reverseProxy.forceSSL;
dns = {
magic_dns = mkDefault true;
base_domain = mkDefault "tail";
search_domains = [ cfg.settings.dns.base_domain ];
override_local_dns = mkDefault true;
nameservers.global = optionals cfg.settings.dns.override_local_dns [
"1.1.1.1"
"1.0.0.1"
"2606:4700:4700::1111"
"2606:4700:4700::1001"
];
};
};
};
services.nginx.virtualHosts = mkIf cfg.reverseProxy.enable {
"${fqdn}" = mkVirtualHost {
inherit (cfg) address port;
ssl = cfg.reverseProxy.forceSSL;
};
};
networking.firewall = mkIf cfg.openFirewall {
allowedTCPPorts = [
80
443
];
allowedUDPPorts = optional cfg.settings.derp.server.enable 3478;
};
};
}