diff --git a/nixos/doc/manual/release-notes/rl-2411.section.md b/nixos/doc/manual/release-notes/rl-2411.section.md index 48dc9b31b685..377512493937 100644 --- a/nixos/doc/manual/release-notes/rl-2411.section.md +++ b/nixos/doc/manual/release-notes/rl-2411.section.md @@ -516,6 +516,9 @@ - `lib.misc.mapAttrsFlatten` is now formally deprecated and will be removed in future releases; use the identical [`lib.attrsets.mapAttrsToList`](https://nixos.org/manual/nixpkgs/unstable#function-library-lib.attrsets.mapAttrsToList) instead. +- Tailscale's `authKeyFile` can now have its corresponding parameters set through `config.services.tailscale.authKeyParameters`, allowing for non-ephemeral unsupervised deployment and more. + See [Registering new nodes using OAuth credentials](https://tailscale.com/kb/1215/oauth-clients#registering-new-nodes-using-oauth-credentials) for the supported options. + - `nixosTests` now provide a working IPv6 setup for VLAN 1 by default. - Kanidm can now be provisioned using the new [`services.kanidm.provision`] option, but requires using a patched version available via `pkgs.kanidm.withSecretProvisioning`. diff --git a/nixos/modules/services/networking/tailscale.nix b/nixos/modules/services/networking/tailscale.nix index 2acae677390c..6804165cd8c2 100644 --- a/nixos/modules/services/networking/tailscale.nix +++ b/nixos/modules/services/networking/tailscale.nix @@ -60,6 +60,33 @@ in { ''; }; + authKeyParameters = mkOption { + type = types.submodule { + options = { + ephemeral = mkOption { + type = types.nullOr types.bool; + default = null; + description = "Whether to register as an ephemeral node."; + }; + preauthorized = mkOption { + type = types.nullOr types.bool; + default = null; + description = "Whether to skip manual device approval."; + }; + baseURL = mkOption { + type = types.nullOr types.str; + default = null; + description = "Base URL for the Tailscale API."; + }; + }; + }; + default = { }; + description = '' + Extra parameters to pass after the auth key. + See https://tailscale.com/kb/1215/oauth-clients#registering-new-nodes-using-oauth-credentials + ''; + }; + extraUpFlags = mkOption { description = '' Extra flags to pass to {command}`tailscale up`. Only applied if `authKeyFile` is specified."; @@ -124,13 +151,22 @@ in { # https://github.com/tailscale/tailscale/blob/v1.72.1/ipn/backend.go#L24-L32 script = let statusCommand = "${lib.getExe cfg.package} status --json --peers=false | ${lib.getExe pkgs.jq} -r '.BackendState'"; + paramToString = v: + if (builtins.isBool v) then (lib.boolToString v) + else (toString v); + params = lib.pipe cfg.authKeyParameters [ + (lib.filterAttrs (_: v: v != null)) + (lib.mapAttrsToList (k: v: "${k}=${paramToString v}")) + (builtins.concatStringsSep "&") + (params: if params != "" then "?${params}" else "") + ]; in '' while [[ "$(${statusCommand})" == "NoState" ]]; do sleep 0.5 done status=$(${statusCommand}) if [[ "$status" == "NeedsLogin" || "$status" == "NeedsMachineAuth" ]]; then - ${lib.getExe cfg.package} up --auth-key 'file:${cfg.authKeyFile}' ${escapeShellArgs cfg.extraUpFlags} + ${lib.getExe cfg.package} up --auth-key "$(cat ${cfg.authKeyFile})${params}" ${escapeShellArgs cfg.extraUpFlags} fi ''; };