Honeypot Live Stats — 82 connections today from 25 unique IPs (2596 total, 112 unique IPs all-time)
Miles Huynh
· Reading time: 6 minutes · Admin

The honeypot diaries: three days, one EC2 box

AUG 18 Domain & bastion AUG 19 Docker & near-miss AUG 20 Ansible & monitoring

Three days, one EC2 box, and a lot of things that broke in interesting ways. A recap of what actually got learned — not the polished version, the real order it happened in.

Aug 18 — Domain, hardening, and infrastructure-as-code

  • Free domain via DuckDNS + real HTTPS via Certbot, then chased down a mixed-content bug when the site lost its styling over the new https://
  • Locked the EC2 security group's SSH rule down to "my IP only," confirmed key-only login, added HTTP Basic Auth in front of /admin
  • Built a custom Bludit plugin from scratch: a live honeypot stats box, reading a JSON file a root cron job writes every 5 minutes
  • Automated blog publishing through the Bludit REST API instead of pasting into the editor by hand
  • SEO pass: Open Graph tags, sitemap, RSS, verified with Google Search Console
  • First real Git session — add/commit/diff/log on the actual automation scripts, not a tutorial repo
  • Provisioned a second EC2 — a bastion host — entirely through Terraform: security group, SSH key pair, and instance defined as code

The moment that actually taught something: SSH to the new bastion timed out for hours despite the security group, network ACL, and route table all checking out — even AWS's own Reachability Analyzer called the path fully reachable. The real cause was two layers down: the home ISP's route to us-east-1, not AWS at all. Switching to phone data connected instantly.

Aug 19 — Containers, indexes, and a five-figure near-miss

  • Locked the real server's SSH down to bastion-only, verified with a ProxyJump one-liner — direct access now times out on purpose
  • Dockerized Bludit locally (nginx + PHP-FPM + MySQL) and learned the counterintuitive part: containers don't save disk space, they isolate
  • Built 300,000 fake rows in MySQL to watch an index actually work — EXPLAIN flipped from type: ALL to type: ref, invisible on the clock, huge on the query plan
  • Nearly subscribed to AWS Bedrock Provisioned Throughput at $80–99/hour instead of the per-token rate — backed out one click before a five-figure monthly line item
  • Designed and shipped an actual logo: four SVG concepts, picked one, hand-embedded it into the theme's navbar.php
  • Cross-posted to dev.to to test the waters outside the blog's own audience

The moment that actually taught something: the Bedrock "Purchase options" page looked like routine setup right up until the number was $80–99 per hour, not per token. Same product name, two completely different pricing models sitting one click apart on the same page.

Aug 20 — Ansible and self-hosted monitoring

  • First Ansible session, on the (disposable) bastion rather than the real server — ad-hoc commands, then a real playbook
  • Watched idempotency happen firsthand: the same yum install htop command reported changed the first run, "already installed" the second
  • Wrote a first two-task playbook, learned to read a PLAY RECAP line before anything else
  • Self-hosted Uptime Kuma via Docker on the bastion — one docker run, and the blog + honeypot now have a real monitoring dashboard
  • Worked out why that dashboard should never point at a company's Fortinet without sign-off — and why "WAN access already disabled" quietly answers the question anyway

The moment that actually taught something: the instinct to monitor company infrastructure from a personal AWS account came from a good place — but the same honeypot logic learned on day one applies in reverse: repeated probes from an unfamiliar IP are exactly the pattern a real security team is watching for.