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.servicerunning three decoy services (SSH 2222, HTTP 8080, MySQL 3306) with a loopback Prometheus metrics endpoint on127.0.0.1:2112- An nginx reverse proxy on port 80, with a public
/healthendpoint and a password-protected/metricsendpoint beelzebub-firstboot.servicefor the first-boot metrics password and info note- A unique per-VM metrics password generated on first boot, in a root-only
0600file - 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).
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).
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 StandardConnect 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>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/healthExpect 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.
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.
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.
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.
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 beelzebubThe 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.
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.
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
Overview
This image runs Beelzebub, the open-source, low-code honeypot and deception framework. Beelzebub stands up decoy services that look like real infrastructure (a fake SSH shell, a fake web server and a fake database), 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 inside your network.
The image is a ready-to-use appliance. beelzebub.service and nginx.service are enabled and start on boot, so the deception layer is already listening when you connect over SSH.
What you get:
- A headless service with no web interface
- Decoy services on port 2222 (SSH), 8080 (HTTP) and 3306 (a fake database), deliberately separate from the real administrative sshd on port 22, so the honeypot never interferes with how you manage the instance
- A shipped security group that opens ports 22 and 80 only. A honeypot should only be exposed on purpose, so the decoy ports stay closed until you deliberately open them
- A Prometheus metrics endpoint, which is the real management surface. Beelzebub binds it to the loopback interface and nginx fronts it on port 80, with an unauthenticated
/healthendpoint for load balancer probes and a password-protected/metricsendpoint - No shared or default credentials. A unique metrics password is generated on each instance's first boot and written to a root-only file
- Decoy services that use static built-in responses, so no external API key is needed
Prerequisites
Before you deploy this image, make sure you have:
- An Amazon Web Services account where you can launch EC2 instances
- IAM permissions to launch instances, create security groups, and subscribe to AWS Marketplace products
- An EC2 key pair in the target Region for SSH access to the instance
- A VPC and subnet in the target Region, with a security group that allows inbound port 22 from your management network
- The AWS CLI (version 2) installed locally, if you plan to deploy from the command line
Launch the instance from the AWS Marketplace
Sign in to the AWS Management Console, open the EC2 service, and select Launch instance. Under Application and OS Images, choose AWS Marketplace AMIs and search for Beelzebub. Select the SecureAnyCloud listing, choose Select, then choose Continue on the subscription summary.
Pick an instance type of m5.large or larger. Choose your EC2 key pair under Key pair (login). Under Network settings, select your VPC and subnet, then create or select a security group that opens port 22 from your management network. Leave the root volume at the default size or larger.
Select Launch instance. First-boot initialisation takes a short time after the instance state becomes Running and the status checks pass. During it, the image resolves the instance address, generates a unique metrics password, writes the per-instance welcome notes, and starts the services.
Launch the instance from the AWS CLI
This command launches an instance from the SecureAnyCloud Beelzebub Marketplace AMI into an existing subnet and security group.
Replace <ami-id> with the AMI ID shown on the Marketplace listing, and <key-name> with your EC2 key pair name. Replace <subnet-id> with your subnet ID, and <security-group-id> with a security group that opens port 22 from your management network.
aws ec2 run-instances \
--image-id <ami-id> \
--instance-type m5.large \
--key-name <key-name> \
--subnet-id <subnet-id> \
--security-group-ids <security-group-id> \
--metadata-options "HttpTokens=required" \
--tag-specifications 'ResourceType=instance,Tags=[{Key=Name,Value=beelzebub}]'When the instance state is Running and both status checks pass, note its public or private IP address for the SSH step.
Connect over SSH
Connect to the instance on the real administrative port 22 with your key pair. This is your normal, untouched admin access, not the honeypot. The login user depends on the operating system variant you launched.
Connecting to your instance
OS variant SSH login user
Ubuntu 24.04 ubuntu
ssh -i /path/to/<key-name>.pem ubuntu@<public-ip>Read the per-instance welcome notes
On first boot, the image generates a unique metrics password. It writes a root-only notes file that records the password alongside this instance's endpoints and decoy ports. Keep this file secret.
sudo cat /root/beelzebub-info.txtThe file shows your unique metrics password, the health and metrics URLs, and the decoy endpoints. The password is unique to your instance:
METRICS_USER=sac METRICS_PASSWORD=<your-metrics-password> METRICS_URL=http://<public-ip>/metrics HEALTH_URL=http://<public-ip>/health SSH_DECOY=<public-ip>:2222 HTTP_DECOY=http://<public-ip>:8080/ MYSQL_DECOY=<public-ip>:3306Confirm the services are running
Check that the honeypot daemon and the reverse proxy are both active:
systemctl is-active beelzebub nginxBoth services return active. For the full unit detail, including the non-root process that runs the honeypot and the decoy ports it listens on, run:
systemctl status beelzebub.service --no-pagerUse the secured metrics endpoint
The Prometheus metrics endpoint is the real management surface. The unauthenticated health probe is meant for load balancers and returns a simple ok:
curl -s http://127.0.0.1/healthThe metrics endpoint itself requires the per-instance password. Without it, nginx returns 401:
curl -s -o /dev/null -w '%{http_code}\n' http://127.0.0.1/metricsWith the password from your welcome notes, it returns the live Prometheus counters. This scrape writes the metrics to a file, then shows the honeypot event counters:
curl -s -u sac:<your-metrics-password> http://127.0.0.1/metrics -o /tmp/metrics.txt grep -E 'beelzebub_events_total|beelzebub_http_events_total' /tmp/metrics.txtPoint your own Prometheus at http://<public-ip>/metrics with the username SecureAnyCloud and this password. This scrapes honeypot activity into your dashboards and alerting.
Check the decoy services and the two separate surfaces
The decoy services and your real administrative SSH are deliberately separate listeners. Confirm that all of these are bound: the real sshd on 22, the nginx metrics proxy on 80, and the three decoys on 2222, 8080 and 3306.
ss -tlnH | awk '{print $4}' | grep -E ':(22|80|2112|2222|3306|8080)$' | sortThe decoy SSH presents a fake server identity, so it looks like a different machine to an attacker. It is entirely separate from the real admin sshd on port 22. Read the decoy banner directly:
timeout 8 bash -c 'exec 3<>/dev/tcp/127.0.0.1/2222; head -c 40 <&3'; echoWatch an interaction being captured
Every connection to a decoy is written to the event log as a structured event. Send a probe to the HTTP decoy, then read the captured event from the log:
curl -s -o /dev/null "http://127.0.0.1:8080/example-attacker-probe" sleep 1
sudo tail -n 20 /var/lib/beelzebub/logs/beelzebub.logThe captured event records the protocol, HTTP method, the request path the attacker touched, the user agent, and the source address. Nothing legitimate should ever touch a decoy, so every such event is worth investigating.
Open the decoy ports to start attracting activity
The shipped security group opens ports 22 and 80 only, so out of the box nothing external can reach the decoys. To begin luring and logging activity, open the decoy ports in the instance security group to the networks you want to observe.
Expose a honeypot only deliberately, and only to networks you understand. Replace <security-group-id> with your instance's security group and <your-mgmt-cidr> with the range you want to watch.
aws ec2 authorize-security-group-ingress \
--group-id <security-group-id> \
--ip-permissions \
IpProtocol=tcp,FromPort=2222,ToPort=2222,IpRanges='[{CidrIp=<your-mgmt-cidr>}]' \
IpProtocol=tcp,FromPort=8080,ToPort=8080,IpRanges='[{CidrIp=<your-mgmt-cidr>}]' \
IpProtocol=tcp,FromPort=3306,ToPort=3306,IpRanges='[{CidrIp=<your-mgmt-cidr>}]'Add your own decoy service
The decoy services are defined by simple YAML files in /etc/beelzebub/services/. Copy one of the shipped definitions and edit its port, protocol and responses to model the service you want to imitate. Then restart the daemon.
This modifies the running honeypot, so run it only when you are ready.
sudo cp /etc/beelzebub/services/http-8080.yaml /etc/beelzebub/services/http-9000.yaml
sudo nano /etc/beelzebub/services/http-9000.yaml
# set a new address and responses
sudo systemctl restart beelzebub.service
# apply the changesOptionally enable the AI-backed shell
Beelzebub can back its SSH decoy with a large language model, so the fake shell answers arbitrary commands convincingly. This is disabled by default and needs no API key out of the box.
To enable it, supply your own LLM API key in the core config and restart the service. The key is your own per-instance secret, and it is never baked into the image.
sudo nano /etc/beelzebub/beelzebub.yaml
# add your own LLM plugin settings and API key
sudo systemctl restart beelzebub.serviceSecurity notes
- Deploy the honeypot on an isolated or closely monitored network segment. By design it invites malicious traffic, and its decoy services are intentionally fake.
- Restrict the real administrative SSH on port 22 to your management network, and open the decoy ports only to the ranges you intend to observe.
- Treat the metrics password in
/root/beelzebub-info.txtas a secret, and put the metrics endpoint behind TLS before exposing it beyond the instance. - Ship the captured events to a SIEM or analytics pipeline, so alerts fire the moment a decoy is touched.
Support
This image is published by SecureAnyCloud with 24/7 technical support by email and chat. We can help with decoy service configuration, the metrics endpoint and TLS, and wiring the metrics into your monitoring. We can also help you open and place the decoy ports safely, enable the optional AI-backed shell with your own key, and plan backups and upgrades.
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 AWS
Launch Beelzebub on AWS with 24/7 support from SecureAnyCloud.
View on Marketplace
Need Help?
Our support team is available 24/7.
sales@secureanycloud.com