A backup server sitting in the same building as everything it protects isn't a real disaster recovery plan. A second, independent backup instance on a cheap cloud VPS closes that gap for a few dollars a month — done right, it doesn't need to trust the network it's protecting against.
You don't need much. If you're only replicating VM/container backups (not bulk media or file shares), a
small droplet/instance — a single vCPU, a couple GB of RAM, and a modest boot disk — is plenty, since the
actual backup data lives on a separate attached block-storage volume sized to your real dataset. Check
du -sh on your actual backup datastore path first, not df on the mount, to size
that volume realistically — the two numbers can differ by an order of magnitude on a shared NAS export.
If you've already set up a reverse tunnel to expose a NAT'd home service to the internet, it's tempting to reach for the same tool here to "hide" the new backup server. Worth pausing on that: a generic TCP tunnel changes which address traffic arrives at — it doesn't add any access control of its own. It solves a NAT problem, not a security problem. A cloud VPS doesn't have a NAT problem; it already has its own public IP. Layering a tunnel on top adds complexity without adding the restriction you actually want.
What actually restricts access is a firewall rule scoped to a specific source IP — most cloud providers offer this as a free, built-in "cloud firewall" or security-group feature, enforced at the network edge before traffic ever reaches the instance:
Verify it immediately after creating it — confirm you can still reach both ports from the allowed address, and ideally confirm from a second network that you can't.
Yes, and it's worth getting a real, trusted certificate instead of clicking through a browser warning every time — see running your own internal certificate authority if you haven't already got one going. The interesting wrinkle: a cloud VPS normally needs a certificate from a public CA (Let's Encrypt or similar) to get a browser-trusted cert, since public CAs validate a domain by actually reaching it over the internet. But if you've firewalled this server down to your own home IP anyway, it's functionally an internal-only service despite having a real public IP and DNS record — so it can just use your existing internal CA the same way every other admin tool on your LAN does, no public-CA validation dance required.
Not specific to this setup, but worth double-checking while you're touching DNS: if the domain hosting this replica is on a zone proxied through a CDN for your other public sites, make sure this particular record is set to DNS-only, not proxied. Backup server protocols and ports typically aren't things a CDN's free-tier proxy passes through cleanly.
The token or credential your home backup server uses to push data offsite should be scoped to the absolute minimum it needs: write new backups, nothing else. No delete, no prune, no modify rights. That way, even if this credential leaks, or your home server is ever compromised, whatever gets its hands on it still can't reach back and destroy backups that already landed offsite.
Point your home backup server at the new offsite instance and set up a push sync job (home → offsite), not a pull. Critically, look for an option often called something like "remove vanished" or "delete extraneous" — and make sure it's off. This setting mirrors deletions: if a backup disappears from the source, it also gets deleted from the destination on the next sync. That's exactly the behavior you don't want for a disaster-recovery copy — a ransomware event, a fat-fingered delete, or a bug on the home side should never be able to cascade into wiping the offsite copies too.
What you get instead, from the two mitigations above, covers a real and specific threat model: a compromised home network or a leaked sync credential can't reach back and destroy the offsite copies. What it does not cover: someone with direct root access on the offsite instance itself deliberately deleting files. If that level of protection matters to you, the realistic path is swapping the backend storage for something with real object-lock support, which is a bigger architectural decision than what's covered here.
Manually trigger the sync job once and actually watch it transfer real data, rather than trusting that a green checkmark on the job configuration means anything. Check the destination instance directly too — its disk usage growing and a snapshot list actually populating is the only real confirmation data arrived, not just that it left the source.