{ config, pkgs, ... }: let svc_domain = config.mine.shared.settings.headscale.domain; svc_domain_dns_magic_domain = "ts.${config.mine.shared.settings.domain}"; grpc_port = 50443; in { services.headscale = { enable = true; settings = { server_url = "https://${svc_domain}"; # grpc grpc_listen_addr = "127.0.0.1:${builtins.toString grpc_port}"; grpc_allow_insecure = true; # dns dns.base_domain = svc_domain_dns_magic_domain; dns.nameservers.global = [ "1.1.1.1" ]; # acl -> save in database policy.mode = "database"; # auth oidc = { only_start_if_oidc_is_available = true; issuer = "https://${config.mine.shared.settings.authelia.domain}"; client_id = "headscale"; client_secret_path = "$CREDENTIALS_DIRECTORY/authelia-secret"; }; # debug log.level = "debug"; }; }; systemd.services.headscale.serviceConfig.LoadCredential = [ "authelia-secret:${config.age.secrets.headscale-authelia-secret.path}" ]; # setup for oidc services.authelia.instances.main.settings.identity_providers.oidc.clients = [{ client_id = "headscale"; client_name = "Headscale"; client_secret = "$pbkdf2-sha512$310000$/xiUR1oDvUEn4OKEu31COw$Z.IMgW3Qb2.mgCyEq1UUDC0i7cX2GOiywUjY4MsNv4ixQCP1jFO7njctCW2mVCqvkgfylDpsWRM3z.uXTs89IA"; consent_mode = "implicit"; redirect_uris = [ "https://${svc_domain}/oidc/callback" ]; scopes = [ "openid" "profile" "email" ]; }]; # nginx services.nginx.virtualHosts."${svc_domain}" = { forceSSL = true; enableACME = true; # headscale gRPC API locations."/headscale" = { extraConfig = '' grpc_pass 127.0.0.1:${builtins.toString grpc_port}; ''; priority = 0; }; # fallback to headscale locations."/" = { proxyPass = "http://127.0.0.1:${builtins.toString config.services.headscale.port}"; proxyWebsockets = true; }; }; # persistence environment.persistence.root.directories = [ "/var/lib/headscale" ]; }