]> git.openstreetmap.org Git - nominatim.git/blob - utils/cron_banip.sh
reduce limits on high loads and order results correctly
[nominatim.git] / utils / cron_banip.sh
1 #!/bin/bash
2 #
3 # Create or update the list of temporarily banned IPs.
4 #
5
6 BASEDIR="$( cd "$( dirname "$0" )" && cd .. && pwd )"
7 if [ "x$BASEDIR" == "x" ]; then
8     echo "Could not determine base dir."
9     exit -1
10 fi
11
12 BLOCKEDFILE=$BASEDIR/settings/ip_blocks
13 LOGFILE=$BASEDIR/log/ip_blocks.log
14
15 LONG_PERIOD='1 hour'
16 SHORT_PERIOD='10 min'
17 COOLOFF_PERIOD='1 hour'
18
19 REVLONG_LIMIT=20000
20 REVSHORT_LIMIT=6000
21 SRCHLONG_LIMIT=4000
22 SRCHSHORT_LIMIT='10 min'
23
24 PSQLCMD='psql -qtA -d nominatim'
25
26 curload=`cat /proc/loadavg | sed 's:[. ].*::'`
27 if [ "$curload" -gt "15" ]; then
28   REVSHORT_LIMIT=$((REVSHORT_LIMIT/2))
29 fi
30
31 # Blocking candidates
32 $PSQLCMD > $BLOCKEDFILE.newblocks << ENDOFQUERY
33 SELECT ipaddress FROM
34 ((SELECT ipaddress FROM
35   (SELECT ipaddress, count(*) FROM new_query_log
36    WHERE type = 'reverse' AND starttime > now() - interval '$LONG_PERIOD'
37    GROUP BY ipaddress)
38   as v
39   WHERE count > $REVLONG_LIMIT) 
40 UNION
41 (SELECT ipaddress FROM
42   (SELECT ipaddress, count(*) FROM new_query_log
43    WHERE type = 'reverse' AND starttime > now() - interval '$SHORT_PERIOD'
44    GROUP BY ipaddress)
45   as v
46   WHERE count > $REVSHORT_LIMIT) 
47 UNION
48 (SELECT ipaddress FROM
49   (SELECT ipaddress, count(*) FROM new_query_log
50    WHERE type = 'search' AND starttime > now() - interval '$LONG_PERIOD'
51    GROUP BY ipaddress)
52   as v
53   WHERE count > $SRCHLONG_LIMIT) 
54 UNION
55 (SELECT ipaddress FROM
56   (SELECT ipaddress, sum(endtime-starttime) as dur FROM new_query_log
57    WHERE type = 'search' AND starttime > now() - interval '$SHORT_PERIOD'
58    GROUP BY ipaddress)
59   as v
60   WHERE dur > '$SRCHSHORT_LIMIT')
61 ) as q ORDER BY ipaddress;
62 ENDOFQUERY
63
64 no_newblocks=`comm $BLOCKEDFILE.newblocks $BLOCKEDFILE -23 | wc -l`
65
66 if [ "x$no_newblocks" != "x0" ]; then
67     date +"%x %X Newly blocked IPs: `comm $BLOCKEDFILE.newblocks $BLOCKEDFILE -23 | tr '\n' ' '`" >> $LOGFILE
68 fi
69
70
71 # Deblockable candidates
72 blocked=`tr '\n' ',' < $BLOCKEDFILE | sed "s:[[:space:]]::g;s:,$::;s:,:'),(':g"`
73
74 if [ "x$blocked" == "x" ]; then
75   mv $BLOCKEDFILE.newblocks $BLOCKEDFILE 
76 else
77     $PSQLCMD > $BLOCKEDFILE.newlifted << ENDOFQUERY
78     SELECT column1 FROM (
79     VALUES ('$blocked')
80     EXCEPT
81     (SELECT DISTINCT ipaddress FROM new_query_log
82      WHERE starttime > now() - interval '$COOLOFF_PERIOD')
83     ) as q ORDER BY column1;
84 ENDOFQUERY
85
86     no_lifted=`cat $BLOCKEDFILE.newlifted | wc -w`
87
88     if [ "x$no_lifted" != "x0" ]; then
89         date +"%x %X Bans lifted: `tr '\n' ' ' < $BLOCKEDFILE.newlifted`" >> $LOGFILE
90     fi
91
92     # Write out new blocks
93     cat $BLOCKEDFILE.newblocks $BLOCKEDFILE | sort -u | comm - $BLOCKEDFILE.newlifted -23 > $BLOCKEDFILE.new
94     mv $BLOCKEDFILE.new $BLOCKEDFILE
95
96     rm $BLOCKEDFILE.newblocks $BLOCKEDFILE.newlifted
97 fi