Skip to main content

Web Server Integration

Block unwanted traffic directly at the web server level — before it ever reaches your application. This guide covers how to use AntiProxies IP databases with Nginx, Apache, HAProxy, Caddy, and IIS.

Overview

AntiProxies databases ship as CSV and JSON files containing IP addresses and CIDR ranges for VPN providers, proxy networks, Tor exit nodes, and datacenter/hosting ranges. By loading these lists into your web server configuration, you can deny or redirect suspicious traffic at the edge — with zero application code changes.

Which databases to use

For web server blocking you will use the VPN/Proxy Ranges, Tor Exit Nodes, and Datacenter Ranges databases. These contain the IP addresses and CIDR ranges needed for server-level rules. The Disposable Email and ISP Reputation databases are better suited for application-level checks.

Preparing Your Data

CSV Format

The VPN/Proxy Ranges database CSV contains columns for the CIDR range, provider name, and type. A typical row looks like:

range,provider,type
103.21.244.0/22,ExampleVPN,Commercial VPN
198.51.100.0/24,ProxyNet,Residential Proxy
192.0.2.1/32,TorNode,Tor Exit Node

Extracting IPs & CIDRs

Most web servers need a plain list of IPs or CIDR ranges — one per line. Extract the first column from the CSV:

# Extract CIDR ranges from CSV (skip header)
tail -n +2 vpn-proxy-ranges.csv | cut -d',' -f1 > blocklist.txt

# Merge all databases into one list
tail -n +2 vpn-proxy-ranges.csv | cut -d',' -f1 >  blocklist.txt
tail -n +2 tor-exit-nodes.csv   | cut -d',' -f1 >> blocklist.txt
tail -n +2 datacenter-ranges.csv | cut -d',' -f1 >> blocklist.txt

The resulting blocklist.txt file will look like:

103.21.244.0/22
198.51.100.0/24
192.0.2.1/32
...

Nginx

Nginx offers two approaches for IP-based blocking: the geo module (recommended for large lists) and direct deny directives.

Using the geo Module

The geo module maps client IP addresses to values using a prefix tree, making it efficient even with very large blocklists. Place this in your http block:

# /etc/nginx/nginx.conf (inside http block)

geo $is_blocked {
    default         0;
    include         /etc/nginx/blocklist.conf;
}

server {
    listen 80;
    server_name example.com;

    if ($is_blocked) {
        return 403;
    }

    # ... your normal configuration
}

Generate the blocklist.conf from your extracted ranges:

# Convert blocklist.txt to Nginx geo format
awk '{print $1, "1;"}' blocklist.txt > /etc/nginx/blocklist.conf

The resulting file will look like:

103.21.244.0/22 1;
198.51.100.0/24 1;
192.0.2.1/32 1;

Using deny Directives

For smaller lists, you can use deny directives directly. Generate the file and include it in your server or location block:

# Convert to deny directives
awk '{print "deny", $1 ";"}' blocklist.txt > /etc/nginx/blocklist-deny.conf
# /etc/nginx/conf.d/example.conf

server {
    listen 80;
    server_name example.com;

    include /etc/nginx/blocklist-deny.conf;
    allow all;

    # ... your normal configuration
}

After updating the blocklist, reload Nginx to apply changes: sudo nginx -s reload

Apache

Apache provides several methods for IP-based access control. The best approach depends on your list size and Apache version.

Using mod_rewrite + RewriteMap

For large blocklists, RewriteMap with a DBM hash is the most efficient approach. First, create a plain-text map file:

# Convert to Apache map format (key value pairs)
awk '{print $1, "blocked"}' blocklist.txt > /etc/apache2/blocklist.map

Then convert it to a DBM hash for faster lookups and add the rewrite rules:

# Convert to DBM hash (run once after each update)
httxt2dbm -i /etc/apache2/blocklist.map -o /etc/apache2/blocklist.dbm
# In your VirtualHost or server config

RewriteEngine On
RewriteMap blocklist "dbm:/etc/apache2/blocklist.dbm"

# Check if the client IP is in the blocklist
RewriteCond ${blocklist:%{REMOTE_ADDR}} =blocked
RewriteRule ^ - [F]

Using Require / Deny

Apache 2.4+ uses mod_authz_host with Require directives. Generate a config snippet:

# Generate Apache 2.4 deny rules
echo "<RequireAll>" > /etc/apache2/conf-available/blocklist.conf
echo "  Require all granted" >> /etc/apache2/conf-available/blocklist.conf
awk '{print "  Require not ip", $1}' blocklist.txt >> /etc/apache2/conf-available/blocklist.conf
echo "</RequireAll>" >> /etc/apache2/conf-available/blocklist.conf

Include it in your VirtualHost:

<VirtualHost *:80>
    ServerName example.com
    DocumentRoot /var/www/html

    <Directory /var/www/html>
        Include conf-available/blocklist.conf
    </Directory>
</VirtualHost>

After updating the blocklist, reload Apache: sudo systemctl reload apache2

HAProxy

HAProxy can load IP lists into ACLs from external files. This is ideal when HAProxy sits in front of your application as a load balancer or reverse proxy.

Place your blocklist.txt file (one CIDR per line) and reference it in your config:

# /etc/haproxy/haproxy.cfg

frontend http_front
    bind *:80
    bind *:443 ssl crt /etc/ssl/certs/example.pem

    # Load the AntiProxies blocklist
    acl is_blocked src -f /etc/haproxy/blocklist.txt
    http-request deny deny_status 403 if is_blocked

    default_backend app_servers

backend app_servers
    server app1 127.0.0.1:8080 check

HAProxy reads the file at startup. To apply updates, reload the service:

sudo systemctl reload haproxy

For runtime updates without a reload, you can use HAProxy's Runtime API:

# haproxy.cfg - enable the Runtime API on a unix socket

global
    stats socket /var/run/haproxy.sock mode 600 level admin

frontend http_front
    bind *:80

    acl is_blocked src -f /etc/haproxy/blocklist.txt
    http-request deny deny_status 403 if is_blocked

    default_backend app_servers

Caddy

Caddy uses the remote_ip matcher to filter requests by client IP. You can list CIDR ranges directly in the Caddyfile.

# Caddyfile

example.com {
    @blocked remote_ip 103.21.244.0/22 198.51.100.0/24 192.0.2.1/32

    respond @blocked 403 {
        body "Access denied"
        close
    }

    # ... your normal site configuration
    reverse_proxy localhost:8080
}

For large lists, generate the matcher from your blocklist:

# Generate Caddy remote_ip ranges (space-separated on one line)
RANGES=$(tr '\n' ' ' < blocklist.txt)
echo "@blocked remote_ip $RANGES"

For very large blocklists (10,000+ ranges), consider using Caddy's JSON config API to load ranges programmatically instead of inlining them in the Caddyfile.

IIS

IIS uses the IP Address and Domain Restrictions feature (part of IIS Security). First, ensure the feature is installed:

# PowerShell - Install the feature
Install-WindowsFeature Web-IP-Security

Then generate deny rules for web.config from your blocklist using PowerShell:

# PowerShell - Generate web.config rules from blocklist
$rules = Get-Content blocklist.txt | ForEach-Object {
    $parts = $_ -split '/'
    if ($parts.Length -eq 2) {
        "      <add ipAddress=`"$($parts[0])`" subnetMask=`"$($parts[1])`" />"
    } else {
        "      <add ipAddress=`"$($parts[0])`" />"
    }
}

$xml = @"
<configuration>
  <system.webServer>
    <security>
      <ipSecurity allowUnlisted="true">
$($rules -join "`n")
      </ipSecurity>
    </security>
  </system.webServer>
</configuration>
"@
$xml | Out-File web.config -Encoding UTF8

IIS ipSecurity uses subnet masks (e.g. 255.255.252.0), not CIDR notation. The script above passes the prefix length directly — IIS 8.0+ accepts both formats. For IIS 7.5 and below, convert CIDR to dotted subnet masks.

Testing Your Setup

After applying your configuration, verify that blocking works correctly:

1. Test with a known blocked IP

Use curl with a spoofed IP from your blocklist (works if your server is behind a reverse proxy that reads X-Forwarded-For):

curl -H "X-Forwarded-For: 103.21.244.1" -I https://example.com

2. Verify legitimate traffic passes

Ensure your own IP is not in the blocklist and test normally:

# Should return HTTP 200
curl -I https://example.com

3. Check server logs

Look for 403 responses in your access logs to confirm blocking is active:

# Nginx
grep " 403 " /var/log/nginx/access.log

# Apache
grep " 403 " /var/log/apache2/access.log