2025-08-19

Modernizing The HoneyNet: Bringing Community Honey Network Into 2025

Eight years ago, I wrote about building a honeypot army with Raspberry Pi, EC2, and Modern Honey Network. Back then, the Modern Honey Network (MHN) project was the gold standard for deploying a large fleet of honeypots, but it was already showing its age as Python 2 deprecation loomed. in 2020, some folks forked the work and got it running on Python 3, but haven't maintained it since. To the surprise of everyone who remembers me introducing the SecKC MHN effort and the stunning WebGL dashboard Wintel and I worked on together, my old MHN server was still running in 2025, dutifully grinding away on Ubuntu 16.04 LTS and Python 2.7.12. For the past 2 years, folks have asked me how to build their own, and I've had to say "First, time-travel back to 2017..."

I'd actually set out to do this work over my vacation a few months ago, but I was not in a good headspace and really just needed to disconnect. I did get familiar with CHN back in May. It ran fine in Docker but it was still dated, and it was going to need some work to integrate with the WebGL Dashboard. In many ways, I felt like some kind of archaeologist, looking at the mostly-abandoned CHN work, the few-and-infrequent MHN updates prior to 2018, and the fossils of purpose-built honeypots, many untouched since before 2015.

What's left of a once-vibrant honeypot ecosystem is a bit of a shame. The original MHN stack had become a museum of dependencies that couldn't be installed on modern systems. Even CHN featured Ubuntu 18.04 base images, archaic PyMongo trying to talk to MongoDB 8.x (spoiler: it can't), and many other outdated Python packages. I also realized that if anything happened to my precious EC2 instance, the entire stack was going to be offline indefinitely. I have backups of everything, but trying to untangle everything to restore a fragile artifact like this wasn't my idea of fun, and I'd probably just let it fade into obscurity. At the same time, I also envisioned getting the whole thing running in Python virtual environments on one of my OpenBSD systems, instead of relying on Docker on a cloud node somewhere. Docker is great, but it should be a deployment consideration, not a hard requirement.

Claude Code -- or -- vibe-technical-debt-repayment

This was the first seriously large project I've used Claude Code to help with. I used it mostly for documentation and test automation. I started by having it unpack how all of the pieces work together and creating a Mermaid syntax diagram (left) and description in Markdown to help better understand the data flow between the honeypots, hpfeeds, mnemosyne, MongoDB, SQLite and the core CHN-Server itself. I also had Claude help me keep track of the project plan, broken up into phases, and when I was getting tired and had to take a break, it could summarize the commit logs, diffs, and create a quick checklist of next-steps that I could come back to the next day to get my head back into the game quicker. When I found a class of problems in the code, Claude highlighted other places the same patterns were found. That wasn't anything I couldn't do in a modern IDE, but it was a nice touch, since I was working in vim the entire time. If you actually try to have Claude write code, it's kind of a mixed bag. Many of its decisions are based on popular and harmful anti-patterns propagated through StackOverflow, Quora and Reddit. You'll have to babysit it and tell it no quite often.

The Modernization Journey

The initial scope seemed straightforward enough: upgrade some dependencies, fix some syntax errors and APIs, clean up a few bugs, get it all running in an OpenBSD VMM instance, then focus on rolling some new Docker containers. What started as a simple refresh turned into a journey through eight years of accumulated technical debt. I started with just the CHN-Server repository, but it had dependencies on the hpfeeds3 repository, and updating that meant messing with the mnemosyne repository. Several projects install my updated hpfeed3 package directly from GitHub in requirements.txt or the Dockerfile. There were layers of compatibility issues forcing me to take a phased, incremental approach to modernization, and a few gotchas that bit me several times, particularly syntax changes around PyMongo. Some bugs weren't obvious until I tried end-to-end testing with real honeypots in the lab. Honestly, I'm sure I missed a few obvious ones, but none that impact basic functionality so far. I threw hundreds of events per hour at the system using an infinite loop of telnet attempts. The system didn't even notice. It's much less resource-intensive.

The front-end needed some work, too. I parameterized the base API URL inside the JavaScript. Rob Scanlon's original work was built with Grunt, and Wintel's middleware used an ancient python2 WebSocket library that is incompatible with anything in modern JavaScript. After a few hours of trying to remove all of the Deprecated bits from the front-end, I decided to revert back to the basics, and gut the WebSocket code from the middleware entirely, and add a REST API to poll the honeypot attacks. I tweaked the Javascript as minimally as possible. I'm really not that comfortable with front-end code.

End to end also revealed a few things that'll need attention soon. The deployment scripts all reference docker containers with architecture tags (-amd64, -arm, etc) that don't exist, for example. Hpfeeds-logger and hpfeeds-cif start up and appear functional, but they need more comprehensive testing than just "the container starts and doesn't immediately crash." I do my own log collection with a custom HPFeeds scraper I wrote in Go last year, replacing the PHP junk I had written back in 2017. I haven't used CIF since 2017 either, and don't really have much need for it. That's future work or maybe even someone else's problem. I'm working on a plan to submit my improvements upstream in a practical way that doesn't require the current maintainers to review massive, monolithic pull requests (if they're even paying attention to PRs). I may end up having to just maintain this fork myself for a while. I'll come up with a more sustainable strategy to keep it up to date if it looks like that's how it will be.

Getting CHN deployed in 2025 is easier than it was in 2017, assuming you can navigate the initial setup. Once I had verified all of the pieces kind of worked on their own, I forked the chn-quickstart project. The guided Docker Compose generator handles most of the complexity, and the whole CHN stack comes up with a simple docker-compose up -d. It's missing the attack-map and custom middleware for the time being, but they're not too hard to deploy next to CHN once it's up and running. I did manage to dockerize the middleware. As of last night, I cut over the DNS records from my old EC2 instance to my new VPS. This thing's actually running in production! nginx handles routing the web requests to the right places, and hosting the static assets of the animated front-end.

The OpenBSD deployment in my lab environment has been rock-solid, with Cowrie honeypots running on Raspberry Pi devices feeding data back to the central server. Watching the attack data flow in real-time through the web interface brings back that same sense of satisfaction I felt eight years ago - except now it's running on modern infrastructure. I need to clean up the OpenBSD init scripts and write some documentation around that part. I don't think it'll be as easy to deploy on bare metal (in Python Virtual Environments with uWSGI) as I'd like.

During the 2020 CHN effort, Duke University's STINGAR team built a bunch of dockerized honeypots that are still functional today, but similarly dated. Modernizing those honeypot projects would be nice. If we concede that the honeypot deployment strategy is just docker images on single board computers, home lab VMs and cloud nodes, it's not really that urgent. Cowrie is actively maintained, and a bare-metal deployment script is on my list of things to build soon.

Links