【不正ログイン】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でのログインか (0だと1以上となり全件ヒット)

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

## setting2
LOG_VOLUME=30000
THRESHOLD=1

## setting3 : gmailなど、外部webmailからのログイン関連を除外する場合に使用
EXCLUSION=(
  .google.com
)

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

## 認証済の一覧抽出
tail -$LOG_VOLUME $MAIL_LOG | grep -i "sasl_username" > $DIR$TMP_FILE

## 一覧から除外
for delobject in ${EXCLUSION[@]}
do
   sed -i "/$delobject/d" $DIR$TMP_FILE
done

## 複数のIPから認証しているかの一覧抽出
cat $DIR$TMP_FILE | awk -F " " '{print $7 " " $9}' | sed -e 's/sasl_username=//g' | sort | uniq > $DIR$LST_FILE

## 複数IPからの認証になっているかユーザー単位でカウント抽出
cat $DIR$LST_FILE | awk -F " " '{print $2}' | sort | uniq -c | sort -r > $DIR$USR_FILE

## 閾値overの複数IPからの認証があればmackerel用ファイルに書き出し
cat $DIR$USR_FILE | while read line
do
   count=`echo $line | awk -F " " '{print $1}'`
   if [ $count -gt $THRESHOLD ]; then
      ipcount=`echo $line | awk -F " " '{print $1}'`
      user=`echo $line | awk -F " " '{print $2}'`
      echo "$ipcount 種類のIPからアクセス ユーザー名は $user ddos-flag" >> $DIR$RESULT_FILE
   fi
done

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

Aug 24 22:23:38 mailsv postfix-587/smtpd[7823]: 4E42547DF91: client=unknown[175.158.119.182], sasl_method=PLAIN, sasl_username=piteki111
Aug 24 22:29:22 mailsv postfix-587/smtpd[7392]: 2EC0847DF91: client=unknown[197.184.166.157], sasl_method=LOGIN, sasl_username=hogeuser
Aug 24 22:29:25 mailsv postfix-587/smtpd[7392]: 2EC0847DF91: client=unknown[197.184.166.156], sasl_method=LOGIN, sasl_username=hogeuser
client=unknown[175.158.119.182], piteki111
client=unknown[197.184.166.157], hogeuser
      2 hogeuser
      1 piteki111
2 種類のIPからアクセス ユーザー名は hogeuser ddos-flag

本例では閾値を1としているので、範囲時間内に2種類以上のIPからアクセスがあった場合に上記のような結果ファイルが生成されます。閾値1だと誤検知が多すぎるのでもう少し大きい値にするのが推奨です。ざっと運用した感じでは、4ぐらいが理想です。

また、setting3ですが、外部のwebmail(特にgmailなど)にログイン情報を追加して利用されているケースでは、複数のIPからログインされてしまいますので、異常がないIPやクライアント名は除外したほうがよいです。

「ddos-flag」という文字列は、mackerelのログ監視で使用するためのキーワードのため、別の文字列に変更しても良いし、無くしてもらっても問題ありません。

mackerelによる監視通知

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

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

mackerelのログ監視の場合、通知後、即復旧になりますので、継続して複数のIPから認証されてメール送信されていると15分毎(cron次第)に毎回通知が飛ぶことになります。

検知後の対応

ツールを作りこめば可能だとは思いますが、誤検知などもあり得るので、手動運用にならざるを得ないのですが、該当アカウントのパスワード変更しかありません。複数のIPからログインされてる時点でIPをFW(ファイアウォール)でブロックしたとしても、いたちごっこになってしまいます。

誤検知0運用まで品質を高めれたら、パスワード変更も自動化したいと思う今日この頃。

コメント