概要
まっさらなUbuntuに実運用に適した設定のメールサーバーを構築するための流れを記述します。ユーザ管理は非UNIXアカウントをDBでなくファイルで管理する方式を採用しています。セキュリティ重視のため送受信共 SSL/TLS を使用します。Outlookだと STARTTLS でなければならないという情報を何処かで聞きました。実際本記事の設定ではOutlookでログインできなかったので注意。今では必須となっている送信ドメイン認証 DKIM を行うため OpenDKIM を使います。※DNSのサービスによっては送信ドメイン認証が使えないところもあります。
要求
- 実用的なセキュリティ
- GmailとYahooメールの迷惑メール判定に合格する
- メールアカウントとUNIXシステムアカウントを分ける
- IMAPをサポートする
- 迷惑メールをフィルタする
- クライアントのアカウント設定のユーザ名にドメインを付けたくない
要件
- 送信ドメイン認証にSPFとDKIMを用いる
- SPFとDKIMに対応したDNSサービス(ドメイン側とサーバ側)を利用する
- Postfix+Dovecot(SASL認証)でサーバを構築する
- Let’s Encryptのドメイン証明書を利用する
- クライアント間の通信はSSL/TLSで行う
送信ドメイン認証に対応したDNSサービス
まず、DNSサービスによっては迷惑メール判定回避のための送信ドメイン認証(SPFとDKIM)が設定不可能な所もあります。現時点での情報を載せます。
ドメイン取得代行サービス
| SPF | DKIM |
| お名前.com | 〇 | 〇 |
| さくらのドメイン | 〇 | × |
サーバー側サービス
| SPF(逆引き) |
| さくらのVPS | 〇 |
| WebARENA Indigo | × |
| WebARENA IndigoPro | 不明 |
最初に
送受信用のサブドメインを分けるパターン(smtp.XXX.xxとかimap.XXX.xx)を良く見かけますが逆引きやら証明書やらリレーやらで煩わしいので理由がない限りサブドメインを作らない方が無難です。
FQDNが正しく設定されているか確認します。ドメイン部が付いて無いとPostfixの初期設定が変化するので注意。
$ hostname -f
[ホスト名].[ドメイン(.xxなど)]
インストールの前にファイアウォールを設定する事をお勧めします。
インストールの前にファイアウォールを設定する事をお勧めします。
$ sudo ufw allow ssh # まだufwを有効にしたことない場合
$ sudo ufw allow smtp
$ sudo ufw allow smtps
$ sudo ufw allow imaps
$ sudo ufw allow http
$ sudo ufw allow 7080 # LiteSpeedの管理画面
$ sudo ufw enable
LiteSpeed
ここではLet’s Encryptを使うために先にLiteSpeed(Webサーバ)をインストールします。Webサーバが必須な訳ではありませんが後でインストールするつもりならこの時点でインストールしちゃいましょう。
$ wget -O - https://repo.litespeed.sh | sudo bash
$ sudo apt update
$ sudo apt install openlitespeed
# 管理画面のユーザ・パスワードを設定する
$ sudo /usr/local/lsws/admin/misc/admpass.sh
# 起動
$ sudo systemctl start lsws
http://[ドメイン名]:7080 にアクセスしExampleのポートを80に変更します。
Let’s Encrypt
ここで指定するメールアドレスは証明書の有効期限が切れそうな時などのお知らせで使用されます。
$ sudo apt install certbot
$ sudo certbot certonly
Saving debug log to /var/log/letsencrypt/letsencrypt.log
How would you like to authenticate with the ACME CA?
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
1: Spin up a temporary webserver (standalone)
2: Place files in webroot directory (webroot)
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Select the appropriate number [1-2] then [enter] (press 'c' to cancel): 【 2 】
Enter email address (used for urgent renewal and security notices)
(Enter 'c' to cancel): 【メールアドレス(外部サーバでもOK)】
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Please read the Terms of Service at
https://letsencrypt.org/documents/LE-SA-v1.3-September-21-2022.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.
Please enter the domain name(s) you would like on your certificate (comma and/or
space separated) (Enter 'c' to cancel): 【ドメイン名】
Requesting a certificate for xxxxx.xx
Input the webroot for xxxxx.xx: (Enter 'c' to cancel): 【/usr/local/lsws/Example/html】
Successfully received certificate.
Certificate is saved at: /etc/letsencrypt/live/xxxxx.xx/fullchain.pem
Key is saved at: /etc/letsencrypt/live/xxxxx.xx/privkey.pem
This certificate expires on 2023-03-13.
These files will be updated when the certificate renews.
Certbot has set up a scheduled task to automatically renew this certificate in the background.
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
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
UNIXシステムアカウントとは別にメールアカウントを作るためバーチャルメールボックスという機能を使っています。メール保管ディレクトリは /var/mail とします。
$ sudo apt install postfix
# SMTP-AUTH用ユーザとグループ追加
$ sudo groupadd -g 10000 vmail
$ sudo useradd -u 10000 -g vmail -s /sbin/nologin vmail
# メール保管ディレクトリ作成
$ sudo mkdir /var/mail
$ sudo chown vmail:vmail /var/mail
$ sudo nano /etc/postfix/main.cf
------------------------------------------
# 詳細情報を隠すため簡略化
smtpd_banner = $myhostname ESMTP
# Let's Encryptの証明書に変更
smtpd_tls_cert_file=/etc/letsencrypt/live/[ドメイン名]/fullchain.pem
smtpd_tls_key_file=/etc/letsencrypt/live/[ドメイン名]/privkey.pem
# バーチャルメールボックスを使用する場合はlocalhostのみを指定
mydestination = localhost
# ↓↓末尾に追記↓↓
# SMTP-AUTH
smtpd_sasl_auth_enable = yes
smtpd_sasl_type = dovecot
smtpd_sasl_path = private/auth
smtpd_client_restrictions =
permit_mynetworks
permit_sasl_authenticated
reject_unknown_client
# Virtual Domain
virtual_mailbox_domains = [ドメイン名]
virtual_mailbox_base = /var/mail
virtual_mailbox_maps = hash:/etc/postfix/vmailbox
virtual_alias_maps = hash:/etc/postfix/virtual
virtual_gid_maps = static:10000
virtual_uid_maps = static:10000
# DKIM
milter_default_action = accept
milter_protocol = 6
smtpd_milters = unix:/opendkim/opendkim.sock
non_smtpd_milters = $smtpd_milters
# Other Security
disable_vrfy_command = yes
smtpd_helo_required = yes
strict_rfc821_envelopes = yes
smtpd_etrn_restrictions = permit_mynetworks, reject
smtpd_helo_restrictions = permit_mynetworks, reject_invalid_hostname
smtpd_sender_restrictions = reject_unknown_sender_domain
smtpd_recipient_restrictions = permit_mynetworks, reject_unauth_destination
$ sudo nano /etc/postfix/master.cf
------------------------------------------
# ↓コメントを外す
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
バーチャルメールボックスの設定ファイルを作成していきます。複数のドメインを使い分けする場合はvirtualファイルはいりません(上記の virtual_alias_maps もコメントアウト)。
$ sudo nano /etc/postfix/virtual
------------------------------------------
[ユーザ名1]@[ドメイン名] [ユーザ名1]
[ユーザ名2]@[ドメイン名] [ユーザ名2]
$ sudo nano /etc/postfix/vmailbox
------------------------------------------
[ユーザ名1]@[ドメイン名] [ユーザ名1]/
[ユーザ名2]@[ドメイン名] [ユーザ名2]/
# ↓複数のドメインを使い分けする例
#[ユーザ名3]@[ドメイン名2] [ドメイン名2]/[ユーザ名3]/
vmailboxの方では行末の / を忘れずに。
$ sudo postmap /etc/postfix/virtual
$ sudo postmap /etc/postfix/vmailbox
vmailboxは必要か?
無くても virtual_alias_maps を工夫すれば運用は可能ですが本来の使い方ではありません。調べると結構このパターンが多いですが、本記事ではvirtualとvmailboxを分けて設定します。こうする事でバーチャルドメインでも単一ドメインならユーザ名にドメインを付けなくても良くなります。
↓つまり上記の設定をしない場合、クライアント側の設定がこうなってしまう。
| ホスト名 | [ドメイン] |
| ユーザ名 | [ユーザ]@[ドメイン] |
| パスワード | [パスワード] |
Dovecot
通信は必ず暗号化するためパスワード認証はCRAM-MD5形式でなく平文でも安全です。もしOutlookで使いたいならパスワード認証の暗号化が必須になります。本記事では平文を使います。ですが、CRAM-MD5形式にしてもデメリットは少ないかと思います。
$ sudo apt install dovecot-imapd
$ sudo nano /etc/dovecot/conf.d/10-master.conf
------------------------------------------
service imap-login {
inet_listener imap {
port = 0 # コメントアウトするだけだとデフォルトポートで動作してしまう
}
inet_listener imaps {
port = 993
ssl = yes
}
:
:
:
# Postfix smtp-auth
unix_listener /var/spool/postfix/private/auth {
mode = 0660
user = postfix
group = postfix
}
$ sudo nano /etc/dovecot/conf.d/10-mail.conf
------------------------------------------
mail_location = maildir:/var/mail/%u
$ sudo nano /etc/dovecot/conf.d/10-auth.conf
------------------------------------------
#!include auth-system.conf.ext # コメントアウト
#!include auth-sql.conf.ext
#!include auth-ldap.conf.ext
!include auth-passwdfile.conf.ext
#!include auth-checkpassword.conf.ext
!include auth-static.conf.ext
$ sudo nano /etc/dovecot/conf.d/auth-passwdfile.conf.ext
------------------------------------------
passdb {
driver = passwd-file
args = username_format=%u /etc/dovecot/users
}
# userdb をコメントアウト
#userdb {
# :
# :
#}
$ sudo nano /etc/dovecot/conf.d/auth-static.conf.ext
------------------------------------------
userdb {
driver = static
args = uid=vmail gid=vmail home=/var/mail/%u
}
$ sudo nano /etc/dovecot/conf.d/10-ssl.conf
------------------------------------------
ssl_cert = </etc/letsencrypt/live/[ドメイン名]/fullchain.pem
ssl_key = </etc/letsencrypt/live/[ドメイン名]/privkey.pem
アカウントのパスワードを設定します。doveadm pw を使ってハッシュ化されたパスワードを生成し、usersファイルに保存します。
$ sudo doveadm pw
Enter new password:[パスワード]
Retype new password:[パスワード]
{CRYPT}$2y$05$tGPBaquyHNg0Sakkk0YZgeYIqyYvGnZnQaqeymVpdD5By15wwSpnS
$ sudo nano /etc/dovecot/users
------------------------------------------
[ユーザ名1]:{CRYPT}$2y$05$tGPBaquyHNg0Sakkk0YZgeYIqyYvGnZnQaqeymVpdD5By15wwSpnS
[ユーザ名2]:{CRYPT}$2y$05$ZfFb0zOIY7KGGDjh5n4/8uuhFOoFEklVDjuUXn0ca8F5jKFW5/tQO
$ sudo chown dovecot:dovecot /etc/dovecot/users
$ sudo chmod go-rw /etc/dovecot/users
メールの保管場所は/var/mail/%d/%n か /var/mail/%u か?
本記事では単一ドメインなので /var/mail/%u にしています。複数のドメインを使い分けする場合は/var/mail/%d/%n にすると良いでしょう。/%d/%n形式にする場合はmail_locationの変更も忘れずに。
$ sudo nano /etc/dovecot/conf.d/10-mail.conf
------------------------------------------
mail_location = maildir:/var/mail/%d/%n
------------------------------------------
OpenDKIM
セレクタ名は任意ですが、本記事では単一のKeyしか扱わないため default にします。
$ sudo apt install opendkim
$ sudo adduser postfix opendkim # ユーザ[postfix]をグループ[opendkim]に追加
# DKIM Milter用ディレクトリ作成
$ sudo mkdir /var/spool/postfix/opendkim
$ sudo chown opendkim:postfix /var/spool/postfix/opendkim
$ sudo nano /etc/opendkim.conf
------------------------------------------
Domain [ドメイン名]
Selector default
KeyFile /etc/dkimkeys/[ドメイン名]/default.private
Socket local:/var/spool/postfix/opendkim/opendkim.sock
$ sudo mkdir /etc/dkimkeys/[ドメイン名]
$ sudo opendkim-genkey -D /etc/dkimkeys/[ドメイン名] -d [ドメイン名]
$ sudo chown -R opendkim:opendkim /etc/dkimkeys
サーバ側の仕上げ
# ↓何も出力されなければOK
$ sudo postfix check
# 再起動
$ sudo systemctl restart postfix dovecot opendkim
# ↓active (running)ならOK
$ sudo systemctl status postfix
$ sudo systemctl status dovecot
# ↓これはまだOKにならない
$ sudo systemctl status opendkim
ここでエラーしても取り合えず進みましょう。
メーラー(クライアント側)の設定
メーラーはThunderbirdが通りやすいです。使う気が無くてもデバッグ目的に使うのもありかと。
受信側
| サーバー名 | [ドメイン名] |
| ポート | 993 |
| ユーザ名 | [ユーザ名] |
| 接続の保護 | SSL/TLS |
| 認証方式 | 通常のパスワード認証 |
送信側
| サーバー名 | [ドメイン名] |
| ポート | 465 |
| 接続の保護 | SSL/TLS |
| 認証方式 | 通常のパスワード認証 |
| ユーザ名 | [ユーザ名] |
送受信テスト
送信/受信共に可能かテストします。この時点ではまだ迷惑メール扱いされる可能性が高いです。送受信できなかったらずっと↓のFAQ参照。疲れたから止めた
ドメイン側のDNSレコード設定
送信ドメイン認証(SPFとDKIM)の設定をしていきます。/etc/dkimkeys/[ドメイン名]/default.txt の中身を整えてDNSレコードに追加する必要があります。作業をしやすくするためどうにかしてクライアント上のテキストエディタで開くことをお勧めします。盗聴されても問題無いデータなのでWebサーバに配置すると楽です。
# Webサーバに置く例
$ sudo cp /etc/dkimkeys/[ドメイン名]/default.txt /usr/local/lsws/Example/html/
$ sudo chmod 666 /usr/local/lsws/Example/html/default.txt
# コピーできたら削除する
$ sudo rm /usr/local/lsws/Example/html/default.txt
↓のようなテキストです。
default._domainkey IN TXT ( "v=DKIM1; h=sha256; k=rsa; "
"p=MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAqchsxtNg6uckZ2xH~~"
"Uvm3fzUFOaHJ9g+nx1EQ7cezWmOKb6LCbhFbfxCDO7loxDV0wDpvpHbr5U/jCe~~" ) ;
( " から " ) ; の中を改行・ダブルクォーテーションを消して結合します。
v=DKIM1; h=sha256; k=rsa; p=MIIBIjANBgkqhkiG9w0BAQEFAAO~~
そうしたらこのテキストとその他諸々をDNSレコードに追加していきます。※DNSレコードのルールはサービス元によって異なります。お名前.comだとこんな感じ↓です。
| ホスト名 | TYPE | TTL | VALUE |
| @ | MX | 3600 | [ドメイン] |
| @ | TXT | 3600 | v=spf1 +ip4:[IPv4アドレス] +ip6:[IPv6アドレス] -all |
| _adsp._domainkey.@ | TXT | 3600 | dkim=unknown |
| default._domainkey.@ | TXT | 3600 | v=DKIM1; h=sha256; k=rsa; p=MIIB~~ |
MXはメールを送信するドメインを記載します。これは古い習慣のような物です。次の v=spf1 +ip4: はSPFの設定です。それ以降の2行はDKIMの設定です。
DNSの更新は瞬時には反映されないので6分程待機。
お名前.comの場合
更新時に 転送用のネームサーバー にチェックが必要らしいです。
サーバ側の逆引き
さくらのVPSだとこんな感じ↓です。
送信ドメイン認証のテスト
クライアントからメールを送信します。送信先はYahooメールを使うと楽です。↓の画面に行き着けば目的達成です。これでももし迷惑メール判定されたら古いテストメールを消すなり文章をまともにすると通る確率が上がる気がします。
ちなみに、Gmailで 高度な暗号化 と表示させるには S/MIME が必要で、おそらく無料では出来ないと思われる。
FAQ
domainkeys=neutral (no sig) は正常?
DKIMがdomainkeys上位互換なので無視しても良いかと思う。
色々書こうと思ったけど疲れた