Running a VPS with public services like a website can quickly become risky if ports are left wide open. I recently hardened my Ubuntu VPS using a combination of Tailscale, Cloudflare, and a strict UFW firewall for my private coding environment setup. This setup follows a true zero-trust model, ie nothing is trusted by default.
Initial Situation
My VPS had Nginx serving a website and SSH enabled. A quick check revealed the issue:
sudo ss -tulnp
Ports 22 (SSH), 80, and 443 were listening on 0.0.0.0, meaning they were potentially accessible to anyone scanning the public IP.
Step 1: Configure a Strict Firewall with UFW
I installed UFW and applied a default-deny policy for maximum security:
sudo apt install ufw -y
sudo ufw default deny incoming
sudo ufw default allow outgoing
Key changes made:
- Restricted SSH (port 22) to accept connections only from the Tailscale network range.
- Removed all broad “Anywhere” rules for web ports 80 and 443.
- Added precise allow rules for only Cloudflare’s official IP ranges (both IPv4 and IPv6). This allows legitimate traffic coming through Cloudflare while blocking everything else.
- Allowed full access through the Tailscale interface for safe administration:
sudo ufw allow in on tailscale0
After applying the rules, I checked the final configuration:
sudo ufw status verbose
Step 2: Enable Tailscale SSH
In the Tailscale admin console, I enabled Tailscale SSH. This lets me connect securely using the VPS’s Tailscale IP instead of exposing the public SSH port.
Step 3: Verification
To confirm everything was working correctly:
- I performed external port scans using nmap from a machine outside my Tailscale network.
- Direct access to the VPS public IP (on ports 22, 80, or 443) was blocked or filtered.
- The website continued to load normally when accessed through the Cloudflare-proxied domain.





















