-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathroundcube-spam-check
executable file
·171 lines (150 loc) · 5.81 KB
/
roundcube-spam-check
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
#!/bin/bash
print_help () {
bold=$(tput bold)
normal=$(tput sgr0)
cat <<- EOF
${bold}NAME${normal}
${bold}roundcube-spam-scan${normal} - roundcube logs spammers reporter
${bold}SYNOPSIS${normal}
${bold}roundcube-spam-scan${normal} [ OPTION ]
${bold}DESCRIPTION${normal}
Scans roundcube logs /var/log/mail.log looking for SASL authenticated users that make more than MAX_CONNECTIONS per time PERIOD.
Covering the typical attacks on a mail server setup
${bold}-p, --period=PERIOD${normal}
A DATE STRING compatible period "1hour", "1minute", etc see man date for more.
Defaults to "1hour"
${bold}-m, --max-connections=MAX_CONNECTIONS${normal}
Threshold value for number of connections beyond a report is made.
Defaults to 90.
${bold}-d, --dissable-account=MAX_NETWORKS,MAX_UNKNOWNS${normal}
Specifies the boundary conditions for the maximum number of networks and unknown IPs
beyond which the user account is automatically disabled.
A separated e-mail is sent when a user is disabled so you don't miss it.
Dissabling accounts is switched off by default.
${bold}-n, --niss=[MASTER_SERVER]${normal}
Disables a NIS account rather than a local account.
It usses SSH and MASTER_SERVER defaults to localhost.
${bold}-l, --logs=LOG_PATH${normal}
/var/log/roundcube/sendmail by default
${bold}-h, --help${normal}
Prints this help text
${bold}EXAMPLES${normal}
roundcube-spam-scan
roundcube-spam-scan -p 30minutes -m 60
roundcube-spam-scan -d 10,10
EOF
}
LOG_PATH='/var/log/roundcube/sendmail'
PERIOD='1hour'
MAX_CONNECTIONS=90
disable=false
nis=false
NIS_SERVER='localhost'
while true; do
case $1 in
-p|--period)
PERIOD=${2}
if [[ ! $(date -d "-${PERIOD}" 2> /dev/null) ]]; then
echo "${PERIOD}: Unsuported DATE STRING" >&2
exit 2
fi
shift; shift ;;
-m|--max-connections)
MAX_CONNECTIONS=${2}
if ! [[ $MAX_CONNECTIONS =~ ^[0-9]+$ ]]; then
echo "${MAX_CONNECTIONS}: Is not a number" >&2
exit 2
fi
shift; shift ;;
-d|--dissable-acount)
disable=true
MAX_NETS=${2//,*/}
MAX_UNKNOWNS=${2//*,/}
if ! [[ $MAX_NETS =~ ^[0-9]+$ && $MAX_UNKNOWNS =~ ^[0-9]+$ ]]; then
echo "${MAX_NETS} or ${MAX_UNKNOWNS}: Are not numbers" >&2
exit 2
fi
shift; shift ;;
-n|--nis)
nis=true;
if [[ "${2}" != "" && "${2}" != -* ]]; then
NIS_SERVER="${2}"
shift
fi
shift ;;
-l|--logs)
LOG_PATH=${2}
shift; shift ;;
-h|--help) print_help; exit 0 ;;
-*) echo "$0: Unrecognized option $1" >&2; exit 2 ;;
*) break ;;
esac
done
log=$(awk -v boundary="$(date '+%Y%m%d%H%M%S' -d -${PERIOD})" \
'BEGIN {
months["Jan"] = "01";
months["Feb"] = "02";
months["Mar"] = "03";
months["Apr"] = "04";
months["May"] = "05";
months["Jun"] = "06";
months["Jul"] = "07";
months["Aug"] = "08";
months["Sep"] = "09";
months["Oct"] = "10";
months["Nov"] = "11";
months["Dec"] = "12";
} /^\[/{
# date = [01-Dec-2014 12:40:37
date = substr($1, 2)
year = substr(date, 8, 4)
month = months[substr(date, 4, 3)];
day = substr(date, 1, 2)
time = substr($2, 1)
hour = substr(time, 1, 2)
minute = substr(time, 4, 2)
second = substr(time, 7, 2)
line_date = year month day hour minute second
if ( line_date > boundary)
print $0
}' ${LOG_PATH})
period=$(echo "${PERIOD}" | sed "s/\([0-9]*\)/\1 /")
message="During the last ${period} the following senders have made at least ${MAX_CONNECTIONS} SMTP connections."
found=false
while read line; do
current=( ${line} )
if [[ ${current[0]} != "" && ${current[0]} -ge $MAX_CONNECTIONS ]]; then
userlogs=$(echo "${log}" | grep "User ${current[1]} \[")
logentry=$(echo "${userlogs}" | head -n1)
ips=$(echo "${userlogs}" | cut -d'[' -f3 | cut -d']' -f1 | sort | uniq)
nets=$(echo "${ips}" | xargs -i nslookup {} \
| grep -oP "\sname\s=\s\K(.*)|^\*\*" | sed "s/.*[0-9].//" | sort | uniq)
unkowns=$(echo "${nets}" | grep '\*\*' | wc -l)
nets=$(echo "${nets}" | grep -v '\*\*' | wc -l)
numips=$(echo "${ips}" | wc -l)
if [[ $found = false ]]; then
echo -e "${message}\n"
found=true
fi
report="${current[0]} (${nets} nets/${unkowns} unknown/${numips} IPs) -- ${logentry}"
if [[ $disable = true && $nets -gt $MAX_NETS && $unknown -gt $MAX_UNKNOWNS ]]; then
report="${report} [DISABLED]"
if [[ $nis = true ]]; then
echo "NIS"
#ssh root@${NIS_SERVER} "
# sed -i 's/^${current[1]}:/${current[1]}:*/' /var/yp/ypfiles/shadow &&
# make -C /var/yp/"
else
echo "LOCAL"
#passwd "${current[1]}" -l
fi
(
echo "Subject: SPAMMER DETECTED AT $(hostname -f) [USER DISABLED]"
echo "To: root@$(hostname -d)"
echo ""
echo "${msg}"
) | sendmail root@$(hostname -d) -
fi
echo "${report}"
fi
done < <(echo "$log" | awk {'print $5'} | sort -n | uniq -c)