tailscale-derp-client-verifier

Why

Because I want to run a tailscale DERP server without trusting it.

  1. tailscale is end-to-end encrypted by design1

  2. Insecure DERP server or connection is still secure for the DERP users, no MITM issue2

  3. --verify-clients requires to add this DERP server as one of your tailscaled nodes, in my opinion, it's risky, even with the ACLs.

  4. --verify-client-url allows derper to check an external URL for whether to permit access3

Build

# with Go 1.22.3+
go build -x -v -trimpath -ldflags "-s -w" -buildvcs=false -o tailscale-derp-client-verifier .

Usage

  1. On the trusted tailscaled node machine: get the nodes.json from your trusted homelab server or laptop, and sync the nodes.json to the DERP server machine:

You can achieve this in many ways, I do this with rclone, systemd timer and S3 object storage:

#! /usr/bin/env bash
set -e
set -x

[ -f "$RCLONE_CONFIG_FILE" ]
[ -d "$WORK_DIR" ]
[ -n "$TAILSCALE_S3_REMOTE_NAME" ]
[ -n "$TAILSCALE_S3_BUCKET" ]

cd $WORK_DIR

tailscale status --json | jq '[recurse | objects | with_entries(select(.key == "PublicKey")) | .[]] | sort' > "temp.nodes.json"

jq -e . "temp.nodes.json"

if [ "$(cat "nodes.json" || true)" != "$(cat "temp.nodes.json")" ]; then
  rclone --config "$RCLONE_CONFIG_FILE" --contimeout=3m --timeout=10m --checksum copyto \
    "temp.nodes.json" "$TAILSCALE_S3_REMOTE_NAME:$TAILSCALE_S3_BUCKET/nodes.json"
  mv "temp.nodes.json" "nodes.json"
fi
  1. On the DERP server machine: run tailscale-derp-client-verifier

If you're not syncing the nodes.json with S3 object storage:

/path/to/tailscale-derp-client-verifier -path /path/to/nodes.json

I use S3, so:

. .env

/path/to/tailscale-derp-client-verifier
# .env file
S3_ACCESS_KEY_ID=
S3_SECRET_ACCESS_KEY=
S3_ENDPOINT=
S3_REGION=
S3_BUCKET=
S3_FILE=nodes.json
S3_FORCE_PATH_STYLE=
  1. On the DERP server machine: deploy the derper
derper <... other args> --verify-clients=false --verify-client-url-fail-open=false --verify-client-url=http://127.0.0.1:3000

Footnotes

  1. https://tailscale.com/security

  2. https://github.com/tailscale/tailscale/issues/12107#issuecomment-2106233579

  3. https://github.com/tailscale/tailscale/pull/11193