Introduction
Perimeter defenses — firewalls, EDR, email filters — keep attackers out. But what happens when one gets in? A compromised credential, a supply-chain backdoor, or an unpatched internal service can hand an attacker a foothold before any alert fires.
Honeypots flip the equation. Instead of trying to block everything, you plant decoys — fake SMB shares, mock SSH servers, bogus RDP endpoints — on your internal network. Any connection to these services is, by definition, suspicious. Real users don't touch them. Attackers probing your network almost always will.
OpenCanary is a lightweight, open-source honeypot framework from Thinkst Canary. It emulates a dozen common services (SSH, FTP, HTTP, Telnet, SMB, MySQL, RDP, and more), logs every interaction to structured JSON, and can forward alerts to a syslog server, webhook, or email. A single Raspberry Pi or small VM running OpenCanary gives you high-fidelity early-warning coverage across your entire LAN — no agents, no per-endpoint cost.
This guide walks you through deploying OpenCanary on Ubuntu 22.04, configuring realistic service personas, forwarding alerts to a syslog pipeline, and verifying your detection coverage end-to-end.
Prerequisites
- Ubuntu 22.04 LTS (or Debian 12) on a dedicated VM or Raspberry Pi
- A static IP on your internal network (e.g.,
192.168.1.50) - Python 3.10+ and
pipinstalled - Firewall rules allowing inbound traffic on all ports you want to monitor
- (Optional) A syslog/SIEM endpoint — Graylog, Wazuh, Loki, or similar
Tip: Place the honeypot on the same VLAN as servers you want to protect, not on a management VLAN. The goal is to look like a real host that an attacker might target during lateral movement.
Step 1 — Prepare the Host
Give the honeypot a believable hostname. Attackers often skip hosts with obviously generic names.
sudo hostnamectl set-hostname fileserver01
echo "127.0.1.1 fileserver01" | sudo tee -a /etc/hostsInstall system dependencies:
sudo apt update && sudo apt install -y \
python3-pip \
python3-dev \
libssl-dev \
libffi-dev \
build-essential \
gitCreate a dedicated service account. Never run OpenCanary as root:
sudo useradd -r -s /usr/sbin/nologin -d /opt/opencanary opencanary
sudo mkdir -p /opt/opencanary /var/log/opencanary
sudo chown opencanary:opencanary /opt/opencanary /var/log/opencanaryStep 2 — Install OpenCanary
Use a Python virtual environment to keep dependencies isolated:
sudo -u opencanary python3 -m venv /opt/opencanary/venv
sudo -u opencanary /opt/opencanary/venv/bin/pip install --upgrade pip
sudo -u opencanary /opt/opencanary/venv/bin/pip install opencanaryVerify the installation:
sudo -u opencanary /opt/opencanary/venv/bin/opencanaryd --version
# Expected: opencanary 0.9.xStep 3 — Generate and Edit the Configuration
OpenCanary uses a JSON config file. Generate the default template:
sudo -u opencanary /opt/opencanary/venv/bin/opencanaryd --copyconfig
sudo mv ~/.opencanary.conf /opt/opencanary/opencanary.conf
sudo chown opencanary:opencanary /opt/opencanary/opencanary.confEdit the config to enable the services you want to emulate:
sudo nano /opt/opencanary/opencanary.confBelow is a production-ready configuration that enables the most commonly targeted services. Adjust the device.node_id to something that fits your naming convention, and set your syslog IP:
{
"device.node_id": "fileserver01-honeypot",
"git.enabled": false,
"ftp.enabled": true,
"ftp.port": 21,
"ftp.banner": "Microsoft FTP Service",
"http.enabled": true,
"http.port": 80,
"http.banner": "Apache/2.4.41 (Ubuntu)",
"http.skin": "basicLogin",
"httpproxy.enabled": false,
"mysql.enabled": true,
"mysql.port": 3306,
"mysql.banner": "5.7.28-0ubuntu0.18.04.4",
"mssql.enabled": false,
"ntp.enabled": false,
"portscan.enabled": true,
"portscan.ignore_localhost": true,
"portscan.synrate": 5,
"portscan.nmaposrate": 5,
"portscan.lorate": 3,
"rdp.enabled": true,
"rdp.port": 3389,
"redis.enabled": false,
"sip.enabled": false,
"smb.enabled": true,
"ssh.enabled": true,
"ssh.port": 22,
"ssh.version": "SSH-2.0-OpenSSH_8.2p1 Ubuntu-4ubuntu0.5",
"tcpbanner.enabled": false,
"telnet.enabled": true,
"telnet.port": 23,
"telnet.banner": "",
"tftp.enabled": false,
"vnc.enabled": true,
"vnc.port": 5900,
"logger": {
"class": "PyLogger",
"kwargs": {
"formatters": {
"plain": {
"format": "%(message)s"
}
},
"handlers": {
"console": {
"class": "logging.StreamHandler"
},
"file": {
"class": "logging.FileHandler",
"filename": "/var/log/opencanary/opencanary.log"
},
"syslog-unix": {
"class": "logging.handlers.SysLogHandler",
"address": ["YOUR_SYSLOG_SERVER_IP", 514],
"socktype": "socket.SOCK_DGRAM"
}
}
}
}
}Replace YOUR_SYSLOG_SERVER_IP with your SIEM/syslog endpoint, or remove that handler block entirely if you're logging to file only.
Step 4 — Configure SMB Shares (Optional but High-Value)
The SMB module requires Samba. On a real network, fake file shares named Finance, HR_Records, or Backups are irresistible to ransomware operators and internal bad actors alike.
sudo apt install -y sambaCreate a decoy share directory:
sudo mkdir -p /srv/honeypot/Finance
sudo chown -R nobody:nogroup /srv/honeypot/Add a share to /etc/samba/smb.conf:
[Finance]
comment = Finance Department Files
path = /srv/honeypot/Finance
browseable = yes
read only = yes
guest ok = yesRestart Samba — OpenCanary hooks into Samba's audit log, so the share needs to exist:
sudo systemctl restart smbd nmbdEnable the SMB audit hook in OpenCanary by adding this to smb.conf under [global]:
[global]
vfs objects = full_audit
full_audit:prefix = %U|%I|%m|%S
full_audit:success = open opendir
full_audit:failure = all
full_audit:facility = LOCAL7
full_audit:priority = NOTICEStep 5 — Run as a systemd Service
Create a systemd unit so OpenCanary starts on boot and restarts on failure:
sudo tee /etc/systemd/system/opencanary.service > /dev/null <<'EOF'
[Unit]
Description=OpenCanary Honeypot
After=network.target
Wants=network.target
[Service]
Type=simple
User=opencanary
Group=opencanary
WorkingDirectory=/opt/opencanary
ExecStart=/opt/opencanary/venv/bin/opencanaryd --start --uid=opencanary --gid=opencanary
ExecStop=/opt/opencanary/venv/bin/opencanaryd --stop
Restart=always
RestartSec=10
StandardOutput=journal
StandardError=journal
[Install]
WantedBy=multi-user.target
EOFEnable and start the service:
sudo systemctl daemon-reload
sudo systemctl enable opencanary
sudo systemctl start opencanary
sudo systemctl status opencanaryExpected output:
● opencanary.service - OpenCanary Honeypot
Loaded: loaded (/etc/systemd/system/opencanary.service; enabled)
Active: active (running) since Mon 2026-06-22 08:30:00 MDT
Step 6 — Configure Firewall Rules
Allow inbound traffic on all honeypot ports. Adjust this list based on what you enabled in the config:
sudo ufw allow 21/tcp comment "Honeypot FTP"
sudo ufw allow 22/tcp comment "Honeypot SSH"
sudo ufw allow 23/tcp comment "Honeypot Telnet"
sudo ufw allow 80/tcp comment "Honeypot HTTP"
sudo ufw allow 445/tcp comment "Honeypot SMB"
sudo ufw allow 3306/tcp comment "Honeypot MySQL"
sudo ufw allow 3389/tcp comment "Honeypot RDP"
sudo ufw allow 5900/tcp comment "Honeypot VNC"
sudo ufw reloadStep 7 — Add Port Scan Detection
OpenCanary's built-in port scan detector (portscan.enabled: true) fires when a source IP probes multiple ports in a short window. This catches Nmap -sS and -sV scans.
Tune the thresholds based on your network noise level. On a quiet internal LAN, lower thresholds work well:
"portscan.synrate": 5,
"portscan.nmaposrate": 5,
"portscan.lorate": 3These values mean: alert if a single source sends more than 5 SYNs/second, detects Nmap OS fingerprint probes, or hits 3+ low-rate scan attempts.
Verification
1. Confirm Services Are Listening
sudo ss -tlnp | grep -E ':21|:22|:23|:80|:3306|:3389|:5900'You should see opencanaryd or python3 processes bound to each port.
2. Trigger a Test Alert
From a separate machine on the same network, attempt an SSH connection:
ssh testuser@192.168.1.50
# Enter any password — it will be rejectedCheck the log:
sudo tail -f /var/log/opencanary/opencanary.logYou should see a structured JSON event like:
{
"dst_host": "192.168.1.50",
"dst_port": 22,
"local_time": "2026-06-22 09:15:32.441",
"logdata": {
"PASSWORD": "Password1",
"USERNAME": "testuser"
},
"logtype": 4001,
"node_id": "fileserver01-honeypot",
"src_host": "192.168.1.105",
"src_port": 54321,
"utc_time": "2026-06-22 15:15:32.441"
}3. Run a Port Scan to Test Detection
From a test machine, run a quick Nmap scan:
nmap -sS -p 1-1000 192.168.1.50Within seconds, the log should show a logtype: 5001 port scan event with the source IP.
4. Test the HTTP Login Trap
Open a browser and navigate to http://192.168.1.50. You'll see a basic login page. Enter any credentials — OpenCanary logs the attempt:
{
"logtype": 3001,
"logdata": {
"USERNAME": "admin",
"PASSWORD": "admin123",
"PATH": "/login"
},
"src_host": "192.168.1.105"
}Optional: Webhook Alerts to Slack or Discord
Add a webhook handler to the logger.handlers section of your config for real-time alerting:
"webhook": {
"class": "opencanary.logger.WebhookHandler",
"url": "https://hooks.slack.com/services/YOUR/WEBHOOK/URL",
"method": "POST",
"data": {
"text": "🚨 Honeypot Alert: {message}"
}
}For Discord, use the same pattern but target your Discord webhook URL and wrap in {"content": "..."} format.
Troubleshooting
Service fails to start — port already in use
sudo ss -tlnp | grep :22If your host's real SSH is on port 22, move it first:
# Edit /etc/ssh/sshd_config: Port 2222
sudo systemctl restart sshd
# Then OpenCanary can claim port 22No events appearing in the log
- Confirm the service is running:
sudo systemctl status opencanary - Check for Python errors:
sudo journalctl -u opencanary -n 50 - Ensure the firewall is not blocking the test traffic
- Verify the log file path is writable:
ls -la /var/log/opencanary/
SMB detection not working
Samba must be running and the full audit VFS module must be loaded. Check:
sudo testparm -s | grep "vfs objects"
sudo systemctl status smbdHigh false-positive rate on port scans
Some network monitoring tools (vulnerability scanners, Nessus, monitoring agents) legitimately probe hosts. Allowlist their IPs:
"portscan.ignorelist": ["192.168.1.10", "192.168.1.11"]Logs flooding on a busy network
Enable rate-limiting in the logger or send only to syslog (less I/O overhead). Avoid writing to both file and syslog simultaneously on low-resource hardware.
Summary
You now have a functional OpenCanary honeypot that:
- Emulates SSH, FTP, HTTP, MySQL, RDP, SMB, VNC, and Telnet services
- Logs every unauthorized connection attempt to structured JSON
- Detects port scans in real time
- Forwards alerts to your syslog/SIEM pipeline
- Runs as a hardened systemd service under a dedicated unprivileged account
Next steps to improve coverage:
- Deploy multiple honeypot nodes on different VLANs for broader lateral-movement detection
- Add fake admin credentials to Active Directory pointing at the honeypot (a "canary token" AD account) — any login attempt immediately signals a compromised credential
- Integrate OpenCanary JSON logs into Wazuh or Graylog for correlation with other sources
- Use the
httproxymodule to catch proxied HTTP requests from infected endpoints - Create DNS canary tokens (domains that exist only in your internal DNS) to detect data exfiltration attempts
Honeypots add no performance overhead to production systems, require minimal maintenance, and deliver zero-false-positive detections by design — every alert is real. On a network where perimeter defenses may be the only layer, a single OpenCanary instance can be the difference between discovering a breach in minutes versus months.