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