current
1{lib, ...}: {
2 den.aspects.services.provides.headscale = domain: {host}: {
3 nixos = {
4 pkgs,
5 config,
6 ...
7 }: {
8 environment.systemPackages = [pkgs.headscale];
9 services.headscale = {
10 enable = true;
11 address = "127.0.0.1";
12 port = 3324;
13 settings = {
14 server_url = "https://${domain}";
15 metrics_listen_addr = "127.0.0.1:9190";
16 derp.server = {
17 enabled = true;
18 stun_listen_addr = "0.0.0.0:3478";
19 verify_clients = true;
20 region_id = 999;
21 region_code = "headscale";
22 region_name = "Headscale Embedded DERP";
23 };
24 database.type = "sqlite";
25 tls_cert_path = null; # Use Caddy for TLS instead.
26 tls_key_path = null;
27 dns = {
28 # Magic DNS is not needed for me.
29 magic_dns = false;
30 override_local_dns = false;
31 };
32 };
33 };
34
35 networking.firewall.allowedUDPPorts = [3478];
36
37 systemd.services.headscale.serviceConfig.EnvironmentFile = config.vaultix.templates.headscale-env.path;
38
39 services.caddy.virtualHosts.${domain}.extraConfig =
40 lib.mkIf config.services.caddy.enable
41 (let
42 localAddress = "http://${config.services.headscale.settings.listen_addr}";
43 in ''
44 encode zstd gzip
45 reverse_proxy ${localAddress}
46 '');
47
48 services.restic.backups."${config.networking.hostName}-backup".paths =
49 lib.mkIf
50 (builtins.hasAttr "${config.networking.hostName}-backup" config.services.restic.backups)
51 ["/var/lib/headscale"];
52
53 vaultix.templates.headscale-env = {
54 content = lib.concatLines (
55 (
56 lib.optional
57 (lib.hasAttr "hosts-${host.name}-ipv4" config.vaultix.placeholder)
58 "HEADSCALE_DERP_SERVER_IPV4=${config.vaultix.placeholder."hosts-${host.name}-ipv4"}"
59 )
60 ++ (
61 lib.optional
62 (lib.hasAttr "hosts-${host.name}-ipv6" config.vaultix.placeholder)
63 "HEADSCALE_DERP_SERVER_IPV6=${config.vaultix.placeholder."hosts-${host.name}-ipv6"}"
64 )
65 );
66 owner = "root";
67 group = config.services.headscale.group;
68 mode = "0440";
69 };
70 };
71 };
72}