コンテンツにスキップ

PostfixとDovecotの設定(SMTP AUTHあり・TLSあり)

PostfixのSMTP・Submission、DovecotのLMTP・IMAP・SASLを構成し、SubmissionとIMAPではTLSを必須にする。


項目 値
OS Debian 13.x
メールサーバー mail.example.com
IPアドレス 192.0.2.10
メールドメイン example.com
送信ユーザー alice / alice@example.com
受信ユーザー bob / bob@example.com
メールボックス ~/Maildir
SMTP TCP 25、STARTTLS任意
Submission TCP 587、STARTTLS必須
IMAP TCP 143、STARTTLS必須
IMAPS TCP 993、Implicit TLS

DNSを使わず確認する場合は、サーバーとクライアントの/etc/hostsで192.0.2.10 mail.example.comを名前解決できるようにする。

Server Certificateの作成を使い、SANにDNS:mail.example.comを含むfullchain.pemとprivkey.pemを用意する。クライアントへ登録するRoot CA証明書をca.crtとする。

SMTPとIMAPのネットワーク動作は、mynetworksに含まれない別のDebianクライアントから確認する。クライアントへ確認用コマンドをインストールする。

Terminal window
sudo apt update
sudo apt install swaks netcat-openbsd openssl ca-certificates

区分 内容
必須 TCP 25のSTARTTLS、TCP 587のTLSとSMTP AUTH、Dovecot LMTP、Maildir、IMAPのTLSと認証
任意 IPv6の待受、TLS最小バージョンの明示
独自CAの場合に必須 検証用クライアントへのRoot CA証明書登録

Terminal window
sudo hostnamectl set-hostname mail.example.com

/etc/hostsにホスト名を登録する。

/etc/hosts
127.0.0.1 localhost
127.0.1.1 mail.example.com mail

完全修飾ドメイン名を確認する。

Terminal window
hostname --fqdn

期待する結果はmail.example.comである。


2. パッケージをインストールする

Section titled “2. パッケージをインストールする”
Terminal window
sudo apt update
sudo apt install postfix dovecot-core dovecot-imapd dovecot-lmtpd

Postfixの設定形式を聞かれた場合はInternet Site、System mail nameはexample.comを指定する。後の手順でmain.cfの値を明示的に設定する。

インストールされたバージョンを確認する。

Terminal window
postconf mail_version
dovecot --version

Debian 13ではDovecot 2.4系が表示される。


Terminal window
sudo adduser alice
sudo adduser bob

各コマンドの対話入力で検証用パスワードを設定する。Linuxユーザー名がメールアドレスのローカル部に対応する。

Terminal window
getent passwd alice bob

aliceとbobのUID、GID、ホームディレクトリが表示されることを確認する。


Postfix用とDovecot用のディレクトリを作成する。

Terminal window
sudo install -d -o root -g root -m 700 \
/etc/postfix/tls/mail.example.com
sudo install -d -o root -g root -m 700 \
/etc/dovecot/tls/mail.example.com

Postfixへ配備する。

Terminal window
sudo install -o root -g root -m 644 fullchain.pem \
/etc/postfix/tls/mail.example.com/fullchain.pem
sudo install -o root -g root -m 600 privkey.pem \
/etc/postfix/tls/mail.example.com/privkey.pem

Dovecotへ配備する。

Terminal window
sudo install -o root -g root -m 644 fullchain.pem \
/etc/dovecot/tls/mail.example.com/fullchain.pem
sudo install -o root -g root -m 600 privkey.pem \
/etc/dovecot/tls/mail.example.com/privkey.pem

fullchain.pemはサーバー証明書、Intermediate CA証明書の順に格納する。Root CA証明書はサーバーから送るチェーンへ含めず、クライアントのTrust Storeへ登録する。

PostfixとDovecotの親プロセスはroot権限で秘密鍵を読み込み、その後に権限を落として接続を処理する。秘密鍵を各サービスの実行ユーザーから常時読み取れる権限にはしない。

証明書のSANと秘密鍵の対応を確認する。

Terminal window
openssl x509 -in fullchain.pem -noout -subject -issuer -dates \
-ext subjectAltName
openssl x509 -in fullchain.pem -pubkey -noout | sha256sum
openssl pkey -in privkey.pem -pubout | sha256sum

SANにDNS:mail.example.comが表示され、2つのSHA-256値が一致することを確認する。


Terminal window
sudoedit /etc/postfix/main.cf

/etc/postfix/main.cfの既存内容を次の設定へ置き換える。

/etc/postfix/main.cf
compatibility_level = 3.10
myhostname = mail.example.com
mydomain = example.com
myorigin = $mydomain
mydestination = $myhostname, localhost.$mydomain, localhost, $mydomain
alias_maps = hash:/etc/aliases
alias_database = hash:/etc/aliases
inet_interfaces = all
inet_protocols = ipv4
mynetworks = 127.0.0.0/8
smtpd_relay_restrictions = permit_mynetworks, permit_sasl_authenticated, reject_unauth_destination
mailbox_transport = lmtp:unix:private/dovecot-lmtp
smtpd_sasl_type = dovecot
smtpd_sasl_path = private/auth
smtpd_sasl_auth_enable = no
smtpd_tls_cert_file = /etc/postfix/tls/mail.example.com/fullchain.pem
smtpd_tls_key_file = /etc/postfix/tls/mail.example.com/privkey.pem
smtpd_tls_security_level = may
smtp_tls_security_level = may

compatibility_level = 3.10はDebian 13のPostfix 3.10系の既定動作を使用する。

mydestinationはexample.comをローカルドメインとし、smtpd_relay_restrictionsはループバックまたはSASL認証済み利用者以外による第三者中継を拒否する。

alias_mapsはローカル配送時に参照するエイリアス、alias_databaseはnewaliasesで更新するエイリアスデータベースを/etc/aliasesへそろえる。

mailbox_transportは、ローカルメールボックスへの最終配送を/var/spool/postfix/private/dovecot-lmtpへ渡す。このUNIXドメインソケット通信はネットワーク上のSMTPやIMAPのTLSとは関係しない。

smtpd_tls_security_level = mayは、TCP 25で接続を受けるときにSTARTTLSを提供するが、相手MTAへ強制しない。smtp_tls_security_level = mayは、Postfixが他のMTAへ接続するとき、相手がSTARTTLSを提供すれば利用する。公開SMTPで相手がTLSに対応していない場合も配送を続ける。

smtpd_sasl_auth_enable = noはTCP 25でSMTP AUTHを提供しない。次のSubmissionサービスだけで認証とTLSを必須にする。

inet_interfaces = allはPostfixをloopback以外のインターフェースでも待ち受けさせる。inet_protocols = ipv4は、この手順のIPv4構成に合わせて待受と送信をIPv4へ限定する。

smtp_tls_security_level = mayは相手MTAがSTARTTLSを提供しない場合も平文で配送し、相手証明書の検証を配送条件にしない。TLSを必須化する配送先には、別途TLSポリシーを設定する。

IPv4とIPv6の両方を使用する場合は、main.cfの2行を次のように変更する。

inet_protocols = all
mynetworks = 127.0.0.0/8, [::1]/128

設定値とDovecot SASL対応を確認する。

Terminal window
postconf -n
postconf -a | grep '^dovecot$'

/etc/postfix/master.cfで既存のsubmission行が有効なら、その行と配下の-oを次の内容へ置き換える。有効な行がなければ末尾へ追加する。

Terminal window
sudoedit /etc/postfix/master.cf
/etc/postfix/master.cf
submission inet n - y - - smtpd
-o smtpd_tls_security_level=encrypt
-o smtpd_sasl_auth_enable=yes
-o smtpd_client_restrictions=permit_sasl_authenticated,reject

smtpd_tls_security_level = encryptは、このTCP 587サービスでSTARTTLSを必須にする。TLSが確立するまでPostfixはAUTHを提示せず、暗号化なしのメール提出も受け付けない。

smtpd_sasl_auth_enable = yesはDovecot SASLによるSMTP AUTHを有効にする。smtpd_client_restrictionsは認証済みクライアントだけを許可する。


既存設定を保存する。

Terminal window
sudo cp -a /etc/dovecot/dovecot.conf \
/etc/dovecot/dovecot.conf.original

/etc/dovecot/dovecot.confを次の内容に置き換える。

Terminal window
sudoedit /etc/dovecot/dovecot.conf
/etc/dovecot/dovecot.conf
dovecot_config_version = 2.4.0
dovecot_storage_version = 2.4.0
protocols {
imap = yes
lmtp = yes
}
listen = 0.0.0.0
mail_driver = maildir
mail_path = ~/Maildir
first_valid_uid = 1000
namespace inbox {
inbox = yes
}
auth_mechanisms = plain login
auth_allow_cleartext = no
auth_username_format = %{user | username}
passdb pam {
}
userdb passwd {
}
ssl = required
ssl_server_cert_file = /etc/dovecot/tls/mail.example.com/fullchain.pem
ssl_server_key_file = /etc/dovecot/tls/mail.example.com/privkey.pem
service imap-login {
inet_listener imap {
port = 143
}
inet_listener imaps {
port = 993
ssl = yes
}
}
service auth {
unix_listener /var/spool/postfix/private/auth {
user = postfix
group = postfix
mode = 0660
}
}
service lmtp {
unix_listener /var/spool/postfix/private/dovecot-lmtp {
user = postfix
group = postfix
mode = 0660
}
}
protocol lmtp {
postmaster_address = postmaster@example.com
}

mail_driverとmail_pathにより、LMTPの保存先とIMAPの参照先を~/Maildirへ統一する。

auth_allow_cleartext = noは、TLSで保護されていない接続でPLAIN・LOGIN認証を拒否する。ssl = requiredはIMAPセッション全体にTLSを要求する。TCP 143ではSTARTTLS後にログインし、inet_listener imapsのTCP 993では接続直後からTLSハンドシェイクを行う。

ssl_server_cert_fileには証明書チェーン、ssl_server_key_fileには対応する秘密鍵を指定する。Dovecot 2.4では、旧設定名のssl_certとssl_keyは使用しない。

authソケットはPostfixからSMTP AUTH要求を受け、dovecot-lmtpソケットはPostfixから配送メッセージを受ける。どちらもPostfixのqueue directory内へ作ることで、chrootされたPostfixプロセスから接続できる。

listen = 0.0.0.0はDovecotを全IPv4アドレスで待ち受けさせる。first_valid_uid = 1000はUID 1000未満のシステムアカウントをメール利用者として扱わないための下限である。namespace inboxは利用者の受信箱となるINBOXを定義する。postmaster_addressはLMTPが配送不能通知を生成するときの送信元アドレスである。

TLSの最小バージョンを明示する場合(任意)

Section titled “TLSの最小バージョンを明示する場合(任意)”

共通ポリシーに依存せずTLS 1.2以上に限定する場合は、任意で次を追加する。

ssl_min_protocol = TLSv1.2

/etc/pam.d/dovecotを確認する。存在しない場合は次の内容で作成する。

Terminal window
sudoedit /etc/pam.d/dovecot
/etc/pam.d/dovecot
auth required pam_unix.so
account required pam_unix.so

authはパスワードを検証し、accountはアカウントを利用できる状態か確認する。


/etc/aliasesにpostmasterの転送先を設定する。既存のエイリアスは残す。

Terminal window
sudoedit /etc/aliases
/etc/aliases
postmaster: alice
Terminal window
sudo newaliases

Terminal window
sudo doveconf -n
sudo postfix check

エラーがなければ再起動する。

Terminal window
sudo systemctl restart dovecot
sudo systemctl restart postfix
sudo systemctl is-active dovecot postfix

両方がactiveになることを確認する。

Terminal window
sudo ss -lntp | grep -E ':(25|143|587|993)\b'

TCP 25、143、587、993で待ち受けていることを確認する。

Terminal window
sudo ls -l \
/var/spool/postfix/private/auth \
/var/spool/postfix/private/dovecot-lmtp

どちらのソケットも所有者とグループがpostfix postfix、モードがsrw-rw----であることを確認する。


11. クライアントへRoot CA証明書を登録する(独自CAの場合)

Section titled “11. クライアントへRoot CA証明書を登録する(独自CAの場合)”

独自CAで発行した場合は、検証用DebianクライアントへRoot CA証明書を登録する。

Terminal window
sudo install -o root -g root -m 644 ca.crt \
/usr/local/share/ca-certificates/skills-root-ca.crt
sudo update-ca-certificates

証明書検証を無効化せず、署名チェーンとmail.example.comの名前を検証できる状態にする。


12. Dovecotのユーザー検索と認証を確認する

Section titled “12. Dovecotのユーザー検索と認証を確認する”
Terminal window
sudo doveadm user alice
sudo doveadm user bob
sudo doveadm auth test alice
sudo doveadm auth test alice@example.com

UID、GID、homeがLinuxユーザーと一致し、どちらのログイン名でもauth succeededになることを確認する。doveadm auth testはローカル管理コマンドによる認証確認であり、ネットワーク上のTLS確認は後の手順で行う。


TCP 25の証明書とSTARTTLSを確認する。

Terminal window
openssl s_client \
-starttls smtp \
-connect mail.example.com:25 \
-servername mail.example.com \
-verify_hostname mail.example.com \
-verify_return_error \
-CAfile /etc/ssl/certs/ca-certificates.crt </dev/null

TCP 587も同様に確認する。

Terminal window
openssl s_client \
-starttls smtp \
-connect mail.example.com:587 \
-servername mail.example.com \
-verify_hostname mail.example.com \
-verify_return_error \
-CAfile /etc/ssl/certs/ca-certificates.crt </dev/null

どちらもVerify return code: 0 (ok)になることを確認する。


Terminal window
swaks \
--server mail.example.com:587 \
--tls \
--tls-verify \
--auth LOGIN \
--auth-user alice@example.com \
--auth-password 'AlicePassword' \
--from alice@example.com \
--to bob@example.com \
--header 'Subject: SMTP AUTH TLS test' \
--body 'submitted with STARTTLS'

TLS検証に成功した後、235 2.7.0 Authentication successfulと250 2.0.0 Ok: queued as ...が表示されることを確認する。

STARTTLS前のSubmissionへ接続し、EHLO応答を確認する。

Terminal window
printf 'EHLO client.example.net\r\nQUIT\r\n' | nc mail.example.com 587

EHLO応答にSTARTTLSがあり、TLS確立前にはAUTHがないことを確認する。

TLSへ切り替えずにメール提出を試す。

Terminal window
printf 'EHLO client.example.net\r\nMAIL FROM:<alice@example.com>\r\nQUIT\r\n' | nc mail.example.com 587

530 5.7.0 Must issue a STARTTLS command firstになることを確認する。

--auth-passwordの値はコマンドラインやシェル履歴へ残るため、検証用以外のパスワードを直接記述しない。

認証済み利用者が外部ドメイン宛てのRCPTを指定できることは、実際の配送を発生させずに確認できる。

Terminal window
swaks \
--server mail.example.com:587 \
--tls \
--tls-verify \
--auth LOGIN \
--auth-user alice@example.com \
--auth-password 'AlicePassword' \
--from alice@example.com \
--to recipient@example.net \
--quit-after RCPT

RCPT TO:<recipient@example.net>に250が返ることを確認する。


15. TCP 25の受信と中継拒否を確認する

Section titled “15. TCP 25の受信と中継拒否を確認する”

検証用クライアントから、未認証でローカルユーザー宛てのRCPTが受理されることを確認する。

Terminal window
swaks \
--server mail.example.com:25 \
--from sender@example.net \
--to bob@example.com \
--quit-after RCPT

RCPT TO:<bob@example.com>に250が返ることを確認する。

同じクライアントから、外部ドメイン宛ての中継が拒否されることを確認する。

Terminal window
swaks \
--server mail.example.com:25 \
--from sender@example.net \
--to recipient@example.net \
--quit-after RCPT

Relay access deniedを含む454または554応答になることを確認する。


Terminal window
postqueue -p
sudo find /home/bob/Maildir/new -maxdepth 1 -type f -printf '%f\n'
sudo journalctl -u postfix -u dovecot --since '-5 minutes'

キューが空になり、BobのMaildirにメールファイルが作成されることを確認する。Postfixログにはrelay=mail.example.com[private/dovecot-lmtp]とstatus=sentが表示される。

LMTPは同一ホストのUNIXドメインソケットを通るため、SMTP SubmissionのTLSがLMTP接続へ引き継がれるわけではない。


Terminal window
openssl s_client \
-starttls imap \
-connect mail.example.com:143 \
-servername mail.example.com \
-verify_hostname mail.example.com \
-verify_return_error \
-CAfile /etc/ssl/certs/ca-certificates.crt

Verify return code: 0 (ok)を確認してから、次のIMAPコマンドを入力する。

a LOGIN bob@example.com BobPassword
b SELECT INBOX
c FETCH 1 BODY.PEEK[HEADER.FIELDS (FROM TO SUBJECT)]
d LOGOUT

a OKでログイン成功、b OKでINBOX選択成功となり、FETCHで配送したメールのヘッダーが表示されることを確認する。


Terminal window
openssl s_client \
-connect mail.example.com:993 \
-servername mail.example.com \
-verify_hostname mail.example.com \
-verify_return_error \
-CAfile /etc/ssl/certs/ca-certificates.crt

TCP接続直後にTLSハンドシェイクが行われ、Verify return code: 0 (ok)になることを確認する。その後はTCP 143のSTARTTLS後と同じIMAPコマンドを使用できる。


19. 暗号化前のIMAPログイン拒否を確認する

Section titled “19. 暗号化前のIMAPログイン拒否を確認する”

この確認は、Dovecotがsecured connectionとして扱うlocalhostではなく、検証用クライアントから実行する。

Terminal window
nc mail.example.com 143

接続後にTLSへ切り替えずログインを試す。

a LOGIN bob@example.com BobPassword

Dovecotがログインを拒否することを確認する。接続時のCAPABILITYにはSTARTTLSとLOGINDISABLEDが表示される。


  • doveconf -nとpostfix checkがエラーにならない。
  • PostfixがTCP 25と587、DovecotがTCP 143と993で待ち受ける。
  • 認証用private/authと配送用private/dovecot-lmtpが存在する。
  • TCP 25はSTARTTLSを提供するが、平文SMTPも受信できる。
  • 未認証のTCP 25接続ではローカル宛てを受理し、外部宛て中継を拒否する。
  • TCP 587はSTARTTLS前のSMTP AUTHとメール提出を拒否する。
  • TLSとSMTP AUTHを使用した利用者は外部ドメイン宛てのRCPTを指定できる。
  • TCP 143はSTARTTLS前のIMAPログインを拒否する。
  • TCP 993は接続直後からTLSを使用する。
  • PostfixとDovecotがmail.example.comをSANに含む証明書を提示する。
  • クライアントが証明書チェーンとホスト名を検証できる。
  • SMTP AUTHで送信したメールがLMTPでBobのMaildirへ保存される。
  • BobがTLSで保護されたIMAP接続からメールを確認できる。