← All projects

Case study · Infrastructure

AMvpn

A self-hosted WireGuard VPN built entirely by hand on Oracle Cloud's free tier — no managed services, no installer scripts doing the thinking for me. What started as a weekend project to avoid paying for a commercial VPN grew into a full security stack: DNS-level ad blocking, a live honeypot, and a custom monitoring dashboard.

01

Why build it

Instead of paying for one.

A commercial VPN means someone else's client app, someone else's billing, and trusting someone else's abuse policy with your traffic. A self-hosted one is a weekend and a few dollars a month — I picked WireGuard over OpenVPN or IPSec for being the simpler, more modern option, and Oracle Cloud's free tier because it's free forever, not a trial, with real bandwidth included.

I provisioned the VM and had WireGuard running the same day — and hit my first real incident before the day was out (more on that below).

02

What's actually running

The stack, as it stands today.

Tunnel
WireGuard, hand-configured
DNS
AdGuard Home — network-wide ad/tracker blocking
Perimeter
Port knocking + fail2ban — SSH invisible to scanners
Threat data
Honeypot with GeoIP enrichment + Telegram alerts
Dashboard
Custom FastAPI backend, vanilla JS frontend
Vulnerability tracking
CVE Watch page, cron-refreshed daily
03

Three things worth knowing

Pulled from the full build log.

01

Locked myself out on day one — and knew how to get back in

Moved SSH off the default port during the initial hardening pass, without opening the new port in the firewall first. Instant lockout, hours into the project. Recovered by provisioning an Oracle rescue VM, attaching the locked server's boot volume as a secondary disk, and editing the firewall rules directly from there before reattaching it as primary. Same day, still shipped the rest of the hardening pass.

02

A week of logs, not a guess, behind "nothing happened"

Pulled a full week of logs — about 50,000 lines — and went through them systematically instead of assuming things were fine. Tens of thousands of routine auth lines turned out to be scheduled jobs, not failed logins. Thousands of firewall drops traced back to known datacenter scanning ranges, not targeted activity. The port-knock sequence held the entire week. Clean, and provably so.

03

A real audit, and the judgment to walk something back

Ran a Lynis baseline audit and worked through the findings — SSH hardening, nginx hardening, kernel-level sysctl settings, tighter file permissions on sensitive configs. Also tried adding CrowdSec on top, hit a networking incompatibility with Oracle Cloud's path to its central API, and pulled it back out rather than fight a tool that wasn't worth its resource cost for this box's actual threat model.

04

See it for real

Two ways to go deeper than this page.