+#!/bin/bash
+#
+# Create or update the list of temporarily banned IPs.
+#
+
+BLOCKEDFILE=/home/lonvia/nominatim/settings/ip_blocks
+LOGFILE=/home/lonvia/nominatim/log/ip_blocks.log
+
+LONG_PERIOD='1 hour'
+SHORT_PERIOD='10 min'
+COOLOFF_PERIOD='1 hour'
+
+REVLONG_LIMIT=20000
+REVSHORT_LIMIT=6000
+SRCHLONG_LIMIT=4000
+SRCHSHORT_LIMIT='10 min'
+
+PSQLCMD='psql -qtA -d nominatim'
+
+# Blocking candidates
+$PSQLCMD > $BLOCKEDFILE.newblocks << ENDOFQUERY
+SELECT ipaddress FROM
+((SELECT ipaddress FROM
+ (SELECT ipaddress, count(*) FROM new_query_log
+ WHERE type = 'reverse' AND starttime > now() - interval '$LONG_PERIOD'
+ GROUP BY ipaddress)
+ as v
+ WHERE count > $REVLONG_LIMIT)
+UNION
+(SELECT ipaddress FROM
+ (SELECT ipaddress, count(*) FROM new_query_log
+ WHERE type = 'reverse' AND starttime > now() - interval '$SHORT_PERIOD'
+ GROUP BY ipaddress)
+ as v
+ WHERE count > $REVSHORT_LIMIT)
+UNION
+(SELECT ipaddress FROM
+ (SELECT ipaddress, count(*) FROM new_query_log
+ WHERE type = 'search' AND starttime > now() - interval '$LONG_PERIOD'
+ GROUP BY ipaddress)
+ as v
+ WHERE count > $SRCHLONG_LIMIT)
+UNION
+(SELECT ipaddress FROM
+ (SELECT ipaddress, sum(endtime-starttime) as dur FROM new_query_log
+ WHERE type = 'search' AND starttime > now() - interval '$SHORT_PERIOD'
+ GROUP BY ipaddress)
+ as v
+ WHERE dur > '$SRCHSHORT_LIMIT')
+) as q ORDER BY ipaddress;
+ENDOFQUERY
+
+no_newblocks=`comm $BLOCKEDFILE.newblocks $BLOCKEDFILE -23 | wc -l`
+
+if [ "x$no_newblocks" != "x0" ]; then
+ date +"%x %X Newly blocked IPs: `comm $BLOCKEDFILE.newblocks $BLOCKEDFILE -23 | tr '\n' ' '`" >> $LOGFILE
+fi
+
+
+# Deblockable candidates
+blocked=`tr '\n' ',' < $BLOCKEDFILE | sed "s:[[:space:]]::g;s:,$::;s:,:'),(':g"`
+
+if [ "x$blocked" == "x" ]; then
+ mv $BLOCKEDFILE.newblocks $BLOCKEDFILE
+else
+ $PSQLCMD > $BLOCKEDFILE.newlifted << ENDOFQUERY
+ VALUES ('$blocked')
+ EXCEPT
+ (SELECT DISTINCT ipaddress FROM new_query_log
+ WHERE starttime > now() - interval '$COOLOFF_PERIOD')
+ENDOFQUERY
+
+ no_lifted=`cat $BLOCKEDFILE.newlifted | wc -w`
+
+ if [ "x$no_lifted" != "x0" ]; then
+ date +"%x %X Bans lifted: `tr '\n' ' ' < $BLOCKEDFILE.newlifted`" >> $LOGFILE
+ fi
+
+ # Write out new blocks
+ cat $BLOCKEDFILE.newblocks $BLOCKEDFILE | sort -u | comm - $BLOCKEDFILE.newlifted -23 > $BLOCKEDFILE.new
+ mv $BLOCKEDFILE.new $BLOCKEDFILE
+
+ rm $BLOCKEDFILE.newblocks $BLOCKEDFILE.newlifted
+fi