All posts
Infrastructure April 17, 2026 · 7 min read · Updated for v1.0.11

Meet FourDollarVPN.

Ninety seconds from nothing to a hardened personal WireGuard VPN on DigitalOcean, for about $4 a month. No config files, no SSH gymnastics, no commercial provider you have to take at their word.

The Story Behind This

I built FourDollarVPN because every time I wanted a personal VPN, I hit the same wall: spin up a server, SSH in, install WireGuard, edit config files, fight with the firewall, generate keys, copy them around, then debug why the tunnel won't come up. It's the kind of task that takes ten minutes if you've done it a hundred times — and an entire afternoon if you haven't.

Meanwhile the alternative — paying a commercial VPN provider — means handing your traffic to a company that might be logging it, might be owned by someone you've never heard of, and might be quietly compromised the next time their shared infrastructure gets popped. Several have been caught lying about their no-log policies. A significant share of the popular "privacy" VPNs are quietly owned by holding companies in jurisdictions with opaque data-handling laws.

FourDollarVPN collapses the do-it-yourself path into one command:

fourdollarvpn setup

About 90 seconds later, you have a hardened WireGuard server running on DigitalOcean and a .conf file (plus a QR code) ready to import into the WireGuard client on any device.

What FourDollarVPN Actually Does

When you run fourdollarvpn setup, it walks through nine steps with a live progress bar showing the current step, elapsed time, and step counter:

  1. Creates a small Ubuntu 24.04 droplet on DigitalOcean (~$4/month, size s-1vcpu-512mb-10gb)
  2. Tags the droplet fourdollarvpn at creation so later commands identify it by tag rather than guessing from its name
  3. Connects over SSH using a freshly generated Ed25519 key. The public half is removed from your DigitalOcean account the moment it's served its purpose (DO bakes it into the droplet's authorized_keys once, at create time). The private half is persisted locally, indexed by the droplet's ID — so if DO ever recycles an IP to a different droplet, the CLI refuses to trust the stranger on the other end.
  4. Installs WireGuard, generates server keys, and configures the interface
  5. Locks down the firewall — only SSH (22/tcp) and WireGuard (51820/udp) are open
  6. Installs fail2ban (5 failed logins = 1 hour ban) and disables SSH password authentication outright
  7. Enables unattended-upgrades so security patches land automatically — with conditional auto-reboot at 04:00 UTC on days a reboot is actually required (a globally-quiet window, typically once every week or two when a kernel lands)
  8. Kicks off a full apt upgrade in the background (your VPN works during it)
  9. Generates your client config locally on your machine — the private key never touches the server
  10. Drops a .conf file and an SVG QR code in your working directory, filenames tagged with the server IP and creation time so nothing silently overwrites anything

Total time typically lands between 60 and 90 seconds.

Adding More Devices

Want your VPN on your phone too? After setup, run:

fourdollarvpn add-client --name phone --open-qr

A QR code pops up in your browser. Open the WireGuard app on your phone, scan, done. The new peer is added to the live WireGuard interface without a restart — existing clients stay connected.

The --name flag is new in v1.0.10 and optional. If you pass one, it's stored as a comment above the peer block on the server (WireGuard ignores comments, so every machine managing the droplet sees the same names). It shows up in fourdollarvpn list-clients, and fourdollarvpn remove-client phone revokes it directly — no more guessing which opaque public-key prefix is the old phone you want to kill. The generated filename also carries the name, so fourdollarvpn-client-phone-10-66-66-3-14220417.conf is self-explanatory when you come back to it three months later.

You can have up to 253 clients per server. Each one gets its own keypair generated locally, so compromising one device doesn't compromise the rest.

One config, one device

Don't reuse the same .conf file on two devices at once. WireGuard will peer-roam to whichever device sent a packet most recently and traffic will flip-flop between them. add-client takes ten seconds — just run it again.

The Security Story

This is where I spent the most time. A VPN you can set up in 90 seconds is only useful if it's actually secure.

Cryptography you can't misconfigure

WireGuard's crypto is fixed and modern — Curve25519, ChaCha20-Poly1305, BLAKE2s. There are no cipher suites to misconfigure because there are no cipher suites to choose.

Strict key separation

Three different kinds of secret, three different lifecycles:

Hardened before any port is exposed

Password authentication is disabled across the board. Root SSH is restricted to key-only (PermitRootLogin prohibit-password). fail2ban rate-limits SSH (5 failures = 1-hour ban) on top of UFW's built-in connection rate limiter. UFW blocks everything except SSH and WireGuard. Kernel hardening (reverse-path filtering, SYN cookies, disabled ICMP redirects, disabled source routing, disabled IPv6, martian-packet logging) is applied via /etc/sysctl.d/ before setup declares victory. WireGuard does not log traffic by design — there's nothing to disable.

Want to go further? Pass --lock during setup to firewall-block SSH entirely after provisioning. The server becomes a black box that does exactly one thing: route encrypted packets. Heads up — this also prevents add-client and check from working, so add all the devices you need first. DigitalOcean's web console (a browser-based VNC, not SSH) still works for emergency recovery.

What About DNS Leaks?

Every client config ships with Cloudflare DNS (1.1.1.1, 1.0.0.1) baked in, and AllowedIPs = 0.0.0.0/0 routes all IPv4 traffic through the tunnel. IPv6 is deliberately not tunneled: the droplet is provisioned with ipv6=false and the kernel has disable_ipv6=1, so any IPv6 traffic on your device stays on your local interface rather than silently blackholing inside the tunnel. Combine that with the WireGuard app's built-in kill switch (Windows, macOS, iOS, and Android all have one) and you get full-tunnel protection that fails closed. If your network is IPv6-only, enable the kill switch — it'll block clear IPv6 rather than fall back to unprotected.

On Linux there's no app-level switch, but a single iptables rule achieves the same thing — full docs are in the repo.

Other Useful Commands

fourdollarvpn status # list your active FourDollarVPN servers fourdollarvpn check # SSH in and verify everything is healthy fourdollarvpn destroy # tear it down and stop billing

fourdollarvpn check is the one I use most after the initial setup — it shows ✓/× for each service, the latest WireGuard handshake (so you can confirm a remote client is actually connecting), the firewall state, and whether the background upgrade has finished.

fourdollarvpn destroy gives you an interactive picker if you don't pass a droplet ID, which matters more than it sounds — nobody wants to memorize droplet IDs at 11pm when they're trying to stop a bill.

Why a Personal VPN Beats a Commercial One

A personal VPN inverts the trust model:

Worth being honest about the limit: streaming services (Netflix, Disney+, BBC iPlayer) block nearly all datacenter IPs regardless of source. A personal DO droplet doesn't get you around those. But for the 80% of "blocked on commercial VPN" cases that aren't streaming, self-hosted on DO usually just works where a commercial provider wouldn't.

The downside has always been the setup friction. FourDollarVPN is my attempt to remove that friction without cutting any corners on hardening.

Some Nice-to-Haves Added Along the Way

A few quality-of-life things that shipped between v1.0.0 and v1.0.11 worth calling out:

One more tip

Once your VPN is running, you don't need the DigitalOcean API token anymore. Revoke it. Or, if you want to keep management access, create a second read-only token for fourdollarvpn status and only use a full-access token when you're actually provisioning.

Try It

You need a DigitalOcean account and an API token. Then grab the prebuilt binary for your OS from the latest release — Windows x64, macOS Apple Silicon, macOS Intel, and Linux x64 are all covered, no Python needed.

A note on OS security warnings

The binaries aren't code-signed yet (that's on the roadmap, but the certificates cost real money). Your OS will warn you the first time you run one. That's cosmetic, not a security problem — the binary is exactly what shipped from the GitHub Actions workflow, and you can verify it with the SHA checksums on the release page if you want. To bypass the warning: on Windows, SmartScreen shows "Windows protected your PC" — click More info, then Run anyway. On macOS, the first launch fails silently; right-click the binary in Finder and pick Open, then click Open on the confirmation dialog. After the first run both OSes remember your choice. Linux doesn't prompt.

Prefer to install from source?

pipx install git+https://github.com/SkyzFallin/FourDollarVPN.git@v1.0.11 fourdollarvpn init # save your token once fourdollarvpn setup # ~90 seconds later you're done

If fourdollarvpn: command not found after installing from source — Python's Scripts/ (Windows) or bin/ (macOS/Linux) directory isn't on your PATH. Every command in this post also works as python -m fourdollarvpn ... with identical behavior. So fourdollarvpn setup becomes python -m fourdollarvpn setup. Prebuilt-binary users don't hit this because the binary is invoked directly.

"Stop renting privacy from people you don't know. Own the server, own the keys, own the silence."

Source code, full docs, and the CLI reference live at github.com/SkyzFallin/FourDollarVPN. MIT licensed. If you hit a bug or want a feature, open an issue — I read every one.

By SkyzFallin · WesCastle Tags: vpn, wireguard, privacy, infrastructure, devops