STARTTLS を openssl で試す

「Azure にインストールした postfix に SMTP-Auth の設定を追加する」
https://qiita.com/nanbuwks/items/85e63ec9b129138bfd18

では、TELNET で SMTP-Auth のテストをしましたが、 AUTH PLAIN で送るフレーズは `ユーザ名\0ユーザ名\0パスワード` を BASE64 エンコードしたものなので、経路盗聴を行うと簡単にユーザ名、パスワードが入手できてしまいます。

これを防ぐためには暗号接続を用いることをまず考えることができますが、postfix では 自前で経路暗号を行うことについては否定的な立場を取っています。
「Postfix TLSサポート」
https://www.postfix-jp.info/trans-2.3/jhtml/TLS_README.html

しかしながら、Ubuntu22.04 のディストリビューションパッケージでは以下のように TLS 関係が設定されていて、

```
smtp_tls_CApath = /etc/ssl/certs
smtp_tls_security_level = may
smtp_tls_session_cache_database = btree:${data_directory}/smtp_scache
smtpd_tls_cert_file = /etc/ssl/certs/ssl-cert-snakeoil.pem
smtpd_tls_key_file = /etc/ssl/private/ssl-cert-snakeoil.key
smtpd_tls_security_level = may

```


> smtpd_tls_security_level = may

ということで有効になっています。

先程の記事での EHLO 応答においても、

> 250-STARTTLS

が含まれており、今までの設定で STARTTLS がつかえるみたいです。
今回は、STARTTLS の応答をテストしてみます。


# 環境

- Ubuntu 22.04
- Postfix
「Azure で postfix のインストールを試す」
https://qiita.com/nanbuwks/items/38b54aaf8c3ecfdbb3cc
「Azure/Ubuntu にインストールした postfix / dovecot を Maildir 対応にする」
https://qiita.com/nanbuwks/items/10e6dd1224ce0c3f76af

で設定したものです。


# telnet で STARTTLS コマンドエラー
```

$ telnet localhost 25
Trying 127.0.0.1...
Connected to localhost.
Escape character is '^]'.
220 test-azure-gen.ugx1l5hl2pbu5oitg4vrqao0jd.phxx.internal.cloudapp.net ESMTP Postfix (Ubuntu)
EHLO
501 Syntax: EHLO hostname
EHLO localhost
250-test-azure-gen.ugx1l5hl2pbu5oitg4vrqao0jd.phxx.internal.cloudapp.net
250-PIPELINING
250-SIZE 10240000
250-VRFY
250-ETRN
250-STARTTLS
250-AUTH PLAIN
250-AUTH=PLAIN
250-ENHANCEDSTATUSCODES
250-8BITMIME
250-DSN
250-SMTPUTF8
250 CHUNKING
```
ここで、
```
STARTTLS
```
と打ち込むと
```
220 2.0.0 Ready to start TLS
```
となります。しかしながらその後の

```
AHTH PLAIN
```
と打ち込むと
```
Connection closed by foreign host.
```
のようにクローズしてしまいます。

# openssl で STARTTLS


「Azre + Ubuntu 環境での dovecot に SSL/TLS で POP3 アクセスする」
https://qiita.com/nanbuwks/items/46dfe58d90f7b19d891f

で行ったように `-quiet` オプションをつけて接続してみます。

```
$ openssl s_client -connect localhost:25 -quiet --starttls smtp
```

:::note warn
2023/09/07 追記


`--starttls smtp` の記述が抜けてました。修正しました。
:::



接続すると、以下のようにずらっと返答が表示されます。

```
CONNECTED(00000003)
Can't use SSL_get_servername
depth=0 CN = test-azure-gen
verify error:num=18:self signed certificate
verify return:1
.
.
.
    Start Time: 1689141539
    Timeout   : 7200 (sec)
    Verify return code: 18 (self signed certificate)
    Extended master secret: no
    Max Early Data: 0
---
read R BLOCK
```

EHLO コマンドを送ってみます。
```
EHLO localhost
250-test-azure-gen.ugx1l5hl2pbu5oitg4vrqao0jd.phxx.internal.cloudapp.net
250-PIPELINING
250-SIZE 10240000
250-VRFY
250-ETRN
250-AUTH PLAIN
250-AUTH=PLAIN
250-ENHANCEDSTATUSCODES
250-8BITMIME
250-DSN
250-SMTPUTF8
250 CHUNKING
```

おや? STARTTLS がありませんね。
試しに STARTTLS を送ると・・・
```
STARTTLS
554 5.5.1 Error: TLS already active
```

既にTLS接続になっているとエラーが出ます。
調べてみると、接続した時点でEHLOとSTARTTLSがなされているということでした。

改めて接続し直して、そのまま AUTH コマンドを送ってみます。

```
AUTH PLAIN
334 
ZXhhbXBsZQBleGFtcGxlAGhvZ2Vob2dlZnVnYWZ1Z2E=
235 2.7.0 Authentication successful
```

問題なく認証できたようです。
ここで送ったフレーズがわかってしまえば、

```

ZXhhbXBsZQBleGFtcGxlAGhvZ2Vob2dlZnVnYWZ1Z2E=
```
は簡単に以下のように復元できます。

```
example\0example\0hogehogefugafuga
```

しかしながら TLS 上でやりとりを行っていることで、経路盗聴を行ったとしてもフレーズ自体を解読することができず、それで安全を担保しています。