SMTP Authを何度も試みててくるIPアドレスをブロックする【postfix】

postfixで何度もSMTP Auth をしてくるSPAMメールの業者のIPアドレスをブロックする

メールサーバーを運用していると、海外からのSPAM業者がSTMPサーバーにアクセスしてきます。いちようメールサーバーはSMTP認証をしているので、メールログには以下のような「authentication failed」ログで溢れていきます

$ sudo  grep "authentication failed" /var/log/maillog | head -3
Oct  7 03:36:21 mail01 postfix/smtpd[30764]: warning: unknown[x.x.x.x]: SASL LOGIN authentication failed: pass1234
Oct  7 03:38:35 mail01 postfix/smtpd[30764]: warning: unknown[x.x.x.x]: SASL LOGIN authentication failed: password
Oct  7 03:39:57 mail01 postfix/smtpd[30764]: warning: unknown[x.x.x.x]: SASL PLAIN authentication failed: qwer1234

数回程度のSMTP認証で失敗になら使用しているユーザーも考えられますが、複数回失敗しているなら間違いなく迷惑メールを送信している業者が高いので、この「authentication failed」でSMTP認証を失敗しているIPアドレスを拾って、そのIPアドレスをiptableや、特定のIPアドレスからアクセスを拒否る設定ができる「smtpd_client_restrictions =check_client_access:hash:【ファイ名】」等で設定してアクセスを拒否します

maillogから、「authentication failed」のあるIPアドレスを抽出します。

$ sudo cat /var/log/maillog | grep 'authentication failed' | awk '{print $7}' 
unknown[x.x.x.x]:
unknown[x.x.x.x]:
unknown[x.x.x.x]:
unknown[x.x.x.x]:
unknown[x.x.x.x]:
unknown[x.x.x.x]:
unknown[x.x.x.x]:
unknown[x.x.x.x]:
unknown[x.x.x.x]:

余計な文字列があるので抽出したIPアドレスを含む文字列を別ファイルに出力してからsedコマンドで整形さるシェルスクリプトを作ります
#!/bin/bash

cat /var/log/maillog | grep 'authentication failed' | awk '{print $7}' > /var/tmp/mail_authfail.log
sed -i -e "s/\[/ /g" /var/tmp/mail_authfail.log
sed -i -e 's/\]\://g' /var/tmp/mail_authfail.log
# authentication failedのログが多いIPアドレスのTOP10をファイルに出力します
cat /var/tmp/mail_authfail.log | awk '{print $2}' | sort | uniq -c | sort -nr | head -10 > /var/tmp/fail_top10.txt

# authentication failedのログが多いIPアドレス
$ cat /var/tmp/fail_top10.txt
    1810 x.x.x.x
    1196 x.x.x.x
    1189 x.x.x.x
    1114 x.x.x.x
     998 x.x.x.x
     992 x.x.x.x
     858 x.x.x.x
     842 x.x.x.x
     780 x.x.x.x
     720 x.x.x.x

「/var/tmp/fail_top10.txt」に「authentication failed」のログが多いIPアドレスが抽出できますので、そのファイルを読み込んでiptables等のIPアドレスを拒否するようなシェルスクリプトを作ります
#!/bin/bash

DATA=`date "+%Y%m%d"`
LOGDIR=/var/tmp/mail_authfail
REJECTCL_FILE=/etc/postfix/reject_client

if [ ! -d ${LOGDIR} ] ; then
  mkdir ${LOGDIR}
fi

# authentication failed のIPアドレスを記録(出力ファイル:fail_top10.txt )
cat /var/log/mail/maillog | grep 'authentication failed' | awk '{print $7}' > ${LOGDIR}/mail_authfail_${DATA}.log
sed -i -e "s/\[/ /g" ${LOGDIR}/mail_authfail_${DATA}.log
sed -i -e 's/\]\://g' ${LOGDIR}/mail_authfail_${DATA}.log
# IPアドレスのランキングTOP10
cat ${LOGDIR}/mail_authfail_${DATA}.log | awk '{print $2}' | sort | uniq -c | sort -nr | head -10 > ${LOGDIR}/fail_top10.txt

while read LINE
do
  FAILCNT=`echo $LINE | awk '{print $1}'`
  FAILIP=`echo $LINE | awk '{print $2}'`
  CNT=`grep ${FAILIP} ${REJECTCL_FILE} | wc -l`
  if [ "$CNT" -eq 0  ] ; then
# reject_clientに追加(Fail回数50以上なら、reject_clientに記載する)
    if [ ${FAILCNT} -gt 50 ] ; then
      echo "${FAILIP}   REJECT" >> ${REJECTCL_FILE}
    fi
  fi
# IPTABLES に追加(Fail回数800以上ならiptablesに追加する)
  if [ ${FAILCNT} -gt 800 ] ; then
    /sbin/iptables -I INPUT -s ${FAILIP} -j DROP
    /etc/init.d/iptables save
  fi
done < ${LOGDIR}/fail_top10.txt

/usr/sbin/postmap ${REJECTCL_FILE}
/etc/init.d/postfix reload


# reject_clientが100行以上の場合は、10行削除
rccnt=`wc -l /etc/postfix/reject_client | awk '{print $1}'`
if [ $rccnt -gt 100 ] ; then
  sed -i -e '1,10d' ${REJECTCL_FILE}
fi

/bin/find ${LOGDIR} -mtime +90 -name "*.log" | xargs rm -f

 

スポンサーリンク