Skip to main content

Tailscale Networking and OpenSSH

What Tailscale does here​

Tailscale connects devices to a private network based on WireGuard, called a tailnet, and assigns stable private addresses to its nodes. It gives the client a secure path to the VPS, with 100.x addresses; it does not automatically create a working service on the destination. SSH still requires sshd listening on port 22 on the VPS.

WSL2 ssh client
-> Windows host's Tailscale connectivity
-> VPS's 100.x Tailscale address
-> Ubuntu sshd
-> authorized_keys public-key authentication

In this setup, Windows is the tailnet node and WSL2 uses its VPN connectivity through the Windows network stack. If WSL2 can already reach the VPS's Tailscale address, there is no need to install a second Tailscale node inside WSL2. WSL networking modes and VPNs can behave differently, so verify the actual route and SSH connection.

This is not Tailscale SSH​

The names are similar, but the two approaches work differently:

ApproachNetworkSSH service and authentication
OpenSSH over TailscaleTailscale supplies the private network pathUbuntu's sshd handles SSH and still uses user public keys
Tailscale SSHTailscale supplies the network and takes over port 22 connections arriving through the tailnetTailscale manages authentication and authorization policies

This series uses the first approach, so do not run:

tailscale set --ssh

Install Tailscale on the VPS and join the tailnet​

First, check whether it is already installed:

[REMOTE: VPS]
command -v tailscale || true
systemctl status tailscaled --no-pager || true

The official Linux quick-install method is:

[REMOTE: VPS]
curl -fsSL https://tailscale.com/install.sh | sh
sudo tailscale up

In a more restrictive environment, inspect the script or configure the official repository manually for the distribution. tailscale up may print a browser authorization URL. Display only that URL and let the operator sign in and authorize the node; never embed an auth key in the script.

Verify the node's state​

[REMOTE: VPS]
tailscale status
tailscale ip -4
systemctl is-enabled tailscaled
systemctl is-active tailscaled

A node shown as enrolled or “online” in the admin console proves registration, not client-to-service reachability. It does not replace an end-to-end test from the actual client.

Verify from WSL2​

[LOCAL: WSL2]
ping -c 3 "$TAILSCALE_IPV4"

ssh \
-i "$HOME/.ssh/id_ed25519" \
-o IdentitiesOnly=yes \
-o PreferredAuthentications=publickey \
-o PasswordAuthentication=no \
"$VPS_USER@$TAILSCALE_IPV4"

ping helps check the basic network path, but a successful SSH connection is the acceptance test for remote management. Inside the successful session, inspect:

[REMOTE: session reached through Tailscale]
printf '%s\n' "$SSH_CONNECTION"

This normally shows the client's Tailscale IP, the client's ephemeral port, the VPS's Tailscale IP, and port 22. These values can confirm that the connection took the intended path.

Common failures​

  • Windows is online, but WSL2 still times out: check the WSL networking mode, Windows VPN/firewall behavior, and the route to 100.x; do not immediately close public port 22.
  • Ping works, but SSH times out: check sshd on the VPS, UFW interface rules, and port listeners.
  • SSH prompts for a new host key: compare the VPS public host-key fingerprint through a known-good path.
  • The console shows the node online, but connections fail: an online state is not application-level verification; test an actual connection from WSL2 itself.

Keep public SSH available until a fresh OpenSSH-over-Tailscale session succeeds reliably; only then tighten public SSH access.

Explore connectionsOpen network