Deployment guide

Anubis

Overview

Anubis is the open source Web AI Firewall: a single Go binary that runs 24/7 under systemd and sits in front of your application as a reverse proxy. It 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. Known AI crawler user agents are blocked outright, so aggressive bots stop hammering your site and running up your bandwidth.

This guide covers deploying and configuring Anubis on Ubuntu 24.04 on Azure, using the SecureAnyCloud Azure Marketplace image. 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 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. In production, replace it with a CA-signed certificate for your own domain.

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. The file is owned by root, is not world-readable, and is injected into the service by systemd. The shipped image carries no signing key, so no two VMs ever share a signing key.

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. After launch, repoint TARGET at your own application.

What you get:

  • 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 blank template so the shipped image carries no key.
  • Ubuntu 24.04 LTS base with the latest security patches applied at build time.
  • Azure Linux Agent for cloud integration and SSH key injection.
  • 24/7 SecureAnyCloud support with guaranteed 24 hour response SLA.

Prerequisites

  • An active Azure subscription, an SSH public key, and a VNet and subnet in the target region
  • A 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.

1

Deploy from the Azure Portal

Search for Anubis in the Azure Marketplace, select the SecureAnyCloud publisher, and choose Create.

Add network security group (NSG) rules for these ports, from the networks your visitors connect from:

  • TCP 22 for admin access
  • TCP 443 for the proxy over HTTPS
  • TCP 80 for the HTTP to HTTPS redirect and the health probe
2

Deploy from the Azure CLI

Run these commands on your own workstation:

RG="anubis-prod"; LOCATION="eastus"; VM_NAME="anubis-01" IMAGE_URN="sac1647283583153:anubis-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 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
# Accept the Marketplace terms once per subscription (required before the first CLI deploy)
az vm image terms accept --urn sac1647283583153:anubis-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 anubis-vnet --subnet anubis-subnet --nsg anubis-nsg --public-ip-sku Standard
3

Verify the Anubis and nginx services

Connect over SSH, then confirm that both services are active and check 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). The demo upstream listens 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
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. A suspicious browser is served a proof-of-work challenge that it must solve before it is let through. 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 "sac 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. 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.

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. Use it to see the firewall working and to feed your monitoring:

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

The output shows 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 that you can scrape from your existing stack.

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, which is owned by root and not world-readable. The shipped image carries no signing key.

The endpoints for this VM are summarized in a root-only file, and the per-instance TLS certificate covers this VM. Inspect all three:

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

The environment file shows 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.

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. Open the environment file:

sudo nano /etc/anubis/default.env

Change the TARGET= line, save the file, then apply the change:

sudo systemctl restart anubis@default

Anubis now proxies allowed traffic to your application and blocks AI scrapers in front of it.

nginx terminates TLS and forwards the real client IP to Anubis in the X-Forwarded-For header, so your policy decisions and logs see the true visitor address.

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 customize it, provide your own policy file and reference it from the environment. Back up the environment file first:

# 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 run 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 built-in default.

9

Use your own domain and a trusted certificate (production)

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

Copy 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 run 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.

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)

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. Follow the logs live with sudo journalctl -u anubis@default -f. The configuration lives at /etc/anubis/default.env. After any change, restart Anubis.

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. 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 the key if a VM is ever exposed.
  • Keep the OS patched. Unattended security upgrades remain enabled on the running VM.
13

Support and Licensing

Anubis is distributed under the MIT License. This SecureAnyCloud image bundles the unmodified official open source release. SecureAnyCloud 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. 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 SecureAnyCloud. Deploy from the Portal or the Azure CLI as shown above.

Need Help?

Email sales@secureanycloud.com for deployment help, configuration questions, or licensing enquiries.

Deploy on Azure

Launch Anubis 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