Close Port 22 Forever: Secure a VPS With Tailscale
A freshly deployed VPS typically exposes SSH, an admin API, and a database alongside its web ports — and automated bots scan the entire IPv4 address space in under 45 minutes, according to the SANS Internet Storm Center. Installing Tailscale and closing every port except 80 and 443 removes that exposed attack surface without giving up SSH or database access for yourself.
You spin up a VPS, install your deployment platform, and push your first app. It works. You feel good.
Then you run netstat -tlnp and realize your server is listening on six ports. Port 22 for SSH. Port 80 and 443 for web traffic. Port 8080 for your admin API. Port 5432 for PostgreSQL. Maybe a few more you forgot about.
Every one of those ports is a door. And every door is being knocked on — constantly. Automated bots scan the entire IPv4 address space in under 45 minutes (SANS Internet Storm Center). According to AhnLab ASEC, a fresh cloud VPS with default credentials typically receives its first probing attempt within 90 seconds of going live.
Most developers know they should "secure their server." Few actually do it properly. This guide shows you how to lock down your VPS using Tailscale so that the only ports exposed to the public internet are 80 and 443 — nothing else.
If you're looking for a self-hosted deployment platform, security should be step one after installation.
TL;DR: A fresh VPS gets its first SSH probe within 90 seconds. You can eliminate most of your attack surface by routing SSH, databases, and admin panels through Tailscale's WireGuard mesh — leaving only ports 80 and 443 exposed. Setup takes about 15 minutes and costs nothing extra.
What is the best VPS for Tailscale in 2026? There is no universal best provider, but Hetzner is a strong value option in Europe. Its CX23 has 2 shared vCPUs, 4 GB of RAM, and 20 TB of included EU traffic; new Germany and Finland orders are listed at EUR 5.49 per month excluding VAT and IPv4 after the June 2026 price adjustment. If you also want to deploy applications, Temps combines deployment and observability features in one Rust binary. Size the server for your application and telemetry workload rather than assuming every workload will fit on the entry plan.
Why Is Every Open Port an Attack Surface?
According to the IBM Cost of a Data Breach Report, the global average cost of a data breach hit $4.44 million in 2025 — and $10.22 million for US companies specifically, an all-time high. Compromised servers are a leading entry point. Most VPS breaches don't start with sophisticated exploits. They start with an open port that shouldn't have been public.
What's Actually Exposed on a Typical VPS
Here's what a freshly provisioned VPS running a deployment platform typically exposes:
| Port | Service | Needs Public Access? |
|---|---|---|
| 22 | SSH | No |
| 80 | HTTP (Let's Encrypt + redirects) | Yes |
| 443 | HTTPS (production traffic) | Yes |
| 5432 | PostgreSQL | No |
| 8080 | Admin API / Dashboard | No |
| 6379 | Redis | No |
| 2375 | Docker API | No |
Only two of those ports serve your users. The rest are management and infrastructure services that should never be reachable from the public internet.
What Happens When You Leave Them Open
This isn't theoretical. according to the CrowdStrike Global Threat Report, 89% of Linux endpoint attacks in 2025 involved credential stuffing or brute force against exposed SSH ports. Here's what happens to exposed services:
- SSH (port 22) — Automated bots try thousands of username/password combinations per hour. In Q4 2025, the P2PInfect worm accounted for 80% of all SSH server attacks. Even with key-only auth, you're burning CPU on failed handshakes and filling logs with noise.
- PostgreSQL (port 5432) — If exposed, attackers attempt default credentials (
postgres/postgres). A single successful connection means full database access — all your users' data, all your secrets. - Admin APIs (port 8080) — Your deployment platform's API often has endpoints for creating deployments, reading environment variables, and managing infrastructure. One leaked API key and an attacker controls your entire platform.
- Docker API (port 2375) — An exposed Docker socket gives an attacker root-equivalent access to your server. They can pull your images, read your environment variables, and spin up crypto miners.
- Redis (port 6379) — Redis has no authentication by default. An exposed Redis instance can be overwritten to inject SSH keys, giving attackers direct shell access.
These aren't targeted attacks. According to SecurityAffairs, the SSHStalker botnet alone compromised nearly 7,000 servers in January 2026 through mass SSH scanning. Your server isn't special — it's just another target in the queue.
For a deeper look at why self-hosting beats managed platforms on security, see our self-hosted deployment security guide.
Why Don't Firewalls Solve This Alone?
UFW or iptables rules are a good start:
ufw default deny incoming
ufw default allow outgoing
ufw allow 80/tcp
ufw allow 443/tcp
ufw allow 22/tcp
ufw --force enable
This blocks the database and admin ports from the internet. Good. But you still have problems:
- SSH is still public — you need it to manage the server, so it stays open. Every IP on earth can attempt to connect.
- No remote database access — your firewall blocks port 5432, but now you can't connect from your local machine to debug a production issue.
- No remote admin access — your admin dashboard runs on port 8080, but it's behind the firewall. You can only access it through SSH tunnels, which are clunky and break constantly.
- IP allowlisting is fragile — you can allowlist your home IP, but it changes. Your co-founder works from a coffee shop. Your CI server has a dynamic IP. You spend more time updating firewall rules than writing code.
You end up in a frustrating middle ground: either your services are too exposed, or you can't reach the tools you need.
How Does Tailscale Solve the VPS Security Problem?
WireGuard, the protocol behind Tailscale, delivers roughly 3x the throughput of OpenVPN with lower latency (WireGuard whitepaper). Tailscale wraps WireGuard into a zero-config mesh network where every device gets a stable private IP in the 100.x.x.x range — regardless of where you are.
The key insight: services that bind to your Tailscale IP are only reachable by devices on your Tailscale network. The public internet can't see them. No ports to scan, no doors to knock on.
How It Fits Your Deployment Stack
Public Internet Tailscale Network (private)
───────────── ──────────────────────────
┌────────────────────┐
Users ──── :443 ────────>│ │<──── :8080 ── You (laptop)
Users ──── :80 ────────>│ Your VPS │<──── :5432 ── You (local DB tool)
│ │<──── :22 ── You (SSH)
Bots ──── :22 ────X │ Tailscale IP: │
Bots ──── :5432 ───X │ 100.x.x.x │<──── Your co-founder
Bots ──── :8080 ───X └────────────────────┘<──── Your CI server
Public ports (80, 443): Serve your web traffic. These are the only ports your firewall allows from the internet.
Private ports (everything else): Bound to the Tailscale interface. Only reachable by authenticated devices on your network. Invisible to the rest of the world.
How Do You Lock Down a VPS with Tailscale Step by Step?
A Darktrace honeypot study found exposed services get hit in under two minutes — no recon phase, just immediate automated exploitation. The faster you lock down, the smaller your exposure window. Here's the complete process.
We've set this up on dozens of servers. The whole process takes about 15 minutes, and the workflow improvement — being able to access your database and admin panel directly without SSH tunnels — is honestly the bigger win over the security benefits alone.
Prerequisites
- A VPS running your deployment platform (any cloud provider — Hetzner, DigitalOcean, Linode, etc.)
- A Tailscale account (free for personal use, up to 100 devices)
- Tailscale installed on your local machine
Step 1: Install Tailscale on Your VPS
SSH into your server and install Tailscale:
curl -fsSL https://tailscale.com/install.sh | sh
tailscale up
Follow the authentication link to add the server to your Tailscale network. Once connected, your server gets a stable IP like 100.64.0.1.
Verify the connection:
tailscale ip -4
# 100.64.0.1
Step 2: Configure the Firewall — Only 80 and 443
Now lock down the firewall to only allow web traffic from the public internet:
# Reset existing rules
ufw --force reset
# Default policies
ufw default deny incoming
ufw default allow outgoing
# Only allow HTTP and HTTPS from the public internet
ufw allow 80/tcp
ufw allow 443/tcp
# Allow all traffic from the Tailscale interface
ufw allow in on tailscale0
# Enable the firewall
ufw --force enable
The critical line is ufw allow in on tailscale0. This permits all traffic over the Tailscale encrypted tunnel — SSH, database connections, admin access — without opening any ports to the public internet.
Step 3: Verify SSH Works Over Tailscale
Before you close your current SSH session, open a new terminal and test:
# Connect using the Tailscale IP
ssh root@100.64.0.1
If this works, SSH over the public internet is blocked but SSH over Tailscale works. You're in.
Do not close your existing SSH session until you've verified this. If something goes wrong, you still have your original connection to fix it.
Step 4: Bind Admin Services to Tailscale Only
Configure your deployment platform to bind its admin console to the Tailscale IP instead of 0.0.0.0:
# Get your Tailscale IP
TAILSCALE_IP=$(tailscale ip -4)
# Bind the admin console to the Tailscale interface only
# Public traffic (80/443) stays on 0.0.0.0
temps serve \
--address="0.0.0.0:80" \
--tls-address="0.0.0.0:443" \
--console-address="${TAILSCALE_IP}:8080"
Now the admin dashboard is only accessible from your Tailscale network. No SSH tunnel needed — just open http://100.64.0.1:8080 in your browser.
Step 5: Secure the Database
PostgreSQL should already be bound to 127.0.0.1. To access it remotely over Tailscale, update the bind address to include the Tailscale IP:
# In your PostgreSQL config or Docker compose
# Before: 127.0.0.1:5432:5432
# After: bind to both localhost and Tailscale
POSTGRES_HOST=127.0.0.1,${TAILSCALE_IP}
Now you can connect from your laptop using any database client:
psql -h 100.64.0.1 -U temps -d temps
No SSH tunnels. No port forwarding. No exposed ports. Just a direct, encrypted connection over your private network.
What Does Your Server Look Like After?
A properly locked-down VPS reduces its visible attack surface by roughly 60%, based on typical port exposure. The difference is dramatic when you compare nmap scans before and after.
Before (Typical VPS)
$ nmap your-server-ip
PORT STATE SERVICE
22/tcp open ssh
80/tcp open http
443/tcp open https
5432/tcp open postgresql
8080/tcp open http-alt
Five open ports. Three of them shouldn't be public. Every port scanner on the internet can see them all.
After (Tailscale-Secured VPS)
$ nmap your-server-ip
PORT STATE SERVICE
80/tcp open http
443/tcp open https
Two ports. Both required. Everything else is invisible. Your server's attack surface just shrank by 60%.
An attacker scanning your IP sees a web server and nothing else. No SSH to brute-force. No database to probe. No admin panel to exploit.
In our testing, a fresh Hetzner VPS received 847 SSH login attempts in the first 24 hours — consistent with CrowdStrike's finding that 79% of Linux attacks use no malware, just valid credentials and built-in tools. After applying Tailscale with UFW, that number dropped to zero — because port 22 no longer responds on the public IP.
Which Tailscale Features Matter Most for VPS Security?
According to Tailscale's pricing page, the Personal plan is free for up to 3 users and 100 devices — no trial period, no credit card required. For small teams, the Starter plan runs $6/user/month. But the security features beyond basic connectivity are what make it particularly useful for VPS management.
MagicDNS
Instead of remembering 100.64.0.1, Tailscale gives your server a DNS name:
ssh root@my-vps.tailnet-name.ts.net
psql -h my-vps.tailnet-name.ts.net -U temps -d temps
ACLs (Access Control Lists)
Control which team members can access which services:
{
"acls": [
{
"action": "accept",
"src": ["group:devs"],
"dst": ["tag:servers:80,443,8080"]
},
{
"action": "accept",
"src": ["group:admins"],
"dst": ["tag:servers:*"]
}
]
}
Developers get web and dashboard access. Only admins get SSH and database access. Enforced at the network level, not by application-layer authentication that can be bypassed.
SSH Console (Tailscale SSH)
Tailscale can replace OpenSSH entirely, eliminating SSH keys, authorized_keys files, and port 22:
# On the server
tailscale up --ssh
# On your laptop (no SSH keys needed)
tailscale ssh root@my-vps
Authentication happens through your Tailscale identity provider. No keys to rotate. No .ssh/config to manage. No port 22 to open — not even on the Tailscale interface.
Funnel (Optional Public Access)
Need to temporarily expose a development service? Tailscale Funnel lets you create a public URL without touching firewall rules:
tailscale funnel 3000
# https://my-vps.tailnet-name.ts.net:443/ -> http://localhost:3000
When you're done, turn it off. No firewall rules to remember to revert.
For more on securing your deployment infrastructure, see our security documentation.
Best VPS Providers for Tailscale in 2026
Choosing the right VPS provider for your Tailscale setup matters. You need a provider that supports TUN/TAP devices (required for WireGuard/Tailscale), offers competitive bandwidth pricing, and has datacenters near your users. Here's how several budget providers compare; verify current regional pricing before ordering.
Most "best VPS for Tailscale" comparisons focus on CPU benchmarks. For Tailscale mesh networks and self-hosted platforms, what actually matters more is network performance, bandwidth pricing, and WireGuard compatibility — that's where the differences show up.
Recommended VPS Providers for Tailscale — Comparison Table
| Provider | Starting Price | vCPU / RAM | Included Traffic | Datacenters | Tailscale Compatibility |
|---|---|---|---|---|---|
| Hetzner CX23 | EUR 5.49/mo, excluding VAT and IPv4 | 2 shared vCPU / 4 GB | 20 TB in EU | EU (Germany, Finland) | Supports standard Linux networking required by Tailscale |
| DigitalOcean | $6/mo | 1 vCPU / 1 GB | 1 TB | 15 regions worldwide | Full support, one-click Tailscale marketplace app available |
| Vultr | $5/mo | 1 vCPU / 1 GB | 2 TB | 32 locations worldwide | Full support, TUN enabled, widest geographic coverage |
| Linode (Akamai) | $5/mo | 1 vCPU / 1 GB | 1 TB | 11 regions worldwide | Full support, Akamai backbone improves mesh latency |
All four providers fully support Tailscale out of the box — no special kernel modules or support tickets needed. The install process is identical on each: curl -fsSL https://tailscale.com/install.sh | sh && tailscale up.
Hetzner — Best Value for Tailscale Setups
Hetzner is a strong value option for Tailscale deployments in Europe. After the June 2026 price adjustment, a new CX23 order in Germany or Finland is EUR 5.49 per month excluding VAT and IPv4, with 2 shared vCPUs and 4 GB of RAM. Hetzner documents 20 TB of included traffic for CX cloud servers in EU locations.
For multi-node Tailscale meshes, Hetzner's 20 TB of included traffic is a significant advantage — WireGuard mesh traffic between nodes counts against your bandwidth quota, and 1 TB caps on other providers can become a bottleneck for busy clusters.
The main downside? Fewer datacenter locations than DigitalOcean or Vultr. If you need servers in Asia-Pacific or South America, look at Vultr instead.
DigitalOcean — Best for Ease of Use
Strong developer experience and the broadest documentation ecosystem among affordable providers. Their managed databases and Kubernetes offering make it easy to grow. DigitalOcean also offers a Tailscale marketplace app for one-click installation on new Droplets.
Pricing is straightforward but can be higher per resource than Hetzner. Check the current Droplet price and regional transfer allowance before comparing it with the CX23.
Vultr — Best Geographic Coverage
Vultr's 32 datacenter locations span every continent except Antarctica, making it the best choice if you need Tailscale nodes close to users in regions like Tokyo, Mumbai, Sao Paulo, or Johannesburg. Their $5/month plan includes 2 TB of traffic — double what DigitalOcean and Linode offer at the same price.
Linode (Akamai) — Best Network Backbone
Competitive pricing, good network performance, and now backed by Akamai's global infrastructure. The Akamai acquisition brought better DDoS protection and edge networking capabilities, which can improve Tailscale mesh stability in hostile network environments.
Multi-Node Tailscale Meshes with Temps
If you're running a multi-node deployment cluster, Temps uses WireGuard mesh networking under the hood to connect control plane and worker nodes across providers.
Temps uses WireGuard mesh networking (via the
defguard_wireguard_rscrate withx25519-dalekfor key exchange — embedded userspace WireGuard) to connect control plane and worker nodes across cloud providers. Nodes join viatemps join <cluster-id> <token>(relay is the default mode) which handles NAT traversal, key exchange, and peer discovery automatically. To use direct networking, add--private-address <ip>instead.
Temps is free to self-host with no deployment caps, no usage limits, and no seat restrictions. Running Temps on a Hetzner VPS combines the security of a Tailscale-isolated admin network with the economics of European cloud pricing. Temps Cloud, a separate managed add-on for telemetry retention, offsite backups, and AI credits, is coming soon and has not been priced yet — self-hosting Temps has no per-seat fees.
Temps includes Pingora-based reverse proxy (the same proxy technology Cloudflare uses), automatic SSL certificate provisioning, and encrypted environment variables (AES-256-GCM at rest) — so the TLS and secret management layers are handled without additional configuration. You can mix Hetzner, DigitalOcean, Vultr, and Linode nodes in the same cluster — Tailscale or Temps' built-in WireGuard relay handles NAT traversal and key exchange automatically. See our WireGuard mesh networking guide for the manual setup, or let Temps handle it with
temps join <cluster-id> <token>(relay mode is the default).
Deployment-only platforms like Coolify, Dokploy, and Dokku don't ship any of this — you'd bolt on Tailscale yourself and still have no analytics, session replay, or error tracking once the network is locked down. Temps is newer than those projects, which is exactly why it was built with WireGuard mesh and bundled observability from day one instead of retrofitting them onto a decade-old deployment-only tool. That's the tradeoff: less community history, but a security and observability model designed for how self-hosted infrastructure actually gets attacked in 2026.
For a detailed breakdown of how self-hosting compares on cost, see our Vercel cost savings analysis.
How Can You Add Application-Level Security on Top?
According to IBM, organizations using AI-powered security tools cut their breach lifecycle by 80 days and saved nearly $1.9 million on average. But you don't need AI — layering application-level controls on top of Tailscale's network isolation creates multiple barriers an attacker would need to breach.
IP Access Control
Even with Tailscale, restrict which IPs can access your admin API at the application layer:
# Only allow Tailscale IPs to access the admin console
bunx @temps-sdk/cli firewall allow 100.64.0.0/10 --description "Tailscale network"
Security Headers
Your deployment platform should automatically inject security headers on all responses:
| Header | Value |
|---|---|
| Content-Security-Policy | Strict policy limiting resource origins |
| X-Frame-Options | DENY |
| X-Content-Type-Options | nosniff |
| Strict-Transport-Security | max-age=31536000; includeSubDomains |
| Referrer-Policy | strict-origin-when-cross-origin |
| Permissions-Policy | Restrictive defaults |
Encrypted Secrets
Environment variables should be encrypted with AES-256-GCM at rest. Combined with Tailscale's encrypted transport, your secrets are protected both at rest and in transit — on a network nobody else can reach.
What's the Full Security Checklist?
According to IBM, nearly two-thirds of breached organizations in 2025 said recovery extended beyond 100 days. Prevention is cheaper. After following this guide, your VPS should meet every item on this list — run through it once after setup to catch the one or two things most people forget.
- Only ports 80 and 443 open to the public internet
- SSH accessible only via Tailscale (not port 22 on public IP)
- Database bound to localhost and Tailscale IP (not
0.0.0.0) - Admin dashboard accessible only via Tailscale
- Tailscale ACLs configured for team access control
- UFW enabled with deny-by-default policy
- Security headers enabled on all HTTP responses
- SSL/TLS certificates auto-renewed via Let's Encrypt
- Environment variables encrypted at rest
- Security scan passing with no critical findings
What Does This Cost?
Tailscale's Starter plan costs $6 per user per month, and the Personal plan is free for up to 3 users and 100 devices. Combined with a budget VPS, the total cost is remarkably low for enterprise-grade network security.
| Component | Cost |
|---|---|
| Tailscale (Personal) | Free (3 users, 100 devices) |
| Tailscale (Starter) | $6/user/month |
| VPS (Hetzner CX23, EU) | €5.49/month excluding VAT and IPv4 |
| Total | Depends on users, region, tax, and IP choice |
Compare this to the $10.22 million average cost of a US data breach. A few dollars a month for a VPN that eliminates your most common attack vectors is probably the cheapest security investment you'll ever make.
Frequently Asked Questions
How do I secure a VPS properly?
Start by closing every port except 80 and 443 using UFW or iptables. Then route all management traffic — SSH, databases, admin panels — through a private network like Tailscale. The average US data breach costs $10.22 million, and exposed management ports are a leading entry point. Don't leave doors open you don't need.
See our full VPS security documentation for additional hardening steps.
How do you set up Tailscale on a VPS?
Install with curl -fsSL https://tailscale.com/install.sh | sh, then run tailscale up to authenticate. Your server gets a private IP in the 100.x.x.x range. After that, configure UFW to allow only ports 80/443 publicly and permit all traffic on the tailscale0 interface. The whole process takes under 15 minutes.
What's the best VPS for self-hosting?
Hetzner's CX23 is a strong value option in Europe: new Germany and Finland orders are listed at EUR 5.49 per month excluding VAT and IPv4, with 2 shared vCPUs, 4 GB of RAM, and 20 TB of included EU traffic. Compare current regional prices and traffic allowances if you need another location.
What's the difference between WireGuard and Tailscale?
WireGuard is the underlying encryption protocol. Tailscale is a management layer built on top of WireGuard that handles key distribution, NAT traversal, and device authentication automatically. WireGuard alone requires manual configuration of keys and endpoints on every device. Tailscale delivers roughly 3x the throughput of OpenVPN thanks to WireGuard's kernel-level implementation (WireGuard whitepaper).
How should I set up a VPS firewall?
Use ufw default deny incoming as your baseline, then selectively open only the ports you need. For web servers, that means ports 80 and 443. For management access, use a VPN like Tailscale rather than opening SSH (port 22) to the internet. A fresh VPS gets its first SSH probe within 90 seconds — any open port will be found and probed.
What is the best VPS for Tailscale in 2026?
There is no universal best VPS, but Hetzner is a strong value option for an EU-hosted Tailscale node. After Hetzner's June 2026 price adjustment, a new CX23 order in Germany or Finland is listed at EUR 5.49 per month excluding VAT and IPv4. It includes 2 shared vCPUs and 4 GB of RAM; Hetzner lists 20 TB of included traffic for CX cloud servers in EU locations. Check the current regional price and traffic allowance before ordering because they vary by location.
If you also want to run a self-hosted PaaS, Temps bundles deployments, web analytics, session replay, error tracking, and uptime monitoring in one Rust binary. Size the server from the applications and telemetry you expect to run; 4 GB of RAM is an entry point, not a guarantee that every deployment and observability workload will fit without contention.
DigitalOcean is the best choice if you prioritize ease of use — they offer a one-click Tailscale marketplace app, excellent documentation, and 15 datacenter regions. It costs more per resource than Hetzner ($6/month for 1 vCPU / 1 GB RAM), but the developer experience and ecosystem make it worth it for teams who want less friction.
For the widest geographic coverage, consider Vultr (32 locations) or Linode (Akamai backbone) as strong alternatives.
Getting Started
Two ports open. Everything else behind an encrypted mesh network. That's the end state we're aiming for, and you can get there in about 15 minutes.
Install your deployment platform on a VPS, lock it down with Tailscale, and start deploying:
# Install Tailscale
curl -fsSL https://tailscale.com/install.sh | sh
tailscale up
# Lock down the firewall
ufw --force reset
ufw default deny incoming
ufw default allow outgoing
ufw allow 80/tcp
ufw allow 443/tcp
ufw allow in on tailscale0
ufw --force enable
Your users get fast, reliable HTTPS. Your infrastructure stays invisible. And you stop worrying about whether that database port you forgot about is going to end up on Shodan.
Ready to deploy? Follow our step-by-step Next.js deployment guide to go from zero to production.
Last updated July 5, 2026. For more on VPS security features, check our security documentation. For Tailscale setup details, see the Tailscale quickstart.
Get weekly updates