An
Networking Azure

Anubis on Ubuntu 24.04 on Azure User Guide

| Product: Anubis on Ubuntu 24.04 LTS on Azure

Overview

This guide covers the deployment and configuration of Anubis on Ubuntu 24.04 on Azure using cloudimg Azure Marketplace images. Anubis is the open source Web AI Firewall: a single Go binary that runs 24/7 under systemd, sits in front of your application as a reverse proxy, and weighs the soul of every incoming request to keep AI scrapers and abusive crawlers off your site. Normal visitors flow straight through to your upstream; suspicious browsers are served a lightweight proof of work challenge; and known AI crawler user agents are blocked outright, so aggressive bots stop hammering your site and running up your bandwidth.

The image installs the latest stable Anubis release, resolved at build time from the official GitHub release package and baked reproducibly into the image (the exact version is recorded in /opt/anubis/VERSION). Anubis runs under systemd as the unit anubis@default.service, and reverse proxies to a target upstream that you point at your own application.

HTTPS out of the box. In this image nginx terminates TLS on port 443 and reverse proxies to Anubis on the loopback interface. On the very first boot the image generates a fresh per instance self signed certificate (its Subject Alternative Names cover the VM public IP, hostname and loopback), so no default certificate ships inside the image. You replace it with a CA signed certificate for your own domain in production.

No default secret ships in the image. Anubis signs the cookies it issues to challenged visitors with an ED25519 key. This image generates that key per instance on the first boot from the kernel random source, straight into /etc/anubis/default.env (owned by root, not world readable, injected into the service by systemd). The shipped image carries only a placeholder, so no two VMs ever share a signing key.

You bring your own upstream. Anubis protects whatever you set as its TARGET. The image ships a small local demo upstream so you can see the firewall working the moment it boots, and you repoint TARGET at your own application after launch.

What is included:

  • The latest stable Anubis release (single Go binary), run under systemd as anubis@default.service

  • nginx terminating TLS on :443 with a per instance self signed certificate regenerated on first boot, reverse proxying to Anubis on 127.0.0.1:8923

  • An unauthenticated /healthz load balancer probe and a 301 redirect to HTTPS on :80, plus a local demo upstream on 127.0.0.1:8000

  • The built in default bot policy: allow normal visitors, challenge suspicious browsers with proof of work, and deny known AI scrapers (Amazonbot, Bytespider, GPTBot family, anthropic-ai, PerplexityBot, Scrapy and many more)

  • Prometheus metrics on 127.0.0.1:9090 showing exactly how many requests were allowed, challenged and denied, broken down by rule

  • A per instance ED25519 signing key generated on first boot into /etc/anubis/default.env, rendered from a placeholder template so the shipped image carries no key

  • Ubuntu 24.04 LTS base with latest security patches applied at build time

  • Azure Linux Agent for seamless cloud integration and SSH key injection

  • 24/7 cloudimg support with guaranteed 24 hour response SLA

Prerequisites

  • Active Azure subscription, SSH public key, VNet + subnet in target region

  • Subscription to the Anubis listing on Azure Marketplace

  • An application (upstream) you want to protect, and a DNS domain you can point at the VM for production

Recommended virtual machine size: Standard_B2s (2 vCPU, 4 GB RAM) is ample for a firewall fronting a typical site. For heavier traffic use Standard_D2s_v5 or larger. Anubis is stateless (its challenge state is in memory), so it scales with CPU and memory.

Step 1: Deploy from the Azure Portal

Search Anubis in Marketplace, select the cloudimg publisher, click Create. NSG rules: TCP 22 (admin), TCP 443 (the proxy over HTTPS) and TCP 80 (HTTP to HTTPS redirect and health probe) from the networks your visitors connect from.

Step 2: Deploy from the Azure CLI

RG="anubis-prod"; LOCATION="eastus"; VM_NAME="anubis-01"
GALLERY_IMAGE_ID="/subscriptions/<sub-id>/resourceGroups/azure-cloudimg/providers/Microsoft.Compute/galleries/cloudimgGallery/images/anubis-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 anubis-vnet --address-prefix 10.100.0.0/16 --subnet-name anubis-subnet --subnet-prefix 10.100.1.0/24
az network nsg create -g "$RG" --name anubis-nsg
az network nsg rule create -g "$RG" --nsg-name anubis-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 anubis-nsg --name allow-https --priority 110 \
  --destination-port-ranges 443 --access Allow --protocol Tcp
az network nsg rule create -g "$RG" --nsg-name anubis-nsg --name allow-http --priority 120 \
  --destination-port-ranges 80 --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 anubis-vnet --subnet anubis-subnet --nsg anubis-nsg --public-ip-sku Standard

Step 3: Verify the Anubis and nginx services

Connect over SSH, then confirm both services are active and see which ports are bound. nginx listens on :443 (TLS) and :80 (redirect and health probe), Anubis listens on 127.0.0.1:8923 (the proxy) and 127.0.0.1:9090 (metrics), and the demo upstream on 127.0.0.1:8000:

sudo systemctl status anubis@default nginx --no-pager | head -14
sudo ss -tlnp | grep -E ':443|:80 |:8923|:9090|:8000'
cat /opt/anubis/VERSION

anubis@default.service and nginx.service both active (running); the Anubis version baked into the image; ss shows nginx listening on :443 for TLS and :80 for the redirect and health probe, Anubis on 127.0.0.1:8923 for the proxy and 127.0.0.1:9090 for metrics, and a loopback demo upstream on 127.0.0.1:8000

Step 4: See the AI firewall in action

Anubis classifies every request. A normal client is proxied straight through to your upstream, a known AI scraper user agent is denied, and a suspicious browser is served a proof of work challenge it must solve before it is let through. You can see all three on the VM with curl:

# A normal visitor (curl) is ALLOWED and proxied to the upstream:
curl -sk https://127.0.0.1/ | grep -q "cloudimg Anubis demo upstream" && echo "normal visitor: proxied to the upstream (allowed)"
# A known AI scraper user agent is DENIED (served the Anubis block page, never reaches the upstream):
curl -sk -A 'Amazonbot/0.1' https://127.0.0.1/ | grep -q "Oh noes" && echo "Amazonbot: blocked by the AI firewall"
# A browser is served the proof of work challenge page (it solves it in the browser, then is let through):
curl -sk -A 'Mozilla/5.0 (X11; Linux x86_64)' https://127.0.0.1/ | grep -q "not a bot" && echo "browser: served the proof of work challenge"

The normal request reaches the demo upstream, the Amazonbot request is denied with the Anubis block page and never touches your application, and the browser request receives the "making sure you're not a bot" proof of work challenge. This is the core of Anubis: real visitors are unaffected while automated AI crawling is stopped at the door.

curl showing a normal request proxied to the cloudimg Anubis demo upstream (allowed), an Amazonbot user agent denied by the AI firewall with the Anubis block page, and a browser user agent served the proof of work challenge page, demonstrating the three ways Anubis classifies traffic

Step 5: Inspect the classification metrics

Anubis exposes Prometheus metrics on 127.0.0.1:9090. The anubis_policy_results counter shows exactly how many requests each policy rule allowed, challenged or denied, so you can see the firewall working and wire it into your monitoring:

curl -s http://127.0.0.1:9090/metrics | grep -E '^# HELP anubis_|^anubis_policy_results|^anubis_challenges_issued' | head -20

You will see anubis_policy_results broken down by action (ALLOW, CHALLENGE, DENY) and rule (for example bot/ai-catchall for the AI scraper denials and threshold/... for the browser challenges), alongside anubis_challenges_issued. These are standard Prometheus counters you can scrape from your existing stack.

The Anubis Prometheus metrics on 127.0.0.1:9090 showing anubis_policy_results broken down by action ALLOW, CHALLENGE and DENY and by rule including bot ai-catchall for AI scraper denials, plus anubis_challenges_issued, proving the firewall is actively classifying traffic

Step 6: Understand the per instance key and configuration

Anubis is configured through the environment file /etc/anubis/default.env, which systemd injects into the service. This image generates the ED25519 signing key on first boot into that file (owned by root, not world readable); the shipped image carries only a placeholder. The endpoints for this VM are summarized in a root only file, and the per instance TLS certificate covers this VM:

sudo grep -E '^BIND|^TARGET|^METRICS_BIND|^DIFFICULTY|^SERVE_ROBOTS_TXT|^ED25519_PRIVATE_KEY_HEX' /etc/anubis/default.env
sudo cat /root/anubis-credentials.txt
sudo openssl x509 -in /etc/nginx/certs/cert.pem -noout -subject -ext subjectAltName

In the environment file you can see BIND (Anubis on loopback :8923), TARGET (the upstream Anubis protects), METRICS_BIND (:9090), DIFFICULTY (the proof of work difficulty), and the per instance ED25519_PRIVATE_KEY_HEX (masked in the screenshot below). The credentials file lists this VM's access URL, and the certificate Subject Alternative Names cover this VM.

The default.env showing BIND on loopback 8923, TARGET pointing at the demo upstream, METRICS_BIND on 9090, DIFFICULTY and the per instance ED25519 signing key masked, alongside the anubis-credentials.txt access URL and the self signed certificate Subject Alternative Names covering this VM

Step 7: Protect your own application

To put Anubis in front of your own application, point TARGET at your upstream and restart the service. Set TARGET to wherever your application listens (for example http://127.0.0.1:3000 for a local app, or http://10.0.0.5:8080 for another host):

sudo nano /etc/anubis/default.env

Change the TARGET= line, save, then apply:

sudo systemctl restart anubis@default

Anubis now proxies allowed traffic to your application and blocks AI scrapers in front of it. Because nginx terminates TLS and forwards the real client IP to Anubis in the X-Forwarded-For header, your policy decisions and logs see the true visitor address.

Step 8: Tune the bot policy

The built in default policy already allows normal visitors, challenges suspicious browsers and denies a large list of known AI scrapers. To customise it, provide your own policy file and reference it from the environment:

# Anubis ships its data files (including example policies) under /usr/share/docs/anubis or the package docs.
sudo cp /etc/anubis/default.env /etc/anubis/default.env.bak

Add a POLICY_FNAME=/etc/anubis/default.botPolicies.yaml line to /etc/anubis/default.env pointing at a policy file you author (start from the upstream default policy documented at the Anubis project site), then sudo systemctl restart anubis@default. Policies can allow, weigh (challenge based on accumulated suspicion) or deny by user agent, path, header, IP range and more. Leaving POLICY_FNAME unset keeps the sensible built in default.

Step 9: Use your own domain and a trusted certificate (production)

The self signed certificate is a convenience for getting started. For production, point a DNS name you control at the VM public IP and replace the certificate:

  • Drop a CA signed certificate and key into /etc/nginx/certs/cert.pem and /etc/nginx/certs/key.pem (or point the nginx ssl_certificate directives at your own paths), then sudo systemctl reload nginx.

  • Alternatively front the VM with a managed certificate from Azure Application Gateway or a CDN and forward to nginx on :443.

  • Visitors then reach your site at your own domain with no certificate trust step, and Anubis keeps the scrapers out.

Step 10: Server components

Component Version / Detail
Firewall / proxy Anubis (latest stable release, baked reproducibly, see /opt/anubis/VERSION)
TLS terminated by nginx on :443 (self signed per VM), certificate at /etc/nginx/certs/
Anubis listener 127.0.0.1:8923 (proxy), 127.0.0.1:9090 (Prometheus metrics)
Front helper nginx (:80 -> 301 https, unauthenticated /healthz, loopback 127.0.0.1:8000 demo upstream)
Signing key per instance ED25519_PRIVATE_KEY_HEX generated first boot into /etc/anubis/default.env
Bot policy built in default (allow visitors, challenge browsers, deny known AI scrapers)
Upstream your application via TARGET (demo upstream shipped)
Operating system Ubuntu 24.04 LTS (patched at build)
License MIT (Anubis)

Step 11: Managing the Anubis service

sudo systemctl status anubis@default --no-pager | head -12
sudo systemctl is-active anubis@default nginx

Apply a configuration change with sudo systemctl restart anubis@default, reload the nginx helper with sudo systemctl reload nginx, and follow the logs live with sudo journalctl -u anubis@default -f. The configuration lives at /etc/anubis/default.env. After any change, restart Anubis.

Step 12: Security recommendations

  • Restrict the NSG. Allow TCP 443 (and 22 for admin) only from the networks your visitors connect from.

  • Use a trusted certificate and your own domain (Step 9) so visitors validate the site without a manual trust step.

  • Point TARGET at your real application and remove the demo upstream from production use.

  • Tune the policy for your traffic (Step 8). Start from the built in default and add allow rules for any legitimate automation you rely on, and stricter rules for abusive ranges.

  • Protect the key. /etc/anubis/default.env holds the ED25519 signing key and is not world readable; keep it that way and regenerate it if a VM is ever exposed.

  • Keep the OS patched. Unattended security upgrades remain enabled on the running VM.

Step 13: Support and Licensing

Anubis is distributed under the MIT License. This cloudimg image bundles the unmodified official open source release; cloudimg provides the packaging, hardening, per instance key and TLS automation, the working demo upstream, and 24/7 support with a guaranteed 24 hour response SLA. Anubis is an independent open source project by Techaro and this image is not affiliated with or endorsed by Techaro or the Anubis project.

Deploy on Azure

Find Anubis on Ubuntu 24.04 on the Azure Marketplace, published by cloudimg. Deploy from the Portal or the Azure CLI as shown above.

Need Help?

Email support@cloudimg.co.uk for deployment help, configuration questions, or licensing enquiries.