decoygrid dev log #001 — starting over
This is the first entry in the decoygrid development log. The project existed in partial form before this site did. Time to document it properly as it gets rebuilt.
What decoygrid is
A honeypot status tracker. The idea: you have honeypots deployed across your environment — fake services, decoy systems, things an attacker might interact with before or after they’ve moved laterally. Knowing their status at a glance matters. Which are live? Have any received connection attempts? What did those look like?
That’s all it does. It’s not a honeypot itself. It doesn’t generate decoys. It tracks them.
What exists right now
A Go binary that:
- reads a config file listing honeypot endpoints (address, port, expected behaviour)
- polls each one on an interval
- outputs structured status to stdout
It works. It’s also incomplete in ways that matter:
- No persistent storage — every run starts from scratch
- No web interface — stdout only
- No alert mechanism — you have to be watching it
- Connection attempt logging doesn’t exist yet
The rebuild approach
Starting with the core loop in clean Go, then layering features in order of usefulness:
- Persistent state — SQLite for simplicity. One file, no dependencies. Records: last seen up, last seen down, total connection attempts, first/last attempt timestamp.
- HTTP status endpoint — single JSON endpoint that returns the current grid state. This is what the web interface (and anything else) reads from.
- Web interface — static HTML served by the binary itself. Status board layout. No frameworks, no build step. Just Go templates outputting HTML.
- Connection attempt logging — where the decoy actually records inbound connection data. This depends on the decoy type and needs to be designed per-protocol.
Everything is one binary. No containers, no orchestration, no external dependencies beyond SQLite. The whole point of Go for this is the single static binary you can drop anywhere.
Why Go
Concurrency is the honest answer. When you’re polling twenty honeypots simultaneously on configurable intervals and logging connection attempts from multiple sources at once, you want goroutines and channels, not threads and mutexes managed by hand. The runtime handles the scheduling. The code stays readable.
The second reason: the binary deploys to the VPS as a single file. Caddy reverse proxies to it. That’s the entire deployment. No language runtime to install, no dependency hell, no version conflicts with whatever else is on the machine.
Current state of the code
The repo is private while it’s in this state. It’ll move to public when there’s something worth publishing — probably around the time the basic persistent state and HTTP endpoint are in place. At that point it’ll have a page under /tools with proper docs and a changelog.
Next dev log entry will cover the SQLite schema and the state management approach.
Tagged: decoygrid, go, honeypot, dev-log