【辞書攻撃】postfixメールログから検知する仕組み

linux

サービス影響のあるものは監視サーバで簡単に検知できるのですが、予兆的なものや、悪い使い方されている状態などは監視するのが難しいことが多いと思います。

その中の最たる例がメールサービスです。

①アカウントを乗っ取るために辞書攻撃でパスワードを取得しようとする

②アカウントを不正利用してスパムメールを大量送信されている

①をされるとサーバの負荷が上がり、場合によってはサービス影響有り
②をされると運用しているサーバのIPアドレスがブラックリストに登録される可能性有り。

放置すると結構ダメージがでかいので是非とも監視は行いましょう。

今回の記事では「辞書攻撃」を検知する仕組みです。その他の検知方法はまた記事に起こします。

監視を行うための環境説明

環境説明は実運用情報の公開になるので、一部改変しています。

メール配送構成

  • クライアントからの通信:内部メールサーバで465,587で受ける
  • 外部からのメール着信:外部からはメールゲートウェイで受けて25とは個別のポートで、内部メールサーバに配送される

postfixで個別のポートをマルチインスタンスで起動させる場合は下記を参照

監視環境

  • postfix:3.3.1 ※バージョンによってログの出力結果が異なる可能性有り
  • メールログ:/var/log/maillog
  • ログ解析:メールサーバ内のシェルスクリプト
  • 監視通知:mackerelのログ監視plugin ※利用環境によって合わせればOK

メールサーバ内のシェルスクリプト

  1. 下記のシェルスクリプトを配置
  2. cronで15分間隔で実行(間隔はお好みで)
#!/bin/bash

## README
## Spam Watcher
## - 辞書攻撃検知
##   - 単一のIPにおいて、複数回の認証エラーが出ている場合に検知
##
## - logのデータ量によって「setting2」の値を変更する
##   - LOG_VOLUME : 直近データから何行分かの指定
##      - 適正値算出法:1日あたりのログ行数平均 / 100 (100≒296=24*4 ※15分間隔で実施のため)
##   - THRESHOLD : 範囲内で同一IPからのアクセス数

## setting1
MAIL_LOG=/var/log/maillog
DIR=/usr/local/tool/spamwatcher/
TMP_FILE=dictionary_atack_log.tmp
LST_FILE=dictionary_atack_log.iplist
RESULT_FILE=dictionary_atack_log.result

## setting2
LOG_VOLUME=10000
THRESHOLD=30

## 前回実行時のファイルを空に
cp /dev/null $DIR$TMP_FILE
cp /dev/null $DIR$LST_FILE
cp /dev/null $DIR$RESULT_FILE

## 認証エラーの一覧抽出
tail -$LOG_VOLUME $MAIL_LOG | grep -i "authentication failed" > $DIR$TMP_FILE

## 閾値overの認証エラーがあれば書き出し
cat $DIR$TMP_FILE | awk -F " " '{print $7}' | sort | uniq -c | sort -r > $DIR$LST_FILE
cat $DIR$LST_FILE | while read line
do
   count=`echo $line | awk -F " " '{print $1}'`
   if [ $count -gt $THRESHOLD ]; then
      ipcount=`echo $line | awk -F " " '{print $1}'`
      address=`echo $line | awk -F " " '{print $2}'`
      echo "$ipcount 回の不正アクセス アクセス元は $address da-flag" >> $DIR$RESULT_FILE
   fi
done

実行すると下記のようなファイルが出来上がります。

Aug 24 22:33:05 mailsv postfix-587/smtpd[8073]: warning: ec2-54-202-203-147.us-west-2.compute.amazonaws.com[54.202.203.147]: SASL PLAIN authentication failed:
Aug 24 22:33:05 mailsv postfix-587/smtpd[7296]: warning: 14-133-163-121.area5a.commufa.jp[14.133.163.121]: SASL PLAIN authentication failed: Connection lost to authentication server
Aug 24 22:33:06 mailsv postfix-587/smtpd[5001]: warning: unknown[193.56.29.222]: SASL LOGIN authentication failed: UGFzc3dvcmQ6
    148 unknown[220.76.91.130]:
     73 unknown[185.176.220.233]:
     46 14-133-163-121.area5a.commufa.jp[14.133.163.121]:
148 回の不正アクセス アクセス元は unknown[220.76.91.130]: da-flag
73 回の不正アクセス アクセス元は unknown[185.176.220.233]: da-flag
46 回の不正アクセス アクセス元は 14-133-163-121.area5a.commufa.jp[14.133.163.121]: da-flag

本例では閾値を30回としているので、上記のような結果ファイルが生成されます。30回だと通知が多すぎるのでもっと大きい値にするのが推奨です。
「da-flag」という文字列は、mackerelのログ監視で使用するためのキーワードのため、別の文字列に変更しても良いし、無くしてもらっても問題ありません。

mackerelによる監視通知

前項で結果は得られてるので、通知の仕組みは何でもよいですが私はmackerelのログ監視pluginで通知をしていますので、参考までに。

[plugin.checks.dictionary-atack]
command = ["check-log", "--file", "/usr/local/tool/spamwatcher/dictionary_atack_log.result", "--pattern", "da-flag", "--return"]

mackerelのログ監視の場合、通知後、即復旧になりますので、継続して辞書攻撃が発生していると15分毎(cron次第)に毎回通知が飛ぶことになります。

検知後の対応

運用次第だとは思いますが、うちでは、状況(サーバへの高負荷が発生など)を確認し、IPレベルでブロックなどの対応を行ったりもしています。

ただ、いたちごっこにもなるので、自動で制御してくれるセキュリティ機器とか入れて手運用無くしたいなと思う今日この頃。

コメント