Skip to main content
Anubis is designed to be deployed behind a reverse proxy. The reverse proxy handles TLS termination and routes traffic to Anubis, which then forwards validated requests to your backend application.

Deployment Architecture

The typical deployment flow looks like this:

IP Address Forwarding

Anubis needs to know the real client IP address to enforce rate limits and detect malicious behavior. Reverse proxies communicate the client IP using standard headers:

X-Real-IP Header

The X-Real-IP header contains the client’s IP address. Anubis reads this header to determine the source of the request.

X-Forwarded-For Header

The X-Forwarded-For header contains a chain of IP addresses representing the request’s path through multiple proxies:
X-Forwarded-For: client-ip, proxy1-ip, proxy2-ip
Anubis processes this header according to these rules:
  • Strips private addresses when --xff-strip-private is enabled (default: true)
  • Flattens the chain to extract the first public IP
  • Sets X-Real-IP from X-Forwarded-For if X-Real-IP is not already set
The middleware chain in Anubis (from main.go:479-482):
h = internal.CustomRealIPHeader(*customRealIPHeader, h)
h = internal.RemoteXRealIP(*useRemoteAddress, *bindNetwork, h)
h = internal.XForwardedForToXRealIP(h)
h = internal.XForwardedForUpdate(*xffStripPrivate, h)

Private Address Stripping

By default, Anubis strips these address ranges from X-Forwarded-For:
  • Private addresses: 10.0.0.0/8, 172.16.0.0/12, 192.168.0.0/16
  • Loopback addresses: 127.0.0.0/8, ::1
  • CGNAT addresses: 100.64.0.0/10
  • Link-local addresses: 169.254.0.0/16, fe80::/10
This prevents IP spoofing through private network ranges.

Deployment Modes

Reverse Proxy Mode (Default)

In this mode, Anubis forwards validated traffic to a backend application:
anubis --bind :3000 --target http://backend:8080
Your reverse proxy forwards all traffic to Anubis, and Anubis forwards validated requests to the backend.

Forward Auth Mode

In this mode, Anubis only validates requests without proxying:
anubis --bind :3000 --target " "
Note the space after the equals sign - this is required to set TARGET to empty when using environment variables. The reverse proxy uses Anubis as an authentication service:
  • Sends requests to /.within.website/x/cmd/anubis/api/check
  • Anubis returns 200 if validated, 401 if challenge required
  • On 401, redirect user to Anubis challenge page

Configuration Flags

—use-remote-address

When running Anubis directly exposed to the internet (not behind a proxy), use this flag to read the client IP from the network socket:
anubis --use-remote-address --bind :8080 --target http://backend:3000
Do not use this flag when behind a reverse proxy - it will read the proxy’s IP instead of the client’s IP.

—custom-real-ip-header

Some environments use custom headers for the client IP:
anubis --custom-real-ip-header CF-Connecting-IP --bind :3000
This reads the client IP from the specified header instead of X-Real-IP.

—xff-strip-private

Controls whether private addresses are stripped from X-Forwarded-For (default: true):
anubis --xff-strip-private=false --bind :3000

Proxy Configuration Requirements

Your reverse proxy must:
  1. Set X-Real-IP header to the client’s IP address
  2. Preserve or set X-Forwarded-For header with the client IP
  3. Set Host header to the original request’s host
  4. Forward protocol information if needed (X-Forwarded-Proto for HTTPS detection)

Health Checks

Anubis exposes health check endpoints:
  • Main health: http://localhost:9090/healthz (configurable with --metrics-bind)
  • Prometheus metrics: http://localhost:9090/metrics
Configure your proxy to skip Anubis validation for health check endpoints.

Unix Socket Support

Anubis supports Unix sockets for high-performance local communication:
anubis --bind unix:///run/anubis/anubis.sock --socket-mode 0770
This is ideal for nginx configurations where Anubis runs on the same server.

Next Steps

See the specific guides for your reverse proxy:

Build docs developers (and LLMs) love