Oh
Security Azure

OpenCanary Honeypot on Ubuntu 24.04 on Azure User Guide

| Product: OpenCanary on Ubuntu 24.04 LTS on Azure

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 port 2222, and the honeypot never listens on port 22.
  • 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.service running the honeypot daemon under systemd
  • Decoy FTP (21), HTTP (80), Telnet (23), MySQL (3306) and SSH (2222)
  • opencanary-firstboot.service for 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, 2222 and 3306 (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.

Terminal showing the opencanary service active and listening on the decoy ports 21, 23, 80, 2222 and 3306 while real admin SSH stays on port 22, with the OpenCanary version reported

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.

Terminal showing the root only instance info note describing the separate admin and decoy planes, this VM's unique alert node id, and the alert log location

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.

Terminal showing OpenCanary detecting a decoy interaction and writing a structured JSON alert capturing the destination port, source host and the credentials the FTP decoy was probed with

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.

Terminal showing several structured JSON alerts from the alert log, each recording the decoy port that was touched, the source host and the interaction details

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.