自宅のAlmaLinuxでメールサーバ構築

勉強のために自宅でメールサーバを構築したので、その方法をメモがてら公開します。

### この記事でやること

自分の**好きなFQDNを取得**し、そのドメイン名で**メールの送受信**ができるメールサーバを0から構築する

（メールサーバに使うOSはCent OSの後継になりそうな[AlmaLinux](https://almalinux.org/)を使用）

### 詳細な要件

ネットワーク関連
- 自宅のLAN内のメールサーバのIPは192.168.1.100（固定IP）
- 自宅のLAN内のゲートウェイのIPは192.168.1.1/24
- 今回取得するFQDNは「mailtest.hopto.org」（[no-ip](https://www.noip.com/d)を使って取得）
- グローバルIPアドレスはホームゲートウェイのWAN側インタフェースに設定されていて、NATによりメールサーバのIPアドレスに変換させる（普通の家のネットワークはこの形になると思います）
- 自宅からインターネットに公開するのはメールサーバのTCP25番ポートのみ

サーバ関連
- OSバージョン：AlmaLinux 9.3
- メール転送エージェント(SMTP)：postfix 3.5.9
- メール配送エージェント(POP/IMAP)：Dovecot 2.3.16
- （複数サーバ建てるのは面倒なので）メールの送信受信機能は全て1つのサーバに集約
- メールを送受信するユーザ名：mailuser

その他
- メール送信にはGoogleのメールサーバを経由させる（Googleアカウントが必要）
- メールクライアントソフトは[Thunderbird](https://www.thunderbird.net/ja/)を使用する（インストールするホストはメールサーバとは別のPC）


# 1. FQDN取得

[no-ip](https://www.noip.com/d)より好きなFQDNを取得します。
取得できるFQDNを適当に選び、「Sign Up」からアカウント登録を完了させます。
テスト用のメールサーバなので、私は無料のFQDNから要件通り「mailtest.hopto.org」を選びました。

![スクリーンショット 2024-04-12 23.29.56.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/395943/2fd35cbf-5400-1bba-4dd5-ec8868ce5d5e.png)

以下の画像を参考にAレコードを登録してください。黒塗り部分は自宅のグローバルIPになっているはずです。
自宅のグローバルIPがわからない人は[cman](https://www.cman.jp/network/support/go_access.cgi)に行って確認してください。

![スクリーンショット 2024-04-12 23.33.24.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/395943/df237aa7-01ac-b2a8-ca3f-0c70ae5aed1a.png)


# 2. AlmaLinux初期構築

ISOを入手してインストールします。細かい手順はメールサーバ構築から外れるので割愛します。
https://almalinux.org/get-almalinux/

IPアドレスは要件通り192.168.1.100に固定しておきます。


```
# ネットワークIFの確認(ここではIF名はens190とします)
nmcli device
# 固定したいIPアドレスの設定
nmcli connection modify ens190 ipv4.address 192.168.1.100/24
# ホームゲートウェイの設定
nmcli connection modify ens190 ipv4.gateway 192.168.1.1
# DHCPではなく手動設定に
nmcli connection modify ens190 ipv4.method manual
# DNSの設定
nmcli connection modify ens190 ipv4.dns 192.168.1.1
# rebootしてもネットワークI/Fが上がるように（これはお好みで）
nmcli connection modify ens190 connection.autoconnect yes
# 再起動
reboot
```

ちなみに`/etc/NetworkManager/system-connections/ens190.nmconnection`というファイルを編集しても同じ結果が得られます。[^1]

ただ、固定IPのやり方はメールサーバ構築とは直接関係はないので、詳細を知りたければ以下の記事を参照してください。

https://qiita.com/miriwo/items/5791f552055fda573cf3

[^1]:CentOS7では`/etc/sysconfig/network-scripts/ifcfg-ens190`でしたが、廃止になったようです。


ここで`dig`コマンドより、先ほど自分で登録したFQDNが名前解決できるか確認します。

```
# digコマンドのインストール
dnf install bind-utils
# 先ほど登録したFQDNの名前解決を試す
dig mailtest.hopto.org
```

以下のようにdigコマンドが帰ってきて、自宅のグローバルIPが見えていればOKです。
（写真の白塗りの部分）

![スクリーンショット 2024-04-12 23.39.01.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/395943/735c38f4-5e6b-9e1e-5537-853ce6c56da0.png)


# 3.postfixのインストールと設定

postfixは現時点（2024年4月）でインストールできる3.5.9を入れます。

```
# 情報収集
[root@localhost ~]# dnf info postfix
Last metadata expiration check: 2:26:45 ago on Fri Apr 12 20:44:11 2024.
Available Packages
Name         : postfix
Epoch        : 2
Version      : 3.5.9
Release      : 24.el9
Architecture : x86_64
Size         : 1.4 M
Source       : postfix-3.5.9-24.el9.src.rpm
Repository   : appstream
Summary      : Postfix Mail Transport Agent
URL          : http://www.postfix.org
License      : (IBM and GPLv2+) or (EPL-2.0 and GPLv2+)
Description  : Postfix is a Mail Transport Agent (MTA).

# postfixのインストール
[root@localhost ~]# dnf install postfix
```

なお、CentOS7ではデフォルトが2.5.4なので、
同じようにyumでインストールするとopenssl関連のエラーが出るかもしれませんが、ここでは詳細は触れません[^2]。

[^2]:もしエラーが出た場合は[ここ](https://qiita.com/gunkan8mmt/items/d9b90c2114e738b31474)を参考にopensslを入れ直してください。


postfixにはメールサーバの設定を記載する`main.cf`、各種デーモンの設定を記載する`master.cf`というファイルがあります。それぞれを編集していきます。

編集の前にまずは好みのエディタをインストールしてください。

```
dnf install emacs
```


それでは`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     # 自宅のLAN内を指定
relayhost = [smtp.gmail.com]:587　＃ GoogleのSMTPサーバを経由してメール送信
home_mailbox = Maildir/ # Maildir形式で受信したいので、ホームディレクトリからの相対パス名を指定する
smtpd_banner = ESMTP MTA        # バナーを固定値にすることで特定のバージョンを狙った攻撃を防ぐ

##################
# 以降は最終行に追加
##################

# SMTP認証を有効化
smtpd_sasl_auth_enable = yes
# SMTPサーバのアクセス制限設定
smtpd_recipient_restrictions =
    permit_mynetworks
    permit_sasl_authenticated
    reject_unauth_destination

# 受信メールサイズの上限を10MBに設定(10 * 1024 * 1024)
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
```

ちなみに**行の途中ではコメントを使えない**ためそのまま入りつけるとエラーになります。ご注意ください。
なお、以下のサイトにも簡単なパラメータ解説がありますので参考にしてください。

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


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

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


# 4.SMTP認証に必要なライブラリ（SASL）のインストール

SASLとは「Simple Authentication and Security Layer」の略で、認証やセキュリティに関する処理(暗号化など)を行うための層です。
SASLを使用するアプリケーションなどは、実際に使われる認証方式のことはSASLにまかせてしまうことで、特定の認証方式に縛られなくて済むようになります。

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

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

今回はGoogleアカウントを使ってメールのリレーをするので、Googleアカウントに関するSASL認証用ファイルの作成をしていきます。

https://qiita.com/tomokei5634/items/f8671a8f1414a8aec3ee

上記を参考にしながら、Googleアカウントのアプリのパスワードを設定します。
なお2024年4月現在、Google側はアプリパスワードをあまり使ってほしくないのか、セキュリティタブからは表示がされません。下記の画面のように検索すると出てきます。[^3]

[^3]: 二段階認証を有効にしているGoogleアカウントでないと「アプリパスワード」と検索しても出てこないので注意してください。

![スクリーンショット 2024-04-13 1.13.28.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/395943/729bb75f-7b6e-97d0-fe38-15bd6d77dd3a.png)

そこで専用のアプリパスワードを作成し、16桁のパスワードを控えてください。

```
# 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
```

設定が完了したらpostfix、saslauthdをスタート＆有効化させます。

```
# postfixのスタートと有効化
systemctl start postfix
systemctl enable postfix

# saslauthdのスタートと有効化
systemctl start saslauthd
systemctl enable saslauthd
```

# 5. 受信メールサーバ構築

dovecotは現時点（2024年4月）でインストールできる2.3.16を入れます。

```
[root@localhost ~]# dnf info dovecot
Last metadata expiration check: 0:30:57 ago on Sat Apr 13 00:07:46 2024.
Installed Packages
Name         : dovecot
Epoch        : 1
Version      : 2.3.16
Release      : 10.el9
Architecture : x86_64
Size         : 18 M
Source       : dovecot-2.3.16-10.el9.src.rpm
Repository   : @System
From repo    : appstream
Summary      : Secure imap and pop3 server
URL          : https://www.dovecot.org/
License      : MIT and LGPLv2
Description  : Dovecot is an IMAP server for Linux/UNIX-like systems, written with security
             : primarily in mind.  It also contains a small POP3 server.  It supports mail
             : in either of maildir or mbox formats.
             : 
             : The SQL drivers and authentication plug-ins are in their subpackages.

[root@localhost ~]# dnf install dovecot

```

以下、dovecotに関する設定ファイルを編集してきます。


```/etc/dovecot/conf.d/10-mail.conf
mail_location = maildir:~/Maildir # メールボックスの形式をMaildirに
```

```/etc/dovecot/conf.d/10-auth.conf
disable_plaintext_auth = no 　　　　# プレーンテキスト認証を許可する
```

```/etc/dovecot/conf.d/10-ssl.conf
ssl = no　　　　　　　　　　　　　　　　# SSL接続をしない
```

設定が完了したらdovecotをスタート＆有効化させます。

```
# dovecotのスタートと有効化
systemctl start dovecot
systemctl enable dovecot
```


# 6.自ドメインメールサーバ用のSMTP認証設定

認証に使うメールユーザを作成します。
最初の要件通りアカウント名は「mailuser」とします。

```
useradd mailuser            # mailuserのユーザ追加（Linuxのアカウントを作成）
passwd mailuser 　　　　　　　# mailuserのパスワード設定
```
ユーザのパスワードは好きに設定してください。

SMTP認証設定をしていきます。

```
# SMTP認証に使うmailuserアカウントのパスワード設定
echo '好きなパスワード' | saslpasswd2 -p -u mailtest.hopto.org -c mailuser
```


```
# 設定した内容の確認
[root@localhost ~]# sasldblistusers2
mailuser@mailtest.hopto.org: userPassword  # 作成した内容で表示される
[root@localhost ~]# 

# もしユーザ名やFQDNを間違えたら-dを使って削除
[root@localhost ~]# saslpasswd2 -d (ユーザ名) -u (FQDN)
```

```
chgrp postfix /etc/sasl2/sasldb2　         # postfixが読めるように権限変更
```

ここはCent7だと`chgrp postfix /etc/sasldb2`でしたが、Almalinuxでは変わっています。


# 7.メール送信テスト

ここまでの設定で**メール送信**はできますので、一度試して見ましょう。
ただし、設定が少し足りていないので送れたとしても送信元アドレスは先ほど使用した**Gmailのアカウント**の状態です。

postfixに入っている`sendmail`コマンドを使ってメール送信します。

```
[root@localhost postfix]# sendmail -t <<EOL
> From: xxxx@example.com # 送信元アドレスを入れる（今はGmailアカウントから送るので適当で可）
> To: yyyy@example.jp    # メールを送りたい自分のアドレスを入れる
> Subject: TitleA        # 適当にタイトルを入れる
> hello world            # 適当に本文を書く
> EOL                    # EOLを入力して送信
[root@localhost postfix]# 
```

`mailq`コマンドでキューを確認してください。


```
[root@localhost postfix]# mailq
Mail queue is empty
```

上記のようにキューが空になったらメール送信は多分成功しています。
送信したメールボックスを確認しましょう。場合によっては迷惑メールボックスに入っている可能性もあります。
**送信元は先ほど設定したGoogleアカウント**になっていることを確認してください。

なお、メール送信に失敗している場合は多分**キューにメールが残って**います。そこにエラーが書かれているので設定漏れがないか見直しましょう。

`cat /var/log/maillog`
にもログが表示されるので、原因分析の際には参考にしてください。

なお、キューに溜まってしまった不要なメールは下記コマンドで削除可能です。
`postsuper -d QUEUE_ID`
※`QUEUE_ID`は`mailq`コマンドで表示された不要なメールのキューID

# 8.ポートの開放設定

ここからは**自分で取得したFQDNを送信元**としてメールを送れるようにするための設定をしていきます。

AlmaLinuxはデフォルトでfirewalldが起動しており、smtp(TCP25)が閉じているので開放します。

```
# I/Fの確認
[root@localhost ~]# firewall-cmd --get-active-zones
public
  interfaces: ens190
# 今空いているポートの確認(servicesの部分)
[root@localhost ~]# firewall-cmd --list-all --zone=public
public (active)
  target: default
  icmp-block-inversion: no
  interfaces: ens190
  sources: 
  services: cockpit dhcpv6-client ssh　　　# 空いているサービスはここ
  ports: 
  protocols: 
  forward: yes
  masquerade: no
  forward-ports: 
  source-ports: 
  icmp-blocks: 
  rich rules: 
[root@localhost ~]# 
```

snmpをfirewalldで開放します。

```
# smtpを開放
firewall-cmd --add-service=smtp --zone=public --permanent
# 設定の反映
firewall-cmd --reload
```

firewalldの設定変更も本筋とはズレるので、詳細は[ここ](https://manual.sakura.ad.jp/vps/support/security/firewalld.html)に譲ります。


これでサーバ側は空いた[^4]ので、自宅のLAN内からは自由にアクセスできるようになりましたが、自宅外からは接続できないかと思います。そのため自宅のゲートウェイのポート開放をします。
ここは個人の環境によるため詳細な手順は割愛します。
やり方がわからない人は「契約プロバイダ名＋ポート解放」で検索してみてください。

[^4]:空いているかどうか不安な方は`nmap`コマンドをインストールして、スキャンを実行してみるのも良いです。メールサーバ上で`lsof -i | grep LISTEN`コマンドを実行することでもポートの状態を見ることができます。

自宅外からちゃんとポート解放されているかのチェックは[cman](https://www.cman.jp/network/support/port.html)で確認できます。
TCP25と登録したFQDNを入力し、「アクセスできました」なればOKです。

外部の公開が怖い方は、Googleのメールサーバからのみを許可するアクセス制限をfirewalldでかけても良いかもしれません。

参考サイト(Googleのメールサーバを調査する方法)

https://deferloader.blog.uhuru.co.jp/1935/


# 9.SMTP認証を実施するためのGmailの設定

構築したサーバを認証していきます。
ここからは先ほど使用したGoogleアカウントの設定画面が続きます。

「アカウントとインポート」より、「他のメールアドレスを追加」をクリックします。

![スクリーンショット 2024-04-13 1.30.38.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/395943/88cd7d86-77f5-28ba-bcf0-88c44db84547.png)

メールアドレスを記入し、「エイリアスとして扱います」を外して進みます。

![スクリーンショット 2024-04-13 1.33.25.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/395943/f33aa617-db3b-9024-dd8c-3f4126be866a.png)

SMTPサーバには自分のFQDNを、ユーザ名は作ったユーザ名を、パスワードはアカウント作成時のパスワードを入れてください。

![スクリーンショット 2024-04-13 1.35.31.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/395943/d28701ff-c12f-a5d7-509e-8ed761b35b53.png)

設定に問題がなければ以下のような設定画面に遷移します。
設定がうまくいっていれば`/var/log/maillog`にGoogleのメールサーバからのアクセスログがあるはずです。
Googleのメールサーバからのアクセス自体が来ていない方は**経路の確認**を、アクセスが来ているけど認証に失敗している方は**パスワードや認証系の設定ミス**を確認してください。

![スクリーンショット 2024-04-13 1.49.22.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/395943/9d24384b-4a94-0ca7-9fdc-2be9c7a7a323.png)

リンクが記載されたメールがGoogleから飛ばされているので、メールサーバ内で受信できたかを確認します。

```
# Maildir形式だと以下にメールがあるはず
[root@localhost ~]# ls /home/mailuser/Maildir/new/ 
1713940940.Vfd00I０f321M260090.localhost.localdomain
# 届いたメールの内容確認
[root@localhost ~]# cat /home/mailuser/Maildir/new/1713940940.Vfd00I０f321M260090.localhost.localdomain 
```

上記のメールに書いてあるリンクをコピーし、ブラウザでそのリンクを開きます。[^5]

[^5]: 記事を書いた当時はプレーンテキストだったのでリンクが簡単に確認できたのですが、最近はbase64でエンコードされているので簡単に確認できなくなっているようです。[適当な変換サイト](https://www.en-pc.jp/tech/base64/)やスクリプトなどでデコードしてリンクを確認してください。

![スクリーンショット 2024-04-13 1.51.35.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/395943/c35a518c-56f8-2c19-147e-ae1b65366b1f.png)

これで設定が完了しました。`sendmail`コマンドを使って再度メールを送付してみましょう。

```
[root@localhost ~]# sendmail -t <<EOL
> From: mailuser@mailtest.hopto.org # 送信元アドレスを入れる(今回はちゃんとしたもの)
> To: yyyy@example.jp　　　　　　　　　# 送りたい自分のメールアドレス
> Subject: hello        
> hello world            
> EOL                    
[root@localhost ~]# 
```

以下のようにメールが来れば成功です。

![スクリーンショット 2024-04-13 1.55.37.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/395943/6f1e0ef4-353f-9409-835d-2427e0647a79.png)



# 10.セキュリティ向上

このタイミングじゃなくても良いのですが、いくつか設定を追加しておきます。

```/etc/postfix/main.cf
#　存在しないユーザー宛メールをunknown_userへ配送する
local_recipient_maps =
luser_relay = unknown_user@localhost
```

```
echo unknown_user: /dev/null >> /etc/aliases　 # unknown_user宛メールを破棄
```

```
# etc/aliasesの変更を反映する
newaliases
systemctl restart postfix
```

自分で構築したサーバがオープンリレーテストに使われないかチェックします。
https://tools.appriver.com/OpenRelay.aspx
アクセス制限をかけている方はうまくチェックできないので注意してください。

`tail -f /var/log/maillog`
をすると色々テスト時のログが出ているのが確認できます。

以下のサイトも参考にpostfixの設定をいじると良いと思います。
https://qiita.com/rocinante-ein/items/9c31cb0e36fb2d01d343


# 11.[Thunderbird](https://www.thunderbird.net/ja/)の設定

もうメールの送受信はできるのですが、せっかくなのでメールソフトの設定もやっていきます。

メールサーバとは別のクライアントPCに[Thunderbird](https://www.thunderbird.net/ja/)を入れて、そこから送受信できるように設定します。

`doveconf`コマンドよりdovecotが使用するポートを確認できます。
特に設定はいじっていないのでデフォルトのimap、pop3、lmtpが表示されるはずです。

```
[root@localhost ~]# doveconf protocols
protocols = imap pop3 lmtp
```

今回はimap(TCP143)を開けてPCと接続させます。

```
firewall-cmd --add-service=imap --zone=public --permanent
firewall-cmd --reload
```

クライアントPCにthunderbirdをインストールし起動させます。
インストール手順はクライアントPCのOSにもよるので割愛します。
インストールできたらセットアップに進みます。

![スクリーンショット 2024-04-13 13.59.29.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/395943/c783cfe2-060b-2594-dd47-d473e1bcb363.png)


自宅の場合は基本的にPCとメールサーバは同じLAN内にいると思いますので、ホスト名をメールサーバのIPアドレスに設定します。
（FQDNで外部から接続させたい場合はまた家のポート解放が必要になります。手順がやや煩雑になるのでここでは省略します）

![スクリーンショット 2024-04-13 14.37.33.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/395943/8408c38d-0e31-c87e-3a5b-2b9a26905acb.png)


接続が保護されませんという警告が出ますが、無視して進めます。

メールを作成します。宛先は自分が持っているお好きなメールアドレスにしてください。

![スクリーンショット 2024-04-13 15.25.40.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/395943/e92bc134-9835-106a-7d72-086c281b0d45.png)

送信先のアカウントで確認します。
今回はGメールを使ったのですが、Gメールで受信が確認できました。

![スクリーンショット 2024-04-13 15.26.31.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/395943/61da7d6c-eae2-723b-e5b4-4e1f4f39caea.png)

Gメール側からの送信（該当メールの返信）も試してみます。

![スクリーンショット 2024-04-13 15.28.09.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/395943/1ed25766-ac6b-4a4a-5359-d86ee0c0b466.png)

thunderbird側で受信が確認できました。

![スクリーンショット 2024-04-13 15.29.01.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/395943/434ab320-e89e-4450-1a74-f25fd86baa8f.png)

# 終わりに

0からメールサーバ構築は、意外と簡単にできるかと思います。
セキュリティがやや不安なところもあるので、今後も使い続けたい場合は色々設定追加していった方が良いかなと思います。


# 参考文献

以下のサイトは本記事の作成の際に参考にさせていただきました。
心より感謝申し上げます。

https://www.lab-infra.com/mail/postfix-dovecot
https://centossrv.com/postfix.shtml
https://centossrv.com/almalinux/postfix.shtml