Uncategorized

Running Anubis on an Nginx Server

| #anubis | #guide | #nginx | #technology |


Anubis, an app written with the help of AI, is a pretty effective firewall that creates a negligible speed bump for most users of a website, but a bump that drastically increases the cost of access for bots and AI scraping assholes who assault servers relentlessly and ignore all please to settle down and let the internet function properly.

But Anubis has some appalling documentation. As written it’s wrong and doesn’t work, and I spent many, many hours trying to make it work. For a while it worked, but it shouldn’t have, and it kept redirecting users to the wrong port. Then it worked, for a whole 24 hours, before freaking out so hard neither Anubis or nginx would freak back in, and I had to basically throw random shit into all three config files both apps were relying on to actually start up and function.

And so here, for the reading pleasure of anyone looking for a config that fucking works, is my setup for Anubis. It doesn’t dive deep, but it will function just fine as of Anubis version 1.27.

Note: The Anubis docs like to mix a bunch of Unix socks stuff into the docs but none of that worked for me, so if you like socks, you won’t be entirely happy with this guide, probably.

Note: The fun thing about following any guide for any software, but especially with Linux, is that there are a million ways to shave a million cats, and my system may not be the same as yours. I’m running Ubuntu server with systemd for controlling the services, and nginx as the webserver. If you’re not doing these things it’s possible this guide will suck for you, soz.


The theory!

Basically you configure nginx to send all traffic to Anubis. Anubis will follow the rules you give it, and pass all traffic back to nginx for normal processing.

Config Files!

There are three config files involved here. One is your site’s existing config file, possibly in /etc/nginx/conf.d or maybe in /etc/nginx/sites-enabled. The second is Anubis’ own config file, which lives in /etc/anubis, and finally an upstream config, which I’m not even sure if it’s required at this point, but like a monkey in a cage I’ve left it there because experience has taught me that if complicated production shit ain’t broke maybe don’t fuck with it.

nginx config 1!

First, set up an upstream listener. This defines the server to which nginx should send traffic with the upstream command. You can either set this up as a separate file (in /etc/nginx/sites-enabled or /etc/nginx/conf.d) so that multiple sites can refer to it, or you can add it in the config file for your site if you only have one, or have different anubis configs, or whatever.

# /etc/nginx/conf.d/upstream.anubis.conf
upstream anubis {
  server localhost:8923;
}

My nginx server config is set up in several blocks for the domain being protected here. The first block listens on port 80 for unencrypted non-https traffic, and tells the incoming requester to use the encrypted listener on port 443. You probably have a similar setup, and I’m not showing mine here because it’s not relevant for this. Find the (second) block listening on port 443, and divide that into two parts. The first is short, including only the SSL setup and the reverse proxy to redirect all traffic to Anubis. It looks like this:

Note: In order to get the correct requesting IP in your log files you may need to update your log profile in the main nginx config file. this page has the details.

server {
    listen 443 ssl http2;
    server_name yoursite.com;
    ssl_certificate     /etc/letsencrypt/live/yoursite.com/fullchain.pem;
    ssl_certificate_key /etc/letsencrypt/live/yoursite.com/privkey.pem;
    # If you were putting the upstream config in this file, you'd put it about where this comment line is.
    location / {
      proxy_set_header Host $host;
      proxy_set_header X-Real-IP $remote_addr;
      proxy_set_header X-Http-Version $server_protocol;
      proxy_set_header X-Forwarded-Host $host;
      #proxy_set_header X-Forwarded-Port $server_port;
      proxy_set_header X-Forwarded-Proto $scheme;
      proxy_pass http://anubis;
    }
  }

That’s the whole config to send all traffic to Anubis. The last line is the one that matters most, everything else is normal nginx SSL and reverse proxy stuff.

proxy_pass http://anubis;

The last line sends traffic to the upstream so make sure the names match.

Rather than explain the next part of the nginx config now, I’m going to follow the logical flow here, so you can see where your traffic is going step by step. After your web traffic hits the nginx server and is redirected as shown above, Anubis will catch it.

Anubis Config!

Anubis (which you should have installed by now) gets its configuration from config files in /etc/anubis. You can call it whatever you want, as long as it ends with .env. I’m currently using just one Anubis setup, and I called it yoursite.env. Obviously you should call it something you like, maybe even the name of your site. It doesn’t matter. Anubis will load every .env file in this directory. Each config in this directory should listen on a different port or things will go wrong.

# /etc/anubis/yoursite.env
BIND=:8923
BIND_NETWORK: tcp
DIFFICULTY=2
METRICS_BIND=:9090
SERVE_ROBOTS_TXT=0
TARGET=http://localhost:3000

What this is doing is listening for traffic from nginx on port 8923, and then sending it back to nginx on port 3000. The other stuff is configured to your particular needs, and Anubis has a lot of stuff you can configure if you want. One thing I changed here was the Difficulty value. Basically this is the amount of math the incoming user or bot is being asked to do in order to be cleared by Anubis. By default it’s four, but I found this to be a lengthy delay for mobile users, so I changed it to two.

When Anubis is installed, it creates a service as you’ve probably seen before. What was new to me, and maybe to you, is that Anubis runs one main service with as many individually controllable components as the .env files you’ve created. These are specified with Anubis followed by @, and then base name of your .env file. For example, anubis@yoursite.service.

You’ll need to start Anubis for the first time, and the official docs say that the way to do this is sudo systemctl enable --now anubis@yoursite.service. This enables the service to run every time the system starts, and starts it immediately. You can check if Anubis has started successfully with sudo systemctl status Anubis@yoursite.service.

When I started working on this project I got a lot of hell no I won’t go errors at this stage. You can get specific information about the details of Anubis’ refusal to do stuff with journalctl: sudo journalctl -xeu anubis@yoursite.service.

And now, traffic goes back to nginx, and this is where we are setting up what’s left of your split-in-two server config to listen to this traffic from Anubis.

nginx config 2!

This is the remaining listen block in your site’s nginx config file. It has everything except the SSL setup, which is handled in the first part. All you really need to do is add the new listen line, which tells nginx to listen on port 3000 for traffic redirected from Anubis, intended for yoursite.com.

#/etc/nginx/sites-enabled/yoursite.conf
server {
  listen 3000;
  real_ip_header X-Real-IP;
  server_name yoursite.com;
  root /var/www/wherever_yoursite_lives;

  etc etc.
}

And that’s it for the config. There are a few things to know about maintaining these things.

I will assume you know how to run nginx already, but you should check that your new config files are valid (sudo nginx -t) before reloading nginx with the changed config (sudo systemctl reload nginx.service).

Anubis will need to restart the service for yoursite every time you change the .env file. This is done like any other service: sudo systemctl restart anubis@yoursite.service.

Anyway that’s how I got it going. The official docs were just a mash of stuff that didn’t work as shown, and I hope that maybe this guide is slightly less frustrating for you. When you spot the inevitable errors, please let me know below.

--NFG
[ Aug 21 2026 ]
Navigation

Got something to add?

Your Comment
Name:
Email:
Website: