Tailscale Networking and OpenSSH
Tailscale gives devices a private tailnet path and stable 100.x addresses. It does not create an application service: the VPS still needs sshd listening on port 22.
WSL2 ssh client -> Windows Tailscale path -> VPS Tailscale IP
-> Ubuntu sshd -> authorized_keys
Here Windows is the tailnet node and WSL2 uses the Windows networking path. If WSL2 can already reach the VPS Tailscale IP, installing a second Tailscale node inside WSL2 adds needless complexity. WSL networking and VPN behavior varies, so verify the actual route.
This is OpenSSH over Tailscale. It is not Tailscale SSH, which takes over tailnet port 22 and manages authentication and authorization. Do not run tailscale set --ssh for this design.
command -v tailscale || true
systemctl status tailscaled --no-pager || true
curl -fsSL https://tailscale.com/install.sh | sh
sudo tailscale up
tailscale status
tailscale ip -4
systemctl is-enabled tailscaled
systemctl is-active tailscaled
The authorization URL is an operator step; never embed an auth key. An admin-console “online” state proves enrollment, not client-to-service reachability.
ping -c 3 "$TAILSCALE_IPV4"
ssh -i "$HOME/.ssh/id_ed25519" \
-o IdentitiesOnly=yes \
-o PreferredAuthentications=publickey \
-o PasswordAuthentication=no \
"$VPS_USER@$TAILSCALE_IPV4"
Inside the successful remote session, printf '%s\n' "$SSH_CONNECTION" shows the source and destination addresses and can confirm the intended path. Ping success alone is insufficient. If WSL2 times out, inspect Windows VPN/firewall behavior and routing; keep public SSH until a fresh OpenSSH-over-Tailscale session succeeds.