Site icon OtCloud Company Limited

Securing Your Koha OPAC: The “Sandwich” WAF Architecture with Anubis

If you are running a Koha library management system, you know the frustration of malicious bots, aggressive SEO scrapers, and automated scripts bogging down your server by spamming search and export endpoints.

While tools like Fail2ban and Apache rate-limiting help, installing a dedicated Web Application Firewall (WAF) like Anubis provides a much stronger layer of defense. However, standard WAF deployments usually take over port 80 and 443 entirely, which creates a massive headache if you want Apache to continue managing your Let’s Encrypt SSL certificates, or if you only want to protect the OPAC while leaving your Intranet intact.

In this guide, I will walk you through setting up the “Local Proxy Sandwich” architecture on Ubuntu 24.04.

The Sandwich Architecture Explained

Instead of putting Anubis on the absolute edge, we will “sandwich” it between two layers of Apache:

  1. The Public Edge (Apache :443): Catches public HTTPS traffic, decrypts it using existing SSL certificates, and passes it locally to Anubis.
  2. The Filter (Anubis :3000): Inspects the decrypted traffic, serves challenge pages to bots, and forwards clean traffic.
  3. The Hidden Backend (Apache :8081): Koha processes the clean traffic securely hidden away from the public internet.

Step 1: Install Anubis and Create the Systemd Service

Download the latest Anubis .deb package and install it.

Bash

wget https://github.com/TecharoHQ/anubis/releases/download/v1.25.0/anubis_1.25.0_amd64.deb
sudo dpkg -i anubis_amd64.deb

Note: As of version 1.25, the .deb package does not include a systemd service file. We must create one manually.

Create the service file:

sudo nano /etc/systemd/system/anubis.service

Paste in the following configuration:

[Unit]
Description=Anubis Web Application Firewall / Proxy
After=network.target

[Service]
Type=simple
EnvironmentFile=-/etc/anubis/default.env
ExecStart=/usr/bin/anubis
Restart=on-failure
RestartSec=5
LimitNOFILE=65536

[Install]
WantedBy=multi-user.target

Reload the system daemon to recognize the new file:

sudo systemctl daemon-reload

Step 2: Configure the Anubis Environment

Now we tell Anubis to listen for traffic coming from the Apache Edge and forward it to the hidden Koha backend.

Open the environment file:

sudo nano /etc/anubis/default.env

Update it with the following local port mappings:

# Listen for decrypted traffic from Apache
BIND=127.0.0.1:3000

# Forward clean traffic to the hidden Koha OPAC backend
TARGET=http://127.0.0.1:8081

# Security and metrics settings
DIFFICULTY=4
METRICS_BIND=127.0.0.1:9090
SERVE_ROBOTS_TXT=0

# CRITICAL: Tell Anubis to read the real user IPs forwarded by Apache
TRUST_X_FORWARDED_FOR=1

# Optional: Customize the challenge page text
CHALLENGE_TITLE="Connecting you to the Library OPAC..."

Enable and start the service:

sudo systemctl enable --now anubis

Step 3: Prepare Apache for Proxying

Apache needs specific modules enabled to act as a reverse proxy.

sudo a2enmod proxy proxy_http headers remoteip rewrite

Next, open Apache’s port configuration to create the hidden backend port:

sudo nano /etc/apache2/ports.conf

Add this line so Apache listens locally for the clean OPAC traffic:

Listen 127.0.0.1:8081

Step 4: The Master VirtualHost Configuration

This is where the magic happens. We will update our Koha site configuration (e.g., /etc/apache2/sites-available/koha.conf) to handle routing. In this example, opac.yourdomain.ac.ke is the public OPAC, and catalogue.yourdomain.ac.ke is the Intranet.

Replace your VirtualHost blocks with this structure:

# ---------------------------------------------------------
# 1. HTTP to HTTPS Redirects (Port 80)
# ---------------------------------------------------------
<VirtualHost *:80>
    ServerName opac.yourdomain.ac.ke
    Redirect permanent / https://opac.yourdomain.ac.ke/
</VirtualHost>

<VirtualHost *:80>
    ServerName catalogue.yourdomain.ac.ke
    RewriteEngine On
    RewriteCond %{REQUEST_METHOD} OPTIONS
    RewriteRule ^ - [R=204,L]
    
    RewriteCond %{REQUEST_METHOD} !=OPTIONS
    RewriteRule ^(.*)$ https://catalogue.yourdomain.ac.ke$1 [R=301,L]
</VirtualHost>

# ---------------------------------------------------------
# 2. PUBLIC OPAC EDGE (Port 443) -> Handoff to Anubis
# ---------------------------------------------------------
<VirtualHost *:443>
    ServerName opac.yourdomain.ac.ke

    # Your standard SSL Configuration
    SSLEngine on
    SSLCertificateFile /path/to/fullchain.pem
    SSLCertificateKeyFile /path/to/privkey.pem

    # Proxy Settings: Send decrypted traffic to Anubis
    ProxyPreserveHost On
    RequestHeader set X-Forwarded-For "%{REMOTE_ADDR}s"
    RequestHeader set X-Forwarded-Proto "https"

    ProxyPass / http://127.0.0.1:3000/
    ProxyPassReverse / http://127.0.0.1:3000/
</VirtualHost>

# ---------------------------------------------------------
# 3. HIDDEN OPAC BACKEND (Port 8081) -> Clean Traffic Only
# ---------------------------------------------------------
<VirtualHost 127.0.0.1:8081>
    ServerName opac.yourdomain.ac.ke
    
    # Crucial: Accepts the real user IP passed from Anubis
    RemoteIPHeader X-Forwarded-For

    # Include your standard Koha OPAC configurations here
    Include /etc/koha/apache-shared.conf
    Include /etc/koha/apache-shared-opac.conf
    
    # ... (Include your rate limiting, env vars, and logging here) ...
</VirtualHost>

# ---------------------------------------------------------
# 4. INTRANET (Port 443) -> Completely Untouched
# ---------------------------------------------------------
<VirtualHost *:443>
   ServerName catalogue.yourdomain.ac.ke

   # Standard SSL
   SSLEngine on
   SSLCertificateFile /path/to/fullchain.pem
   SSLCertificateKeyFile /path/to/privkey.pem

   # Standard Koha Intranet configs
   Include /etc/koha/apache-shared.conf
   Include /etc/koha/apache-shared-intranet-plack.conf
   Include /etc/koha/apache-shared-intranet.conf
</VirtualHost>

Step 5: Restart and Verify

Check your Apache configuration for typos:

sudo apache2ctl configtest

If it returns Syntax OK, restart Apache to apply the new architecture:

sudo systemctl restart apache2

Finally, verify that your ports are correctly bound by running sudo netstat -pnlt. You should see Anubis actively listening on 127.0.0.1:3000, Apache handling the public edge on 0.0.0.0:443, and Apache silently waiting for clean traffic on 127.0.0.1:8081.

Your OPAC is now completely shielded by Anubis bot-protection, while your Intranet and SSL renewals remain entirely unaffected!

YES! This post was ~95% AI generated using Gemini 3.1 Pro and the steps tested in a real world setup to ascertain its effectiveness.

Exit mobile version