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 --reverseafter 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