commit 3115cd3d2569f9d1fef29012fbe343457658bbad from: xs date: Tue Jan 30 16:37:55 2024 UTC Getting some cleaning done, untested commit - effb1e2f38efb6598e6abdb74c593d6db6c06eb1 commit + 3115cd3d2569f9d1fef29012fbe343457658bbad blob - 0dc12990ebcf6103910cec0b8cabc9c1f5fca1b1 blob + 4f4bc80afc0114b65f0acf94dfd5b565c0930b04 --- README.md +++ README.md @@ -45,3 +45,6 @@ For me it has been quite effective. - [ ] parametrize the table name, as 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. blob - 73554eacfb8a06df4ebd0bf358405ed2bf6e8789 blob + 53df0d9dbe584a8333a21e6a5baa442d545ff606 --- http-ban.sh +++ http-ban.sh @@ -1,87 +1,85 @@ #!/bin/sh + QUICK_WHITELIST=192.168.10.10 + 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-" -whitelist() { - printf %s\\n $QUICK_WHITELIST + +# 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 } -last_access() { - doas /bin/cat /var/www/logs/access.log + +IN_400_HOSTS() { + awk '$(NF-1) >= 400 && $(NF-1) < 500 { print $2 }' | sort | uniq -c } + +IN_500_HOSTS() { + awk '$(NF-1) >= 500 && $(NF-1) < 600 { print $2 }' | sort | uniq -c +} + +# Our local logs access() { last_access + doas /bin/cat /var/www/logs/access.log doas /usr/bin/zcat /var/www/logs/access.log.*gz 2>/dev/null } -NOT_200_Q() { - awk '$(NF-1) != 200 {print}' | sort -} -NOT_200_C() { - awk '$(NF-1) != 200 {print $(NF-1), $2}' | sort -nk1 | uniq -c | sort -nk1 -} -NOT_200_HOSTS_C() { - awk '$(NF-1) != 200 {print $2}' | sort | uniq -c | sort -nk1 -} -IN_300_HOSTS_Q() { - awk '$(NF-1) >= 300 && $(NF-1) < 400 { print }' | sort -} -IN_300_HOSTS_C() { - awk '$(NF-1) >= 300 && $(NF-1) < 400 { print $2 }' | sort | uniq -c | sort -nk1 -} -IN_400_HOSTS_Q() { - awk '$(NF-1) >= 400 && $(NF-1) < 500 { print }' | sort -} -IN_400_HOSTS_C() { - awk '$(NF-1) >= 400 && $(NF-1) < 500 { print $2 }' | sort | uniq -c | sort -nk1 -} -IN_500_HOSTS_Q() { - awk '$(NF-1) >= 500 && $(NF-1) < 600 { print }' | sort -} -IN_500_HOSTS_C() { - awk '$(NF-1) >= 500 && $(NF-1) < 600 { print $2 }' | sort | uniq -c | sort -nk1 -} -limit() { - awk -vtrig="${1:-10}" ' $1 >= trig { print $2 }' -} -pre_block() { - last_access | IN_500_HOSTS_C | limit 1 - last_access | IN_400_HOSTS_C | limit 3 - access | IN_300_HOSTS_C | limit 3 -} + apply_whitelist() { - GF=$(for ip in $(whitelist); do printf -- '-ve %s\n' "$ip"; done) + GF=$(for ip in $(printf %s\\n $QUICK_WHITELIST); do printf -- '-ve %s\n' "$ip"; done) GF=${GF:-'.*'} grep $GF } + +limit() { + 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() { pre_block | sort | uniq | apply_whitelist } + umask 127 + block | sort >/tmp/http-ban.new + 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) + rm /tmp/http-ban.* + test -n "$NEW" -o -n "$GRACE" || exit 0 -test -n "$NEW" && - log BANNING NEW IPs && - log <<. + +# There's new IP's +if test -n "$NEW"; then + log Banning new IPs: + log <<.. $NEW -. -test -n "$GRACE" && - log GRACING OLD IPs && - log <<. -$GRACE -. -ban <<. +.. + ban <<.. $NEW -. -grace <<. +.. +fi + +# There's Old IP's not attacking anymore +if test -n "$GRACE"; then + log Gracing old IPs: + log <<.. $GRACE -. -test -n "$QUICK_WHITELIST" && - grace <<. -$QUICK_WHITELIST -. +.. + + grace <<.. +$GRACE +.. +fi