From the beginning I've written script which collect all data about failed attempts of penetration:
#!/bin/bash
function getDate() {
echo "$@" | grep -o "^[[:alpha:]]\+[[:space:]]\+[[:digit:]]\+[[:space:]]\+[[:digit:]]\+:[[:digit:]]\+:[[:digit:]]\+"
}
invalidUsers=$(
for filename in $(ls -t1 /var/log/auth.log*); do
if [[ "${filename}" =~ gz$ ]]; then
gzip -dc "${filename}"
else
cat "${filename}"
fi
done | grep "Failed password for invalid user")
ipList=$(echo "${invalidUsers}" | grep -o "\([[:digit:]]*\.\)\{3\}[[:digit:]]*" | sort --unique)
for ipAddress in $(echo "${invalidUsers}" | grep -o "\([[:digit:]]*\.\)\{3\}[[:digit:]]*" | sort -u); do
currentViolation=$(echo "${invalidUsers}" | grep "${ipAddress}")
currentNumber=$(echo "${currentViolation}" | wc -l)
if [[ "${currentNumber}" -eq 1 ]]; then
whenDate="at "$(getDate "${currentViolation}")
else
fromDate=$(getDate $(echo "${currentViolation}" | head -n 1))
toDate=$(getDate $(echo "${currentViolation}" | tail -n 1))
whenDate="from ${fromDate} to ${toDate}"
fi
userNames=$(echo "${currentViolation}" | sed "s|^.*user \([^ ]*\) from.*$|\1|g" | sort -u | paste -s -d ,)
echo "${ipAddress}: ${currentNumber} time(s) ${whenDate}. User names: ${userNames}"
done | sort --key=2 --general-numeric-sort --reverse
after it I learned about TCP Wrappers and use it for limit number of attempts. I want to press your attention on the way how can be determined if your services compiled with supporting of TCP Wrappers:$ strings -f /usr/sbin/* | grep hosts_access /usr/sbin/in.tftpd: hosts_access /usr/sbin/sshd: hosts_access /usr/sbin/stunnel: hosts_access /usr/sbin/stunnel: See hosts_access(5) manual for details /usr/sbin/tcpd: hosts_access_verbose /usr/sbin/vsftpd: hosts_access /usr/sbin/xinetd: hosts_accessWell the main idea is to check every attempt to use ssh and block it if IP is included in black list. This list should be appended every time by data from auth.log analyse and include all addresses which have 5 or more failed attempts. Some notes should be listed here to be unforgotten:
- we have to use both hosts.allow and hosts.deny. Information about aclexec can be found in hosts_options(5) hosts.allow:
sshd : ALL : aclexec <some checking script> %ahosts.deny:
sshd : ALL
#!/bin/bash
function getTempFilename(){
prefix="$1"
#generate new name
tempFile="${tmpPlace}/${prefix}${RANDOM}"
while [ -f "${tempFile}" ] ; do
tempFile="${tmpPlace}/${prefix}${RANDOM}"
done
echo "${tempFile}"
}
declare -r NUMBER_TRIES=5
BLOCK_FILE_NAME="/var/blackList"
tmpPlace=/tmp
grep Failed /var/log/auth.log /var/log/auth.log.0 2>/dev/null | grep -o "\([[:digit:]]*\.\)\{3\}[[:digit:]]*" | sort | uniq -c | while read count ipAddress ; do
if [[ "${count}" -gt ${NUMBER_TRIES} ]] ; then
echo "${ipAddress}" >> "${BLOCK_FILE_NAME}"
fi
done
tmpFileName=$(getTempFilename balckList)
sort -g "${BLOCK_FILE_NAME}" | uniq > "${tmpFileName}"
mv "${tmpFileName}" "${BLOCK_FILE_NAME}"
grep "$1" "${BLOCK_FILE_NAME}" && exit 1
exit 0
2 comments:
Good work Beggy! But it seems to me that zcat "${filename}" would be shorter for gzip -dc "${filename}" though both acts the same...
Sure - you are right. I just forget it as "one more command", but it standard command so you are right - it is better to use zcat instead gzip. Thank you :)
Post a Comment