I Built a Honeypot for My $15 Blog Server

Within hours of putting this blog online, the bots found it.

Not readers—automated scripts probing for vulnerabilities. Requests for /wp-admin, /.env, /phpmyadmin, /config.php. Hundreds of them, all looking for doors that don’t exist on a static site.

At first I just blocked them. Then I thought: why not have some fun?

The Attack Surface That Isn’t

This blog is static HTML served by lighttpd. No PHP, no database, no WordPress. The bots are wasting their time—but they don’t know that.

Looking at my access logs, I saw patterns:

All returning 403 or 404. Boring.

The Honeypot

Instead of blocking these requests, I decided to welcome them:

1. A fake login page at /wp-admin that looks like a generic admin panel. When bots submit credentials, I log them—username, password, IP, user agent.

2. A gzip bomb for the config hunters. When something requests /.env, they get a 500KB file that decompresses to 500MB of zeros. Most HTTP clients automatically decompress gzip responses. Their scanner gets a nasty surprise.

The Technical Bits

The Gzip Bomb

dd if=/dev/zero bs=1M count=500 | gzip -9 > secrets.gz

This generates 500MB of zeros (the most compressible data possible), then compresses at maximum level. The result: 500MB becomes ~500KB—a 1000:1 compression ratio.

Why does this hurt? Most HTTP clients see the Content-Encoding: gzip header and automatically decompress. The bot’s scanner downloads 500KB, then tries to expand 500MB into memory. On a scanner hitting thousands of sites in parallel, this can crash the process or exhaust disk space.

The Credential Harvester

The fake login is just static HTML with a form:

<form method="POST" action="/honeypot/cgi/login.sh">
  <input name="user" placeholder="Username">
  <input name="pass" type="password" placeholder="Password">
  <button>Log In</button>
</form>

When submitted, a tiny CGI script logs everything and redirects to the bomb:

# Read the POST data
read -n $CONTENT_LENGTH POST_DATA

# Log it
echo "IP: $REMOTE_ADDR" >> /var/log/honeypot.log
echo "Credentials: $POST_DATA" >> /var/log/honeypot.log

# Redirect to the bomb as a "reward"
echo "Location: /honeypot/secrets.gz"

The bot thinks it’s logging in. Instead, its credentials are captured and it receives a gzip bomb as thanks.

The Redirect Trap

In lighttpd, I redirect attack paths to the honeypot:

# Config hunters get the bomb directly
/.env           → /honeypot/secrets.gz
/.git/config    → /honeypot/secrets.gz
/backup.sql     → /honeypot/secrets.gz

# Admin hunters get the fake login first
/wp-admin       → /honeypot/wp-login.html
/phpmyadmin     → /honeypot/wp-login.html
/admin          → /honeypot/wp-login.html

Legitimate visitors never see these paths. Only scanners do.

The Kill Switch

A simple flag file controls bomb serving—useful if I’m serving too much bandwidth:

if [ -f ".bomb-enabled" ]; then
    cat secrets.gz  # Serve the bomb
else
    echo "404"      # Just log, no bomb
fi

I can toggle this from my admin dashboard. Logging continues either way.

The Results

Within the first day:

The passwords are exactly what you’d expect from automated scripts cycling through common credential lists.

The Numbers

Component Size
Gzip bomb (compressed) 500 KB
Gzip bomb (decompressed) 500 MB
Compression ratio 1000:1
Fake login page 824 bytes
CGI scripts ~40 lines each

Is This Useful?

Practically? Not really. The bots aren’t learning anything—they’ll be back tomorrow with the same scripts.

But there’s something satisfying about turning nuisance traffic into entertainment. And the credential logs are genuinely interesting—a window into the automated attack patterns that every server on the internet faces constantly.

If you run a server, check your access logs sometime. You’re probably getting probed right now.


The honeypot runs on the same Raspberry Pi Zero 2 W that serves this blog. The trap is set at paths like /wp-admin and /.env—feel free to poke around, but don’t say I didn’t warn you.