Redhat系OS + メールサーバーの構築

目次

概要

このドキュメントはLinux環境で安全なメールサーバーを構築するための手順です。

導入背景と選定理由

さくらVPSサーバー環境で、クライアントとWebメールがセキュリティの問題でGoogle等の大手からメール拒否されるようになったため、対応が必須になった。

事前準備

独自ドメインを取得してください。

1. サーバー基礎設定

1.1 さくらVPSサーバーの作成とSSHログイン

1.2 swap領域の解放とパッケージ更新

1.3 epelリポジトリ、Certbotのインストール

# インストール
sudo dnf -y install epel-release
sudo dnf -y install certbot

1.4 Virtualbox用メールユーザーの追加

# ユーザー追加(id:5000を指定)
sudo groupadd -g 5000 mailuser
sudo useradd -u 5000 -g mailuser -s /sbin/nologin mailuser

2. メールサーバーの構築

2.1 メールのドメイン設定

今回は以下のように3ドメインを同時運用する想定です。

2.2 Postfixインストールと詳細設定

# Postfixインストール
sudo dnf -y install postfix

# main.cfのバックアップ
sudo cp -rp /etc/postfix/main.cf /etc/postfix/main.cf_backup

# main.cfの設定
sudo vi /etc/postfix/main.cf

# 以下の行を修正
## 95行目あたり
#myhostname = virtual.domain.tld
↓
myhostname = mx.record-holder.tokyo

## 102行目あたり
#mydomain = domain.tld
↓
mydomain = record-holder.tokyo

## 118行目あたり
#myorigin = $mydomain
↓
myorigin = $mydomain

## 135行目あたり
inet_interfaces = localhost
↓
inet_interfaces = all

## 138行目あたり
inet_protocols = all
↓
inet_protocols = ipv4

## 183行目あたり
mydestination = $myhostname, localhost.$mydomain, localhost
↓
mydestination = $myhostname, localhost.$mydomain

## 283行目あたり
#mynetworks = 168.100.189.0/28, 127.0.0.0/8
↓
mynetworks = 168.100.189.0/28, 127.0.0.0/8, 10.0.0.0/24

## 315行目 そのまま
#relay_domains = $mydestination

## 429行目追加
# バーチャルドメインの設定(メールアドレスの@の後になる)
virtual_mailbox_domains = mx.record-holder.tokyo, mx.record-holder.jp, mx.record-holder.net
virtual_mailbox_base = /home/mailuser/mail
virtual_mailbox_maps = lmdb:/etc/postfix/vmailbox
virtual_minimum_uid = 100
virtual_uid_maps = static:5000
virtual_gid_maps = static:5000

# Virtual alias
virtual_alias_maps = lmdb:/etc/postfix/virtual

## 438行目
#home_mailbox = Maildir/
↓
home_mailbox = Maildir/

## 593行目追加
smtpd_banner = $myhostname ESMTP

## 736行目 追加
meta_directory = /etc/postfix
shlib_directory = /usr/lib64/postfix

## 以下 最終行へ追記
# SMTP VRFY コマンドは無効にする
disable_vrfy_command = yes

# クライアントに対して HELO コマンドを要求する
smtpd_helo_required = yes
# 1 メールのサイズを制限する
# 下例は 10M バイト
message_size_limit = 10240000

# SMTP-Auth の設定
smtpd_sasl_type = dovecot
smtpd_sasl_path = private/auth
smtpd_sasl_auth_enable = yes
smtpd_sasl_security_options = noanonymous
smtpd_sasl_local_domain = $myhostname
smtpd_recipient_restrictions = 
   permit_mynetworks,
   permit_sasl_authenticated,
   reject_unauth_destination, 
   permit

# 最終行に追記
# 送信元クライアントホストの DNS の正引きと逆引きが一致しない場合は接続要求を拒否する
smtpd_client_restrictions = permit_mynetworks, reject_unknown_client_hostname, permit

# FROM に設定されている送信者アドレスのドメインが DNS 登録にない または
# FQDN で登録されていない場合は接続要求を拒否する
smtpd_sender_restrictions = permit_mynetworks, reject_unknown_sender_domain, reject_non_fqdn_sender

# HELO コマンドを受信した際に 接続元ホスト名が DNS に登録されていない または FQDN で登録されていない場合は接続要求を拒否する
smtpd_helo_restrictions = permit_mynetworks, reject_non_fqdn_hostname, reject_invalid_helo_hostname, permit

# 最終行に追記 (証明書は自身は取得した証明書に置き換え)
smtpd_tls_cert_file = /etc/letsencrypt/live/mx.record-holder.tokyo/fullchain.pem
smtpd_tls_key_file = /etc/letsencrypt/live/mx.record-holder.tokyo/privkey.pem
smtpd_tls_session_cache_database = btree:${data_directory}/smtpd_scache
smtpd_tls_auth_only=yes
#smtp_tls_loglevel=1
#tls_server_sni_maps = hash:/etc/postfix/tls_sni_map

# master.cfの設定
sudo cp -rp /etc/postfix/master.cf /etc/postfix/master.cf_backup
sudo vi /etc/postfix/master.cf

#
# ====================================================================
# service type  private unpriv  chroot  wakeup  processlimit command
#                    (yes)     (yes)   (yes)
# ====================================================================

smtp      inet  n       -       n       -       -       smtpd

# --------------------------------------------------------------------
# SMTP Submission
# --------------------------------------------------------------------
submission inet n       -       n       -       -       smtpd
-o smtpd_tls_security_level=encrypt
-o smtpd_sasl_auth_enable=yes
-o smtpd_tls_auth_only=yes
-o smtpd_recipient_restrictions=permit_sasl_authenticated,reject
-o smtpd_relay_restrictions=permit_sasl_authenticated,reject
-o smtpd_client_restrictions=permit_sasl_authenticated,reject

2.3 Dovecotインストールと詳細設定

# Dovecotインストール
sudo dnf -y install dovecot

# dovecot.conf
sudo vi /etc/dovecot/dovecot.conf

## 30行目
listen = *, ::

# 10-auth.conf
sudo cp -rp /etc/dovecot/conf.d/10-auth.conf  /etc/dovecot/conf.d/10-auth.conf_backup
sudo vi /etc/dovecot/conf.d/10-auth.conf

## 10行目(平文認証を許可する場合、コメントアウト外す)
#disable_plaintext_auth = no

## 100行目(認証方法追加)
auth_mechanisms = plain
↓
auth_mechanisms = plain login

## 125行目
#!include auth-passwdfile.conf.ext
↓
!include auth-passwdfile.conf.ext

## 127行目
#!include auth-static.conf.ext
↓
!include auth-static.conf.ext

# 10-ssl.conf
sudo cp -rp /etc/dovecot/conf.d/10-ssl.conf  /etc/dovecot/conf.d/10-ssl.conf_backup
sudo vi /etc/dovecot/conf.d/10-ssl.conf

ssl = required

ssl_cert = </etc/letsencrypt/live/mx.record-holder.tokyo/fullchain.pem
ssl_key = </etc/letsencrypt/live/mx.record-holder.tokyo/privkey.pem

ssl_min_protocol = TLSv1.2

# 10-mail.conf
sudo cp -rp /etc/dovecot/conf.d/10-mail.conf  /etc/dovecot/conf.d/10-mail.conf_backup
sudo vi /etc/dovecot/conf.d/10-mail.conf

## 30行目
#mail_location =
↓
mail_location = maildir:~/Maildir    

# 10-master.conf
sudo cp -rp /etc/dovecot/conf.d/10-master.conf  /etc/dovecot/conf.d/10-master.conf_backup
sudo vi /etc/dovecot/conf.d/10-master.conf

## 107〜109行目
# Postfix smtp-auth
unix_listener /var/spool/postfix/private/auth {
    mode = 0666
    #user = postfix
    #group = postfix
}
↓
unix_listener /var/spool/postfix/private/auth {
    mode = 0666
    user = postfix
    group = postfix
}

# auth-passwdfile.conf.ext
sudo vi /etc/dovecot/conf.d/auth-passwdfile.conf.ext

# 21~24行目
userdb {
    driver = static
    args = uid=mailuser gid=mailuser home=/home/mailuser/mail/%d/%n
}

## dovecotを有効化する
sudo systemctl enable --now dovecot
↓を確認
Created symlink '/etc/systemd/system/multi-user.target.wants/dovecot.service' → '/usr/lib/systemd/system/dovecot.service'.

# dovecot再起動
sudo systemctl restart dovecot

# opensslで接続確認
openssl s_client -connect mx.record-holder.tokyo:993 -servername mx.record-holder.tokyo

# ユーザー設定
## パスワード設定
sudo doveadm pw -s SHA512-CRYPT

Enter new password: → パスワード入力
Retype new password: → パスワード再入力

## 以下のレスポンスをコピー
{SHA512-CRYPT}$6$eV/QPqGNW3WFHwCr$cn.ULhZPUon/TTxDz7c7X9nHcQl7wZ468iMtNAEqzy5D8F7hEOXxphIz2IX.Jsye.NwBeOrpVWieB8ZsEWFgE0

## 受信ユーザーファイルを開く
sudo vi /etc/dovecot/users
hoge@mx.record-holder.tokyo:コピーしたレスポンス

## 同様に以下のアドレスも追加
hoge@mx.record-holder.net
hoge@mx.record-holder.jp

2.4 複数ドメイン対応のLet's Encryptインストール

# 複数ドメイン対応SAN値のインストール
sudo certbot certonly \
--manual \
--preferred-challenges dns \
--email admin@mx.record-holder.tokyo \
--agree-tos \
-d mx.record-holder.tokyo \
-d mx.record-holder.net \
-d mx.record-holder.jp

# 以下の応答を確認
Please deploy a DNS TXT record under the name:

_acme-challenge.mx.record-holder.net.

with the following value:

{ランダムな文字列}

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Press Enter to Continue

※Enterは押さないで次の作業

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Please deploy a DNS TXT record under the name:

# ドメイン登録先のDNSにレコードを追加する

サブドメイン名  種別    値
_acme-challenge.mx.record-holder.net  TXT  {ランダムな文字列}

Googleのdigで追加DNSレコードが反映されるか確認
https://toolbox.googleapps.com/apps/dig/#TXT/_acme-challenge.mx.record-holder.net.

# Enterを押して、以下を確認
Successfully received certificate.

# 証明書の確認
sudo certbot certificates

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Found the following certs:
Certificate Name: mx.record-holder.tokyo
    Serial Number: 524cc97e7b4e0ffb736302cf359326dfdb8
    Key Type: ECDSA
    Domains: mx.record-holder.tokyo mx.record-holder.net mx.record-holder.jp
    Expiry Date: 2026-11-12 00:38:09+00:00 (VALID: 89 days)
    Certificate Path: /etc/letsencrypt/live/mx.record-holder.tokyo/fullchain.pem
    Private Key Path: /etc/letsencrypt/live/mx.record-holder.tokyo/privkey.pem
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

2.5 Postfixの有効化、起動

sudo systemctl enable --now postfix
# 以下のメッセージを確認
Created symlink '/etc/systemd/system/multi-user.target.wants/postfix.service' → '/usr/lib/systemd/system/postfix.service'.
# 状態の確認
sudo systemctl status postfix

2.6 バーチャルメールボックスの設定

sudo vi /etc/postfix/vmailbox

record-holder.tokyo DOMAIN
hoge@mx.record-holder.tokyo mx.record-holder.tokyo/hoge/Maildir/
record-holder.jp DOMAIN
hoge@mx.record-holder.jp mx.record-holder.jp/hoge/Maildir/
record-holder.net DOMAIN
hoge@mx.record-holder.net mx.record-holder.net/hoge/Maildir/

# フォーマットをlmdb方式にしてpostmap(1回目だけ)
postmap lmdb:/etc/postfix/vmailbox
postmap /etc/postfix/vmailbox

2.7 Let's Encryptの確認

# SSLの有効期限が設定されているか
sudo certbot certificates
# SMTP/IMAPのポートが解放されているか
sudo ss -lntp | grep -E ':25|:587|:993'

2.8 メールクライアントの設定

# アカウント設定

Thunderbirdを起動
アカウントを追加→「メールアカウント」を選択

氏名:任意
メールアドレス:hoge@mx.record-holder.tokyo

「続ける」ボタンをクリック

以下が初期設定として画面表示される

受信IMAP
サーバー:mx.record-holder.tokyo
ポート番号:993
セキュリティ:SSL/TLS
ユーザー名:hoge
認証:通常のパスワード認証

送信SMTP
サーバー:mx.record-holder.tokyo
ポート番号:587
セキュリティ:STARTTLS
ユーザー名:hoge
認証:通常のパスワード認証

「設定を編集」をクリック

IMAP設定。以下を変更
・認証方式:自動検出
・ユーザー名:hoge@mx.record-holder.tokyo

「続ける」をクリック

SMTP設定。以下を変更
・認証方式:自動検出
・ユーザー名:hoge@mx.record-holder.tokyo

「テスト」をクリック
画面上に「次のアカウント設定が、指定されたサーバーを調べることにより見つかりました: 」と出たら「続ける」をクリック
設定したパスワードを入力
→パスワードが正しければ、アカウントが追加される

hoge@mx.record-holder.tokyo が成功したら同様にhoge@mx.record-holder.jp、hoge@mx.record-holder.netもアカウント追加。

2.9 OpenDKIMのインストール、設定、DNSレコードの追加

# EPEL, CRB からインストール
sudo dnf --enablerepo=epel,crb -y install opendkim opendkim-tools

# DKIM の設定確認
sudo vi /etc/opendkim.conf
↓の設定になっていること
KeyFile /etc/opendkim/keys/default.private

# DKIM を設定するドメイン用のディレクトリ作成
sudo mkdir -p /etc/opendkim/keys

# root権限で鍵を作成
cd /etc/opendkim/keys
sudo opendkim-genkey -b 2048 -d mx.record-holder.tokyo -s default
sudo ls -l /etc/opendkim/keys/

-rw------- 1 opendkim opendkim 1704 Aug 15 21:12 default.private ←秘密鍵
-rw------- 1 root     root      508 Aug 15 21:12 default.txt ←公開鍵

# 秘密鍵の権限を設定
sudo chown opendkim:opendkim /etc/opendkim/keys/default.private
sudo chmod 600 /etc/opendkim/keys/default.private

# 公開鍵の確認
sudo cat /etc/opendkim/keys/default.txt

default._domainkey	IN	TXT	( "v=DKIM1; k=rsa; "
  "p=MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA8YxQwWj0nQfSuTAdv6B7DIbt+rR4nHNpXuHi9mLAscoJQsqs8sI4JhfbRJwrkURCj4eDoJj91yS7K5yILyV7I347Xe0iP7dn8AGvzHFRPWwN26DXybCdf52N6mWI7zxiygJeD8ma2VXUzE4eYnwIwrqBYALTW3vnyf92BR4LKZqS2Uj4x4f4Wc6hI5avCkmMJ0ns/hhxyiyfun"
  "06McPJGZ7JqH1uQaBY73f6omsMQZZsbjo0sMFfE6qQ87CqfDTHqbl1AXxljiE/U9IEGPslxUoiWKRZVqMFd1/oPggE0G/LDEFwxgRxFMrsoUQL6Hf1n89PwFQ4KQxG7x+80VWLywIDAQAB" )  ; ----- DKIM key default for mx.record-holder.tokyo


# DNS サーバー(onamae)へMXレコードと公開鍵を登録します。
## record-holder.tokyo

# MXレコード
mx.record-holder.tokyo    IN      A   ${メールサーバーのIPアドレス}
mx.record-holder.tokyo    IN      MX  mx.record-holder.tokyo    10

# 公開鍵 
default._domainkey.mx     IN      TXT     v=DKIM1; k=rsa; p=MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA8YxQwWj0nQfSuTAdv6B7DIbt+rR4nHNpXuHi9mLAscoJQsqs8sI4JhfbRJwrkURCj4eDoJj91yS7K5yILyV7I347Xe0iP7dn8AGvzHFRPWwN26DXybCdf52N6mWI7zxiygJeD8ma2VXUzE4eYnwIwrqBYALTW3vnyf92BR4LKZqS2Uj4x4f4Wc6hI5avCkmMJ0ns/hhxyiyfun06McPJGZ7JqH1uQaBY73f6omsMQZZsbjo0sMFfE6qQ87CqfDTHqbl1AXxljiE/U9IEGPslxUoiWKRZVqMFd1/oPggE0G/LDEFwxgRxFMrsoUQL6Hf1n89PwFQ4KQxG7x+80VWLywIDAQAB

## record-holder.jp(ムームードメイン)
mx.record-holder.jp       IN      A   ${メールサーバーのIPアドレス}
mx.record-holder.jp       IN      MX  mx.record-holder.jp   10
default._domainkey.mx     IN      TXT     上と同じ 

## record-holder.net(バリュードメイン)
mx.record-holder.net      IN      A   ${メールサーバーのIPアドレス}
mx.record-holder.net      IN      MX  mx.record-holder.net  10
default._domainkey.mx     IN      TXT     上と同じ 

# OpenDKIMの再起動
sudo systemctl status opendkim
sudo systemctl enable opendkim
sudo systemctl start opendkim
sudo systemctl status opendkim
→activeならば正常。
→エラーが出ている場合は、/etc/opendkim/keys のディレクトリ権限を修正
sudo chown root:opendkim /etc/opendkim/keys

# /etc/postfix/main.cf 最終行に追記 opendkimの設定
smtpd_milters = unix:/run/opendkim/opendkim.sock
non_smtpd_milters = $smtpd_milters
milter_default_action = accept

# メール送信時にメールログ以下のエラーが出ていた場合、ユーザーpostfixをグループopendkimに追加
warning: connect to Milter service unix:/run/opendkim/opendkim.sock: Permission denied

sudo usermod -aG opendkim postfix
id postfix
sudo systemctl restart postfix

2.10 DNSレコードの追加(SPF、DMARC)と確認

record-holder.tokyoから設定。

# SPF
mx  IN  TXT v=spf1 ip4:${メールサーバーのIPアドレス} -all

# DMARC
_dmarc.mx  IN  TXT v=DMARC1; p=none; adkim=r; aspf=r

# 時間をおいてから確認
dig TXT mx.record-holder.tokyo +short
→ v=spf1 ip4:${メールサーバーのIPアドレス} -all が反映されていること
dig TXT _dmarc.mx.record-holder.tokyo +short
→ v=DMARC1; p=none; adkim=r; aspf= が反映されていること

# 反映が確認できたら、ほかのドメインにも適用

2.11 動作確認テスト

* 作成したメールアドレスどうしで送受信 
* 作成したメールアドレスに外部から送信
* IMAP稼働確認
    * sudo ss -lntp | grep ':993'
    * openssl s_client -connect mx.record-holder.tokyo:993 -servername mx.record-holder.tokyo
    * sudo journalctl -u dovecot -f
* SMTP Submission確認
    * sudo ss -lntp | grep ':587'
    * openssl s_client \
    -connect mx.record-holder.tokyo:587 \
    -servername mx.record-holder.tokyo \
    -starttls smtp \
    -crlf
    * 接続状態のまま、EHLO test.example
    250-mx.record-holder.tokyo
    250-PIPELINING
    (省略)
    250 CHUNKING

サーバー設定あとがき

実際のサーバーの操作をもとに、手順書として残しました。
ちなみにAWSのEC2はOBP25bのSMTPポート制限に引っかかるので、AWS SESを使うのが一般的です。
メールヘッダーのFromはどこのドメインから送信しても、$myhostnameに指定されている、mx.record-holder.tokyoになります。
OSもRHEL系の9と10では変化があり、大きなところではmapの形式がhashからlmdbに変わっています。
9のときにインストールに苦労した部分も10では解消されていたりしますので、ぜひ新しいOSをお試しください。