SMTP-AUTHでtelnetの認証失敗
SMTP-AUTHの認証失敗でドハマリ。
メールクライアントからはSMTP-AUTHで接続できていたが、telnetを使用して確認した時に認証失敗して一苦労。
■事象
SMTP-AUTHのPLAIN認証を確認するため、"ユーザ名\0ユーザ名\0パスワード"の形式で、BASE64エンコードする。
[root@dev ~]# perl -MMIME::Base64 -e 'print encode_base64("user01\0user01\0passwd");' dXNlcjAxAHVzZXIwMQBwYXNzd2Q=
以下の様な感じで、認証に失敗する。
[root@dev ~]# telnet localhost 25 Trying ::1... Connected to localhost. Escape character is '^]'. 220 dev.larcaim.intra ESMTP MailServer EHLO dev.larcaim.intra 250-dev.larcaim.intra 250-PIPELINING 250-SIZE 10240000 250-ETRN 250-AUTH PLAIN 250-AUTH=PLAIN 250-ENHANCEDSTATUSCODES 250-8BITMIME 250 DSN AUTH PLAIN dXNlcjAxAHVzZXIwMQBwYXNzd2Q= 535 5.7.8 Error: authentication failed:
■原因
今回の事象の原因は以下の2つ。
1.そもそも認証時の書式が間違っている。
正しくは"ユーザ名\0パスワード"。
2.BASE64エンコード時のエスケープが間違っている
NULL値をエスケープする場合に、「"」と「'」の使い方で結果が異なる。
[root@dev ~]# perl -MMIME::Base64 -e "print encode_base64('user01\0user01\0passwd');"
dXNlcjAxXDB1c2VyMDFcMHBhc3N3ZA==
[root@dev ~]# perl -MMIME::Base64 -e 'print encode_base64("user01\0user01\0passwd");'
dXNlcjAxAHVzZXIwMQBwYXNzd2Q=
■対処
"ユーザ名\0パスワード"の形式で、BASE64エンコードする。クォートの使い方を正す。
[root@dev ~]# perl -MMIME::Base64 -e "print encode_base64('user01\0passwd');" dXNlcjAxXDBwYXNzd2Q=
■調査
そもそも解決の糸口となったのは、以下のサイト。
Chiral Software, Inc. GSA IT70 Java, Android, security software developers in Los Angeles
http://chiralsoftware.com/linux-system-administration/secure-relaying-postfix-sasl-tls-dovecot.seam
このサイトではJarファイルをダウンロードすることで、Javaで簡単にBase64エンコードできる方法が記載されているが、
この方法で、生成した文字列でSMTP-AUTH認証に成功した。(使い所少ないけど、Perlでエンコードより覚えやすい)
Base64可逆なのでデコードしてみると、書式が間違っていることが判明。
さらに、PerlでBase64エンコードする場合、NULL値をエスケープすると「"」と「'」の使い方で結果が異なることがわかった。
# 「'」でエンコード [root@dev ~]# perl -MMIME::Base64 -e "print encode_base64('user01\0user01\0passwd');" dXNlcjAxXDB1c2VyMDFcMHBhc3N3ZA== # 「"」でエンコード [root@dev ~]# perl -MMIME::Base64 -e 'print encode_base64("user01\0user01\0passwd");' dXNlcjAxAHVzZXIwMQBwYXNzd2Q= # エンコードした文字列をデコードする [root@dev ~]# perl -MMIME::Base64 -e "print decode_base64('dXNlcjAxXDB1c2VyMDFcMHBhc3N3ZA==');" user01\0user01\0passwd [root@dev ~]# perl -MMIME::Base64 -e "print decode_base64('dXNlcjAxAHVzZXIwMQBwYXNzd2Q=');" user01user01passwd # NULL値(\0)がなければ、結果は変わらない。 [root@dev ~]# perl -MMIME::Base64 -e 'print encode_base64("user");' dXNlcg== [root@dev ~]# perl -MMIME::Base64 -e "print encode_base64('user');" dXNlcg==
よって、SMTP-AUTH時に、認証メカニズムでLOGINから認証している場合は、おそらくエンコード結果が変わらないので問題なかったはず。
PLAINでの書式でNULL値が入っていたため、結果が異なり困った。
ほとんどのサイトで上記設定でイケてるようなので、そもそもOpenVPS上でやってる自分の環境がおかしいのかもしれない。
Dovecot2やLDAP2.4など、アップデートされた構築は一苦労。CentOS5から6に乗り換えてるだけだけど。