CRAM-MD5でSMTP認証テスト

CRAM-MD5でSMTP認証のテストを実施しました。
理由は、成功時のログがどういったものなのかを把握できていなかったのもあり、実際に接続してメールを送信してみました。
ただ、CRAM-MD5で認証にパスするには、サーバから送られたコードを利用してユーザIDやパスワードなどを使って新たにコードを生成して送信しなければなりません。このコードで認証判定されるので間違っていると当然認証にパスしません。

コード生成用のスクリプト(cram-md5.sh)を利用します。

#!/bin/bash

if [ $# -ne 3 ]; then
  echo "構文:"
  echo "cram-md5.sh [ユーザID] [パスワード] [Base64コード]"
  exit 1
fi
USERID=${1:?}
PASSWD=${2:?}
WORD=${3:?}

function hmac-md5() {
  CODE=${1:?}
  KEY=${2:?}
        echo "$CODE" | base64 -d  | openssl dgst -md5 -hmac "$KEY" | awk '{print $2}'
}

echo
echo "出力:"
echo "以下のコードを貼り付けてください"

echo
echo  "${USERID}" $(hmac-md5 "${WORD}" "${PASSWD}") | base64 | tr -d '\n'
echo
echo
exit 0

※ユーザIDはメールサーバのユーザIDです。
※パスワードはメールサーバのログインパスワードです。
※Base64コードはSMTPサーバから送られてくるタイムスタンプとサーバー名をBase64エンコードしたコードです。

テストにはopensslコマンドを使用します。
実行はSMTPサーバのローカルから行いました。

$ openssl s_client -starttls smtp -connect mail.phoenixknight.jp:587 -crlf
CONNECTED(00000003)
depth=2 O = Digital Signature Trust Co., CN = DST Root CA X3
verify return:1
depth=1 C = US, O = Let's Encrypt, CN = Let's Encrypt Authority X3
verify return:1
depth=0 CN = phoenixknight.jp
verify return:1
---
Certificate chain
 0 s:/CN=phoenixknight.jp
   i:/C=US/O=Let's Encrypt/CN=Let's Encrypt Authority X3
 1 s:/C=US/O=Let's Encrypt/CN=Let's Encrypt Authority X3
   i:/O=Digital Signature Trust Co./CN=DST Root CA X3
---
以下省略


    Start Time: 1537151340
    Timeout   : 300 (sec)
    Verify return code: 0 (ok)
---
250 8BITMIME

以下を入力します。

ehlo localhost

次の応答があります。

250-ik1-331-25649.vs.sakura.ne.jp
250-PIPELINING
250-SIZE 10240000
250-ETRN
250-ENHANCEDSTATUSCODES
250 8BITMIME

※DSNを無効にしているの表示されていませんが通常はDSNも表示されます。
以下を入力します。

auth cram-md5

次の応答があります。

334 PDA3Nzg3NTMyMDgxMzMwMDAuMTUzNzE1MTM2NEBpazEtMzMxLTI1NjQ5LnZzLnNha3VyYS5uZS5qcD4=

334の後の英数字が次のコード生成に必要なBase64コードです。(毎回異なります)

例えばこれをBase64でデコードするともとの文字列に変換できます。

$ echo "PDA3Nzg3NTMyMDgxMzMwMDAuMTUzNzE1MTM2NEBpazEtMzMxLTI1NjQ5LnZzLnNha3VyYS5uZS5qcD4=" | base64 -d
<0778753208133000.1537151364@ik1-331-25649.vs.sakura.ne.jp>

※@マークの前は時間を表す数値です。
※@マークの後ろはサーバ名です。

CRAM-MD5認証に必要なコードをcram-md5.shを実行して生成します。

例)ここでは、以下の情報で生成しました。

ユーザID:centos7@phoenixknight.jp
パスワード:zaq12345
Base64コード:PDA3Nzg3NTMyMDgxMzMwMDAuMTUzNzE1MTM2NEBpazEtMzMxLTI1NjQ5LnZzLnNha3VyYS5uZS5qcD4=


※これは説明用で実際には存在していませんのでこのまま利用しないでください。(すべて自己責任でお願いします)

$ ./cram-md5.sh centos7@phoenixknight.jp zaq12345 PDA3Nzg3NTMyMDgxMzMwMDAuMTUzNzE1MTM2NEBpazEtMzMxLTI1NjQ5LnZzLnNha3VyYS5uZS5qcD4=


出力:
以下のコードを貼り付けてください

Y2VudG9zN0BwaG9lbml4a25pZ2h0LmpwIDFjODg0OGZjZjczNGRkNTI4YjkxOWVhNzUzYzEzNzRiCg==

この出力結果を入力します。

250 8BITMIME
ehlo localhost
250-ik1-331-25649.vs.sakura.ne.jp
250-PIPELINING
250-SIZE 10240000
250-ETRN
250-ENHANCEDSTATUSCODES
250 8BITMIME
auth cram-md5
334 PDA3Nzg3NTMyMDgxMzMwMDAuMTUzNzE1MTM2NEBpazEtMzMxLTI1NjQ5LnZzLnNha3VyYS5uZS5qcD4=
Y2VudG9zN0BwaG9lbml4a25pZ2h0LmpwIDFjODg0OGZjZjczNGRkNTI4YjkxOWVhNzUzYzEzNzRiCg==

次の応答があります。

235 2.7.0 Authentication successful

この段階ではまだメールログファイルにはログイン成功が書き込まれません。
ここで「quit」すれば終了できますが、メール送信も行うのであれば以下を行います。

※メール送信元は「centos7@phoenixknight.jp」宛先は「test@example.com」でどちらも実在しないアドレスですので、実行時には実際のメールアドレスに置き換えてください。

mail from:<centos7@phoenixknight.jp>
250 2.1.0 Ok
rcpt to:<test@example.com>
250 2.1.5 Ok
data
354 End data with <CR><LF>.<CR><LF>
subject:CRAM-MD5 test
to:test@example.com
from:centos7@phoenixknight.jp
CRAM-MD5 テストに成功しました
.
250 2.0.0 Ok: queued as A4FCE204384E
quit
221 2.0.0 Bye
closed

これまでの作業のメールログファイルの内容です。
キューID=A4FCE204384Eで処理されています。

Sep 17 12:48:22 ik1-331-25649 postfix/smtpd[7771]: connect from ik1-331-25649.vs.sakura.ne.jp[153.126.190.153]
Sep 17 12:48:22 ik1-331-25649 postfix/smtpd[7771]: Anonymous TLS connection established from ik1-331-25649.vs.sakura.ne.jp[153.126.190.153]: TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)
Sep 17 12:49:26 ik1-331-25649 postfix/smtpd[7771]: A4FCE204384E: client=ik1-331-25649.vs.sakura.ne.jp[153.126.190.153], sasl_method=cram-md5, sasl_username=centos7@phoenixknight.jp
Sep 17 12:50:26 ik1-331-25649 postfix/cleanup[7862]: A4FCE204384E: message-id=<20180917034926.A4FCE204384E@ik1-331-25649.vs.sakura.ne.jp>
Sep 17 12:50:26 ik1-331-25649 milter-manager[7282]: [statistics] [milter][header][add](23635): <DKIM-Filter>=< OpenDKIM Filter v2.11.0 ik1-331-25649.vs.sakura.ne.jp A4FCE204384E>: opendkim
Sep 17 12:50:26 ik1-331-25649 opendkim[7019]: A4FCE204384E: no signature data
Sep 17 12:50:27 ik1-331-25649 milter-manager[7282]: [statistics] [session][header][add](23631): <DKIM-Filter>=< OpenDKIM Filter v2.11.0 ik1-331-25649.vs.sakura.ne.jp A4FCE204384E>
Sep 17 12:50:27 ik1-331-25649 postfix/qmgr[4377]: A4FCE204384E: from=<centos7@phoenixknight.jp>, size=566, nrcpt=1 (queue active)
Sep 17 12:50:27 ik1-331-25649 postfix/smtp[7916]: A4FCE204384E: to=<test@example.com>, relay=mfgw4.ocn.ad.jp[153.153.63.103]:25, delay=76, delays=75/0.36/0.17/0.21, dsn=2.0.0, status=sent (250 2.0.0 Ok: queued as C5B4BD40283)
Sep 17 12:50:27 ik1-331-25649 postfix/qmgr[4377]: A4FCE204384E: removed
Sep 17 12:51:13 ik1-331-25649 postfix/smtpd[7771]: disconnect from ik1-331-25649.vs.sakura.ne.jp[153.126.190.153]
Sep 17 12:51:13 ik1-331-25649 milter-manager[7282]: [statistics] [session][end][unknown][abort][170.763](23631)
Sep 17 12:51:13 ik1-331-25649 milter-manager[7282]: [statistics] [sessions][finished] 4729(+1) 0

以下が受信したメールのソースコードです。
※宛先がtest@example.comになっていますが、実際には実在するocnメールアドレスへ送信しています。

From - Mon Sep 17 12:51:16 2018
X-Account-Key: account1
X-UIDL: 209221.GDkywh9cmAXeQUxFBHho2NmIiTA=
X-Mozilla-Status: 0001
X-Mozilla-Status2: 00000000
X-Mozilla-Keys:                                                                                 
Return-Path: centos7@phoenixknight.jp
Received: from md-lpx-nw005.ocn.ad.jp (LHLO md-lpx-nw005) (153.138.217.18)
 by mzcstore232.ocn.ad.jp with LMTP; Mon, 17 Sep 2018 12:50:28 +0900 (JST)
Received: from md-mta-cb003.ocn.ad.jp ([153.138.211.71])
	by md-lpx-nw005 with LMTP id SLMRJYQkn1szRQAA2u8eSg
	; Mon, 17 Sep 2018 12:50:28 +0900
Received: from mf-omf-ucb041c1 (mf-omf-ucb041c1.ocn.ad.jp [153.153.66.175])
	by md-mta-cb003.ocn.ad.jp (Postfix) with ESMTP id 8D03078001E0E
	for <test@example.com>; Mon, 17 Sep 2018 12:50:28 +0900 (JST)
Received: from mfgw702.ocn.ad.jp ([153.153.63.103])
	by mf-omf-ucb041c1 with ESMTP
	id 1kYOgRLnhgiro1kYOgX3Gl; Mon, 17 Sep 2018 12:50:28 +0900
X-OCN-SPAM-CHECK: 0.00%
X-OCN-ANALYSIS: v=2.2 cv=Foh1xyjq c=1 sm=1 tr=0
 a=hcIgXx65Y2ZndAuFGt4Xtg==:117 a=sAqO2iPG/dFDfo7Tkx4bYw==:17 a=JBFolyDoGHsA:10
Received-SPF: pass (mf-ofc-ucb070: domain designate client-ip as permitted sender) client-ip=153.126.190.153; envelope-from=<centos7@phoenixknight.jp>; helo=ik1-331-25649.vs.sakura.ne.jp;
Authentication-Results: mf-ofc-ucb070; spf=pass smtp.mailfrom=centos7@phoenixknight.jp
Received: from ik1-331-25649.vs.sakura.ne.jp (ik1-331-25649.vs.sakura.ne.jp [153.126.190.153])
	by mfgw702.ocn.ad.jp (Postfix) with ESMTP id C5B4BD40283
	for <test@example.com>; Mon, 17 Sep 2018 12:50:27 +0900 (JST)
Received: from localhost (ik1-331-25649.vs.sakura.ne.jp [153.126.190.153])
	(using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits))
	(No client certificate requested)
	by ik1-331-25649.vs.sakura.ne.jp (Postfix) with ESMTPSA id A4FCE204384E
	for <test@example.com>; Mon, 17 Sep 2018 12:49:12 +0900 (JST)
DKIM-Filter: OpenDKIM Filter v2.11.0 ik1-331-25649.vs.sakura.ne.jp A4FCE204384E
subject:cram-md5 test
to:test@example.com
from:centos7@phoenixknight.jp
Message-Id: <20180917034926.A4FCE204384E@ik1-331-25649.vs.sakura.ne.jp>
Date: Mon, 17 Sep 2018 12:49:12 +0900 (JST)

CRAM-MD5 テストに成功しました

以上により、SMTP認証でログイン成功すればメールログには「sasl_username=メールユーザID」の行が記載されることが確認できました。
やっぱり、先日の件はパスワードを盗まれてリモートログインされていたということが確実になりました。
対策はできているのでもう問題はないはずです。

ディストリビューション

CentOS 7.x