CentOS6.9/CentOS7.4でメール関連のSSLログの調査および設定変更

改訂(2018/1/25): CentOS6.6からCentOS6.9およびCentOS7.4用に改訂

#はじめに
この記事の続きです。

> CentOS6.9/CentOS7.4でメール関連のSSLログの取得および調査
> http://qiita.com/qiitamatumoto/items/608b56e63eec26702caf

ログを基に 接続を抑制したいSSLプロトコルの接続テストおよび設定ファイルの変更を行なってみます。

流れとしては

-集計したログを基にopensslで接続テスト用コマンドを生成。
-dovecotやpostdixの設定変更
-openssl接続テスト用コマンドで通信が遮断される事を確認

#dovecot

前回の記事のログ集計スクリプトですが再掲すると以下のとおりです。

```
# ./cat-maillog0.sh | ./count-dovecot-tls.sh　
    459 TLSv1 with cipher AES128-SHA (128/128 bits)
   1174 TLSv1 with cipher AES256-SHA (256/256 bits)
   5940 TLSv1 with cipher DHE-RSA-AES256-SHA (256/256 bits)
   1626 TLSv1 with cipher RC4-MD5 (128/128 bits)
   1179 TLSv1.2 with cipher DHE-RSA-AES128-GCM-SHA256 (128/128 bits)
  12730 TLSv1.2 with cipher DHE-RSA-AES128-SHA (128/128 bits)
      1 TLSv1.2 with cipher RC4-SHA (128/128 bits)
```

以上のようになりました。

上記のログを基にテストでopensslコマンドで通信を行なうには次のようなコマンドになります。 「#」 の後は接続数です。

変換ルールについてはマニュアル(man openssl, man s_client)参照下さい。

```
openssl s_client -connect 127.0.0.1:110  -starttls pop3 -tls1 -cipher AES128-SHA # count=459
openssl s_client -connect 127.0.0.1:110  -starttls pop3 -tls1 -cipher AES256-SHA # count=1174
openssl s_client -connect 127.0.0.1:110  -starttls pop3 -tls1 -cipher DHE-RSA-AES256-SHA # count=5940
openssl s_client -connect 127.0.0.1:110  -starttls pop3 -tls1 -cipher RC4-MD5 # count=1626
openssl s_client -connect 127.0.0.1:110  -starttls pop3 -tls1_2 -cipher DHE-RSA-AES128-GCM-SHA256 # count=1179
openssl s_client -connect 127.0.0.1:110  -starttls pop3 -tls1_2 -cipher DHE-RSA-AES128-SHA # count=12730
openssl s_client -connect 127.0.0.1:110  -starttls pop3 -tls1_2 -cipher RC4-SHA # count=1
```

上記のopensslコマンドを一つ一つ実行して下さい。

```
openssl s_client -connect 127.0.0.1:110  -starttls pop3 -tls1 -cipher AES128-SHA
.
(色々表示される)
.
+OK Dovecot ready
```

最後にOK Dovecot readyと出たら接続成功です。入力待ちになりますのでQUITと入力して下さい。接続終了します。

```
openssl s_client -connect 127.0.0.1:110  -starttls pop3 -tls1 -cipher AES128-SHA
.
(色々表示される)
.
+OK Dovecot ready
QUIT   <-- 手入力する。
DONE
```

入力待ちにならずに接続が切られたら、指定した暗号形式での接続失敗です。

とりあえず現在は全ての接続に成功するはずですが、、成功しないならなんらかの別の問題があるかもしれません。


##dovecotの設定ファイル修正

dovecotの設定ファイルは以下になります。
>/etc/dovecot/conf.d/10-ssl.conf

SSLのcipherの設定は大体apacheと同じようです。apacheの設定などを参考に記載下さい。CentOS6.9およびCentOS7.4で確認しています。

設定例を３件挙げます。ログを精査し、身内の利用者ののメールリーダーの更新を促しつつ強めの設定に切り替えてください。

ゆるい設定。大部分のメールリーダーは対応。

```/etc/dovecot/conf.d/10-ssl.conf
ssl_protocols = !SSLv2 !SSLv3
ssl_cipher_list = HIGH:MEDIUM:!aNULL:!MD5:!SEED:!IDEA:!RC4:!3DES
```

並みの設定。!RSAを追加。

メールサーバとは別の検査ですが、SSL-LabのWebのSSLサーバ検査で2018/1/19以降TLS_RSAはWEAK診断となるようです。(REF: https://qiita.com/qiitamatumoto/items/f93286fc82ec9a0cdff7 )

```/etc/dovecot/conf.d/10-ssl.conf
ssl_protocols = !SSLv2 !SSLv3
ssl_cipher_list = HIGH:MEDIUM:!aNULL:!MD5:!SEED:!IDEA:!RC4:!3DES:!RSA
```

強めの設定。!TLSv1を追加。BEAST脆弱性に対応。

```/etc/dovecot/conf.d/10-ssl.conf
ssl_protocols = !SSLv2 !SSLv3 !TLSv1
ssl_cipher_list = HIGH:MEDIUM:!aNULL:!MD5:!SEED:!IDEA:!RC4:!3DES:!RSA
```

次に、暗号化を強制する設定もおすすめです。

```/etc/dovecot/conf.d/10-ssl.conf
# 暗号化を強制
ssl = required
```

修正後OSを再起動すると設定が反映されます。


##設定が反映されたかの確認

(ゆるめの設定では)先ほどのopenssl接続テスト例でRC4が使われている以下の２個は入力待ちにならず接続がきられると思います。

```
openssl s_client -connect 127.0.0.1:110  -starttls pop3 -tls1 -cipher RC4-MD5 # count=1846
openssl s_client -connect 127.0.0.1:110  -starttls pop3 -tls1_2 -cipher RC4-SHA # count=1
```

上記コマンドの接続がきられたら設定が成功です。

念のため、無効化を想定してない暗号化方式まで無効になってないかの確認を行なってください。

#Postfix

dovecotとほぼ同じ流れになります。

Postfixがメールを受信したときのログの集計結果。

```
# ./cat-maillog0.sh | ./count-postfix-receive-tls.sh
      3 SSLv3 with cipher DHE-RSA-AES256-SHA (256/256 bits)
      1 SSLv3 with cipher EDH-RSA-DES-CBC-SHA (56/56 bits)
      2 TLSv1 with cipher ADH-AES256-SHA (256/256 bits)
      7 TLSv1 with cipher AES128-SHA (128/128 bits)
     15 TLSv1 with cipher AES256-SHA (256/256 bits)
      6 TLSv1 with cipher DHE-RSA-AES128-SHA (128/128 bits)
    301 TLSv1 with cipher DHE-RSA-AES256-SHA (256/256 bits)
     20 TLSv1 with cipher DHE-RSA-CAMELLIA256-SHA (256/256 bits)
      7 TLSv1 with cipher EDH-RSA-DES-CBC3-SHA (128/168 bits)
      1 TLSv1 with cipher RC4-MD5 (128/128 bits)
      8 TLSv1.1 with cipher DHE-RSA-AES256-SHA (256/256 bits)
   1365 TLSv1.2 with cipher ADH-AES256-GCM-SHA384 (256/256 bits)
     25 TLSv1.2 with cipher AES128-GCM-SHA256 (128/128 bits)
      1 TLSv1.2 with cipher AES256-GCM-SHA384 (256/256 bits)
      2 TLSv1.2 with cipher AES256-SHA (256/256 bits)
      3 TLSv1.2 with cipher AES256-SHA256 (256/256 bits)
    195 TLSv1.2 with cipher DHE-RSA-AES128-SHA (128/128 bits)
     76 TLSv1.2 with cipher DHE-RSA-AES256-GCM-SHA384 (256/256 bits)
      4 TLSv1.2 with cipher DHE-RSA-AES256-SHA256 (256/256 bits)
      3 TLSv1.2 with cipher RC4-SHA (128/128 bits)
```

(Postfixがメールを送信した時については今回は省略します。)

opensslのテストコマンド例。

```
openssl s_client -connect 127.0.0.1:25  -starttls smtp -ssl3 -cipher DHE-RSA-AES256-SHA # count=3
openssl s_client -connect 127.0.0.1:25  -starttls smtp -ssl3 -cipher EDH-RSA-DES-CBC-SHA # count=1
openssl s_client -connect 127.0.0.1:25  -starttls smtp -tls1 -cipher ADH-AES256-SHA # count=2
openssl s_client -connect 127.0.0.1:25  -starttls smtp -tls1 -cipher AES128-SHA # count=7
openssl s_client -connect 127.0.0.1:25  -starttls smtp -tls1 -cipher AES256-SHA # count=15
openssl s_client -connect 127.0.0.1:25  -starttls smtp -tls1 -cipher DHE-RSA-AES128-SHA # count=6
openssl s_client -connect 127.0.0.1:25  -starttls smtp -tls1 -cipher DHE-RSA-AES256-SHA # count=301
openssl s_client -connect 127.0.0.1:25  -starttls smtp -tls1 -cipher DHE-RSA-CAMELLIA256-SHA # count=20
openssl s_client -connect 127.0.0.1:25  -starttls smtp -tls1 -cipher EDH-RSA-DES-CBC3-SHA # count=7
openssl s_client -connect 127.0.0.1:25  -starttls smtp -tls1 -cipher RC4-MD5 # count=1
openssl s_client -connect 127.0.0.1:25  -starttls smtp -tls1_1 -cipher DHE-RSA-AES256-SHA # count=8
openssl s_client -connect 127.0.0.1:25  -starttls smtp -tls1_2 -cipher ADH-AES256-GCM-SHA384 # count=1365
openssl s_client -connect 127.0.0.1:25  -starttls smtp -tls1_2 -cipher AES128-GCM-SHA256 # count=25
openssl s_client -connect 127.0.0.1:25  -starttls smtp -tls1_2 -cipher AES256-GCM-SHA384 # count=1
openssl s_client -connect 127.0.0.1:25  -starttls smtp -tls1_2 -cipher AES256-SHA # count=2
openssl s_client -connect 127.0.0.1:25  -starttls smtp -tls1_2 -cipher AES256-SHA256 # count=3
openssl s_client -connect 127.0.0.1:25  -starttls smtp -tls1_2 -cipher DHE-RSA-AES128-SHA # count=195
openssl s_client -connect 127.0.0.1:25  -starttls smtp -tls1_2 -cipher DHE-RSA-AES256-GCM-SHA384 # count=76
openssl s_client -connect 127.0.0.1:25  -starttls smtp -tls1_2 -cipher DHE-RSA-AES256-SHA256 # count=4
openssl s_client -connect 127.0.0.1:25  -starttls smtp -tls1_2 -cipher RC4-SHA # count=3
```

Opensslテストコマンドでの接続時の挙動ですが、接続成功の場合は最後に「250 DSN」と表示されて入力待ちになります。QUITと入力して終了させて下さい。

(執筆メモ: 挙動が違うので除外: SSLv3 with cipher DES-CBC-SHA (56/56 bits))

```
openssl s_client -connect 127.0.0.1:25  -starttls smtp -ssl3 -cipher DES-CBC-SHA
.
(色々表示される)
.
250 DSN
QUIT   <-- 手入力する。
DONE
```

とりあえず現在は全ての接続に成功するはずですが、、成功しないならなんらかの別の問題があるかもしれません。

##postfixの設定ファイル修正

postfixの設定ファイルは以下になります。
>/etc/postfix/main.cf

設定例。暗号化方式については後述しています。

```/etc/postfix/main.cf
##
# SMTP AUTH(sasl)設定
smtpd_sasl_auth_enable = yes

(SASLの設定は環境依存のため省略)

#saslを使う場合は 暗号化強制がおすすめ。
smtpd_tls_auth_only = yes

# SSLのサーバ側の設定。
smtpd_tls_cert_file = (環境依存)
smtpd_tls_key_file = (環境依存)
smtpd_tls_CAfile = /etc/pki/tls/certs/ca-bundle.crt
smtpd_tls_loglevel = 1
smtpd_tls_session_cache_database = btree:/etc/postfix/smtpd_scache

##
# SSLのクライアント側の設定。 (サーバの場合はsmtp[d] です。)
smtp_tls_security_level=may
smtp_tls_loglevel = 1
smtp_tls_CAfile = /etc/pki/tls/certs/ca-bundle.crt

##
# メール送信時の設定
# STARTTLSが使えるときは使う。
#
# Postfix-2.3以降
# Ref: http://www.postfix-jp.info/trans-2.3/jhtml/postconf.5.html#smtp_tls_security_level
# Ref: http://www.postfix-jp.info/trans-2.3/jhtml/postconf.5.html#smtpd_tls_security_level
smtp_tls_security_level = may
smtpd_tls_security_level = may

##
# disalle protocol
# Ref: http://faq.nttpc.co.jp/faq/show/6857?site_domain=webarena

smtp_tls_protocols = （後述）
smtpd_tls_protocols = $smtp_tls_protocols
smtp_tls_mandatory_protocols = $smtp_tls_protocols
smtpd_tls_mandatory_protocols = $smtp_tls_protocols

# 上記
# *mandatory*無し:SSL通信が可能だが必須で無い時。
# *mandatory*有:SSL通信を強制されている時。
# Ref: http://www.postfix-jp.info/trans-2.3/jhtml/postconf.5.html#smtpd_tls_mandatory_protocols
#
# 多分上記の違いは
# Ref: http://www.postfix-jp.info/trans-2.3/jhtml/postconf.5.html#smtpd_tls_security_level
# smtpd_tls_security_level=encryptの時の話。

##
# disable ciphers
# Ref: http://www.postfix.org/postconf.5.html#smtp_tls_exclude_ciphers
smtp_tls_exclude_ciphers = (後述)
smtp_tls_mandatory_exclude_ciphers = $smtp_tls_exclude_ciphers
smtpd_tls_exclude_ciphers = $smtp_tls_exclude_ciphers
smtpd_tls_mandatory_exclude_ciphers = $smtp_tls_exclude_ciphers

# Ref: http://www.postfix.org/postconf.5.html#smtpd_tls_mandatory_ciphers
smtp_tls_ciphers =medium
smtp_tls_mandatory_ciphers = medium
smtpd_tls_ciphers = medium
smtpd_tls_mandatory_ciphers = medium
#
# 補足、上記設定、SSLの暗号化が弱い(脆弱性がある)くせにSSL暗号化を
# 強要している所に送信するとメールが送信できんので注意。
```

有効にするcipherの記載方法がapache(dovecot)と違います。詳細はマニュアルをご覧ください。

後述になっている暗号化方式の部分の例を述べます。

前述のdovecotの場合は通信相手はすべて身内の方々のメールリーダーになります。そのためコントロールが可能です。

しかしpostfixの場合は外部からのメール受信を行いますので誰が送ってくるかわからないということです。そのためSSLの通信の暗号化強度を上げ過ぎると送信元が未対応のため通信エラーになる可能性があります。少々ゆるめにせざるをえないと思います。なお多くの場合はSSLを使った送信に失敗すると暗号化無しで再送すると思います（未保障）。

ただしSMTP-AUTH(SASL)を使いメールを送信するユーザはすべて身内の方々のメールリーダーになりますので、コントロールが可能です。なのでSASLを暗号化強制する「smtpd_tls_auth_only = yes」という設定は検討に値します。

ゆるめの設定。大部分の送信元が対応している方式。また大部分のメールリーダーが対応。

```/etc/postfix/main.cf
smtp_tls_protocols = !SSLv2, !SSLv3
smtp_tls_exclude_ciphers = RC4,MD5,DES,3DES
```

並みの設定。RSAを追加。必ず身内のユーザのメールリーダーが対応済みであるかを確認してください。

```/etc/postfix/main.cf
smtp_tls_protocols = !SSLv2, !SSLv3
smtp_tls_exclude_ciphers = RC4,MD5,DES,3DES,RSA
```

強めの設定。BEAST脆弱性に対応。!TLSv1を追加。十分な検討を要します。

```/etc/postfix/main.cf
smtp_tls_protocols = !SSLv2, !SSLv3, !TLSv1
smtp_tls_exclude_ciphers = RC4,MD5,DES,3DES,RSA
```

##設定が反映されたかの確認

(ゆるめの設定では)先ほどのopenssl接続テスト例でプロトコルがSSLv3の2個と、cipherでRC4が使われている以下の２個は入力待ちにならず接続がきられると思います。

```
openssl s_client -connect 127.0.0.1:25  -starttls smtp -ssl3 -cipher DHE-RSA-AES256-SHA # count=3
openssl s_client -connect 127.0.0.1:25  -starttls smtp -ssl3 -cipher EDH-RSA-DES-CBC-SHA # count=1
openssl s_client -connect 127.0.0.1:25  -starttls smtp -tls1 -cipher RC4-MD5 # count=1
openssl s_client -connect 127.0.0.1:25  -starttls smtp -tls1_2 -cipher RC4-SHA # count=3
```

上記コマンドの接続がすぐに切られたら設定が成功です。

念のため、無効化を想定してない暗号化方式まで無効になってないかの確認を行なってください。

#opensslテストコマンドの変換スクリプト

opensslコマンドを毎回入力するのは煩雑なので、以下のスクリプトを使っています。Postfixがメールを受信する時のスクリプトは掲載していますが送信するときについては省略しています。

接続回数が１回の例については読み飛ばすようにしています。

```
::::::::::::::
./check-dovecot-tls.pl
(dovecotの集計結果をopensslコマンドに変換。)
::::::::::::::
#!/usr/bin/perl
while(<STDIN>){
    s/^\s+//;
    ($count, $protocol, $dummy, $dummy, $cipher, $bits)= split(/\s+/, $_);

    $protocol ="-ssl3" if($protocol eq "SSLv3");
    $protocol ="-tls1" if($protocol eq "TLSv1");
    $protocol ="-tls1_1" if($protocol eq "TLSv1.1");
    $protocol ="-tls1_2" if($protocol eq "TLSv1.2");

    next if($count == 1);

    $IP="127.0.0.1";
    #$IP="サーバのホスト名を記載";

    print("echo QUIT | openssl s_client -connect ${IP}:110  -starttls pop3 ${protocol} -cipher ${cipher}  >& /dev/null # count=${count}\n");
    print("RETVAL=\$?; if [ \$RETVAL = \"0\" ]; then echo -n OK; else echo -n NG; fi;\n");
    print("echo \" : ${cipher} ${protocol} count=${count}\"\n");
}

::::::::::::::
./check-postfix-receive-tls.pl
(postfix受信時の集計結果をopensslコマンドに変換。)
::::::::::::::
#!/usr/bin/perl
while(<STDIN>){
    s/^\s+//;
    ($count, $protocol, $dummy, $dummy, $cipher, $bits)= split(/\s+/, $_);

    $protocol ="-ssl3" if($protocol eq "SSLv3");
    $protocol ="-tls1" if($protocol eq "TLSv1");
    $protocol ="-tls1_1" if($protocol eq "TLSv1.1");
    $protocol ="-tls1_2" if($protocol eq "TLSv1.2");

    next if($count == 1);
    $IP="127.0.0.1";
    #$IP="サーバのホスト名を記載";

    print("echo QUIT | openssl s_client -connect ${IP}:25  -starttls smtp ${protocol} -cipher ${cipher} >& /dev/null # count=${count}\n");
    print("RETVAL=\$?; if [ \$RETVAL = \"0\" ]; then echo -n OK; else echo -n NG; fi;\n");
    print("echo \" : ${cipher} ${protocol} count=${count}\"\n");
}
```

上記をファイルに保存し、chmod +xをしてください。

実行例

```
全てのログを検査
# ./cat-maillog.sh | ./count-postfix-receive-tls.sh  | ./check-postfix-receive-tls.pl > p.sh
# ./cat-maillog.sh | ./count-dovecot-tls.sh | ./check-dovecot-tls.pl > d.sh
```

出力(p.sh, d.sh)を目視で確認の上、実行してください。OKは通信成功。NGは通信失敗です。

```
# sh p.sh
NG : DHE-RSA-AES256-SHA -ssl3 count=3
OK : ADH-AES256-SHA -tls1 count=2
OK : AES128-SHA -tls1 count=7
OK : AES256-SHA -tls1 count=15
OK : DHE-RSA-AES128-SHA -tls1 count=6
OK : DHE-RSA-AES256-SHA -tls1 count=301
OK : DHE-RSA-CAMELLIA256-SHA -tls1 count=20
NG : EDH-RSA-DES-CBC3-SHA -tls1 count=7
OK : DHE-RSA-AES256-SHA -tls1_1 count=8
OK : ADH-AES256-GCM-SHA384 -tls1_2 count=1365
OK : AES128-GCM-SHA256 -tls1_2 count=25
OK : AES256-SHA -tls1_2 count=2
OK : AES256-SHA256 -tls1_2 count=3
OK : DHE-RSA-AES128-SHA -tls1_2 count=195
OK : DHE-RSA-AES256-GCM-SHA384 -tls1_2 count=76
OK : DHE-RSA-AES256-SHA256 -tls1_2 count=4
NG : RC4-SHA -tls1_2 count=3

# sh d.sh
OK : AES128-SHA -tls1 count=459
OK : AES256-SHA -tls1 count=1174
OK : DHE-RSA-AES256-SHA -tls1 count=5940
NG : RC4-MD5 -tls1 count=1626
OK : DHE-RSA-AES128-GCM-SHA256 -tls1_2 count=1179
OK : DHE-RSA-AES128-SHA -tls1_2 count=12730

```

#最後に

設定変更後も身内のユーザからの接続がエラーになっていないか、しばらく監視してください。設定変更した旨の周知をするといつも使ってない端末などを起動して確かめる方があるていど居るようです。

本資料ではCentOS6とCentOS7で同じ設定変更例を挙げましたが、OSにより利用可能な暗号化方式が異なります。opensslで通信確認をする場合は同じOSで確認ください。

#参考文献

WebサーバのSSLの脆弱性調査はSSL-Labで手軽にできますが、メールサーバはSSL-Labで検査ができません。以下のツールで検査可能です。

> 素早くSSL/TLSのテストが行えるtestssl.sh
> https://qiita.com/nvsofts/items/87855614ff4ffeb49353

以上。