技術検証：自宅のAlmaLinux 9.3でのメールサーバー構築およびメール送信の検証

## はじめに
本記事では、AlmaLinux 9.3 上にメールサーバーを構築する手順を解説します。メールサーバーは企業や個人システムにおいて、重要な役割を果たしています。

:::note warn
**今回は、Postfix を使ってSMTPサーバーを構築し、Dovecot を使用してIMAP/POPサーバーのセットアップを行います。**
:::

さらに、SMTP認証設定やメール送信テストを実施し、最終的に個人のGmailにメールが送信できる状態を目指します。

## 前提条件
今回の検証を進めるにあたり、以下の環境が必要です。

:::note info
**検証環境**
- **Linuxディストリビューション:**
仮想環境または実際のサーバーで稼働しているLinux（本記事ではAlmaLinux 9.3を使用）

- **管理者権限を持つユーザーアカウント:**
sudo権限でコマンド操作が可能

- **ドメイン名（example.com など）**
前回の記事で無料ドメインを取得している前提です。まだの方は、[No-IPを使って無料でドメインを取得する方法](https://qiita.com/free-honda/items/133f6a47a92f996b2dd4)をご参照ください
:::

**自宅のVirtualBox環境**
今回も VirtualBox 上で構築した検証環境を使用します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3662571/70df8950-ddfa-2728-1d71-60373a8276e9.png)


:::note info
※検証には実行中の「AlmaLinux」を使用します。
:::

## 知識整理

メールサーバーを構築するにあたり、次の知識や環境設定が必要です。

:::note info
**・Linuxの基本操作**
**・PostfixやDovecotに関する基礎知識**
**・セキュリティ設定（ファイアウォールやSSL）**
:::

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3662571/5e19959f-2813-b304-20e7-099924ae785a.png)
引用画像：https://qiita.com/N-line/items/fe1e80497bef34d79443

メール配送のプロセスは少し複雑ですが、この流れを理解しておくと、構築作業がスムーズに進められます。

:::note warn
メールの配送は、以下のような流れで行われます。
**①MUAからメールが送信され、MTA（メール転送エージェント）に送られる**
**②送信されたMTAが、次のMTAにメールを転送**
**③最後にMDAが受け取り、MRAを通じて受信者のMUAにメールが届く**
:::

## 構築・検証の流れ

メールサーバーを構築する手順について、以下の6つのステップに分けて詳しく解説します。

:::note 
- **ステップ1: 必要なパッケージのインストール**
- **ステップ2: Postfixの設定**
- **ステップ3: SASLのインストールとDovecotの設定**
- **ステップ4: ファイアウォール設定**
- **ステップ5: SMTP認証設定**
- **ステップ6: メール送信テスト**
:::

事前に検証環境が構築されていることが前提としています。

## ステップ1: 必要なパッケージのインストール
まず、メールサーバーを構築するために必要なソフトウェアをインストールします。Postfix、Dovecot、その他関連パッケージをAlmaLinuxの公式リポジトリからインストールします。

```
sudo dnf update -y
sudo dnf install -y postfix dovecot opendkim opendkim-tools spamassassin clamav
```

**エラー発生**

このエラーは、opendkimとopendkim-toolsの依存ライブラリが見つからないことが原因です。

```
[root@HONDA-TEST ~]# sudo dnf install -y postfix dovecot opendkim opendkim-tools spamassassin clamav
Last metadata expiration check: 0:07:55 ago on Sat 21 Sep 2024 05:42:28 AM JST.
Package postfix-2:3.5.9-24.el9.x86_64 is already installed.
Error:
 Problem 1: conflicting requests
  - nothing provides libmilter.so.1.0()(64bit) needed by opendkim-2.11.0-0.36.el9.x86_64 from epel
  - nothing provides libmemcached.so.11()(64bit) needed by opendkim-2.11.0-0.36.el9.x86_64 from epel
 Problem 2: conflicting requests
  - nothing provides libmemcached.so.11()(64bit) needed by opendkim-tools-2.11.0-0.36.el9.x86_64 from epel
(try to add '--skip-broken' to skip uninstallable packages or '--nobest' to use not only best candidate packages)
```

:::note warn
具体的には、以下のライブラリが欠落していることが原因となります。
**・libmilter.so.1.0**
**・libmemcached.so.11**
:::

**解決策**
手動での追加を試みましたが、解決しなかったため、**--skip-brokenオプション**を使って依存関係の解決ができないパッケージをスキップしました。

```
sudo dnf install -y postfix dovecot opendkim opendkim-tools spamassassin clamav --skip-broken
```

正常にpostfixがインストールされました。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3662571/175048b3-d696-6858-cd18-64240ba6b6fd.png)

## ステップ2: Postfixの設定
Postfixはデフォルトでインストール後すぐに使用可能ですが、特定のメールドメインやネットワークに対応するために設定を変更する必要があります。

**Postfixメイン設定ファイルの編集**
以下のコマンドで設定ファイルを編集します。

```
sudo vi /etc/postfix/main.cf
```

設定ファイルに次の設定を追加または編集します。

```/etc/postfix/main.cf
# 以下のパラメータはそれぞれの場所で編集していく
myhostname = mailtest.hopto.org # 取得したドメインのFQDN
mydomain = mailtest.hopto.org   # 取得したドメインのFQDN
myorigin = $mydomain            # メール送信の際に送信元メアドの@以降に自分のドメイン名を付加
inet_interfaces = all           # 全てのIFからの受信を許可
mydestination = $myhostname, localhost.$mydomain, localhost ＃ 作ったドメイン宛のメールを受信できるようにする
mynetworks = 192.168.1.0/24, 127.0.0.0/8, [::1]/128     # 自宅のLAN内を指定
relayhost = [smtp.gmail.com]:587　＃ GoogleのSMTPサーバを経由してメール送信
home_mailbox = Maildir/ # Maildir形式で受信したいので、ホームディレクトリからの相対パス名を指定する
smtpd_banner = ESMTP MTA        # バナーを固定値にすることで特定のバージョンを狙った攻撃を防ぐ

# 残りは最終行に追加
smtpd_sasl_auth_enable = yes    
# SMTPサーバのアクセス制限設定
smtpd_recipient_restrictions =
    permit_mynetworks
    permit_sasl_authenticated
    reject_unauth_destination
message_size_limit = 10485760
# Gmailを使用する際のSASL認証設定
smtp_use_tls = yes
smtp_sasl_auth_enable = yes
smtp_sasl_password_maps = hash:/etc/postfix/sasl_passwd
smtp_sasl_tls_security_options = noanonymous
smtp_sasl_mechanism_filter = plain
```
:::note warn
「#」がついたコメント行は設定ファイルに不要なので削除してください。これを削除しないとサービス起動時にエラーが発生する可能性があります。
:::

以下のサイトにもパラメーター解説がありますので、ご参照ください。

https://inaba-serverdesign.jp/blog/20160620/postfix_send_mail.html

次に、master.cfを編集します。

```
vi /etc/postfix/master.cf
```

以下のコメント行を解除します。

```/etc/postfix/master.cf
submission inet n       -       n       -       -       smtpd　　　#コメントアウトを解除
  -o smtpd_sasl_auth_enable=yes　　　          　　　　　　　　                #コメントアウトを解除
```

## ステップ3: SASLのインストールとDovecotの設定
SASLを使用することで、実際に使われる認証方式をSASLに任せ、特定の認証方式に縛られずに利用できます。

以下のコマンドを実行して、必要なライブラリをインストールします。

```
dnf install cyrus-sasl cyrus-sasl-plain
```

事前に、以下のサイトを参考にしながらGmailの「アプリパスワード」を取得する必要があります。

https://www.yukibnb.com/entry/g_app_password

取得した専用パスワードを使い、以下のコマンドを実行します。

:::note info
**Gmailのメールアドレスとアプリパスワードの箇所は、ご自身の環境に合わせて修正してください。**
:::

```
# sasl_passwdの作成
echo [smtp.gmail.com]:587 Gmailのメールアドレス:アプリパスワード(16桁) > /etc/postfix/sasl_passwd
# sasl_passwdのアクセス権をrootのみに制限
chmod 640 /etc/postfix/sasl_passwd
# データベースの作成
postmap /etc/postfix/sasl_passwd
```

次に、Dovecotの設定ファイルを編集します。以下の箇所のコメントを解除または値を修正します。

```
vi /etc/dovecot/conf.d/10-mail.conf

**編集内容**
mail_location = maildir:~/Maildir # メールボックスの形式をMaildirに設定
```

```
vi /etc/dovecot/conf.d/10-auth.conf

**編集内容**
disable_plaintext_auth = no 　　　　# プレーンテキスト認証を許可
```


**Postfixサービス関連の起動と自動起動設定**
設定を変更後、Postfixおよび関連サービスを起動し、saslauthdのスタートと自動起動を有効にします。

```
sudo systemctl start postfix
sudo systemctl enable postfix

sudo systemctl start saslauthd
sudo systemctl enable saslauthd

sudo systemctl start dovecot
sudo systemctl enable dovecot
```

## ステップ4: ファイアウォール設定

メールサーバーが外部からアクセスできるよう、SMTP（ポート25）、IMAP（ポート143）、POP3（ポート110）の通信を許可します。

```
sudo firewall-cmd --permanent --add-service=smtp
sudo firewall-cmd --permanent --add-service=imap
sudo firewall-cmd --permanent --add-service=pop3
sudo firewall-cmd --reload
```

## ステップ5: SMTP認証設定

ここでは、認証に使用する「testmail」というLinuxアカウントを作成します。

```
useradd testmail
passwd testmail
```

次に、SMTP認証に使用する「testmail」アカウントのパスワードを設定します。

```
echo '任意のパスワード' | saslpasswd2 -p -u honda.zapto.org -c testmail
```


```
[root@HONDA-TEST ~]# sasldblistusers2
testmail@honda.zapto.org: userPassword
[root@HONDA-TEST ~]#
```

:::note info
**honda.zapto.orgの箇所は、ご自身のドメイン名に置き換えてください。**
:::

SASL認証のデータベースファイルを作成し、postfix グループに変更します。

```
sudo touch /etc/sasl2/sasldb2
sudo chgrp postfix /etc/sasl2/sasldb2
```
適切なパーミッションを設定し、Postfixを再起動します。

```
sudo chmod 640 /etc/sasl2/sasldb2
sudo systemctl restart postfix
```

## ステップ6: メール送信テスト
設定が完了したら、メールサーバーの動作確認を行います。外部のメールクライアントを使用して、SMTPによる送信や、IMAP/POP3による受信をテストします。

```
[root@HONDA-TEST ~]# sendmail -t <<EOL
> From: 〇〇@gmail.com #送信元
> To: 〇〇@gmail.com #送信先
> Subject: テストメール
> テストメールになります。
> EOL
[root@HONDA-TEST ~]#
```

:::note alert
**私の環境では、ホスト名の完全修飾ドメイン名（FQDN）として解決できず、以下のエラーが発生しました。**
```
My unqualified host name (HONDA-TEST) unknown; sleeping for retry
unable to qualify my own domain name (HONDA-TEST) -- using short name
```

このエラーは、/etc/hosts ファイルに以下のエントリーを追加することで解消されました。
```
vi /etc/hosts

**追記内容**
127.0.0.1   HONDA-TEST honda.zapto.org
```


:::

新しいセッションとしてテラタームなどからSSH接続を行い、リアルタイムでログを確認します。
```
sudo tail -f /var/log/maillog

**ログ結果**
Sep 22 10:08:10 HONDA-TEST postfix/local[14154]: 170012220CF2: to=<root@honda.zapto.org>, relay=local, delay=2.7, delays=2.5/0.18/0/0.02, dsn=2.0.0, status=sent (delivered to maildir)
```

**dsn=2.0.0 と表示されていれば、メール送信が成功しています。**

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3662571/40206bc7-292f-4cc1-053b-1d040455032f.png)

実際にメールBOXに届いていることも確認できました(テスト検証のため、2回送りました)。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3662571/94560642-c2b8-c3b5-1052-435041ce4d8a.png)


## まとめ

この記事では、SASLのインストールからDovecotやPostfixの設定、ファイアウォールの構成まで、メールサーバーのセットアップをしてきました。

:::note warn
**正直、今回のメールサーバーの構築にはかなり苦戦し、エラー解消にかなり時間がかかりましたが、なんとか乗り越えました。**
:::

トラブルシューティングの具体的な対処法も載せてあるので、同じようにハマった人には役立つ内容になれば幸いです！

## おまけ

sendmailコマンド実行後、「Permission denied エラー」でメールディレクトリの作成に失敗した場合の対処方法の紹介になります。

```
<root@honda.zapto.org>, relay=local, delay=3.2, delays=3/0.12/0/0.08, dsn=5.2.0, status=bounced (maildir delivery failed: create maildir file /root/Maildir/tmp/1726962970.P7684.HONDA-TEST: Permission denied)
```

:::note alert
**これは、Postfixが /root/Maildir/tmp/ にメールを保存できないために、メール配信が失敗するケースです。この問題を回避するためには、Maildirの作成と権限設定を以下の手順で行います。**
:::

まず、Maildirが正しく作成されているか確認します。次のコマンドでMaildirの存在を確認してください。
```
ls -l /root/Maildir
```

Maildirが存在しない場合は、次のコマンドで再作成します。
```
sudo mkdir -p /root/Maildir/{cur,new,tmp}
```

権限が正しく設定されているか確認し、必要に応じて再設定します。
```
sudo chown -R root:root /root/Maildir
sudo chmod -R 700 /root/Maildir
```

設定を適用するためにPostfixを再起動します。
```
sudo systemctl restart postfix
```

## 参考記事
https://qiita.com/N-line/items/fe1e80497bef34d79443

https://qiita.com/minnsou/items/357fc3d081e1f7baeb1c

https://www.kagoya.jp/howto/it-glossary/mail/postfix/