OpenCanary Honeypot on Ubuntu 24.04 on Azure User Guide
Overview
OpenCanary is a lightweight, low interaction honeypot daemon from Thinkst. It stands up a set of decoy network services and raises an alert the moment anyone touches them. Because nothing legitimate should ever connect to a decoy, every interaction is a high signal, low noise indicator of reconnaissance or compromise, delivered without the false positive fatigue of a traditional intrusion detection system.
The cloudimg image installs OpenCanary into a self contained Python virtualenv at /opt/opencanary/opencanary-env, runs it as the opencanary.service systemd unit, and enables a functional decoy surface out of the box: FTP on 21, HTTP on 80, Telnet on 23, MySQL on 3306 and a decoy SSH on 2222. Every interaction is written as structured JSON to /var/log/opencanary/opencanary.log.
Two cleanly separated planes. The image keeps the decoys and your real administration apart:
- Admin plane: the operating system's own SSH on port
22, key only (your Azure SSH key), with no image baked password and no shared bootstrap credential. This is how you administer the box. The decoy SSH is on port2222, and the honeypot never listens on port22. - Decoy plane: the emulated FTP, HTTP, Telnet, MySQL and SSH listeners. Any touch of these is logged as an alert. That is the product working as designed, and nothing an attacker does on a decoy touches the real system.
Per VM identity, no shared fingerprint. An alert node id baked once and shared across every image would make every deployment's alerts collide and would fingerprint the image. On each VM's first boot, opencanary-firstboot.service mints a fresh, unique alert node id and records it to a root only info note, so no two deployments share an identity and the image gives nothing away about its origin.
What is included:
- OpenCanary (verified at 0.9.8, BSD 3-Clause) in a self contained virtualenv at
/opt/opencanary opencanary.servicerunning the honeypot daemon under systemd- Decoy FTP (
21), HTTP (80), Telnet (23), MySQL (3306) and SSH (2222) opencanary-firstboot.servicefor the per VM alert node id and the instance info note- Structured JSON alert log at
/var/log/opencanary/opencanary.log - Real admin SSH kept key only on port 22, separate from the decoys
- Ubuntu 24.04 LTS base, fully patched, unattended security upgrades enabled
- 24/7 cloudimg support, 24h response SLA
Prerequisites
An active Azure subscription, an SSH key pair, and a VNet with a subnet. OpenCanary is lightweight; Standard_B2s (2 vCPU, 4 GB RAM) is ample for most deployments. Alerts live on the OS disk, so expand the disk if you expect to retain a long history locally rather than forwarding it off the box.
Step 1: Deploy the Virtual Machine
Option A: Azure Portal
Search the Marketplace for OpenCanary Honeypot on Ubuntu 24.04, choose your VM size, and provide your SSH public key. Attach a network security group that allows:
- TCP
22(your real admin SSH) from your management network only. - TCP
21,23,80,2222and3306(the decoys) from the networks you want to expose the sensor to. To collect real internet reconnaissance, allow these from the internet; to run an internal deception sensor, allow them only from the internal ranges you are monitoring.
Option B: Azure CLI
RG="opencanary-prod"; LOCATION="eastus"; VM_NAME="opencanary-01"
GALLERY_IMAGE_ID="/subscriptions/<sub-id>/resourceGroups/azure-cloudimg/providers/Microsoft.Compute/galleries/cloudimgGallery/images/opencanary-ubuntu-24-04/versions/<version>"
SSH_KEY="$(cat ~/.ssh/id_rsa.pub)"
az group create --name "$RG" --location "$LOCATION"
az network vnet create -g "$RG" --name oc-vnet --address-prefix 10.90.0.0/16 --subnet-name oc-subnet --subnet-prefix 10.90.1.0/24
az network nsg create -g "$RG" --name oc-nsg
az network nsg rule create -g "$RG" --nsg-name oc-nsg --name allow-admin-ssh --priority 100 \
--source-address-prefixes "<your-mgmt-cidr>" --destination-port-ranges 22 --access Allow --protocol Tcp
az network nsg rule create -g "$RG" --nsg-name oc-nsg --name allow-decoys --priority 110 \
--source-address-prefixes "Internet" --destination-port-ranges 21 23 80 2222 3306 --access Allow --protocol Tcp
az vm create -g "$RG" --name "$VM_NAME" --image "$GALLERY_IMAGE_ID" \
--size Standard_B2s --storage-sku StandardSSD_LRS \
--admin-username azureuser --ssh-key-values "$SSH_KEY" \
--vnet-name oc-vnet --subnet oc-subnet --nsg oc-nsg --public-ip-sku Standard
Step 2: Connect via SSH
Connect on the real admin port 22 with your key. This is the administration plane, kept completely separate from the decoys.
ssh azureuser@<vm-ip>
Find the public IP with az vm show -d -g opencanary-prod -n opencanary-01 --query publicIps -o tsv.
Step 3: Verify the honeypot is running
OpenCanary runs as a systemd service. Confirm it is active and that the decoys are listening, while your real SSH stays on port 22.
sudo systemctl start opencanary 2>/dev/null || true
sleep 2
sudo systemctl is-active opencanary
ss -tln | grep -E ':21 |:23 |:80 |:2222 |:3306 |:22 ' || true
/opt/opencanary/opencanary-env/bin/python -c 'import importlib.metadata as m; print("opencanary", m.version("opencanary"))'
echo "opencanary verified"
You should see opencanary reporting active, listening sockets for the decoys on 0.0.0.0:21, :23, :80, :2222 and :3306, your real admin SSH on 0.0.0.0:22, and the OpenCanary version.

Step 4: Read this VM's instance info
The first boot service wrote a root only note describing the two planes, this VM's unique alert node id, and the decoy endpoints.
sudo cat /root/opencanary-info.txt
The note is owned root:root with mode 0600. It records the decoy endpoints, the per VM alert node id, and where the alert log lives.

Step 5: See the honeypot detect an interaction
OpenCanary alerts on any touch of a decoy. Trigger the HTTP and FTP decoys locally to watch the honeypot detect the interaction and write a structured alert. This runs against loopback on the VM itself, so it never leaves the box; real attackers reaching the decoys over the public IP produce the same alerts.
curl -s -m 10 -o /dev/null --user admin:admin "ftp://127.0.0.1:21/" || true
curl -s -m 10 -o /dev/null "http://127.0.0.1:80/index.html" || true
sleep 2
sudo tail -n 5 /var/log/opencanary/opencanary.log | jq -c '{logtype, dst_port, src_host, logdata}'
echo "decoy interaction detected and logged"
Each line is a structured alert. You will see an entry for the FTP login attempt (dst_port 21) capturing the username and password that were tried, and an entry for the HTTP request (dst_port 80) recording the path and user agent. Because the decoys are emulated, none of this touched a real service.

Step 6: Read the captured alerts
Every decoy interaction is written to the structured JSON alert log. Inspect recent alerts to see what OpenCanary captured.
sudo tail -n 12 /var/log/opencanary/opencanary.log | jq -c '{utc_time, logtype, dst_port, src_host, logdata}'
echo "alerts read"
Each alert carries a logtype, the decoy port that was touched (dst_port), the source host, and the details in logdata (for example the credentials tried against the FTP, Telnet, MySQL or SSH decoys). This is the intelligence you forward to your monitoring pipeline.

Step 7: Forward alerts to your SIEM, email or a webhook
The JSON alert log at /var/log/opencanary/opencanary.log is designed to be shipped to a log pipeline. Point Filebeat, Fluent Bit, Vector or rsyslog at that file to forward alerts to Elasticsearch, Splunk, a Graylog input or any SIEM. OpenCanary can also emit alerts directly to email, a webhook, syslog or hpfeeds by adding a handler to the logger block in the configuration and restarting the service.
# Edit the logger.kwargs.handlers block in the config to add an email, webhook or syslog sink:
sudo nano /etc/opencanaryd/opencanary.conf
sudo systemctl restart opencanary
The OpenCanary documentation lists the available handlers (SMTP for email, a generic Webhook handler, Slack, syslog and hpfeeds) and the exact fields each one needs.
Optional: catch attackers on the standard SSH port
By default the decoy SSH listens on 2222 and your real admin SSH owns port 22, so administration always works out of the box. If you want the honeypot to catch attackers hitting the standard SSH port, you must first move your real administrative SSH to another port, then redirect inbound traffic. Doing this in the wrong order will lock you out.
# 1. FIRST move real admin SSH to 2022 and confirm you can reconnect on the new port,
# then in a NEW session:
# 2. Redirect inbound tcp/22 to the decoy SSH on 2222:
sudo iptables -t nat -A PREROUTING -p tcp --dport 22 -j REDIRECT --to-port 2222
Persist the iptables rule (for example with iptables-persistent) once you have confirmed admin access on the new port, and update your NSG to allow the new admin port from your management network only.
Managing the service
sudo systemctl status opencanary # health and recent log lines
sudo systemctl restart opencanary # apply config changes
sudo journalctl -u opencanary -f # live service log
sudo tail -f /var/log/opencanary/opencanary.log # live alerts
Edit /etc/opencanaryd/opencanary.conf to enable or disable decoy services, change their ports and banners, and add alert handlers. Restart the service after any change.
Server Components
| Component | Version | Path |
|---|---|---|
| OpenCanary | 0.9.8 | /opt/opencanary (virtualenv /opt/opencanary/opencanary-env) |
| Decoy FTP | — | 0.0.0.0:21 |
| Decoy HTTP | — | 0.0.0.0:80 |
| Decoy Telnet | — | 0.0.0.0:23 |
| Decoy MySQL | — | 0.0.0.0:3306 |
| Decoy SSH | — | 0.0.0.0:2222 |
| Real admin SSH | OpenSSH | 0.0.0.0:22 (key only) |
Filesystem Layout
| Path | Description |
|---|---|
/opt/opencanary |
OpenCanary virtualenv and runtime |
/opt/opencanary/opencanary-env |
Self contained Python virtualenv |
/etc/opencanaryd/opencanary.conf |
Main configuration (decoys, ports, logger) |
/var/log/opencanary/opencanary.log |
Structured JSON alert log |
/root/opencanary-info.txt |
Root only per VM instance info note |
Persistence, first boot and updates
The OpenCanary install and config live under /opt/opencanary and /etc/opencanaryd and are captured into the image, so a VM launched from this image is ready immediately. On first boot, opencanary-firstboot.service mints the per VM alert node id, resolves the instance address, writes the root only info note, then disables itself so subsequent reboots are unaffected. The OS ships fully patched with unattended security upgrades enabled.
systemctl is-enabled opencanary opencanary-firstboot
apt-mark showhold
echo "no held packages expected above"
Security Recommendations
- Keep the NSG for port 22 restricted to your management network. Only the decoy ports should be broadly reachable.
- Never place real secrets, credentials or data on this VM. The honeypot is a sensor, and any host exposed to attackers should be treated as disposable.
- Forward the JSON alert log off the box to your SIEM so captured intelligence survives even if the sensor is rebuilt.
- Review alerts regularly and rebuild the sensor periodically from a fresh image so each deployment gets a new per VM alert identity.
Support
Every cloudimg deployment includes 24/7 support with a 24 hour response SLA. Contact support@cloudimg.co.uk for help with deployment, configuration or scaling.
This is a repackaged open source software product with additional charges for cloudimg support services. OpenCanary is distributed under the BSD 3-Clause license and is a trademark of its respective owner. All product and company names are trademarks or registered trademarks of their respective holders. Use of them does not imply any affiliation with or endorsement by them.