Part 4 of the home server series. Set up private remote access with Tailscale, a free Oracle VPS as a public gateway, frp tunneling to bypass CGNAT, Nginx reverse proxy, and SSL with Certbot.
In Part 2 we set up Nextcloud, and in Part 3 we added Samba NAS. Everything works great — on your home network.
But the moment you step outside your house, your server disappears. You can't reach it from a coffee shop, your office, or while traveling. Your phone's auto-backup stops working on mobile data.
This part fixes that. After this guide, you'll access your server from anywhere in the world through two paths:
- Private path (Tailscale): A direct encrypted tunnel between your devices and your server. Fast, simple, free. For personal use.
-
Public path (Oracle VPS + frp): A clean URL like
files.yourdomain.comthat anyone can open in a browser. For sharing with family.
This is the most complex part of the series, but I'll walk through every step.
The CGNAT problem
Before we start, you need to understand why this is necessary.
Most Indian ISPs (Airtel, Jio, ACT, BSNL) use CGNAT — Carrier-Grade NAT. This means your home doesn't have a public IP address. Hundreds of homes share one public IP. Nobody on the internet can reach your server directly.
It's like living in an apartment building where the entire building has one phone number. Someone calling that number reaches the building's reception, not your flat. There's no way to ring your flat directly from outside.
Two solutions:
- Tailscale — creates a private tunnel that bypasses CGNAT entirely. Only your devices can use it.
- Oracle VPS + frp — your server reaches out to a public VPS, and the VPS forwards traffic back through the tunnel. Anyone on the internet can access your server through the VPS.
Let's set up both.
Part A: Tailscale (Private Access)
Tailscale is the easiest way to access your server remotely. It creates an encrypted WireGuard VPN mesh between all your devices. No port forwarding, no firewall rules, no configuration headaches.
Step 1: Install Tailscale on your server
curl -fsSL https://tailscale.com/install.sh | sh
sudo tailscale up
It will print a URL. Open that URL in a browser and sign in with your Google or Microsoft account. Your server is now on your Tailscale network.
Check your server's Tailscale IP:
tailscale ip -4
You'll get something like 100.x.x.x. Note this down — this is your server's private remote address.
Step 2: Install Tailscale on your devices
- Mac/Windows: Download from tailscale.com/download
- iPhone: Download from the App Store
- Android: Download from the Play Store
Sign in with the same account you used on your server. That's it — your devices can now talk to each other.
Step 3: Test it
From your phone (on mobile data, not WiFi) or a laptop outside your home, try:
http://100.x.x.x:8888
Replace 100.x.x.x with your server's Tailscale IP. You should see Nextcloud.
For NAS access from your Mac:
smb://100.x.x.x
For SSH:
ssh your-username@100.x.x.x
Everything works exactly like it does at home — because Tailscale makes it feel like you're on the same network.
Step 4: Allow Tailscale through the firewall
sudo ufw allow in on tailscale0
This allows all traffic through the Tailscale interface while keeping your server locked down on the regular network.
💡 HTTP over Tailscale is completely safe. WireGuard encrypts ALL traffic regardless of HTTP vs HTTPS. Your ISP can't see what you're accessing. You don't need SSL for the Tailscale path.
Step 5: Update Nextcloud trusted domains
Add your Tailscale IP to Nextcloud's trusted domains so it doesn't block access:
docker exec -it nextcloud bash
nano /var/www/html/config/config.php
Add your Tailscale IP to the array:
'trusted_domains' =>
array (
0 => '192.168.1.100',
1 => 'files.yourdomain.com',
2 => '100.x.x.x',
),
Save, exit the container, and restart Nextcloud:
exit
docker restart nextcloud
Tailscale is done
That's really it. Tailscale handles NAT traversal, encryption, key exchange, and DNS — all automatically. Your phone's Nextcloud auto-backup now works on mobile data too.
Use Tailscale for: Personal file access, SSH, streaming videos, NAS access. Anything where you're the only user.
Tailscale can't do: Give family members access without installing the app on their devices. That's what the public path is for.
Part B: Oracle VPS + frp (Public Access)
This is the more complex setup, but it gives you a public URL like files.yourdomain.com that anyone can open in a browser — no app required.
The architecture:
Internet → Cloudflare (DNS + SSL) → Oracle VPS → frp tunnel → Your home server
Step 1: Get a free Oracle Cloud VPS
Oracle Cloud has an Always Free tier that gives you a VPS that never expires and never costs anything.
- Go to cloud.oracle.com and create an account
- Go to Compute → Instances → Create Instance
- Choose these settings:
- Shape: VM.Standard.E2.1.Micro (this is the free one)
- OS: Ubuntu 22.04 or 24.04
- Region: Pick the closest to you (Mumbai for India)
- Add your SSH public key — if you don't have one, generate it:
# On your Mac or local machine
ssh-keygen -t ed25519 -f ~/.ssh/oracle_key
cat ~/.ssh/oracle_key.pub
Copy the public key and paste it into the Oracle instance creation form.
- Click Create and wait for it to provision (takes 1-2 minutes)
- Note the public IP address Oracle assigns
Step 2: Configure Oracle Cloud security rules
Oracle blocks almost all ports by default. You need to open them:
- In the Oracle Console, go to your instance → Subnet → Security Lists
- Add Ingress Rules for:
| Port | Protocol | Source | Purpose |
|---|---|---|---|
| 80 | TCP | 0.0.0.0/0 | HTTP |
| 443 | TCP | 0.0.0.0/0 | HTTPS |
| 7000 | TCP | 0.0.0.0/0 | frp server |
- Also open these ports in the VPS's own firewall:
# SSH into your Oracle VPS
ssh -i ~/.ssh/oracle_key ubuntu@your-oracle-vps-ip
# Open ports
sudo iptables -I INPUT 6 -m state --state NEW -p tcp --dport 80 -j ACCEPT
sudo iptables -I INPUT 6 -m state --state NEW -p tcp --dport 443 -j ACCEPT
sudo iptables -I INPUT 6 -m state --state NEW -p tcp --dport 7000 -j ACCEPT
sudo netfilter-persistent save
Step 3: Get a domain and set up Cloudflare
You need a domain name to point to your VPS. A .com domain costs about ₹850/year through Cloudflare Registrar.
- Register a domain on Cloudflare Registrar or any registrar (Namecheap, Porkbun, etc.)
- Add your domain to Cloudflare (free plan) if you didn't register through them
-
Create an A record:
- Name:
files(this createsfiles.yourdomain.com) - Content: your Oracle VPS public IP
- Proxy status: DNS only (gray cloud) — important for frp to work
- Name:
- Make sure your domain's nameservers point to Cloudflare
Step 4: Install frp server on Oracle VPS
frp (Fast Reverse Proxy) creates the tunnel between your VPS and home server.
SSH into your Oracle VPS and install frp:
# Download frp
cd /opt
sudo wget https://github.com/fatedier/frp/releases/download/v0.61.0/frp_0.61.0_linux_amd64.tar.gz
sudo tar -xzf frp_0.61.0_linux_amd64.tar.gz
sudo mv frp_0.61.0_linux_amd64 frp
Create the server config:
sudo nano /opt/frp/frps.toml
bindPort = 7000
vhostHTTPPort = 8080
vhostHTTPSPort = 8443
auth.method = "token"
auth.token = "your-secret-token-here"
⚠️ Change
your-secret-token-hereto a strong random string. This token must match on both the VPS and your home server. Use something likeopenssl rand -hex 32to generate one.
Create a systemd service so frp starts on boot:
sudo nano /etc/systemd/system/frps.service
[Unit]
Description=frp server
After=network.target
[Service]
Type=simple
ExecStart=/opt/frp/frps -c /opt/frp/frps.toml
Restart=on-failure
RestartSec=5
[Install]
WantedBy=multi-user.target
Start it:
sudo systemctl daemon-reload
sudo systemctl enable frps
sudo systemctl start frps
sudo systemctl status frps
You should see active (running).
Step 5: Install frp client on your home server
Back on your home server:
cd /opt
sudo wget https://github.com/fatedier/frp/releases/download/v0.61.0/frp_0.61.0_linux_amd64.tar.gz
sudo tar -xzf frp_0.61.0_linux_amd64.tar.gz
sudo mv frp_0.61.0_linux_amd64 frp
Create the client config:
sudo nano /opt/frp/frpc.toml
serverAddr = "your-oracle-vps-ip"
serverPort = 7000
auth.method = "token"
auth.token = "your-secret-token-here"
[[proxies]]
name = "nextcloud"
type = "http"
localPort = 8888
customDomains = ["files.yourdomain.com"]
Replace:
-
your-oracle-vps-ipwith your Oracle VPS public IP -
your-secret-token-herewith the same token from Step 4 -
files.yourdomain.comwith your actual domain
Create a systemd service:
sudo nano /etc/systemd/system/frpc.service
[Unit]
Description=frp client
After=network.target
[Service]
Type=simple
ExecStart=/opt/frp/frpc -c /opt/frp/frpc.toml
Restart=on-failure
RestartSec=5
[Install]
WantedBy=multi-user.target
Start it:
sudo systemctl daemon-reload
sudo systemctl enable frpc
sudo systemctl start frpc
sudo systemctl status frpc
The tunnel is now live. Your home server is connected to the Oracle VPS.
Step 6: Set up Nginx on Oracle VPS
Nginx receives incoming web traffic on the VPS and forwards it through the frp tunnel to your home server.
SSH into your Oracle VPS:
sudo apt install nginx -y
Create the Nginx config:
sudo nano /etc/nginx/sites-available/nextcloud
server {
listen 80;
server_name files.yourdomain.com;
client_max_body_size 10G;
location / {
proxy_pass http://127.0.0.1:8080;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_read_timeout 86400;
proxy_send_timeout 86400;
}
}
Replace files.yourdomain.com with your actual domain.
Enable the config:
sudo ln -s /etc/nginx/sites-available/nextcloud /etc/nginx/sites-enabled/
sudo nginx -t
sudo systemctl restart nginx
At this point, http://files.yourdomain.com should load your Nextcloud. But it's not secure yet — no HTTPS.
Step 7: Set up SSL with Certbot
Let's Encrypt gives you free SSL certificates. Certbot automates the entire process.
On your Oracle VPS:
sudo apt install certbot python3-certbot-nginx -y
sudo certbot --nginx -d files.yourdomain.com
Certbot will:
- Ask for your email (for renewal notifications)
- Ask you to agree to terms
- Automatically configure Nginx for HTTPS
- Set up auto-renewal (certificates renew every 90 days automatically)
Test the renewal:
sudo certbot renew --dry-run
If it says "Congratulations, all simulated renewals succeeded", you're set.
Step 8: Update Nextcloud for HTTPS
Now that you have SSL, tell Nextcloud to use HTTPS:
Back on your home server:
docker exec -it nextcloud bash
nano /var/www/html/config/config.php
Add these lines inside the config array:
'overwrite.cli.url' => 'https://files.yourdomain.com',
'overwriteprotocol' => 'https',
Save, exit, and restart:
exit
docker restart nextcloud
Test everything
Open https://files.yourdomain.com in any browser, from any network. You should see your Nextcloud login page with a valid SSL certificate (green padlock).
Try it from your phone on mobile data. Try sharing a file link with someone. It all works now.
The complete picture
You now have two access paths:
| Path | URL | Via | Best for |
|---|---|---|---|
| Private | http://100.x.x.x:8888 |
Tailscale | Personal use, large files, NAS |
| Public | https://files.yourdomain.com |
Cloudflare → VPS → frp | Sharing with family, mobile backup |
Both work from anywhere. The private path is faster (direct tunnel). The public path is more convenient (just a URL).
Your phone's Nextcloud app can use either:
- Set it to
https://files.yourdomain.comfor universal access - Set it to the Tailscale IP for faster transfers when Tailscale is connected
Troubleshooting
files.yourdomain.com not loading?
- Check frpc on home server:
sudo systemctl status frpc - Check frps on Oracle VPS:
sudo systemctl status frps - Check Nginx on Oracle VPS:
sudo systemctl status nginx - Restart the chain:
sudo systemctl restart frpc(home) →sudo systemctl restart frps(VPS) →sudo systemctl restart nginx(VPS)
"502 Bad Gateway" error?
- The frp tunnel is down. Check
sudo systemctl status frpcon your home server - Make sure the auth tokens match in both
frps.tomlandfrpc.toml
SSL certificate not working?
- Run
sudo certbot --nginx -d files.yourdomain.comagain - Make sure the Cloudflare proxy is set to "DNS only" (gray cloud), not "Proxied" (orange cloud)
Tailscale not connecting?
- Check status:
sudo tailscale status - Restart:
sudo tailscale down && sudo tailscale up - Make sure Tailscale is installed and signed in on both devices with the same account
Nextcloud "Access through untrusted domain" error?
- Add the domain to trusted_domains in Nextcloud's config (Step 5 of Part A)
Nextcloud redirect loop after enabling HTTPS?
- Remove the overwrite setting:
docker exec -it nextcloud php occ config:system:delete overwriteprotocol - Clear browser cookies for your domain
- Re-add the setting carefully
What you should have now
✅ Tailscale installed — private encrypted access from anywhere
✅ Oracle Free VPS running as a public gateway
✅ frp tunnel connecting your home server to the VPS
✅ Nginx reverse proxy handling incoming traffic
✅ SSL certificate via Let's Encrypt — valid HTTPS
✅ https://files.yourdomain.com working from any browser, any network
✅ Phone auto-backup working on mobile data
✅ Family can access shared files via a simple link — no app needed
Your home server is now fully accessible from anywhere in the world, and your home IP is completely hidden.
What's next
🔒 Part 5: Security hardening + lessons learned — The final part. We'll set up UFW firewall rules properly, configure Fail2Ban to block brute-force attacks, harden SSH, add basic monitoring, and cover everything I learned the hard way. Don't skip this one — your server is now public-facing.
All config files from this series are available in the companion GitHub repo:
👉 github.com/sasrath/homecloud
Follow for Part 5 — it's the one that keeps everything secure. If you hit any snags with the VPS or frp setup, drop a comment and I'll help you debug it.
Your server is now live on the internet. Let's make sure it stays safe. 🔒
Top comments (0)