The End of the SSH Key Management Nightmare
I used to spend my Monday mornings chasing new developers for their public keys. Every time someone joined the team, I had to manually distribute those keys across dozens of production and staging servers. When a contractor finished their project, I had to meticulously scrub their access from every authorized_keys file. It was a manual, error-prone grind that felt completely out of place in a modern DevOps workflow.
Six months ago, I moved our entire infrastructure to Tailscale SSH. The objective was straightforward: eliminate individual keys and hide Port 22 from the public internet. After half a year in production, the results have been a massive relief. We no longer worry about brute-force attacks on our public IPs. Quite simply, there are no public SSH ports left for hackers to scan.
Moving Beyond the Vulnerabilities of Port 22
Traditional SSH relies on a reachable IP address and a cryptographic key pair. While this is secure if you follow every best practice, it has a glaring flaw: visibility. If you check your /var/log/auth.log on a standard cloud VPS, you will likely see over 5,000 failed login attempts from global botnets every single day. That is a lot of unnecessary noise and risk.
Tailscale SSH flips this logic on its head. Instead of verifying a file (the key), it verifies your identity. Since Tailscale is built on WireGuard, it creates a private mesh network—often called a “Tailnet”—between your devices. When you try to connect, Tailscale checks if your authenticated identity from providers like Google, Microsoft, or Okta has permission to access that specific machine. If the identity matches, the connection is encrypted and routed through a secure tunnel.
Here is the kicker: your server’s SSH daemon doesn’t even need to listen on a public interface. You can configure your firewall (UFW, iptables, or AWS Security Groups) to block all incoming traffic on Port 22. As long as the Tailscale service is running, you can connect securely from anywhere.
Setting Up the Environment
Security starts with a solid foundation. Even though we are moving away from traditional SSH, you still need a strong root or sudo password for initial setup or emergency local access. During my server builds, I use the password generator at toolcraft.app/en/tools/security/password-generator. It runs entirely in your browser. No data ever leaves your machine, making it a reliable way to generate 32-character high-entropy strings.
Step 1: Install Tailscale on the Server
First, get the Tailscale agent running on your target machine. For most Linux distributions, you can use this simple script:
curl -fsSL https://tailscale.com/install.sh | sh
Step 2: Authenticate and Enable SSH
Next, bring the node into your Tailnet. We use the --ssh flag to tell Tailscale to handle the SSH traffic for this machine.
sudo tailscale up --ssh
After running this, follow the provided URL to authenticate the machine in your browser. The server is now part of your private network. The --ssh flag instructs the Tailscale daemon to listen for connections on the Tailscale interface (typically 100.x.y.z), effectively bypassing the standard sshd.
Defining Access Control Lists (ACLs)
With Tailscale SSH active, security logic moves from local server files to a centralized Admin Console. You manage everything via a JSON-based Access Control List (ACL). This is where you define exactly who can access which resource.
In our production setup, I group users into categories like group:admin and group:dev. Here is a simplified version of the configuration I use to manage access:
{
"groups": {
"group:admin": ["[email protected]"],
"group:dev": ["[email protected]", "[email protected]"]
},
"ssh": [
{
"action": "accept",
"src": ["group:admin"],
"dst": ["tag:production", "tag:staging"],
"users": ["root", "ubuntu", "admin"]
},
{
"action": "check",
"src": ["group:dev"],
"dst": ["tag:staging"],
"users": ["ubuntu"],
"checkPeriod": "12h"
}
]
}
The "action": "check" feature is a game-changer. It forces users to perform a multi-factor authentication (MFA) check in their browser before the SSH connection is granted. This provides a level of security that standard SSH keys can’t match without a massive amount of custom configuration.
Shutting the Front Door
Once you have confirmed you can connect via Tailscale, it is time to lock Port 22. If you are on Ubuntu using UFW, run these commands:
sudo ufw deny 22/tcp
sudo ufw reload
If you use AWS or DigitalOcean, remove the inbound rule for Port 22 in your Security Groups. Your server is now invisible to the internet’s constant background noise of SSH scanners.
The Daily Workflow: Verification & Monitoring
Connecting to a server now feels seamless. On my local machine, I no longer need to manage identity files or remember IP addresses. I just use the server’s Tailscale hostname:
tailscale ssh ubuntu@prod-db-01
I am never prompted for a password or a key passphrase. Since I am already logged into Tailscale on my laptop, my identity is already proven. If I try to connect from an unauthenticated device, the network layer simply refuses the connection.
Centralized Auditing
The biggest surprise over the last few months was the quality of the logs. The Tailscale Admin Console provides a real-time record of every SSH connection across the fleet. It shows the user, the target machine, and the authentication method used.
On the server itself, standard commands like who or last still work. Tailscale integrates with the system’s login records, so your existing auditing scripts won’t break. For high-security environments, Tailscale also offers “Session Recording.” This captures every command typed and every response received, streaming the data to a secure storage bucket for later review.
Reliability and the “Break-Glass” Scenario
Colleagues often ask what happens if Tailscale goes down. If the coordination servers are unreachable, existing connections remain active. Tailscale uses a distributed architecture, making a total blackout highly unlikely.
However, I still keep a “break-glass” local user for emergencies. I use a high-entropy password accessible only via the cloud provider’s web console, such as AWS Systems Manager or DigitalOcean’s recovery console. This ensures we are never locked out of our own hardware.
A Shift to Zero Trust
Moving to identity-based SSH has fundamentally changed my approach to perimeter security. We have abandoned the “castle and moat” strategy of building thick walls around Port 22. Instead, we use a Zero Trust model where every connection is verified by identity, regardless of the user’s location.
If you are tired of the ~/.ssh/authorized_keys dance, give this a try. It takes about 20 minutes to set up your first server. Once you experience keyless access, you will never want to go back to manual management again.

