Deployment guide

Beelzebub

Overview

Beelzebub is a self-hosted, open-source honeypot and deception framework. It stands up low-interaction decoy services that impersonate real infrastructure, so any connection to them is suspicious by definition. Every interaction is captured as a structured event and exposed as Prometheus metrics, which gives you an early-warning tripwire for reconnaissance and intrusion attempts. Nothing legitimate should ever touch a decoy, so a single hit is a high-signal alert rather than noise to sift out of production logs.

This SecureAnyCloud image installs the Beelzebub binary at /usr/local/bin/beelzebub. It runs as the beelzebub service and is driven by YAML under /etc/beelzebub/. Out of the box it runs three decoy services. Its Prometheus metrics endpoint is bound to loopback 127.0.0.1:2112 and served through nginx on port 80. nginx is ready for your TLS certificate.

The image takes a deliberately different posture for each of two surfaces. A honeypot's decoys are meant to be inviting bait, so this image does not lock them down. They run inside Beelzebub's own sandbox and grant no real access to the host.

What the image does secure is the management surface. The Prometheus metrics endpoint is bound to loopback and served through nginx. GET /health is an unauthenticated liveness endpoint for load balancer probes, while /metrics requires HTTP Basic Auth (username SecureAnyCloud). A beelzebub-firstboot.service oneshot generates a unique password on each VM's first boot, writes it to a root-only file and to an nginx htpasswd, resolves the instance URL, writes a root-only info note, then disables itself. No two VMs share a password, and none is baked into the image.

Real SSH stays out of the way. Your administrative SSH login is the normal Ubuntu sshd on port 22 (azureuser). The SSH decoy runs on a separate port (2222), so an attacker probing the decoy never touches your real management access.

The decoy services shipped by default:

  • SSH decoy on port 2222: pretends to be an OpenSSH server with a fake shell
  • HTTP decoy on port 8080: pretends to be an Apache web server
  • MySQL decoy on port 3306: pretends to be a MySQL 5.7 database

Note on the interface: Beelzebub is a headless daemon with no web UI. You configure it through YAML (/etc/beelzebub/), observe it through its Prometheus metrics, and extend it by adding decoy service definitions. This guide uses curl against the metrics endpoint and the decoys, and edits the YAML directly.

What you get:

  • Beelzebub (verified at 3.8.0) built as a single self-contained binary at /usr/local/bin/beelzebub
  • beelzebub.service running three decoy services (SSH 2222, HTTP 8080, MySQL 3306) with a loopback Prometheus metrics endpoint on 127.0.0.1:2112
  • An nginx reverse proxy on port 80, with a public /health endpoint and a password-protected /metrics endpoint
  • beelzebub-firstboot.service for the first-boot metrics password and info note
  • A unique per-VM metrics password generated on first boot, in a root-only 0600 file
  • Ubuntu 24.04 LTS base, patched at build time
  • 24/7 SecureAnyCloud support, 24h response SLA

Prerequisites

You need an active Azure subscription, an SSH key pair, and a VNet with a subnet.

Beelzebub is lightweight. The recommended VM size is Standard_B2s (2 vCPU, 4 GB RAM), which is sufficient for typical deployments.

Decide which decoys you want to expose to the networks you are monitoring, then open those ports on the network security group (NSG).

1

Deploy from the Azure Portal

Search the Marketplace for Beelzebub Honeypot on Ubuntu 24.04, choose your VM size, and attach an NSG.

Allow TCP 22 (your real SSH) from your management network only. Allow TCP 80 (the metrics endpoint) from the hosts that scrape it.

Then open the decoy ports (2222, 8080, 3306) to the network segment you want to monitor. Exposing a decoy to a subnet is what lets it catch anything that scans or probes that subnet.

In production, front port 80 with TLS (see the Enable HTTPS step below).

2

Deploy from the Azure CLI

RG="beelzebub-prod"; LOCATION="eastus"; VM_NAME="beelzebub-01" IMAGE_URN="sac1647283583153:beelzebub-ubuntu-24-04:default:latest" SSH_KEY="$(cat ~/.ssh/id_rsa.pub)" az group create --name "$RG" --location "$LOCATION" az network vnet create -g "$RG" --name beelzebub-vnet --address-prefix 10.90.0.0/16 --subnet-name beelzebub-subnet --subnet-prefix 10.90.1.0/24 az network nsg create -g "$RG" --name beelzebub-nsg az network nsg rule create -g "$RG" --nsg-name beelzebub-nsg --name allow-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 beelzebub-nsg --name allow-metrics --priority 110 \
  --source-address-prefixes "<your-mgmt-cidr>" --destination-port-ranges 80 443 --access Allow --protocol Tcp az network nsg rule create -g "$RG" --nsg-name beelzebub-nsg --name allow-decoys --priority 120 \
  --source-address-prefixes "<monitored-subnet-cidr>" --destination-port-ranges 2222 8080 3306 --access Allow --protocol Tcp
# Accept the Marketplace terms once per subscription (required before the first CLI deploy)
az vm image terms accept --urn sac1647283583153:beelzebub-ubuntu-24-04:default:latest
az vm create -g "$RG" --name "$VM_NAME" --image "$IMAGE_URN" \
  --size Standard_B2s --storage-sku StandardSSD_LRS \
  --admin-username azureuser --ssh-key-values "$SSH_KEY" \
  --vnet-name beelzebub-vnet --subnet beelzebub-subnet --nsg beelzebub-nsg --public-ip-sku Standard
3

Connect via SSH

Connect to the standard Ubuntu sshd on port 22 for administrative access. It is separate from the SSH decoy on port 2222.

ssh azureuser@<vm-ip>
4

Verify the services are running

Beelzebub's Prometheus metrics endpoint listens on loopback 127.0.0.1:2112, and nginx fronts it on port 80. The three decoy services listen on their own ports (2222, 8080, 3306). The health endpoint is public. The metrics endpoint requires your password.

sudo systemctl start beelzebub nginx 2>/dev/null || true
sudo systemctl is-active beelzebub nginx ss -tln | grep -E ':80 |127.0.0.1:2112|:2222|:8080|:3306' curl -s http://127.0.0.1/health

Expect both services active, the Prometheus metrics socket bound to loopback 127.0.0.1:2112, nginx on port 80, the three decoy ports listening, and ok from the public health endpoint. Port 2112 is bound to 127.0.0.1 only, so the metrics are never reachable except through the authenticated nginx proxy.

5

Read your per-VM metrics password

This VM generated the password on first boot and stored it in a root-only file. Read it and keep it secret, because it authenticates every request to the metrics endpoint. Then confirm that unauthenticated requests are rejected.

sudo cat /root/beelzebub-info.txt echo "unauthenticated /metrics -> HTTP $(curl -s -o /dev/null -w '%{http_code}' http://127.0.0.1/metrics)"

The info note holds METRICS_PASSWORD, the instance URLs and the decoy endpoints. It is owned root:root with mode 0600. An unauthenticated call to /metrics returns 401, because nginx enforces authentication.

6

Watch the honeypot catch a probe

This is what Beelzebub is for. Load your password into a shell variable and read the current event count from the authenticated metrics endpoint. Then send a few requests to the HTTP decoy, exactly as a scanner probing for a login page would. Read the metrics again and watch the counter climb.

export
BZ_PW=$(sudo grep '^METRICS_PASSWORD=' /root/beelzebub-info.txt | cut -d= -f2-)
echo "authenticated /metrics -> HTTP $(curl -s -o /dev/null -w '%{http_code}' -u sac:$BZ_PW http://127.0.0.1/metrics)"
echo "before: $(curl -s -u sac:$BZ_PW http://127.0.0.1/metrics | grep '^beelzebub_http_events_total ')" for i in 1 2 3; do curl -s -o /dev/null http://127.0.0.1:8080/wp-login.php; curl -s -o /dev/null http://127.0.0.1:8080/; done
echo "after: $(curl -s -u sac:$BZ_PW http://127.0.0.1/metrics | grep '^beelzebub_http_events_total ')" curl -s -u sac:$BZ_PW http://127.0.0.1/metrics | grep -E '^beelzebub_.*_total '

The authenticated /metrics call returns 200, and beelzebub_http_events_total increases with every hit on the HTTP decoy.

Each protocol has its own counter (beelzebub_ssh_events_total, beelzebub_http_events_total, beelzebub_tcp_events_total and more), and beelzebub_events_total is the grand total. Point Prometheus at this endpoint to alert the moment any of these counters moves.

7

Interact with the decoys

To an attacker, the decoys look like ordinary network services. Probe them yourself to see what an intruder would see. The SSH decoy presents an OpenSSH banner and a fake shell. The HTTP decoy serves a fake Apache page. The MySQL decoy answers on the database port.

curl -s http://127.0.0.1:8080/ timeout 2 bash -c 'exec 3<>/dev/tcp/127.0.0.1/2222; head -c 40 <&3'

Each of these interactions is recorded as an event and reflected in the metrics from Step 6. No legitimate traffic hits these ports, so anything that does is worth investigating.

8

Add or edit decoy services

Each decoy is a single YAML file in /etc/beelzebub/services/, and the core settings live in /etc/beelzebub/beelzebub.yaml. To add a decoy, drop in a new YAML file and restart the service. This example adds a fake Telnet decoy on port 2323:

sudo tee /etc/beelzebub/services/telnet-2323.yaml >/dev/null <<'YAML' apiVersion: "v1" protocol: "tcp" address: ":2323" description: "Telnet decoy" banner: "Ubuntu 22.04 LTS" deadlineTimeoutSeconds: 10 YAML
sudo systemctl restart beelzebub
sudo systemctl is-active beelzebub

The protocol can be ssh, http or tcp. The address is the listening port. For HTTP and SSH, define commands with a regex and a handler response to script how the decoy behaves. See the Beelzebub documentation for the full configuration reference.

Open any new decoy port on your NSG for the network segment you want to monitor.

9

Scrape the metrics from Prometheus

Point your Prometheus server at the metrics endpoint. The endpoint is password-protected, so use a basic_auth block in your scrape config. In production, scrape over HTTPS (see the next step).

scrape_configs: - job_name: beelzebub metrics_path: /metrics basic_auth: username: sac password: <your-metrics-password> static_configs: - targets: ['<your-domain>']

Alert on any increase in beelzebub_events_total, or on a specific protocol counter. This turns the honeypot into an active tripwire that pages you when something touches a decoy.

10

Enable HTTPS

nginx fronts the metrics endpoint on port 80 and is ready for TLS. Point a DNS record at the VM. Then obtain a certificate with certbot and let it configure nginx for port 443:

sudo apt-get update && sudo apt-get install -y certbot python3-certbot-nginx
sudo certbot --nginx -d <your-domain>

After the certificate is issued, restrict the NSG so that only 443 (and 22 from your management network) reaches the management surface. Scrape the metrics over https://<your-domain>/metrics with the password. The decoy ports remain open to the segment you are monitoring.

Persistence, first boot and updates

The Beelzebub configuration (/etc/beelzebub/) lives on the OS disk and is captured into the image, so a VM launched from this image is ready immediately. The first-boot service generates the per-VM metrics password and writes the info note, then disables itself, so later reboots are unaffected.

The binary is compiled from the pinned upstream release during the image build, and the build toolchain is removed before capture. The image ships a single static binary with no compiler left behind. The OS is patched at build time and ships with unattended security upgrades enabled.

/usr/local/bin/beelzebub version systemctl is-enabled beelzebub-firstboot.service ls -1 /etc/beelzebub/services/

Support

Every SecureAnyCloud deployment includes 24/7 support with a 24-hour response SLA. Contact sales@secureanycloud.com for help with deployment, configuration or scaling.

This is a repackaged open-source software product with additional charges for SecureAnyCloud support services. Beelzebub is distributed under the GNU General Public License v3.0. SecureAnyCloud is not affiliated with or endorsed by the Beelzebub project or its authors. 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.

Deploy on Azure

Launch Beelzebub Honeypot on Ubuntu 24.04 LTS on Azure with 24/7 support from SecureAnyCloud.

View this image

Need Help?

Our support team is available 24/7.

sales@secureanycloud.com

Deploy on Azure