February 19, 2026 (1mo ago)
Written by Temps Team
Last updated March 27, 2026 (2w ago)
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.
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.
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.
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:
postgres/postgres). A single successful connection means full database access — all your users' data, all your secrets.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.
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:
You end up in a frustrating middle ground: either your services are too exposed, or you can't reach the tools you need.
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.
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.
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.
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
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.
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.
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.
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.
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.
$ 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.
$ 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.
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.
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
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.
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.
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.
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. We've tested Tailscale on all four major budget VPS providers — here's how they compare as of March 2026.
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.
| Provider | Starting Price | vCPU / RAM | Included Traffic | Datacenters | Tailscale Compatibility |
|---|---|---|---|---|---|
| Hetzner CX22 | EUR 3.79/mo | 2 vCPU / 4 GB | 20 TB | EU (Germany, Finland), US (Virginia, Oregon) | Full support, TUN device enabled by default, fastest WireGuard handshake in testing |
| 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 offers the best price-to-performance ratio for Tailscale deployments. Starting at EUR 3.79/month for the CX22 (2 vCPUs, 4 GB RAM, 20 TB traffic), you get roughly 4x the resources of comparably priced competitors. European datacenters in Falkenstein, Nuremberg, and Helsinki have excellent connectivity. US East (Ashburn) and US West (Hillsboro) locations are newer but solid.
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.
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 higher per-resource than Hetzner. The $6/month Droplet gives you 1 vCPU and 1 GB RAM — half the specs of Hetzner's CX22 at a higher price.
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.
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.
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. 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 --relay.
For a detailed breakdown of how self-hosting compares on cost, see our Vercel cost savings analysis.
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.
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"
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 |
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.
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.
0.0.0.0)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 CX22) | €4.49/month |
| Total | ~$5-11/month |
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.
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.
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.
Hetzner's CX22 at €4.49/month offers the best price-to-performance for self-hosting — 2 vCPUs, 4 GB RAM, and 20 TB of included traffic. DigitalOcean and Linode are solid alternatives if you need datacenters outside Europe or the US.
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).
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.
Hetzner is the best value VPS for Tailscale — starting at EUR 3.79/month, you get 2 vCPUs, 4 GB RAM, and 20 TB of included traffic. The generous bandwidth allowance is especially important for Tailscale mesh networks where inter-node WireGuard traffic counts against your quota. TUN devices are enabled by default, so Tailscale works immediately after installation with no extra configuration.
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.
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 March 23, 2026. For more on VPS security features, check our security documentation. For Tailscale setup details, see the Tailscale quickstart.