CentOS8でサーバー構築 - 7.Postfix3.3+Dovecot2.3の暗号化設定(SSL/TLS)

以前、CentOS8でサーバー構築 - 2.Postfix+Dovecot(MTA)で、Gmail経由でメールを送受信できるところまで設定しました。
今回は、暗号化してSMTPS Port465、POP3S Port995でメールの送受信をできるようにします。
Portはルーター、firewalld、パケットフィルタリング、などは開けておくこと。
使用するホスト名:mail.kowloonet.net

Let's Encryptで証明書取得

無料でアラートが出ないSSLを使えるようになったなんて、便利になったもんです。。
ここでは Let's Encrypt でTLS暗号化します。
certbotをdnfでインストールできるか確認
# dnf info certbot
Last metadata expiration check: 0:03:12 ago on Sun 14 Jun 2020 10:52:38 AM JST.
Available Packages
Name         : certbot
Version      : 1.4.0
Release      : 1.el8
Architecture : noarch
Size         : 46 k
Source       : certbot-1.4.0-1.el8.src.rpm
Repository   : epel
Summary      : A free, automated certificate authority client
URL          : https://pypi.python.org/pypi/certbot
License      : ASL 2.0
Description  : certbot is a free, automated certificate authority that aims
             : to lower the barriers to entry for encrypting all HTTP traffic on the
             : internet.
epelリポジトリをインストールしていない場合はインストールする。
epelリポジトリ追加・インストール
# dnf -y install epel-release
certbotインストール
# dnf install cerbot
certbot用に使用するホスト名 mail.kowloonet.netで外部から接続できるようにする。
certbot実行時に使用するホスト名がhttpやhttpsで正しく接続できるかを確認しに行きます。
使用するホスト名はDNSレコードに追加しておくこと。
Webサーバーを公開していない場合のやり方は割愛します。
Apacheバーチャルホスト設定
# vi /etc/httpd/conf.d/virtualhost-kowloonet.net.conf
<VirtualHost *:80>
  ServerName kowloonet.net
  ServerAlias mail.kowloonet.net
  DocumentRoot /var/www/html
</VirtualHost>
Apache再起動
# systemctl restart httpd
certbotで証明書作成
# certbot certonly --webroot -w /var/www/html/ -m メールアドレス -d mail.kowloonet.net --agree-tos

Saving debug log to /var/log/letsencrypt/letsencrypt.log
Plugins selected: Authenticator webroot, Installer None

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Would you be willing to share your email address with the Electronic Frontier
Foundation, a founding partner of the Let's Encrypt project and the non-profit
organization that develops Certbot? We'd like to send you email about our work
encrypting the web, EFF news, campaigns, and ways to support digital freedom.
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
(Y)es/(N)o: N ←初回だけ聞かれる

Saving debug log to /var/log/letsencrypt/letsencrypt.log
Plugins selected: Authenticator webroot, Installer None
Obtaining a new certificate
Performing the following challenges:
http-01 challenge for mail.kowloonet.net
Using the webroot path /var/www/html for all unmatched domains.
Waiting for verification...
Cleaning up challenges

IMPORTANT NOTES:
 - Congratulations! Your certificate and chain have been saved at:
   /etc/letsencrypt/live/mail.kowloonet.net/fullchain.pem
   Your key file has been saved at:
   /etc/letsencrypt/live/mail.kowloonet.net/privkey.pem
   Your cert will expire on 2020-09-12. To obtain a new or tweaked
   version of this certificate in the future, simply run certbot
   again. To non-interactively renew *all* of your certificates, run
   "certbot renew"
 - If you like Certbot, please consider supporting our work by:

   Donating to ISRG / Let's Encrypt:   https://letsencrypt.org/donate
   Donating to EFF:                    https://eff.org/donate-le

Postfixの設定

Postfixのバージョンは 3.3.1でした。
Postfixのバージョン確認
# postconf | grep mail_version
mail_version = 3.3.1
milter_macro_v = $mail_name $mail_version
main.cf設定
# vi /etc/postfix/main.cf
# the server certificate first, then the issuing CA(s) (bottom-up order).
#
#smtpd_tls_cert_file = /etc/pki/tls/certs/postfix.pem
smtpd_tls_cert_file = /etc/letsencrypt/live/mail.kowloonet.net/fullchain.pem
・
・
#smtpd_tls_key_file = /etc/pki/tls/private/postfix.key
smtpd_tls_key_file = /etc/letsencrypt/live/mail.kowloonet.net/privkey.pem

# Announce STARTTLS support to remote SMTP clients, but do not require that
# clients use TLS encryption (opportunistic TLS inbound).
#
smtpd_tls_security_level = may
・
・
# Use TLS if this is supported by the remote SMTP server, otherwise use
# plaintext (opportunistic TLS outbound).
#
smtp_tls_security_level = may

tls_high_cipherlist = HIGH:!aNULL:!eNULL:!SSLv2:!SSLv3:!kRSA:!kDHd:!EXPORT:!ADH:!DSS:!PSK:!SRP:!RC4:!MD5:!DES:!3DES:!EXP:!SEED:!IDEA:!3DES:!LOW@STRENGTH
smtp_tls_ciphers = high
smtpd_tls_ciphers = high
smtpd_tls_mandatory_ciphers = high

smtpd_tls_mandatory_protocols=!SSLv2,!SSLv3
smtp_tls_mandatory_protocols=!SSLv2,!SSLv3
smtpd_tls_protocols=!SSLv2,!SSLv3
smtp_tls_protocols=!SSLv2,!SSLv3
master.cfの設定
# vi /etc/postfix/master.cf
# ======================================
smtp      inet  n       -       n       -       -       smtpd
#smtp      inet  n       -       n       -       1       postscreen
#smtpd     pass  -       -       n       -       -       smtpd
#dnsblog   unix  -       -       n       -       0       dnsblog
#tlsproxy  unix  -       -       n       -       0       tlsproxy
#submission inet n       -       n       -       -       smtpd
#  -o syslog_name=postfix/submission
#  -o smtpd_tls_security_level=encrypt
#  -o smtpd_sasl_auth_enable=yes
#  -o smtpd_tls_auth_only=yes
#  -o smtpd_reject_unlisted_recipient=no
#  -o smtpd_client_restrictions=$mua_client_restrictions
#  -o smtpd_helo_restrictions=$mua_helo_restrictions
#  -o smtpd_sender_restrictions=$mua_sender_restrictions
#  -o smtpd_recipient_restrictions=
#  -o smtpd_relay_restrictions=permit_sasl_authenticated,reject
#  -o milter_macro_daemon_name=ORIGINATING
smtps     inet  n       -       n       -       -       smtpd
#  -o syslog_name=postfix/smtps
  -o smtpd_tls_wrappermode=yes
  -o smtpd_sasl_auth_enable=yes
#  -o smtpd_reject_unlisted_recipient=no
#  -o smtpd_client_restrictions=$mua_client_restrictions
#  -o smtpd_helo_restrictions=$mua_helo_restrictions
#  -o smtpd_sender_restrictions=$mua_sender_restrictions
#  -o smtpd_recipient_restrictions=
#  -o smtpd_relay_restrictions=permit_sasl_authenticated,reject
#  -o milter_macro_daemon_name=ORIGINATING
#628       inet  n       -       n       -       -       qmqpd
pickup    unix  n       -       n       60      1       pickup
cleanup   unix  n       -       n       -       0       cleanup
qmgr      unix  n       -       n       300     1       qmgr
#qmgr     unix  n       -       n       300     1       oqmgr
tlsmgr    unix  -       -       n       1000?   1       tlsmgr
Postfix再起動
# systemctl restart postfix

Dovecotの設定

アップグレードしてdovecotのバージョンが2.2から2.3に変わり、設定ファイルが結構変わり以前だったら出なかったWarningが結構出るようになり、 色々mergeするのも面倒だったので、dovecotを一旦removeして再インストールしました。
Dovecotのバージョン2.3.8で対応します。
デフォルトで ssl = required になっていましたq。
アップデートに伴いWarning出た件は下記参照。
dovecote再インストール
# dnf remove dovecot
# dnf -y install dovecot
remove後も設定ファイルは 10-ssl.conf.rpmsave などで残ります。
dovecotのバージョン確認
# dovecot --version
2.3.8 (9df20d2db)
10-mail.conf設定
# vi /etc/dovecot/conf.d/10-mail.conf
# <doc/wiki/MailLocation.txt>
#
mail_location = maildir:~/Maildir
10-auth.conf設定
# vi /etc/dovecot/conf.d/10-auth.conf
# See also ssl=required setting.
disable_plaintext_auth = no
10-ssl.confの設定
# vi /etc/dovecot/conf.d/10-ssl.conf
# SSL/TLS support: yes, no, required. 
# disable plain pop3 and imap, allowed are only pop3+TLS, pop3s, imap+TLS and imaps
# plain imap and pop3 are still allowed for local connections
ssl = required

# PEM encoded X.509 SSL/TLS certificate and private key. They're opened before
# dropping root privileges, so keep the key file unreadable by anyone but
# root. Included doc/mkcert.sh can be used to easily generate self-signed
# certificate, just make sure to update the domains in dovecot-openssl.cnf
#ssl_cert = </etc/pki/dovecot/certs/dovecot.pem
#ssl_key = </etc/pki/dovecot/private/dovecot.pem
ssl_cert = </etc/letsencrypt/live/mail.kowloonet.net/fullchain.pem
ssl_key = </etc/letsencrypt/live/mail.kowloonet.net/privkey.pem
・
・
# SSL DH parameters
# Generate new params with `openssl dhparam -out /etc/dovecot/dh.pem 4096`
# Or migrate from old ssl-parameters.dat file with the command dovecot
# gives on startup when ssl_dh is unset.
ssl_dh = </etc/dovecot/dh.pem

# Minimum SSL protocol version to use. Potentially recognized values are SSLv3,
# TLSv1, TLSv1.1, and TLSv1.2, depending on the OpenSSL version used.
ssl_min_protocol = TLSv1.2

# SSL ciphers to use, the default is:
#ssl_cipher_list = ALL:!kRSA:!SRP:!kDHd:!DSS:!aNULL:!eNULL:!EXPORT:!DES:!3DES:!MD5:!PSK:!RC4:!ADH:!LOW@STRENGTH
# To disable non-EC DH, use:
#ssl_cipher_list = ALL:!DH:!kRSA:!SRP:!kDHd:!DSS:!aNULL:!eNULL:!EXPORT:!DES:!3DES:!MD5:!PSK:!RC4:!ADH:!LOW@STRENGTH
#ssl_cipher_list = PROFILE=SYSTEM
ssl_cipher_list = HIGH:!aNULL:!eNULL:!SSLv2:!SSLv3:!kRSA:!kDHd:!EXPORT:!ADH:!DSS:!PSK:!SRP:!RC4:!MD5:!DES:!3DES:!EXP:!SEED:!IDEA:!3DES:!LOW@STRENGTH
・
・
# Prefer the server's order of ciphers over client's.
ssl_prefer_server_ciphers = yes
ssl_prefer_server_ciphers:
このディレクティブを yes に設定すると、接続先のクライアントが指定された暗号化の命令に従います。
dh.pemの作製
 OpenSSL 1.1.1c FIPS です。
# openssl dhparam 4096 -out /etc/dovecot/dh.pem
 結構時間かかります。
v2.2の古いパラメータを使いたい場合は
dd if=/var/lib/dovecot/ssl-parameters.dat bs=1 skip=88 | openssl dhparam -inform der > dh.pem
と書いてあったので、特に必要ない場合は
openssl dhparam 4096 > dh.pem
の方が良さげです。
dovecot起動設定
# systemctl start dovecot
# systemctl enable dovecot
Created symlink /etc/systemd/system/multi-user.target.wants/dovecot.service → /usr/lib/systemd/system/dovecot.service.
指定するcipherを個別に TLS_AES_256_GCM_SHA384:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-ECDSA-AES128-GCM-SHA256 など指定しても良いです。
こちらを参考にしました
4.13. TLS 設定の強化 Red Hat Enterprise Linux 7 | Red Hat Customer Portal
推奨事項を満たす暗号化スイートを一覧表示
# openssl ciphers -v 'kEECDH+aECDSA+AES:kEECDH+AES+aRSA:kEDH+aRSA+AES' | column -t
TLS_AES_256_GCM_SHA384         TLSv1.3  Kx=any   Au=any    Enc=AESGCM(256)             Mac=AEAD
TLS_CHACHA20_POLY1305_SHA256   TLSv1.3  Kx=any   Au=any    Enc=CHACHA20/POLY1305(256)  Mac=AEAD
TLS_AES_128_GCM_SHA256         TLSv1.3  Kx=any   Au=any    Enc=AESGCM(128)             Mac=AEAD
TLS_AES_128_CCM_SHA256         TLSv1.3  Kx=any   Au=any    Enc=AESCCM(128)             Mac=AEAD
ECDHE-ECDSA-AES256-GCM-SHA384  TLSv1.2  Kx=ECDH  Au=ECDSA  Enc=AESGCM(256)             Mac=AEAD
ECDHE-ECDSA-AES256-CCM8        TLSv1.2  Kx=ECDH  Au=ECDSA  Enc=AESCCM8(256)            Mac=AEAD
ECDHE-ECDSA-AES256-CCM         TLSv1.2  Kx=ECDH  Au=ECDSA  Enc=AESCCM(256)             Mac=AEAD
ECDHE-ECDSA-AES128-GCM-SHA256  TLSv1.2  Kx=ECDH  Au=ECDSA  Enc=AESGCM(128)             Mac=AEAD
ECDHE-ECDSA-AES128-CCM8        TLSv1.2  Kx=ECDH  Au=ECDSA  Enc=AESCCM8(128)            Mac=AEAD
ECDHE-ECDSA-AES128-CCM         TLSv1.2  Kx=ECDH  Au=ECDSA  Enc=AESCCM(128)             Mac=AEAD
ECDHE-ECDSA-AES256-SHA384      TLSv1.2  Kx=ECDH  Au=ECDSA  Enc=AES(256)                Mac=SHA384
ECDHE-ECDSA-AES128-SHA256      TLSv1.2  Kx=ECDH  Au=ECDSA  Enc=AES(128)                Mac=SHA256
ECDHE-ECDSA-AES256-SHA         TLSv1    Kx=ECDH  Au=ECDSA  Enc=AES(256)                Mac=SHA1
ECDHE-ECDSA-AES128-SHA         TLSv1    Kx=ECDH  Au=ECDSA  Enc=AES(128)                Mac=SHA1
ECDHE-RSA-AES256-GCM-SHA384    TLSv1.2  Kx=ECDH  Au=RSA    Enc=AESGCM(256)             Mac=AEAD
ECDHE-RSA-AES128-GCM-SHA256    TLSv1.2  Kx=ECDH  Au=RSA    Enc=AESGCM(128)             Mac=AEAD
ECDHE-RSA-AES256-SHA384        TLSv1.2  Kx=ECDH  Au=RSA    Enc=AES(256)                Mac=SHA384
ECDHE-RSA-AES128-SHA256        TLSv1.2  Kx=ECDH  Au=RSA    Enc=AES(128)                Mac=SHA256
ECDHE-RSA-AES256-SHA           TLSv1    Kx=ECDH  Au=RSA    Enc=AES(256)                Mac=SHA1
ECDHE-RSA-AES128-SHA           TLSv1    Kx=ECDH  Au=RSA    Enc=AES(128)                Mac=SHA1
DHE-RSA-AES256-GCM-SHA384      TLSv1.2  Kx=DH    Au=RSA    Enc=AESGCM(256)             Mac=AEAD
DHE-RSA-AES256-CCM8            TLSv1.2  Kx=DH    Au=RSA    Enc=AESCCM8(256)            Mac=AEAD
DHE-RSA-AES256-CCM             TLSv1.2  Kx=DH    Au=RSA    Enc=AESCCM(256)             Mac=AEAD
DHE-RSA-AES128-GCM-SHA256      TLSv1.2  Kx=DH    Au=RSA    Enc=AESGCM(128)             Mac=AEAD
DHE-RSA-AES128-CCM8            TLSv1.2  Kx=DH    Au=RSA    Enc=AESCCM8(128)            Mac=AEAD
DHE-RSA-AES128-CCM             TLSv1.2  Kx=DH    Au=RSA    Enc=AESCCM(128)             Mac=AEAD
DHE-RSA-AES256-SHA256          TLSv1.2  Kx=DH    Au=RSA    Enc=AES(256)                Mac=SHA256
DHE-RSA-AES128-SHA256          TLSv1.2  Kx=DH    Au=RSA    Enc=AES(128)                Mac=SHA256
DHE-RSA-AES256-SHA             SSLv3    Kx=DH    Au=RSA    Enc=AES(256)                Mac=SHA1
DHE-RSA-AES128-SHA             SSLv3    Kx=DH    Au=RSA    Enc=AES(128)                Mac=SHA1
v2.2の設定ファイル 10-ssl.conf を修正していたら下記エラーが起こりました。
v2.3にアップデート後に設定ファイルを適切に対応するには
/usr/share/doc/dovecot/example-config/conf.d/10-ssl.conf
を参考にすると良いです。
Jun 22 08:31:30 kowloonet dovecot[6465]: config: Warning: Obsolete setting in /etc/dovecot/conf.d/10-ssl.conf:51: ssl_dh_parameters_length is no longer needed
Jun 22 08:31:30 kowloonet dovecot[6465]: config: Warning: Obsolete setting in /etc/dovecot/conf.d/10-ssl.conf:54: ssl_protocols has been replaced by ssl_min_protocol
Jun 22 08:37:56 kowloonet dovecot[6569]: config: Warning: please set ssl_dh=</etc/dovecot/dh.pem
ssl_dh を指定しない時のエラー。
un 22 08:21:10 kowloonet dovecot[6388]: pop3-login: Error: Failed to initialize SSL server context: Can't load DH parameters: error:1408518A:SSL routines:ssl3_ctx_ctrl:dh key too small: user=<>, rip=xxx.xxx.xxx.xxx, lip=xxx.xxx.xxx.xxx, session=<VbetYaCoIfF+hMEL>

Gmail宛にメールが送信されない件

maillog
Apr  1 07:51:34 kowloonet postfix/smtpd[2696]: disconnect from softbank126200169177.bbtec.                  net[126.200.169.177] ehlo=1 auth=1 mail=1 rcpt=1 data=1 rset=1 quit=1 commands=7
Apr  1 07:51:35 kowloonet postfix/smtp[2699]: 6E1F9C172C: to=, r                  elay=gmail-smtp-in.l.google.com[64.233.189.27]:25, delay=1.5, delays=0.09/0.03/0.85/0.53,                   dsn=5.7.1, status=bounced (host gmail-smtp-in.l.google.com[64.233.189.27] said: 550-5.7.1                   [160.16.139.144      12] Our system has detected that this message is 550-5.7.1 likely uns                  olicited mail. To reduce the amount of spam sent to Gmail, 550-5.7.1 this message has been                   blocked. Please visit 550-5.7.1  https://support.google.com/mail/?p=UnsolicitedMessageErr                  or 550 5.7.1  for more information. 6-20020a630e46000000b003824f9f2affsi710091pgo.451 - gs                  mtp (in reply to end of DATA command))
DNSレコードに下記を追加することで解決。
エントリ名タイプデータTTL
@TXTv=spf1 a:mail.kowloonet.net include:_spf.google.com ~all 3600s
参照: https://support.google.com/a/answer/10684623?hl=ja&ref_topic=10685331