105 lines
2.9 KiB
Nix
105 lines
2.9 KiB
Nix
{
|
|
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;
|
|
};
|
|
};
|
|
}
|