commit - 78bfe33e2736141f6e7e5566694c61ddbf273dd2
commit + 88f3e13dadb91d43520a3e4ceff3b61170d32759
blob - 238890e43813e6caf6c352887e3de6e476bfe15e
blob + c384389b84d8488db0b174aac34dfff0d1c144ce
--- README.md
+++ README.md
For me it has been quite effective.
+# Environment Variables
+
+- `HTTPBAN_WHITELIST`: List of whitelisted IP's
+- `HTTPBAN_LIMIT_500`: Number of hits in the 500's HTTP return code range
+- `HTTPBAN_LIMIT_400`: Number of hits in the 400's HTTP return code range
+- `HTTPBAN_LIMIT_300`: Number of hits in the 300's HTTP return code range
+
# Installation
1. Create an user
# cat /etc/doas.conf
permit nopass _httpban cmd /bin/cat args /var/www/logs/access.log
permit nopass _httpban cmd /usr/bin/zcat args /var/www/logs/access.log.*gz
- permit nopass _httpban cmd /sbin/pfctl args -t players -T show
- permit nopass _httpban cmd /sbin/pfctl args -t players -T add -f-
- permit nopass _httpban cmd /sbin/pfctl args -t players -T delete -f-
+ permit nopass _httpban cmd /sbin/pfctl args -t httpban -T show
+ permit nopass _httpban cmd /sbin/pfctl args -t httpban -T add -f-
+ permit nopass _httpban cmd /sbin/pfctl args -t httpban -T delete -f-
-4. Create a <players> table in /etc/pf.conf
+4. Create a <httpban> table in /etc/pf.conf
# cat /etc/pf.conf
- table <players> persist
- block in quick on egress from <players>
+ table <httpban> persist
+ block in quick on egress from <httpban>
3. Run it as _httpban (here every 5 minutes)
# crontab -eu _httpban
+ HTTPBAN_WHITELIST='127.0.0.1 67.225.146.248'
+ HTTPBAN_500=20
+ HTTPBAN_400=15
+ HTTPBAN_300=10
*/5 * * * * -s http-ban
-# TODO
-
-- [ ] parametrize the table name, as <players> is not really a good name
-- [ ] remove unused filter functions
-- [ ] make it more pleasant to read / give the impression I'm mentally saner
-
-WORK branch: I have no idea if it works. Probably not yet. Need more
-time to test and yet tired.
+WORK branch: bug fix and testing phase
blob - 16531b725391f48cc1450c1af17d46e12651916a
blob + 20656c482a7d12328bafbce1863ef45312abbb33
--- http-ban.sh
+++ http-ban.sh
#!/bin/sh
-# WARNING!
-# Export this variable properly to avoid locking you out
-: ${QUICK_WHITELIST:=127.0.0.1}
+: ${HTTPBAN_WHITELIST:=127.0.0.1}
+: ${HTTPBAN_LIMIT_500:=10}
+: ${HTTPBAN_LIMIT_400:=10}
+: ${HTTPBAN_LIMIT_300:=10}
+: ${HTTPBAN_TABLE:=httpban}
alias log="logger -st http-ban"
alias show="doas /sbin/pfctl -t players -T show"
alias ban="doas /sbin/pfctl -t players -T add -f-"
alias grace="doas /sbin/pfctl -t players -T delete -f-"
-# Filter functions returning 'count IP' based on HTTP return code
+# Filter functions returning 'count IP' based on HTTP return code
IN_300_HOSTS() {
awk '$(NF-1) >= 300 && $(NF-1) < 400 { print $2 }' | sort | uniq -c
}
awk -vtrig="${1:-10}" ' $1 >= trig { print $2 }'
}
-pre_block() {
- access | IN_500_HOSTS | limit 1
- access | IN_400_HOSTS | limit 3
- access | IN_300_HOSTS | limit 3
-}
-
block() {
- GF=$(for ip in $(printf %s\\n $QUICK_WHITELIST); do printf -- '-e "^%s$" ' "$ip"; done)
- pre_block | sort | uniq | {
- if test -n "$GF"; then
- grep -v $GF
- else
- cat -
- fi
+ set -- $HTTPBAN_WHITELIST
+ set -- $(for ip; do printf -- '-e %s ' "$ip" done)
+ {
+ access | IN_500_HOSTS | limit "$HTTPBAN_LIMIT_500"
+ access | IN_400_HOSTS | limit "$HTTPBAN_LIMIT_400"
+ access | IN_300_HOSTS | limit "$HTTPBAN_LIMIT_300"
+ } | sort | uniq | {
+ test -n "$*" && grep -v "$@" || cat
}
}
block | sort >/tmp/http-ban.new
+# Diff processing
show | sort | awk '{ print $1 }' >/tmp/http-ban.current
-
DIFF=$(comm /tmp/http-ban.new /tmp/http-ban.current)
NEW=$(comm -23 /tmp/http-ban.new /tmp/http-ban.current)
GRACE=$(comm -13 /tmp/http-ban.new /tmp/http-ban.current)