Tailscale lets you SSH into a server that has no public IP and no open router ports. You run tailscale up on the server, sign in to the Tailscale app on your phone with the same account, then connect to the machine's 100.x address or its MagicDNS name. ACLs decide who gets in and as which user.

How to install Tailscale and run tailscale up on a Linux server

tailscale up joins the machine to your tailnet and prints a login URL. Once you authenticate, the machine gets a 100.x address. On Linux, the official script installs both the package and the service:

curl -fsSL https://tailscale.com/install.sh | sh
sudo tailscale up
tailscale ip -4
tailscale status

tailscale ip -4 prints the machine's tailnet IPv4 address, and tailscale status lists the other devices with their names and state. Traffic between nodes is encrypted over WireGuard. Each node opens its connection outbound, so you don't need to forward TCP port 22 on the router or have a public IP.

On macOS, iOS and Android you don't type tailscale up. You install the Tailscale app and sign in from its interface.

Tailscale 100.x addresses and MagicDNS: which host your SSH client targets

Every Tailscale node gets an address from the 100.64.0.0/10 range, reachable only inside your tailnet. MagicDNS also gives it a name that matches the machine name. Any SSH client accepts all three forms:

ssh [email protected]
ssh deploy@servidor
ssh [email protected]

The short name is the most convenient. If it doesn't resolve on a given device, use the full .ts.net name instead. Save the connection under its MagicDNS name rather than the IP. That way, if the node re-registers and its address changes, the name still points to the right machine.

If you'd rather not depend on Tailscale, Prialo private mesh network solves the same problem: reaching machines without opening ports.

Tailscale SSH vs OpenSSH with keys: comparison table

sudo tailscale set --ssh turns on Tailscale SSH on the server. Tailscale then answers connections to port 22 that arrive over the tailnet and authenticates them with your account identity, so no keys are needed in authorized_keys. The alternative is to keep OpenSSH with keys and use Tailscale purely as the network.

What is comparedOpenSSH with keys over TailscaleTailscale SSH
AuthenticationEd25519 or RSA key in authorized_keysTailscale account identity
Who grants accesssshd and authorized_keys on each serverThe ssh section of the ACL policy file
Re-authenticationNot available by defaultThe check action requires confirming the login again
If Tailscale is unavailableThe key still works from the local networkNo access through that path
Client on iOS/AndroidAny SSH client with the key loadedAny SSH client connected to the tailnet

If you stay with keys, use Ed25519. OpenSSH has supported it since version 6.5 (January 2014), and FIDO2-backed ed25519-sk keys since 8.2. In termi1 you can generate the key on the phone itself; it is kept in the system's secure store, and the private key never leaves the device.

Tailscale ACLs for SSH: restricting who gets in and as which user

The Tailscale policy file has two layers. acls controls who can reach port 22, and ssh controls who may use Tailscale SSH and as which local user. This example lets only the admins group in, and only as deploy, on servers tagged as production:

{
  "groups": { "group:admins": ["[email protected]"] },
  "tagOwners": { "tag:prod": ["group:admins"] },
  "acls": [
    { "action": "accept", "src": ["group:admins"], "dst": ["tag:prod:22"] }
  ],
  "ssh": [
    { "action": "check", "src": ["group:admins"], "dst": ["tag:prod"], "users": ["deploy"] }
  ]
}

You apply the tag to the server with the --advertise-tags=tag:prod option of tailscale up. With "action": "accept" access is immediate; with "check" Tailscale asks you to confirm your identity before the session opens. Each field is explained in the official Tailscale SSH documentation.

Mosh, tmux and SFTP over Tailscale from your phone with termi1

Mosh starts mosh-server through an initial SSH connection and then switches to UDP, on ports 60000-61000 by default. Inside the tailnet those ports don't need opening on the router either:

mosh deploy@servidor
tmux new -A -s main

termi1 keeps the session alive with Mosh when you move from Wi-Fi to mobile data, and tmux preserves whatever you left running for when you come back. Mosh does no port forwarding and no X11 forwarding, so open a separate SSH session if you need a tunnel. The termi1 keyboard has Esc, Ctrl, Tab and arrow keys for driving tmux. Its built-in SFTP lets you upload or download files over the same MagicDNS name without leaving the session.

If you mark your connections to tag:prod servers as production in termi1, Production Guard stops the AI from pressing Enter on them. It also holds back anything that deletes, stops or changes something before it reaches the prompt. The app is on the App Store for iPhone and on Google Play.

4 mistakes when connecting over SSH through Tailscale

  1. The Tailscale app on the phone is disconnected. If the Tailscale VPN isn't active, neither 100.x addresses nor MagicDNS names resolve, and the SSH client times out.
  2. Rerunning tailscale up with different options. tailscale up expects you to repeat every non-default option you set before. To change a single setting, use tailscale set.
  3. Leaving port 22 open on the public interface. With ufw, allow the tailnet interface first, then remove the general rule: sudo ufw allow in on tailscale0 and sudo ufw delete allow 22/tcp. Check that you can get in over Tailscale before removing it.
  4. Wrong permissions with OpenSSH. sshd rejects the key if ~/.ssh is not set to 700 or if authorized_keys is not set to 600.

Frequently asked questions

Does Tailscale need open router ports for SSH?

Tailscale does not need any open router ports for SSH. Each node opens its connection outbound, and traffic is encrypted over WireGuard inside the tailnet. All you need is for the server and the phone to be signed in to the same account, with ACLs that allow port 22.

What is the difference between Tailscale SSH and SSH with keys?

Tailscale SSH authenticates with your Tailscale account identity and enforces the ssh section of your ACLs, so no keys are needed in authorized_keys. SSH with keys runs regular OpenSSH over the tailnet and keeps working from the local network even when Tailscale is unavailable.

Does Mosh work over Tailscale?

Mosh works over Tailscale. It starts mosh-server through an initial SSH connection, then uses UDP inside the tailnet, on ports 60000-61000 by default. You don't need to open those ports on the router, but the server's local firewall must allow them on the Tailscale interface.

Can I use MagicDNS instead of the 100.x address?

MagicDNS gives every tailnet machine a name that matches its hostname, so you can type ssh deploy@servidor instead of the 100.x address. If the short name doesn't resolve, use the full name ending in .ts.net shown in the Tailscale admin console.