Linux/postfix、dovecotのSSL対応

メールサーバのSSL化(2016-06-19、更新: 2016-11-24)


postfix と dovecot を統合しつつ、SSLで通信するようにします。
(前回の postfixインストールdovecotインストール の続きです。)
以下、環境は CentOS 7 です。


はじめに saslauth

postfix のログイン認証も dovecot 側と統合させたいので、SASL認証を導入します。

# yum install cyrus-sasl-devel
# which saslauthd
/sbin/saslauthd
# vi /etc/sysconfig/saslauthd
MECH=shadow  # pamからshadowへ変更。PAMは後日改めて・・・

CentOS 7 など、systemd 環境なら以下。

# systemctl enable  saslauthd

あるいは、/etc/init.d に起動スクリプトを作って chkconfig --add で登録します。

Dovecot のSSL関連設定

まず、Dovecotの設定から。

conf.d/10-master.conf

service imap-login {
 inet_listener imap {
   #port = 143 # コメントアウト
   port = 0    # 追記
 }
 inet_listener imaps {
   port = 993  # コメント外す
   ssl = yes   # コメント外す
 }

service pop3-login {
  inet_listener pop3 {
    #port = 110 # コメントアウト
    port = 0    # 追記
  }
  inet_listener pop3s {
    port = 995  # コメント外す
    ssl = yes   # コメント外す
  }
  
 # Postfix smtp-auth
 unix_listener /var/spool/postfix/private/auth { # コメント外す
   mode = 0666      # コメント外す
   group = postfix  # 追記
   user = postfix   # 追記
 }

unix_listener はpostfix と連携させるために必要。
アカウント認証をdovecotとpostfixで別々にやらずに、dovecot側で一元管理させるためにやっています。
よって、unix_listener は postfix と divecotで同じPATH設定にしなければいけません。
(postfix のログで、「warning: SASL: Connect to ~~ failed: Permission denied」となったら、この設定が怪しい)

conf.d/10-auth.conf

disable_plaintext_auth = yes

暗号化するのが目的なので、平文で認証を行わないようにします。

conf.d/10-mail.conf

mail_location = maildir:/var/spool/mail/%u

メールの保存場所。postfix に合わせる。

conf.d/10-ssl.conf

ssl = yes
(中略)
ssl_cert = </etc/postfix/certs/ssl_cert.pem
ssl_key = </etc/postfix/certs/ssl_key.pem
(中略)
ssl_protocols = !SSLv3   # v3にする。v2はNG

最後のssl_protocols は古いバージョン(2.2.26以前?)だとデフォルト値が 「!SSLv2」だったので、
新しめの openssl との組み合わせでエラーになってしまいます。
(「Fatal: Invalid ssl_protocols setting: Unknown protocol 'SSLv2'」
 これはopensslが「SSLv2 support removed」状態なので、v2を認識できないらしい。
 せめて受信時ではなく起動時にエラーが出れば分かりやすいのですが・・・)

そして必要なサーバ証明書を設定。Opensslは既にインストール済みだったので、

# mkdir -p /etc/postfix/certs/
# cd /etc/postfix/certs/
# openssl req -new -x509 -days 3650 -nodes -out ssl_cert.pem -keyout ssl_key.pem

証明書の作成の詳細は Linux/OpenSSL を参照。オレオレ証明書を作成してますね。

conf.d/10-logging.conf

log_path=/var/log/dovecot.log
(中略))
auth_verbose = yes
(中略)
verbose_ssl = yes

ログ出力はお好みで。色々出力する設定にした上で tail -f /var/log/dovecot.log で追いました。

Postfix のSSL関連設定

ソースから make する前に確認

まず先に、後述のconfig の設定を行ってみて上手く動けば一番良いのですが、postfix のログに
「warning: TLS has been selected, but TLS support is not compiled in」
だの出てきたら、ソースからコンパイルが必要な可能性があります。
で、
既にpostfixのパッケージが入っていたら、削除してからソースからインストールすること。
ソースからのコンパイルについては、postfixのインストールを参照。

make

make tidy  # 以前のビルドで残っているファイルがある場合
make makefiles \
   CCARGS=' \
     -DUSE_TLS \
     -I/usr/local/include \
     -DUSE_SASL_AUTH \
     -DDEF_SERVER_SASL_TYPE=\"dovecot\" \
     -DUSE_CYRUS_SASL \
     -I/usr/include/sasl \
   ' \
   AUXLIBS=" \
     -L/usr/local/lib64 \
     -lssl \
     -lcrypto \
     -L/usr/local/lib \
     -lsasl2 \
   "
make
make install

パッと見は絶望的な make の引数ですが、内容は2つです。
ソースにあるテキストを less 等で確認しましょう(vi だと文字化けします)。

  • TLS(とOpenSSL)周りの README_FILES/TLS_README
  • SASL周りの README_FILES/SASL_README

これにならって、-I と -L は各環境に合わせたPATHに変えます。
(上記の例だと OpenSSLをソースから 64環境に入れているので、その辺は変わると思います)

main.cf

smtpd_use_tls = yes
smtpd_tls_key_file = /etc/postfix/certs/ssl_key.pem
smtpd_tls_cert_file = /etc/postfix/certs/ssl_cert.pem
smtpd_sasl_security_options = noanonymous
smtpd_sasl_tls_security_options = $smtpd_sasl_security_options
smtpd_sasl_auth_enable = yes
smtpd_recipient_restrictions =
        permit_mynetworks
        permit_sasl_authenticated
        reject_unauth_destination
broken_sasl_auth_clients = yes
smtpd_sasl_type = dovecot
smtpd_sasl_path = /var/spool/postfix/private/auth
smtpd_sasl_local_domain = $myhostname

一体いくつオプションあるんだよ!?細かいチューニングは後日やるとして・・・*1
smtpd_tls_key_file、smtpd_tls_cert_file、smtpd_sasl_path は前述のdovecotに合わせること。

master.cf

 submission inet n       -       n       -       -       smtpd
   -o syslog_name=postfix/submission
   -o smtpd_tls_security_level=encrypt
   -o smtpd_sasl_auth_enable=yes
   -o smtpd_client_restrictions=permit_sasl_authenticated,reject
   -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_client_restrictions=permit_sasl_authenticated,reject
   -o smtpd_relay_restrictions=permit_sasl_authenticated,reject
   -o milter_macro_daemon_name=ORIGINATING

submission と smtps のコメントを外して有効化。オプション(-o)は・・・postfixのバージョン上がるとどんどん増えるので、よしなに。

firewall(CentOS 7)

デフォルトではメール送受信もままならないはずなので、ここで必要な通信に穴をあけます。 まず、確認。

# firewall-cmd --list-services  # いま有効なサービス
# firewall-cmd --list-all       # もう少し詳細に有効なサービスを表示
# firewall-cmd --list-all-zones # ほかのゾーンも全て表示
# ls -lta /usr/lib/firewalld/services/  # 「サービス」の内容が書かれたファイルはこちら
# firewall-cmd --add-service=smtp --zone=public --permanent
# firewall-cmd --add-service=pop3s --zone=public --permanent
# firewall-cmd --add-service=imaps --zone=public --permanent
# firewall-cmd --reload
# firewall-cmd --list-all  

submissionポートもfirewallに追加します。将来追加されるかもしれませんが・・・
あ、あとsmtps(port=465)も同じく(下はsubmissionの例のみですが、同じ要領で)。

# cp -pi /usr/lib/firewalld/services/smtp.xml /etc/firewalld/services/smtp_submission.xml
# vi /etc/firewalld/services/smtp_submission.xml
(port="587" に書き換える)
# firewall-cmd --reload
# firewall-cmd --get-services
(smtp_sbumission が増えていることを確認)
# firewall-cmd --add-service=smtp_submission --zone=public --permanent
# firewall-cmd --reload

これで送受信ができるか確認しましょう。
ただし、今回は証明書に「オレオレ証明書」を使っているので、メールソフトによってはエラーになります(別途、証明書のインポートが必要になります)。

参考: over SSL と STARTTLS の違い

私の場合はメール送受信がISP(インターネットサービスプロバイダ)経由なので、submissionポート を使わざるを得ないのですが、
その場合はメールソフト側の設定がややこしいことになります。

  • メールを受信する場合
    たぶん、pop3s や imaps など、いわゆる「over SSL」で繋がる場合が多いかと
  • メールを送信する場合
    smtps が使えない場合が多く、submissionポート(587)経由からの「STARTTLS」で繋ぐことになるかと

何が違うのかというと、

  • 前者は最初からSSL/TLS接続をするのですが、
  • 後者は最初は普通の(安全ではない)通信で接続して、途中からSSL/TLSへ切り替える、

という違いがあります。

技術的な話はさておき、メールソフト側で受信と送信の方法が変わることに混乱するかもしれません、
いや、混乱しましたので、ここにメモしておきます。


*1 正常なアクセスなのに「SASL LOGIN authentication failed: Invalid authentication mechanism」が出て、どうやら smtpd_sasl_tls_security_options が足りなかったようで追加しました。ここはまだまだ、更新の余地がありそうです・・・

  最終更新のRSS