Home › The Stash

Home Honeypot Lab: Build a Tripwire That Catches Snoopers (OpenCanary)

LabOctober 6, 2026

BeginnerTestedTime ~45 minTool OpenCanaryRuns on any Linux box or NAS with DockerCost $0Exam Security+ · CySA+ · Network+

0 / 7 steps

The goal

Put a fake server on your home network that nothing legitimate should ever touch: a decoy SSH server, an FTP server, a NAS login page and a database. If anything knocks, you get its real address, what it tried, and even the password it typed. It’s a tripwire for snooping devices, compromised gadgets and curious guests.

Home network only. Never port-forward it. This lab is a tripwire inside your network, not a trap on the internet. Opening these ports on your router would invite the whole internet to your home connection. An internet-facing honeypot belongs on a separate, throwaway server, and that’s a different lab.

Why it works. A honeypot has no real users, so normal traffic almost never touches it. Your laptop never needs to log in to a fake FTP server. When it lights up, that deserves investigation — but your own tests, discovery tools and authorised scanners can trigger it too, so check the source and context before you treat an alert as an incident.

The tool. OpenCanary is the free, open-source version of Thinkst’s commercial Canary honeypots. It pretends to be the services you choose, and logs every touch as one line of JSON.

Steps

01Pick the right host (this matters)

You need an always-on Linux machine with Docker on your home network: a NAS with Docker (QNAP Container Station, Synology Container Manager), a Raspberry Pi, an old laptop, or a Linux VM bridged to your network.

Not Docker Desktop on Windows or Mac. We tried. It works, but every intruder shows up with Docker’s own internal address (172.17.0.1) instead of the real device, which defeats the point of a tripwire. OpenCanary needs Linux’s host networking to see the true source address. Its own documentation says the same.

02Write the config

On the host, make a folder for the honeypot and its logs:

$ mkdir -p ~/opencanary/logs && cd ~/opencanary

Save this as opencanary.conf in that folder. It turns on four decoys: FTP on 2121, SSH on 2222, a NAS-style login page on 8088 and MySQL on 3307, ports a NAS is unlikely to be using already.

{
  "device.node_id": "home-tripwire",
  "ip.ignorelist": [],
  "logtype.ignorelist": [],
  "git.enabled": false,
  "git.port": 9418,
  "git.max_connections": 32,
  "git.timeout": 10,
  "ftp.enabled": true,
  "ftp.port": 2121,
  "ftp.banner": "FTP server ready",
  "ftp.log_auth_attempt_initiated": false,
  "http.banner": "Apache/2.4.52 (Ubuntu)",
  "http.enabled": true,
  "http.port": 8088,
  "http.skin": "nasLogin",
  "http.log_unimplemented_method_requests": false,
  "http.log_redirect_request": false,
  "https.enabled": false,
  "https.port": 443,
  "https.skin": "nasLogin",
  "https.certificate": "/etc/ssl/opencanary/opencanary.pem",
  "https.key": "/etc/ssl/opencanary/opencanary.key",
  "httpproxy.enabled": false,
  "httpproxy.port": 8080,
  "httpproxy.skin": "squid",
  "llmnr.enabled": false,
  "llmnr.query_interval": 60,
  "llmnr.query_splay": 5,
  "llmnr.hostname": "DC03",
  "llmnr.port": 5355,
  "logger": {
    "class": "PyLogger",
    "kwargs": {
      "formatters": {
        "plain": {
          "format": "%(message)s"
        },
        "syslog_rfc": {
          "format": "opencanaryd[%(process)-5s:%(thread)d]: %(name)s %(levelname)-5s %(message)s"
        }
      },
      "handlers": {
        "console": {
          "class": "logging.StreamHandler",
          "stream": "ext://sys.stdout"
        },
        "file": {
          "class": "logging.FileHandler",
          "filename": "/var/tmp/opencanary.log"
        }
      }
    }
  },
  "portscan.enabled": false,
  "portscan.ignore_localhost": false,
  "portscan.logfile": "/var/log/kern.log",
  "portscan.synrate": 5,
  "portscan.nmaposrate": 5,
  "portscan.lorate": 3,
  "portscan.ignore_ports": [],
  "smb.auditfile": "/var/log/samba-audit.log",
  "smb.enabled": false,
  "mysql.enabled": true,
  "mysql.port": 3307,
  "mysql.banner": "5.5.43-0ubuntu0.14.04.1",
  "mysql.log_connection_made": false,
  "ssh.enabled": true,
  "ssh.port": 2222,
  "ssh.version": "SSH-2.0-OpenSSH_8.9p1 Ubuntu-3ubuntu0.10",
  "redis.enabled": false,
  "redis.port": 6379,
  "rdp.enabled": false,
  "rdp.port": 3389,
  "sip.enabled": false,
  "sip.port": 5060,
  "snmp.enabled": false,
  "snmp.port": 161,
  "ntp.enabled": false,
  "ntp.port": 123,
  "tftp.enabled": false,
  "tftp.port": 69,
  "tcpbanner.maxnum": 10,
  "tcpbanner.enabled": false,
  "tcpbanner_1.enabled": false,
  "tcpbanner_1.port": 8001,
  "tcpbanner_1.datareceivedbanner": "",
  "tcpbanner_1.initbanner": "",
  "tcpbanner_1.alertstring.enabled": false,
  "tcpbanner_1.alertstring": "",
  "tcpbanner_1.keep_alive.enabled": false,
  "tcpbanner_1.keep_alive_secret": "",
  "tcpbanner_1.keep_alive_probes": 11,
  "tcpbanner_1.keep_alive_interval": 300,
  "tcpbanner_1.keep_alive_idle": 300,
  "telnet.enabled": false,
  "telnet.port": 23,
  "telnet.banner": "",
  "telnet.max_connections": 64,
  "telnet.timeout": 120,
  "telnet.honeycreds": [],
  "telnet.log_tcp_connection": false,
  "mssql.enabled": false,
  "mssql.version": "2012",
  "mssql.port": 1433,
  "vnc.enabled": false,
  "vnc.port": 5000
}

Want the real ports? On a dedicated box that isn’t using them itself, change the four .port values to 21, 22, 80 and 3306 for an even more convincing decoy. Rename device.node_id if you run more than one.

03Start it with Docker

Save this as docker-compose.yml in the same folder, then start it.

services:
  opencanary:
    image: thinkst/opencanary:latest
    container_name: opencanary
    network_mode: host
    restart: unless-stopped
    volumes:
      - ./opencanary.conf:/root/.opencanary.conf:ro
      - ./logs:/var/tmp
$ docker compose up -d

On a QNAP? Container Station → Applications → Create, paste the same file, and change the two paths on the left of each volume to full paths such as /share/Container/opencanary/opencanary.conf and /share/Container/opencanary/logs. That’s exactly how ours runs.

04Check it’s armed

Look at the container’s output. The last line should say it’s running.

$ docker logs opencanary 2>&1 | tail -n 3
... "logdata": {"msg": {"logdata": "Canary running!!!"}}, "logtype": 1001 ...

If a port is already taken, the log says so. Pick another port for that decoy in the config and run docker compose restart.

05Play the intruder

From a different device on your network (a laptop or your phone), trip all three main decoys. Swap in your honeypot host’s IP address. Use made-up credentials only: the honeypot records exactly what you type.

1. In a browser, open the fake login page and try any username and password:

http://192.168.1.20:8088

2. Try an FTP login and an SSH connection from a terminal:

$ curl "ftp://guest:guest123@192.168.1.20:2121/"
$ ssh -p 2222 root@192.168.1.20

Spot the disguise: our login page called itself a “Synology RackStation” while running on a QNAP. Snoopers think they’ve found one kind of NAS and waste time on a fake.

06Read what it caught

Every touch is one JSON line in the log file. Show the latest, skipping the start-up messages:

$ grep -v '"logtype": 1001' logs/opencanary.log | tail -n 10

A login on the fake page looks like this (addresses changed):

{"dst_port": 8088, "logdata": {"HOSTNAME": "192.168.1.20", "PASSWORD": "Summer2026", "PATH": "/index.html", "SKIN": "nasLogin", "USERAGENT": "curl/8.21.0", "USERNAME": "nas-admin"}, "logtype": 3001, "node_id": "home-tripwire", "src_host": "192.168.1.50", "src_port": 63608, "utc_time": "2026-10-06 18:56:17.4"}

The fields that matter: src_host is the device that knocked, dst_port is which decoy, and logdata is what it tried. logtype tells you what happened:

  • 2000 — FTP login attempt (username and password recorded).
  • 3000 / 3001 — someone loaded the fake web page / tried to log in on it.
  • 4000 / 4001 / 4002 — SSH connection / the client’s software version / an SSH login attempt.
  • 8001 — a MySQL login attempt. Just opening the port is ignored by default.

The client version is a gift: ours logged SSH-2.0-OpenSSH_for_Windows_9.5, so we knew the “intruder” was a Windows machine before we even looked up its address.

07Decide what you’ll do when it fires

A tripwire is only useful if you act on it. When a real alert appears:

  • Identify the device — look up the src_host address in your router’s list of connected devices.
  • Ask the boring question first — is it a new gadget doing network discovery, or something you just installed? Note it, and add known-harmless devices to ip.ignorelist in the config.
  • If you can’t explain it — disconnect it from the network, change the Wi-Fi password, and check the device before it comes back.

Next level: OpenCanary can send each alert to email or a webhook (Discord, Slack), and its JSON log drops straight into a SIEM. Point it at the Splunk beginners lab setup and you have a real alert pipeline.

Lab complete

Your decoy records interactions with its exposed services. Review each alert against your own tests, scanners and network context before deciding whether it indicates unauthorized activity. A connection record shows an address, not a person.

Before you leave — prove it

From your phone, trip the fake login page with a made-up password. Find that exact attempt in the log and match its src_host to your phone in your router’s device list. If you can do that in under two minutes, you’re ready for a real alert.

What you learned

  • Deception as detection — unexpected access to a decoy deserves investigation; check the source first, because your own tests and scanners can trip it too.
  • Host networking — why containers on Windows and Mac hide the real source address.
  • Reading honeypot logs — source, decoy, log type and what was attempted.
  • Incident response basics — identify, explain, contain.

Put it on your resume. Deployed an OpenCanary honeypot on my home network (decoy SSH, FTP, NAS login and database) with alerting on any connection. Change it to match what you actually did.

NextHunt through real attack logs in Splunk→

Go deeper

Original walkthrough. Tested on 6 October 2026 with the thinkst/opencanary Docker image on a QNAP NAS (Container Station, host networking) and on Docker Desktop for Windows, where every source showed as Docker’s own address. Every log line above came from those tests. Spot something wrong? tell me and I will fix it.

Nyx P.S. Our QNAP now introduces itself as a Synology to anyone snooping. Identity theft, but make it defensive. 😏