Build a secure private network across VPS instances with Tailscale

You manage half a dozen VPS instances spread across different providers, some for databases, some for web apps, one for monitoring. Every time they need to talk to each other you either punch holes in firewall rules, set up a traditional VPN with all its key distribution headaches, or, worse, expose private APIs to the public internet. There is a better way. Tailscale gives you a WireGuard-based mesh network where every node can reach every other node over an encrypted tunnel, without any open ports or manual peer configuration. This post walks through setting it up across multiple Linux VPS instances on Ubuntu 24.04.
Tailscale 能在不需要开放端口的情况下,通过 WireGuard 加密,将多台 VPS 轻松连接成一个安全的内网。
Tailscale connects multiple VPS instances into a secure private network over WireGuard encryption, without opening any ports.
Prerequisites
- At least two VPS instances running Ubuntu 24.04 LTS (the setup works on Debian 12, AlmaLinux 9, and most other distros, just adjust the package manager)
- Root or sudo access on each machine
- A Tailscale account (free tier: up to 3 users, 100 devices, more than enough for most setups)
- SSH access to each VPS
Why Tailscale instead of a traditional VPN
Traditional VPNs like OpenVPN or WireGuard direct peer-to-peer require you to configure each node manually, generate keys, write config files, open firewall ports, manage IP allocation. Add a fifth node and you touch four existing configs. TLS-based solutions like ZeroTier are better but still require a central controller and some static configuration. Tailscale wraps WireGuard with identity-based authentication: each node authenticates to a coordination server using your SSO provider (Google, GitHub, Microsoft) or a pre‑shared key. The coordination server handles NAT traversal, key exchange, and route distribution. From your perspective it is a single tailscale up command per machine. The mesh is encrypted end-to-end with WireGuard, and nodes talk directly whenever possible, no central relay unless both sides are behind restrictive NATs.
Step 1, Install Tailscale on each VPS
The Tailscale package is in the official repositories for most distros, but the upstream repo gives you the latest version. Run these commands on every node you want in the mesh:
curl -fsSL https://tailscale.com/install.sh | sh
sudo tailscale up
The installer script detects your distro and adds the Tailscale APT repository (for Debian/Ubuntu) or YUM/DNF repository (for RHEL-based). On AlmaLinux 9, the script works identically, it adds the Tailscale Copr repo and installs tailscale and tailscaled. After installation, sudo tailscale up opens a browser window (or gives you a URL to visit) where you authenticate with your identity provider. Once authenticated, the node appears in your Tailscale admin console with a unique 100.x.y.z IP address.
Verify the node is connected:
tailscale status
Expected output (simplified):
100.101.1.1 web-server linux active
100.101.1.2 db-server linux active
Step 2, Test connectivity between nodes
With two or more nodes authenticated, you can already reach them by their Tailscale IP. From the first VPS:
ping 100.101.1.2
If the ping succeeds, your mesh is working. The traffic is encrypted with WireGuard even though you never touched a WireGuard config file. You can also verify the actual protocol being used:
tailscale status --json | grep -E "VIA|Direct"
This shows whether the connection is direct (punching through NAT) or relayed via a Tailscale DERP relay server. Direct is always preferred, lower latency, no middlebox. If a connection stays on relay, the two VPS are behind symmetric NATs or one is on a strict firewall. The relay adds maybe 10-20 ms, acceptable for most workloads.
Several SSH connections to the same VPS means each session is separate, closing one does not affect others.
Step 3, Enable SSH over Tailscale only (optional, but recommended)
Once the mesh works, you can lock down SSH so it only listens on the Tailscale interface. This removes SSH entirely from the public internet, no more bruteforce on port 22. Edit /etc/ssh/sshd_config on each VPS, find or add this directive:
ListenAddress 100.101.1.1
Use the node's own Tailscale IP. Then restart SSH:
sudo systemctl restart sshd
Verify: from a different node, connect with ssh [email protected], it should work. From outside the mesh (e.g. your laptop not on Tailscale) the connection times out because no socket listens on the public IP port 22. Keep a second SSH session open to the public IP until you are sure the Tailscale path works, misconfiguring this locks you out if you only have one access route.
Step 4, Route services through the mesh
You now have a private IPv4 network across all your VPS. Point your services to the Tailscale IPs of the nodes they need to reach. Examples:
- PostgreSQL: set
listen_addresses = 'localhost,100.101.1.2'inpostgresql.conf. Clients on other VPS connect topostgresql://[email protected]:5432/db. - Redis: bind to
100.101.1.2inredis.confinstead of0.0.0.0. Only mesh nodes can reach it. - Nginx reverse proxy: proxy_pass upstream to
http://100.101.1.3:3000for your app server.
This eliminates the need to manage firewall rules per source IP, the network boundary is the mesh itself. If a node is not authenticated into the Tailscale network, it has no route to those services.
Step 5, Add more nodes (no config updates needed)
New VPS: install Tailscale, run tailscale up, authenticate. That is it. Every existing node can already reach the new one at its 100.x.y.z address. No config files to edit, no WireGuard peers to add, no firewall rules to update. The coordination server distributes the new node's route to all clients. This is the single biggest operational advantage over a hand-rolled WireGuard mesh, it scales linearly with the number of nodes because there is no O(n²) config management.
Troubleshooting
Node shows offline in tailscale status
Check the Tailscale daemon is running: sudo systemctl status tailscaled. If the daemon is up but the node is offline, the issue is usually upstream DNS or connectivity to login.tailscale.com. Run journalctl -u tailscaled --no-pager -n 30 to see the last log lines. Common fix: sudo tailscale logout; sudo tailscale up to reauthenticate.
Ping succeeds but TCP connections fail
Tailscale uses UDP for WireGuard payload. Some cloud providers or datacenter firewalls block UDP on high ports (the default WireGuard port). If TCP works but ICMP fails (or vice versa), check that the machine can reach the Tailscale coordination server on TCP 443 and that outbound UDP on the ephemeral port range (usually 1024-65535) is not blocked. The simplest test: curl -I https://login.tailscale.com from the node.
Connection stays on relay, never switches to direct
Both nodes must be able to send UDP to each other's public IP and port. In most cases Tailscale's NAT traversal works automatically. When it does not, the typical cause is a symmetric NAT or a firewall that drops UDP without a prior outbound connection. The only mitigation is to accept the relay latency or change the VPS provider to one with less restrictive NAT. Most VPS with a dedicated public IP allow direct connections.
Why this works so well on a VPS
A Linux VPS with a dedicated IPv4 is the ideal node for a Tailscale mesh. Unlike residential NATs, a VPS on a public IP has no inbound firewall restrictions by default, the WireGuard packets land directly. This means your VPS nodes always connect to each other directly with minimum latency, never relying on Tailscale's relay servers. The mesh also works across providers: a DigitalOcean droplet in Singapore talks directly to a Hetzner server in Finland over an encrypted WireGuard tunnel, no central hub needed. For workloads that require low-latency inter-node communication, database replication, cache clusters, microservices, the direct path over a dedicated IP makes Tailscale faster than a VPN through a central gateway.
If you are renting a VPS for automation workflows like n8n or running a multi-node Docker Swarm, dropping services onto the Tailscale mesh removes the need to expose ports to the internet at all. Your CI/CD pipeline, monitoring stack, and internal APIs all communicate over the encrypted overlay.
FAQ
Does Tailscale work without internet access?
No. The first authentication and key exchange require reaching the Tailscale coordination server. Once the session is established, the mesh can survive brief outages because nodes cache the current peers, but a full disconnect for more than a few minutes causes the session to expire and nodes to drop offline until the coordination server is reachable again.
Is there a limit to how many VPS I can connect?
The free Tailscale plan allows up to 100 devices and 3 users. For a personal or small-team infrastructure of a few dozen VPS, this is sufficient. The Personal Pro plan (about $6/month as of 2026) allows unlimited users and 100 devices, plus access controls.
Does Tailscale replace a traditional site-to-site VPN?
For most use cases, connecting VPS instances, developers' laptops, and office networks, yes. If you need to route an entire subnet through a single gateway (e.g., connect an office LAN of 50 machines through one exit node), Tailscale can do that with its subnet router feature. For full site-to-site with policy-based routing and vendor interoperability, a dedicated WireGuard or IPsec setup may still be the right tool.
Is the Tailscale coordination server a single point of failure?
It is only required for initial authentication and key distribution. Existing connections persist even if the coordination server goes offline temporarily. For most self-hosted setups this is acceptable. If you need full self-sovereignty, the open-source Headscale project provides the same API and can be run on your own VPS.
Can I use my own WireGuard keys instead of Tailscale's?
No. Tailscale manages key generation and rotation on the client side. If you need to use your own keys or integrate with an existing WireGuard setup, a hand-rolled WireGuard mesh is the correct choice, but you lose the zero-configuration benefits.
Do I need to open any ports on my VPS firewall?
No. Tailscale uses outbound-only connections to the coordination server and NAT traversal for peer-to-peer traffic. The WireGuard packets are sent using UDP on random high ports, but since the VPS initiates the outbound connection to the coordination server, no inbound port rules are required.
Bài viết liên quan
- Set up a WireGuard VPN on your VPS in 10 minutes
- Reverse proxy with automatic HTTPS using Caddy
- Hardening SSH on a new VPS: keys, ports, fail2ban, and CrowdSec
- User and sudo permissions management on Linux VPS
Tailscale 搭建多台 VPS 安全私有网络指南
Tailscale 基于 WireGuard 的端到端加密,让你在多台 VPS 之间快速建立一个安全的私有网络。每台机器只需安装并运行一次 tailscale up 命令,无需手动配置密钥、防火墙规则或路由。所有节点通过 100.x.y.z 网段直接通信,即使 VPS 分布在不同机房或国家。对于使用越南 VPS 运行数据库、微服务或自动化任务的用户,这种方法显著简化网络管理,同时保证传输加密。Tailscale 免费版支持最多 100 台设备,足以覆盖中小型基础设施。如果你需要完全自主控制,可以考虑自托管开源的 Headscale。


