Ubuntu 22.04 でメールサーバーを作ったのでメモ
令和にもなって自分でメールサーバーを作ってみたのでメモ。
OS は Ubuntu 22.04。
パッケージ更新後に自動的に再起動
メールとは関係ないけど apt で再起動が必要な更新があった場合は自動的に再起動するようにした。
/etc/apt/apt.conf.d/50unattended-upgrades
:
Unattended-Upgrade::Automatic-Reboot "true";
Lets Encrypt
TLS 証明書を作るために certbot をインストール。自分はさくらのクラウドのDNSを使ってるのでそれ用のモジュールも追加。
# apt install certbot python3-certbot-dns-sakuracloud
https://certbot-dns-sakuracloud.readthedocs.io/en/stable/ に従って /root/.secrets/certbot/sakuracloud.ini
を作っておく:
dns_sakuracloud_api_token = XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX
dns_sakuracloud_api_secret = XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
証明書作成:
# certbot certonly --dns-sakuracloud --dns-sakuracloud-credentials ~/.secrets/certbot/sakuracloud.ini -m hoge@example.com -d \*.example.com -d \*.example.net
証明書の期限が近づいたら自動的に更新するように cron に設定:
/etc/cron.weekly/letsencrypt
:
#!/bin/bash
certbot renew
[追記] ↑ 自動的に /etc/cron.d/certbot が作られるからこれは不要だった。
Postfix
SMTP サーバーとして Postfix をインストール。
# apt install postfix postfix-policyd-spf-python
root 宛のメールは自分に転送するように設定。
/etc/aliases
:
root: tommy
# newaliases
master.cf の submission(587ポート) と smtps(465ポート)のコメントを外して有効にする。
/etc/postfix/master.cf
:
submission inet n - y - - 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 - y - - 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
受信メールを SPF チェックする。
/etc/postfix/master.cf
:
spfcheck unix - n n - 0 spawn
user=policyd-spf argv=/usr/bin/policyd-spf /etc/postfix-policyd-spf-python/policyd-spf.conf
main.cf はこんな感じで。そんなに特殊なことはしてないはず。
/etc/postfix/main.cf
:
compatibility_level = 3.6
alias_maps = hash:/etc/aliases
myhostname = host.example.com
mydestination = $myhostname, $mydomain
home_mailbox = Maildir/
smtpd_relay_restrictions =
permit_mynetworks
permit_sasl_authenticated
reject_unauth_destination
check_policy_service unix:private/spfcheck
smtpd_helo_required = yes
mailbox_size_limit = 0
message_size_limit = 102400000
recipient_delimiter = +-
strict_rfc821_envelopes = yes
smtpd_use_tls = yes
smtpd_tls_cert_file = /etc/letsencrypt/live/example.com/fullchain.pem
smtpd_tls_key_file = /etc/letsencrypt/live/example.com/privkey.pem
smtpd_tls_loglevel = 1
smtpd_sasl_type = dovecot
smtpd_sasl_path = private/auth
mua_client_restrictions =
mua_helo_restrictions =
mua_sender_restrictions =
IMAP は Dovecot を使うので SASL として Dovecot を使用するのと、SPF チェック用の設定 check_policy_service
をしているくらい。
mua_*_restrictions
は master.cf の submission と smtps に書かれてるので、設定しておかないと warning が出るので空で設定しておく。
Dovecot
IMAP サーバーとして Dovecot をインストール。
# apt install dovecot-imapd
143 ポートは使わないので無効化。
/etc/dovecot/conf.d/10-master.conf
:
service imap-login {
inet_listener imap {
port = 0
}
inet_listener imaps {
port = 993
ssl = yes
}
Postfix 認証用の Socket ファイルを指定。
/etc/dovecot/conf.d/10-master.conf
:
service auth {
〜〜
unix_listener /var/spool/postfix/private/auth {
mode = 0666
user = postfix
group = postfix
}
〜〜
}
メールボックスは各ユーザーのホーム直下の Maildir
。
/etc/dovecot/conf.d/10-mail.conf
:
mail_location = maildir:~/Maildir
TLS 証明書は Lets Encrypt のやつ。
/etc/dovecot/conf.d/10-ssl.conf
:
ssl_cert = </etc/letsencrypt/live/example.com/fullchain.pem
ssl_key = </etc/letsencrypt/live/example.com/privkey.pem
パスワードはデフォルトで OS のユーザーパスワードと同じものが使われるけど、外から叩かれるものなので OS のパスワードとは変えておきたい。
/etc/dovecot/conf.d/10-auth.conf
の auth-system.conf.ext
をコメントアウトして1行追加:
#!include auth-system.conf.ext
!include auth-hoge.conf.ext
専用の認証設定ファイルを作成。
/etc/dovecot/conf.d/auth-hoge.conf.ext
:
passdb {
driver = passwd-file
args = scheme=SHA512-CRYPT username_format=%u /etc/dovecot/users
}
userdb {
# <doc/wiki/AuthDatabase.Passwd.txt>
driver = passwd
# [blocking=no]
#args =
# Override fields from passwd
#override_fields = home=/home/virtual/%u
}
passdb
は auth-passwdfile.conf.ext
から、userdb
は auth-system.conf.ext
からコピー。
パスワードファイルの /etc/dovecot/users
はこんな形式:
ユーザー名:{SHA512-CRYPT}$6$Gm.4X5ktmas.00pC$z9zEBRJvyyAtuczb81eyr26K/sdjkt9uZ.9mgQT1RR6s6JijHxdnyhQtDGnu70DV9v9Ijkn0bvWYFfkOFWZij0
ハッシュ文字列はこんな風にして作成できる:
# doveadm pw -s SHA512-CRYPT -p hogehoge
{SHA512-CRYPT}$6$Gm.4X5ktmas.00pC$z9zEBRJvyyAtuczb81eyr26K/sdjkt9uZ.9mgQT1RR6s6JijHxdnyhQtDGnu70DV9v9Ijkn0bvWYFfkOFWZij0
fail2ban
Postfix や Dovecot の認証が同じIPアドレスから複数回失敗したときにそのIPアドレスからの接続をブロックするために fail2ban をインストール。デフォルトで SSH 認証にも効くようになってる。
# apt install fail2ban
/etc/fail2ban/jail.d/postfix.conf
:
[postfix-sasl]
enabled = true
/etc/fail2ban/jail.d/dovecot.conf
:
[dovecot]
enabled = true
デフォルトでは10分以内に5回認証に失敗したら10分間ブロックする。
証明書更新時にサービスをリロードする
はてぶで、証明書更新時にサービスをリロードしないといけないのでは…という指摘があったので追記。
たしかにその通りでした 🙏
/etc/letsencrypt/renewal-hooks/post
配下に実行ファイルを置いておくと証明書が更新されたときに実行してくれるので、次のようなファイルを置いておく。
/etc/letsencrypt/renewal-hooks/post/postfix
#!/bin/bash
/usr/sbin/postfix reload
/etc/letsencrypt/renewal-hooks/post/dovecot
#!/bin/bash
/usr/sbin/dovecot reload
Postfix は証明書ファイルは smtpd プロセスが読み込んでて、smtpd プロセスはある程度動作したら自動的に再起動するので、この処理は実はやらなくてもいい。けどちゃんとやっといた方が安心感はある。
Dovecot は imap-login プロセスが TLS の処理をしてて、これは接続毎に起動されるんだけど、証明書ファイルの読み込みは config という別のプロセスがやっててこれは明に指示しないと再読込してくれないのだった。
DNS の設定
ちゃんと書いておいた方がいいかもしれないと思って追記。
上にも書いたけど DNS はさくらのクラウドのサービスを使ってる。1ゾーンあたり44円/月。安い。
メールサービスなので、MX と A と SPF(TXT) と PTR は必須。
こんな感じで設定:
@ MX 10 mx.example.com.
@ TXT v=spf1 mx -all
mx A 192.0.2.1
host A 192.0.2.1
最後の host
(host.example.com
)は、Postfix の myhostname
に書いたホスト名。これを PTR に設定しておく。
MTA によってはクライアントのIPアドレスを逆引きして正引きした結果がそのIPアドレスを含まないと接続を拒否されることがあるので。
PTR はサーバーのIPアドレスを管理してる業者じゃないと設定できない。業者によってやり方は異なる。
Oracle Cloud は無料で使えるんでそこにメールサーバー立てようかと思ってたんだけど、無料だと PTR を設定できないので断念した。
しかし大昔は自力で DNS サーバーも立ててたんだけど面倒くさくなってしまったな…。
Discussion