openssl s_client で SMTP STARTTLS と SMTP AUTH を動作確認する

概要: openssl s_client コマンドについて

openssl の s_client サブコマンドで、TLS 接続の手動確認をすることが可能だ。例えば、HTTPS の確認は以下のように実行できる。

$ openssl s_client -connect www.example.com:443
(中略)
GET / HTTP/1.0(Enter)
Host: www.example.com(Enter2回押す)

さらに、最初は平文接続して、アプリケーションプロトコル上の STARTTLS コマンドで TLS 状態に入りたい場合もある。SMTP、IMAP、LDAP、FTP などの STARTTLS が相当する。これも s_client サブコマンドの -starttls オプションで実現できる。

SMTP の場合、以下のコマンドで接続可能だ。

$ openssl s_client -connect mail.example.com:587 -starttls smtp

しかし、RCPT TO: を大文字で打った瞬間に、RENEGOTIATING という表示とともに先へ進めなくなってしまう。

$ openssl s_client -connect mail.example.com:587 -starttls smtp
CONNECTED(00000003)
depth=2 C = JP, O = "SECOM Trust Systems CO.,LTD.", OU = Security Communication RootCA2
verify return:1
depth=1 C = JP, L = Academe, O = National Institute of Informatics, CN = NII Open Domain CA - G4
verify return:1
depth=0 C = JP, L = Academe, O = Example, OU = Example Dept, CN = mail.example.com
verify return:1
(中略)
250 DSN
EHLO mail.example.com
250-mail.example.com
250-PIPELINING
250-SIZE 52428800
250-ETRN
250-AUTH PLAIN LOGIN
250-AUTH=PLAIN LOGIN
250-ENHANCEDSTATUSCODES
250-8BITMIME
250 DSN
MAIL FROM: test@example.com
250 2.1.0 Ok
RCPT TO: test@example.jp
RENEGOTIATING
depth=2 C = JP, O = "SECOM Trust Systems CO.,LTD.", OU = Security Communication RootCA2
verify return:1
depth=1 C = JP, L = Academe, O = National Institute of Informatics, CN = NII Open Domain CA - G4
verify return:1
depth=0 C = JP, L = Academe, O = Example, OU = Example Dept, CN = mail.example.com
verify return:1

標準入力の一文字目が大文字の「R」になっていると、openssl s_client の TLS 再ネゴシエーションコマンドとして解釈されてしまうためである。

再ネゴシエーションを回避するには、先頭の r を小文字で打つか、openssl s_client のオプションとして -ign_eof または -quiet を追加する。

$ openssl s_client -quiet -connect mail.example.com:587 -starttls smtp

さらに、SMTP AUTH のテストも組み込んでみる。

実行例1: AUTH PLAIN

SMTP AUTH の PLAIN コマンドで必要な文字列は、「ユーザ名\0ユーザ名\0パスワード」(\0はヌル文字)という合成文字列を BASE64 エンコードしたものである。あらかじめ文字列を作っておく。

$ printf 'username\0username\0password' | base64
dXNlcm5hbWUAdXNlcm5hbWUAcGFzc3dvcmQ=

さきほどのエンコード文字列を AUTH PLAIN の引数として与える。

$ openssl s_client -quiet -connect mail.example.com:587 -starttls smtp
depth=2 C = JP, O = "SECOM Trust Systems CO.,LTD.", OU = Security Communication RootCA2
verify return:1
depth=1 C = JP, L = Academe, O = National Institute of Informatics, CN = NII Open Domain CA - G4
verify return:1
depth=0 C = JP, L = Academe, O = Example, OU = Example Dept, CN = mail.example.com
verify return:1
250 DSN
EHLO mail.example.com
250-mail.example.com
250-PIPELINING
250-SIZE 10485760
250-ETRN
250-AUTH PLAIN LOGIN
250-AUTH=PLAIN LOGIN
250-ENHANCEDSTATUSCODES
250-8BITMIME
250 DSN
AUTH PLAIN dXNlcm5hbWUAdXNlcm5hbWUAcGFzc3dvcmQ=
235 2.7.0 Authentication successful ←認証成功
MAIL FROM: test@example.com
250 2.1.0 Ok
RCPT TO: test@example.jp
250 2.1.5 Ok ←メールリレー成功
QUIT
221 2.0.0 Bye

実行例2: AUTH LOGIN

AUTH LOGIN コマンドでは、ユーザ名とパスワードをそれぞれ BASE64 エンコードした文字列が必要になる。

$ printf "username" | base64
dXNlcm5hbWU=
$ printf "password" | base64
cGFzc3dvcmQ=

サーバからの 334 VXNlcm5hbWU6 に対してはユーザ名のエンコード文字列を、334 UGFzc3dvcmQ6 に対してはパスワードのエンコード文字列を入力する。

$ openssl s_client -quiet -connect mail.example.com:587 -starttls smtp
depth=2 C = JP, O = "SECOM Trust Systems CO.,LTD.", OU = Security Communication RootCA2
verify return:1
depth=1 C = JP, L = Academe, O = National Institute of Informatics, CN = NII Open Domain CA - G4
verify return:1
depth=0 C = JP, L = Academe, O = Example, OU = Example Dept, CN = mail.example.com
verify return:1
250 DSN
EHLO mail.example.com
250-mail.example.com
250-PIPELINING
250-SIZE 10485760
250-ETRN
250-AUTH PLAIN LOGIN
250-AUTH=PLAIN LOGIN
250-ENHANCEDSTATUSCODES
250-8BITMIME
250 DSN
AUTH LOGIN
334 VXNlcm5hbWU6
dXNlcm5hbWU=
334 UGFzc3dvcmQ6
cGFzc3dvcmQ=
235 2.7.0 Authentication successful ←認証成功
MAIL FROM: test@example.com
250 2.1.0 Ok
RCPT TO: test@example.jp
250 2.1.5 Ok ←メールリレー成功
QUIT
221 2.0.0 Bye

参考URL: