すでに Postfix/Dovecot が平文で構築されていることを前提に設定します。
まだ構築が完了していなければこちらで構築しておいてください。
項目 内容 備考 OS CentOS 7.9.2009 手元で稼働中の Linux。
ホントは最新の CentOS8 で設定したかったが、
CentOS7 よりもサポートが短くなってしまった。DNS サーバの IP アドレス 192.168.122.3 リモート更新可能な設定がされていること。 SMTP サーバ ソフトウェア Postfix 2.10.1 CentOS7 に付属のもの 全体設定 /etc/postfix/main.cf プロトコル設定 /etc/postfix/master.cf POP3/IMAP サーバ ソフトウェア Dovecot 2.2.36 CentOS7 に付属のもの。
起動設定ファイルは /etc/dovecot/dovecot.confメールファイル設定 /etc/dovecot/conf.d/10-master.conf conf.d/*.conf は dovecot.conf から追加で読み込まれる。 ログイン認証設定 /etc/dovecot/conf.d/10-auth.conf SSL 設定 /etc/dovecot/conf.d/10-ssl.conf メールサーバ名 mail.example.jp - 管理者のメールアドレス admin@example.jp - ユーザのメールアドレス who@example.jp -
この手順書は主に下記 1-b を取り扱っている。
1-a. メールサーバが Web サーバと同居可能の場合。
サーバ機がポート 80 や 443 を利用可能な場合は HTTP-01 チャレンジを使用して証明書を取得する。1-b. リモートから DNS の更新ができる場合。
下記手順 2, 4, 6 ~ 9 を実施する。(6-1 では HTTP-01 チャレンジを利用する)
- メールサーバがすでに Web サーバと同居している場合。
- 一時的にポート 80 や 443 を利用できる場合。
下記手順 2 ~ 9 を実施する。(6-1 では DNS-01 チャレンジを利用する)1-c. Web サーバと同居できず、DNS の更新許可も無い場合。
Let's Encrypt は手動で利用できるので、上記 1-a または 1-b を他のサーバで実施し、Let's Encrypt のチャレンジの種類はここに記述がある。
証明書ファイルをメールサーバへコピーすることにより取得・更新する。
$ cat /etc/system-release
$ dig example.jp -t mx +short | sort -n
CentOS Linux release 7.9.2009 (Core)
$ /usr/sbin/postconf | grep ^mail_versionドメイン名とメールサーバ名が紐づいていること。
10 mail.example.jp.
複数ある場合は、優先順位の値 (この場合は 10) が小さいものから優先される。
$ /usr/sbin/dovecot --version
mail_version = 2.10.1
2.2.36
3-1. メールサーバから DNS の更新ができるように設定
ここを参考にしてメールサーバから DNS の更新ができるようにしておく。3-2. DNS 更新コマンドを確認する。
$ nsupdate -V3-3. メールサーバから DNS の更新ができることを確認
nsupdate 9.11.4-P2-RedHat-9.11.4-26.P2.el7_9.5
3-3-1. TXT レコードの追加
$ nsupdate << EOF3-3-2. TXT レコードの削除
server 192.168.122.3
update add _acme-challenge.mail.example.jp. 60 in txt "check string"
send
EOF
$ dig @192.168.122.3 -t txt _acme-challenge.mail.example.jp +short
"check string"
$ nsupdate << EOF
server 192.168.122.3
update delete _acme-challenge.mail.example.jp. txt
send
EOF
$ dig @192.168.122.3 -t txt _acme-challenge.mail.example.jp +short
(何も表示されなければ OK)
4-1. epel のインストール
$ su4-2. certbot のインストール
# yum -y install epel-release
# yum -y update epel-release
# yum -y install certbot
# certbot --version
# exit
certbot 1.11.0
$
5-1. DNS-01 チャレンジ文字列登録用スクリプトを作成する。
$ su5-2. DNS-01 チャレンジ文字列削除用スクリプトを作成する。
# cd /etc/sysconfig/
/etc/sysconfig/# vim certbot-dns-authenticator.sh (754)
/etc/sysconfig/# chmod 754 certbot-dns-authenticator.sh・$CERTBOT_DOMAIN は certbot の実行時に指定されたサーバ名が自動的に入る。(下記手順 6-1 における mail.example.jp のこと)
#!/bin/bash MYDNS_SERVER=192.168.122.3 nsupdate << EOF server $MYDNS_SERVER update add _acme-challenge.$CERTBOT_DOMAIN. 60 in txt $CERTBOT_VALIDATION send EOF
・$CERTBOT_VALIDATION は Let's Encrypt サーバから指示された文字列が自動的に入る。
certbot から呼ばれるスクリプトのマクロはここに説明がある。
/etc/sysconfig/# vim certbot-dns-cleanup.sh (754)
/etc/sysconfig/# chmod 754 certbot-dns-cleanup.sh
#!/bin/bash MYDNS_SERVER=192.168.122.3 nsupdate << EOF server $MYDNS_SERVER update delete _acme-challenge.$CERTBOT_DOMAIN. txt send EOF
/etc/sysconfig/# exit
$
6-1. certbot を実行
下記 6-1-a, 6-1-b のどちらかを実行する。6-2. 証明書ファイルを確認する。
いずれの場合も、最初はオプション --staging を付けて実行し、すべての正常動作が確認出来たら、これを取り除いて再度実行する。
本番サーバに対する証明書取得・更新の頻度は 5 回/週 の制限があります。
$ su
#
6-1-a.「HTTP-01 チャレンジ」を使用する場合。
# 既存 Web サーバが停止中または、ポート 80 を使用可能の場合。(メールサーバ単体なら、こちらを使うはず)6-1-b.「DNS-01 チャレンジ」を使用する場合。
# certbot certonly --staging --standalone -d mail.example.jp
# 既存 Web サーバが稼働中の場合。(メールサーバ名と同一の Web サーバを持たないと使えない*1)
# certbot certonly --staging --webroot -w /var/www/html/ -d mail.example.jp
*1認証サーバが -d で指定したサーバをアクセスするので http://mail.example.jp/ が必要になる。
# certbot certonly --staging \
--manual \
--preferred-challenges=dns \
--manual-auth-hook /etc/sysconfig/certbot-dns-authenticator.sh \
--manual-cleanup-hook /etc/sysconfig/certbot-dns-cleanup.sh \
--renew-hook="systemctl restart postfix; systemctl restart dovecot" \
-d mail.example.jp
Saving debug log to /var/log/letsencrypt/letsencrypt.log Plugins selected: Authenticator manual, Installer None Enter email address (used for urgent renewal and security notices) (Enter 'c' to cancel): admin@example.jp ⏎ Starting new HTTPS connection (1): acme-staging-v02.api.letsencrypt.org/directory - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Please read the Terms of Service at https://letsencrypt.org/documents/LE-SA-v1.2-November-15-2017.pdf. You must agree in order to register with the ACME server. Do you agree? - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - (Y)es/(N)o: y ⏎ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Would you be willing, once your first certificate is successfully issued, 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 ⏎ Account registered. Requesting a certificate for mail.example.jp Performing the following challenges: dns-01 challenge for mail.example.jp Running manual-auth-hook command: /etc/sysconfig/certbot-dns-authenticator.sh Waiting for verification... Cleaning up challenges Running manual-cleanup-hook command: /etc/sysconfig/certbot-dns-cleanup.sh Running deploy-hook command: systemctl restart postfix; systemctl restart dovecot IMPORTANT NOTES: - Congratulations! Your certificate and chain have been saved at: /etc/letsencrypt/live/mail.example.jp/fullchain.pem Your key file has been saved at: /etc/letsencrypt/live/mail.example.jp/privkey.pem Your certificate will expire on 2021-10-20. 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
# cd /etc/letsencrypt/live/mail.example.jp/
/etc/letsencrypt/live/mail.example.jp/# ls -l
/etc/letsencrypt/live/mail.example.jp/# cd ../../archive/mail.example.jp/
-rw-r--r--. 1 root root 692 7月 22 10:40 README lrwxrwxrwx. 1 root root 38 7月 22 10:40 cert.pem -> ../../archive/mail.example.jp/cert1.pem lrwxrwxrwx. 1 root root 39 7月 22 10:40 chain.pem -> ../../archive/mail.example.jp/chain1.pem lrwxrwxrwx. 1 root root 43 7月 22 10:40 fullchain.pem -> ../../archive/mail.example.jp/fullchain1.pem lrwxrwxrwx. 1 root root 41 7月 22 10:40 privkey.pem -> ../../archive/mail.example.jp/privkey1.pem
/etc/letsencrypt/archive/mail.example.jp/# ls -l
/etc/letsencrypt/archive/mail.example.jp/# exit
-rw-r--r--. 1 root root 1842 7月 22 10:40 cert1.pem -rw-r--r--. 1 root root 3749 7月 22 10:40 chain1.pem -rw-r--r--. 1 root root 5591 7月 22 10:40 fullchain1.pem -rw-------. 1 root root 1704 7月 22 10:40 privkey1.pem
$
7-1. POP3s/IMAPs を許可する。(ポート 995/993 を開く)
$ su7-2. POP3s/IMAPs の暗号化を指定する。
# cd /etc/dovecot/conf.d/
/etc/dovecot/conf.d/# vim 10-master.conf
service imap-login { inet_listener imap { #port = 143 # ポート 143 は禁止する。 } inet_listener imaps { port = 993 ssl = yes }
service pop3-login { inet_listener pop3 { #port = 110 # ポート 110 は禁止する。 } inet_listener pop3s { port = 995 ssl = yes } }
/etc/dovecot/conf.d/# vim 10-auth.conf7-3. dovecot を再起動する。
/etc/dovecot/conf.d/# vim 10-ssl.conf
# connection is considered secure and plaintext authentication is allowed. # See also ssl=required setting. # #disable_plaintext_auth = yes # 平文のパスワードを拒否 # Authentication cache size (e.g. 10M). 0 means it's disabled. Note that
# 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 # SSL 接続を必須にする。(yes だと平文も許可) # 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/letsencrypt/live/mail.example.jp/fullchain.pem ssl_key = </etc/letsencrypt/live/mail.example.jp/privkey.pem # If key file is password protected, give the password here. Alternatively
/etc/dovecot/conf.d/# systemctl restart dovecotIMAPs の設定は、以下になる。
/etc/dovecot/conf.d/# exit
$
ポート 993 接続の保護 SSL/TLS 認証方式 通常のパスワード認証
POP3s の設定は、以下になる。
ポート 995 接続の保護 SSL/TLS 認証方式 通常のパスワード認証
8-1. 全体設定に暗号化を指定する。
$ su8-2. プロトコル設定に暗号化を指定する。
# cd /etc/postfix/
/etc/postfix/# vim main.cf
以下を追加する。
smtpd_use_tls = yes smtp_tls_security_level = may smtpd_tls_cert_file = /etc/letsencrypt/live/mail.example.jp/fullchain.pem smtpd_tls_key_file = /etc/letsencrypt/live/mail.example.jp/privkey.pem smtpd_tls_loglevel = 1 smtpd_tls_received_header = yes smtpd_recipient_restrictions = permit_mynetworks permit_sasl_authenticated reject_unauth_destination
/etc/postfix/# vim master.cfSMTP の設定は、以下になる。(定番はこちら)
/etc/postfix/# systemctl restart postfix
#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=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_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=permit_sasl_authenticated,reject # -o milter_macro_daemon_name=ORIGINATING
/etc/postfix/# exit
$
ポート 587 接続の保護 STARTTLS 認証方式 通常のパスワード認証
smtps を有効にした場合は以下も使用可能。(正規プロトコルだが、デファクトになっていない)
ポート 465 接続の保護 SSL/TLS 認証方式 通常のパスワード認証
9-1. 自動更新オプションを確認する。
$ cat /etc/letsencrypt/renewal/mail.example.jp.conf9-2. 証明書を更新してみる。
# renew_before_expiry = 30 days version = 1.11.0 archive_dir = /etc/letsencrypt/archive/mail.example.jp cert = /etc/letsencrypt/live/mail.example.jp/cert.pem privkey = /etc/letsencrypt/live/mail.example.jp/privkey.pem chain = /etc/letsencrypt/live/mail.example.jp/chain.pem fullchain = /etc/letsencrypt/live/mail.example.jp/fullchain.pem # Options used in the renewal process [renewalparams] authenticator = manual account = 3o8ob75eZ94ea36ii7f673c58b9e2i33 manual_public_ip_logging_ok = None manual_auth_hook = /etc/sysconfig/certbot-dns-authenticator.sh server = https://acme-staging-v02.api.letsencrypt.org/directory manual_cleanup_hook = /etc/sysconfig/certbot-dns-cleanup.sh pref_challs = dns-01, renew_hook = systemctl restart postfix; systemctl restart dovecot
下記オプションが指定されていること。
オプション 実行のタイミング 内容 manual_auth_hook 認証時に実行される。 DNS-01 チャレンジの TXT を DNS サーバへ登録する。 manual_cleanup_hook 認証直後に実行される。 DNS-01 チャレンジの TXT を DNS サーバから削除する。 renew_hook 証明書取得が成功したときに実行される。 Postfix と Dovecot を再起動する。 authenticator 更新方法
(http を使用した場合)上記 6-1-a の --standalone で証明書を取得した場合は authenticator = standalone が設定される。
証明書の更新時に他のプロセスでポート 80 を使用してはいけない。
(postfixadmin 等は 443 のみで起動すること)
$ su9-3. 証明書の自動更新用ファイルを確認する。
# certbot renew
まだ更新期限の 30 日前を迎えていないので更新されない。
更新しようともしない (No renewals were attempted) ので、Let's Encrypt サーバに負荷はかからない。
Saving debug log to /var/log/letsencrypt/letsencrypt.log - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Processing /etc/letsencrypt/renewal/mail.example.jp.conf - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Cert not yet due for renewal - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - The following certificates are not due for renewal yet: /etc/letsencrypt/live/mail.example.jp/fullchain.pem expires on 2021-10-20 (skipped) No renewals were attempted. - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
# ls -l /usr/lib/systemd/system/certbot-renew.*9-4. 証明書の更新を systemd (timer) に登録する。
-rw-r--r--. 1 root root 284 1月 6 2021 /usr/lib/systemd/system/certbot-renew.service -rw-r--r--. 1 root root 195 1月 6 2021 /usr/lib/systemd/system/certbot-renew.timer
[certbot-renew.service] (無変更)
[Unit] Description=This service automatically renews any certbot certificates found [Service] EnvironmentFile=/etc/sysconfig/certbot Type=oneshot ExecStart=/usr/bin/certbot renew --noninteractive --no-random-sleep-on-renew $PRE_HOOK $POST_HOOK $RENEW_HOOK $DEPLOY_HOOK $CERTBOT_ARGS
[certbot-renew.timer] (無変更)
[Unit] Description=This is the timer to set the schedule for automated renewals [Timer] OnCalendar=*-*-* 00/12:00:00 RandomizedDelaySec=12hours Persistent=true [Install] WantedBy=timers.target
# systemctl enable certbot-renew.timer
# systemctl start certbot-renew.timer
# systemctl status certbot-renew.timer | grep Active
OS 起動時に自動更新のタイマーも起動されるようになった。(waiting)# systemctl list-timers | grep certbot-renew.timer
Active: active (waiting) since 木 2021-07-22 22:21:30 JST; 12s ago
次は 10 時間後 ("10h left") に certbot-renew.service が実行される。# exit
金 2021-07-23 08:31:02 JST 10h left n/a n/a certbot-renew.timer certbot-renew.service
$
$ su
# firewall-cmd --zone=public --add-service=imaps --permanent
# firewall-cmd --zone=public --add-service=pop3s --permanent
# firewall-cmd --zone=public --add-service=smtps --permanent
# firewall-cmd --zone=public --add-service=smtp-submission --permanent # ← 前段「5. ポートアクセスの許可」で実施済のはず。
# firewall-cmd --reload
# firewall-cmd --zone=public --list-all
# exit
public (active) target: default icmp-block-inversion: no interfaces: enp1s0 enp8s0 sources: services: cockpit dhcpv6-client http https imap imaps pop3 pop3s smtp smtp-submission smtps ssh ports: protocols: forward: yes masquerade: no forward-ports: source-ports: icmp-blocks: rich rules:
$