This guide walks through running Abusive HTTP Watch against a real access log on an OpenBSD system. The same flow works on FreeBSD and Linux with minor adjustments.

1. Install the script

Drop the script into a system location and make it executable.

doas install -m 0755 abusive_http_watch.pl /usr/local/sbin/abusive_http_watch

The daemon has no external Perl dependencies — only the standard library (Fcntl, IO::Handle, Sys::Syslog, Socket). If perl is on the system, the script will run.

2. Create the runtime directory

The daemon writes the blocklist to a single file. Pick a path that your firewall will read from.

doas mkdir -p /var/www/run
doas chown _www:_www /var/www/run

The blocklist file (/var/www/run/abusive_http_hosts by default) is created on first run if it does not exist.

3. Test against a recent log

Before wiring the daemon into the system, run it directly against an access log to see how it behaves.

ABUSIVE_DEBUG=1 abusive_http_watch /var/www/logs/access.log

Debug output ([dbg] ip=…, [dbg] token match ip=…, [dbg] count ip=… N/3) lets you watch the matcher in real time. When an IP exceeds the hit threshold (default 3), you will see [added] <ip> -> /var/www/run/abusive_http_hosts.

Press Ctrl-C to stop. Inspect the blocklist:

cat /var/www/run/abusive_http_hosts

You should see a short list of IPs — the loudest probers in the window you observed.

4. Wire the firewall to read the blocklist

On OpenBSD, add an <abusive> table that loads from the file:

table <abusive> persist file "/var/www/run/abusive_http_hosts"
block in quick on egress from <abusive> label abusive

Reload pf:

doas pfctl -f /etc/pf.conf

The table now blocks everything from those IPs at the firewall — no more web-server CPU spent on them.

To pick up new entries automatically, reload the table on a short interval. A simple cron approach:

*/2 * * * * /sbin/pfctl -t abusive -T replace -f /var/www/run/abusive_http_hosts

For Linux, the equivalent is an nftables set or ipset reloaded from the same file by a similar cron.

5. Run as a daemon

Install the rc.d script (see Operations for the script). Enable and start:

doas rcctl enable abusive_http_watch
doas rcctl start abusive_http_watch

The daemon is now following the log continuously and writing the blocklist. tail -f /var/log/daemon (or whichever syslog facility is configured) shows added events live.

6. Verify

Wait a few minutes, then check:

wc -l /var/www/run/abusive_http_hosts
doas pfctl -t abusive -T show | wc -l

The numbers should match. If they do, you are done — the daemon is running, blocklist is growing, firewall is filtering.

If the blocklist file stays empty after an hour or two on a public web server, your access log is unusually clean (congratulations) or the daemon is not reading from the path you think it is. See Operations for troubleshooting.