[solved] Possible to automatically authenticate Tailscale after every rebuild/reboot?

Update: Got some good info on both reddit and the tailscale forums on this.

Here’s my working config combining both those recommendations:

  # always allow traffic from your Tailscale network
  networking.trustedInterfaces = [ "tailscale0" ];

  # allow the Tailscale UDP port through the firewall
  allowedUDPPorts = [ config.services.tailscale.port ];

  # Tailscale keys
  # Create a secrets location for your tailscale auth keys.  Create a reusable key at
  # https://login.tailscale.com/admin/settings/authkeys, save it in a file, and put that file in your secrets location
  # If you're running an "Erase Your Darlings" setup, don't forget to persist your tailscale secrets location  
  environment.etc."tailscale".source = "/persist/etc/tailscale/";
  
  # Tailscale autu-auth config, based on:
  # https://tailscale.com/blog/nixos-minecraft/
  services.tailscale.enable = true;

  # create a systemd oneshot job to authenticate to Tailscale on startup
  systemd.services.tailscale-autoconnect = {
    description = "Automatic connection to Tailscale";

    # make sure tailscale is running before trying to connect to tailscale
    after = [ "network-pre.target" "tailscale.service" ];
    wants = [ "network-pre.target" "tailscale.service" ];
    wantedBy = [ "multi-user.target" ];

    # set this service as a oneshot job
    serviceConfig.Type = "oneshot";

    # have the job run this shell script
    script = with pkgs; ''

      # wait for tailscaled to settle
      echo "Waiting for tailscale.service start completion ..." 
      sleep 5
      # (as of tailscale 1.4 this should no longer be necessary, but I find it still is)

      # check if already authenticated
      echo "Checking if already authenticated to Tailscale ..."
      status="$(${tailscale}/bin/tailscale status -json | ${jq}/bin/jq -r .BackendState)"
      if [ $status = "Running" ]; then  # do nothing
      	echo "Already authenticated to Tailscale, exiting."
        exit 0
      fi

      # otherwise authenticate with tailscale
      echo "Authenticating with Tailscale ..."
      # old: ${tailscale}/bin/tailscale up --authkey $(cat /etc/tailscale/tskey-reusable)
      ${tailscale}/bin/tailscale up --auth-key file:/etc/tailscale/tskey-reusable
    '';
  };

I’m running Tailscale free tier, and every time I rebuild and reboot, I have to re-authenticate Tailscale.

Eg, after the system starts, I manually run sudo tailscale up, and it gives me a tailscale authentication url to load in a browser.

Is there 1) any way to automate this process, and 2) reuse a prior Tailscale authentication instead of creating a new one? (I have 8 different Tailscale authentications for the same workstation now in the Tailscale control panel)

1 Like

You probably should look into tailscale documentation and especially read the service configuration documentation (or ask their support). Once you have that information it’s just a matter of enriching the configuration of the systemd.services.tailscale service that is created by the services.tailscale config entry, probably.

2 Likes

Bit of a necrobump but it pops up via search engines so figured I’d post how I solved it:

  services.tailscale = {
    enable = true;
    openFirewall = true;
    authKeyFile = config.age.secrets.vpn-preauth.path;
    extraUpFlags = [
      "--login-server=https://your-instance" # if you use a non-default tailscale coordinator
      "--accept-dns=false" # if its' a server you prolly dont need magicdns
    ];
  };

  age.secrets.vpn-preauth.file = ../secrets/vpn-preauth.age;

Remember to make your preauth key reproducible and (if possible? idk about official Tailscale but it is with Headscale) make it last for how long fits with your security policy (rotating it often is kind of annoying, but at the same time it only applies when new servers are enrolled into Tailscale)

2 Likes

Oh nice, thx for the update, that services module didn’t exist when I posted this. Much nicer to have that built into NixOS now. Will convert my own config to that now. Cheers!