blob: 902c2c18661aa01052c3bbd5078a61615f16acda (
plain)
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
|
#!/bin/sh
# Script to trawl logs for nastiness and log bad IP addresses
# From http://netnix.blogspot.com/2005/06/openbsd-ssh-protection.html
# Warning and whitelist features by Olivier Mehani <shtrom-openbsd@ssji.net>
#
# Minimal pf.conf file:
# table <whitelist> persist file "/etc/whitelist"
# table <kiddies> persist file "/etc/blockers.list"
# pass in quick on egress proto tcp from <whitelist> to (egress) port ssh
# block in quick on $ext_if from <kiddies>
# Crontab entry:
# */5 * * * * /usr/local/sbin/denyhost.sh
#
# Remember to manually populate your <whitelist> table:
# # pfctl -vt whitelist -T add ADDRESS
# or by creating file /etc/whitelist (adding it to /etc/changelist may
# also be a good idea)
#
LOCAL_ADDR=root@`hostname`
HTTP_LOG=/srv/www/logs/access_log
HTTP_PATTERN="etc.passwd"
SSH_LOG=/var/log/authlog
SSH_PATTERN=".*\(Invalid user\|Failed password\).*from \([0-9a-fA-F.:]\+\).*"
AUTHTRIES=3 # single digit
EXPIRY=604800 # s; 1w
BLOCKERS_FILE=/etc/blockers.list
TMP_DIR=/tmp
PATH=/usr/local/bin:$PATH
PIDFILE=/var/run/denyhost.sh.pid
MAIL=mail
# Exit if another instance is already running.
if test -e $PIDFILE && kill -0 `cat $PIDFILE` 2>/dev/null; then
echo "$0 process already running (`cat $PIDFILE`), exiting" >&2
exit 0
else
echo $$ > $PIDFILE
fi
function process_ip
{
HOST_FILE=`mktemp ${TMP_DIR}/denyhost.host.XXXXXX`
host $IP > $HOST_FILE
HOSTS=`gsed -n "s/.*\(:\|domain name pointer\) \(.\+\)/\2/p" $HOST_FILE | \
gsed ':a N;s/\n/, /g; ta'`
WHOIS_FILE=`mktemp ${TMP_DIR}/denyhost.whois.XXXXXX`
whois $IP > $WHOIS_FILE
ABUSE=`extract_email $WHOIS_FILE`
HTTP_HOST_LOG=`mktemp ${TMP_DIR}/denyhost.host_http.log.XXXXXX`
grep $IP $HTTP_FILTERED_LOG > $HTTP_HOST_LOG
SSH_HOST_LOG=`mktemp ${TMP_DIR}/denyhost.host_ssh.log.XXXXXX`
grep $IP $SSH_FILTERED_LOG > $SSH_HOST_LOG
LOGINS=`gsed -n "s/.*sshd\[[0-9]\+\]: \(Invalid user\|Failed password for\( invalid user\)\?\) \([^[:space:]]\+\) from.*/\3/p" $SSH_HOST_LOG | \
sort | uniq | gsed ':a N;s/\n/, /g; ta'`
if [ -z "$ABUSE" ]; then
NETS=`gsed -n "s/.*\(NET-[-0-9]\+\).*/\1/p" $WHOIS_FILE`
for NET in $NETS; do
whois $NET >> $WHOIS_FILE
done
ABUSE=`extract_email $WHOIS_FILE`
fi
if [ -z "$ABUSE" ]; then
DEST_ADDR="${LOCAL_ADDR}"
SUBJECT="Host $IP (admin unknown) is compromised"
else
DEST_ADDR="$ABUSE"
CC="-c $LOCAL_ADDR"
SUBJECT="Host $IP is compromised"
fi
(
if [ -n "$ABUSE" ]; then
cat << EOF
Greetings,
[ This is an automated email, please report any problem to
<shtrom-admin@ssji.net> ]
Unauthorised login attempts have recently been observed from an IP address
in one of your administrative ranges ($IP), as identified by WHOIS
information.
Please find below reports from the blocking system, including logs of
connection attempts at the bottom.
Could you please take this machine down for cleanup, or forward this
message to its administrator in charge.
EOF
fi
echo "Offending IP: $IP"
echo "Hostnames: $HOSTS"
echo "Abuse addresses: $ABUSE"
echo "Usernames tried: $LOGINS"
echo
echo "Host and WHOIS information:"
cat $HOST_FILE
cat $WHOIS_FILE
echo
echo "Incriminating logs (HTTP):"
cat $HTTP_HOST_LOG
echo
echo "Incriminating logs (SSH):"
cat $SSH_HOST_LOG
) | $MAIL ${CC} -s "${SUBJECT}" $DEST_ADDR
rm -f $HOST_FILE $WHOIS_FILE $SSH_HOST_LOG $HTTP_HOST_LOG
}
function extract_email
{
gsed -ne "/abuse.*@/{ \
/whois-contact@lacnic.net/d; \
/mail-abuse@cert.br/d; \
/cert@cert.br/d; \
/search-apnic-not-arin@apnic.net/d; \
/hostmaster@nic.ad.jp/d; \
/hostmaster@ripe.net/d; \
/.*@apnic.net/d; \
/abusepoc@afrinic.net/d; \
/ncc@ripe.net/d; \
/search-ripe-ncc-not-arin@ripe.net/d; \
s/.*[^-+\._A-Za-z0-9]\([-+\._A-Za-z0-9]\+@\([-A-Za-z0-9]\+\.\)\+[A-Za-z]\+\).*/\1/p \
}" \
$1 |
sort | uniq | gsed ':a N;s/\n/, /g; ta'
}
NEW_BLOCKERS_FILE=`mktemp ${TMP_DIR}/denyhost.blockers.list.XXXXXX`
# HTTP exploiters
HTTP_FILTERED_LOG=`mktemp ${TMP_DIR}/denyhost.http.log.XXXXXX`
grep -v -f ${BLOCKERS_FILE} ${HTTP_LOG} \
> ${HTTP_FILTERED_LOG}
grep ${HTTP_PATTERN} ${HTTP_FILTERED_LOG} | cut -d" " -f 2 | \
uniq >> ${NEW_BLOCKERS_FILE}
# SSH exploiters
SSH_FILTERED_LOG=`mktemp ${TMP_DIR}/denyhost.ssh.log.XXXXXX`
grep -v "Received disconnect" ${SSH_LOG} | \
grep -v -f ${BLOCKERS_FILE} \
> ${SSH_FILTERED_LOG}
gsed -n "s/${SSH_PATTERN}/\2/p" ${SSH_FILTERED_LOG} | \
sort | uniq -c | \
gsed "/^ *[1-$AUTHTRIES] */d;s/.* //" \
>> ${NEW_BLOCKERS_FILE}
for IP in `cat $NEW_BLOCKERS_FILE`; do
process_ip $IP
done
# Flush entries older than a week
pfctl -t kiddies -T expire $EXPIRY 1>/dev/null 2>&1
# Add new entries
pfctl -t kiddies -Tadd -f ${NEW_BLOCKERS_FILE} 1>/dev/null 2>&1
pfctl -t kiddies -Tshow | sed 's/^ *//' > ${BLOCKERS_FILE}
rm ${HTTP_FILTERED_LOG} ${SSH_FILTERED_LOG} ${NEW_BLOCKERS_FILE}
rm ${PIDFILE}
|