[Raspberry pi4] Docker でメールサーバー(Postfix + Dovecot)を建てる。

Docker

今回はDockerを使ってメールサーバの起動と諸々の設定までやってしまおう。という話。

概要

自宅のメールサーバーとして、PostfixとDovecotを使っていますが、ネイティブのパッケージでインストールすると、そもそもの設定が複雑で、かつ再構築やPCの移行時には、なにをどう設定してあるのかをすっかり忘れてしまうわけです。それに加え、スパム対策やFail2Banなど他ツールの設定も必要なので本当に面倒です。今回は Dockerを使って簡単インストールを目標にします。

ここでセットアップするラズパイは、Ubuntuのインストール、外部にポート開放ができる準備と、ドメインの設定、Let’s EncryptのSSL証明書を取得済みの状態です。

過去の関連記事
  1. Ubuntu 19.10 でPPPOE接続をしてポート開放を行う。
  2. [Raspberry pi4] Ubuntu 20.10 のヘッドレスインストール。 キーボード、ディスプレイなしでインストールする方法
  3. [Raspberry pi4] NginxのインストールとLet’s EncryptからSSLサーバー証明書を取得する
  4. [Raspberry pi4] Docker でメールサーバーを建てる。 ★ 今ここ
  5. [Raspberry pi4] Docker で WordPress を動かす。

試した環境

Raspberry Pi4 (RAM 8GB)
Ubuntu 20.10 (arm64)

$ docker –version
Docker version 20.10.2, build 2291f61

$ docker-compose –version
docker-compose version 1.25.0, build unknown

Dockerイメージは docker-mailserver を使いました。

以下のポートを使用します
・25 SMTP
・587 Submission
・993 IMAPS

docker-mailserver について

メールサーバの構築には docker-mailserver を使います。

A fullstack but simple mail server (SMTP, IMAP, LDAP, Antispam, Antivirus, etc.). Only configuration files, no SQL database. Keep it simple and versioned. Easy to deploy and upgrade.

Why this image was created.

「シンプルかつ設定のバージョン管理が可能で、アップグレードも簡単にできる」 まさに私が望んでいたものでした。

docker-mailserverの 推奨スペックはこんな感じです。

推奨環境スペック
  • 1 Core
  • 1-2GB RAM
  • Swap enabled for the container
最低スペック:
  • 1 vCore
  • 512MB RAM

動かすサービスの種類と量によって、必要なリソースは変わってくるのでしょう。RaspberryPi 4であればひとまずは大丈夫そうです。

構築手順

それでは Docker で構築していきます。

docker-mailserver を取ってくる

まず、ラズパイに、githubのリポジトリをクローンします。

$ cd ~
$ git clone https://github.com/docker-mailserver/docker-mailserver.git

基本設定

クローンすると、docker-compose.ymlと、各種設定ファイルを取得できるので、メールサーバに関する基本的な情報を加えていきます。

compose.env コピーして .env ファイルを作ります。

$ cd ~/docker-mailserver
$ cp compose.env .env

.env には コンテナのホスト名、ドメイン名、コンテナ名を書きます。DOMAINNAME はメールサーバで使うメールのドメインになります。ホスト名、コンテナ名は何でも良いと思います。SELINUX_LABEL= には何も設定しません。

.envの設定例
# –––––––––––––––––––––––––––––––––––––––––––––––
# ––– Docker Compose Settings Variables –––––––––
# –––––––––––––––––––––––––––––––––––––––––––––––

HOSTNAME=mail           # コンテナのホスト名
DOMAINNAME=nosubject.io # メールサーバのドメイン名
CONTAINER_NAME=mail     # コンテナの名前

# –––––––––––––––––––––––––––––––––––––––––––––––
# ––– SELinux Compose File Settings Variables –––
# ––– options: empty, '-z' or '-Z'  –––––––––––––
# –––––––––––––––––––––––––––––––––––––––––––––––

SELINUX_LABEL=

mailserver.env にメールサーバの設定していきます。このファイルを変更するだけで、PostfixとDovecot だけでなく、いろいろなサービスを有効にできます。沢山あって使いこなせないほどですが、とりあえずは必要最低限で設定してみます。

mailserver.env の設定例(変更したところだけの抜粋です)
# ポストマスターのメールアドレス
POSTMASTER_ADDRESS=xxxx@nosubject.io

# スプーフィングを防止する
SPOOF_PROTECTION=1

# Fail2Banを有効にする
ENABLE_FAIL2BAN=1

# SSLにLet's Encryptを使う
SSL_TYPE=letsencrypt

# メッセージサイズの制限 デフォルトの10MBから20MBに変更。
POSTFIX_MESSAGE_SIZE_LIMIT=20480000

# OP25B対策でRELAY HOSTを設定する。
RELAY_HOST=smtp.gmobb.jp
RELAY_PORT=587
RELAY_USER=xxxxxxxxxx@xxxx.gmobb.jp
RELAY_PASSWORD=XXXXXXX

OP25B対策のため、RELAY_HOSTを設定しプロバイダのSMTP経由で送信しています。

Diff
diff --git a/mailserver.env b/mailserver.env
index 61f1f85..672c2bd 100644
--- a/mailserver.env
+++ b/mailserver.env
@@ -16,7 +16,7 @@ ONE_DIR=0

 # empty => postmaster@domain.com
 # => Specify the postmaster address
-POSTMASTER_ADDRESS=
+POSTMASTER_ADDRESS=postmaster@nosubject.io

 # Set different options for mynetworks option (can be overwrite in postfix-main.cf)
 # **WARNING**: Adding the docker network's gateway to the list of trusted hosts, e.g. using the `network` or
@@ -47,7 +47,7 @@ TLS_LEVEL=
 #           See also https://en.wikipedia.org/wiki/Email_spoofing
 # 1 => (recommended) Mail spoofing denied. Each user may only send with his own or his alias addresses.
 #       Addresses with extension delimiters(http://www.postfix.org/postconf.5.html#recipient_delimiter) are not able to send messages.
-SPOOF_PROTECTION=
+SPOOF_PROTECTION=1

 # Enables the Sender Rewriting Scheme. SRS is needed if your mail server acts as forwarder. See [postsrsd](https://github.com/roehling/postsrsd/blob/master/README.md#sender
-rewriting-scheme-crash-course) for further explanation.
 #  - **0** => Disabled
@@ -63,7 +63,7 @@ ENABLE_CLAMAV=0
 #    cap_add:
 #      - NET_ADMIN
 # Otherwise, `iptables` won't be able to ban IPs.
-ENABLE_FAIL2BAN=0
+ENABLE_FAIL2BAN=1

 # 1 => Enables Managesieve on port 4190
 # empty => disables Managesieve
@@ -85,7 +85,7 @@ SMTP_ONLY=
 # custom => Enables custom certificates
 # manual => Let's you manually specify locations of your SSL certificates for non-standard cases
 # self-signed => Enables self-signed certificates
-SSL_TYPE=
+SSL_TYPE=letsencrypt

 # Set how many days a virusmail will stay on the server before being deleted
 # empty => 7 days
@@ -113,7 +113,7 @@ POSTFIX_MAILBOX_SIZE_LIMIT=
 # Set the message size limit for all users. If set to zero, the size will be unlimited (not recommended!)
 #
 # empty => 10240000 (~10 MB)
-POSTFIX_MESSAGE_SIZE_LIMIT=
+POSTFIX_MESSAGE_SIZE_LIMIT=20480000

 # Enables regular pflogsumm mail reports.
 # This is a new option. The old REPORT options are still supported for backwards compatibility. If this is not set and reports are enabled with the old options, logrotate will be used.
@@ -417,16 +417,16 @@ DEFAULT_RELAY_HOST=
 #
 # empty => don't configure relay host
 # default host to relay mail through
-RELAY_HOST=
+RELAY_HOST=smtp.gmobb.jp

 # empty => 25
 # default port to relay mail
-RELAY_PORT=25
+RELAY_PORT=587

 # empty => no default
 # default relay username (if no specific entry exists in postfix-sasl-password.cf)
-RELAY_USER=
+RELAY_USER=xxxxxxxxxx@xxxx.gmobb.jp

 # empty => no default
 # password for default relay user
-RELAY_PASSWORD=
+RELAY_PASSWORD=XXXXXXX

起動前の設定 その2

docker-compose.yml を変更します。

ラズパイなので、ログファイルをRAMディスク(tmpfs)へ出力しておかないと、SDカードの寿命がすぐに来てしまいます。コンテナ内のログファイルをホスト側の/var/log/mailserver(tmpfs)に出力するようにします。あと ホスト側の letsencrypt の証明書を使うようにマウント設定をしています。

./docker-compose.yml の設定例
version: '3'

services:
  mailserver:
    image: docker.io/mailserver/docker-mailserver:latest
    hostname: ${HOSTNAME}
    domainname: ${DOMAINNAME}
    container_name: ${CONTAINER_NAME}
    env_file: mailserver.env
    ports:
      - "25:25"
      # - "143:143" # 追記:外部に公開が不要なポートは外しておくこと。
      # LAN内だけに公開する場合は、"127.0.0.1:143:143" とする必要がある。
      - "587:587"
      - "993:993"
    volumes:
      - maildata:/var/mail
      - mailstate:/var/mail-state
      # ログの出力先をホスト側のtmpfsに変更
      # - maillogs:/var/log/mail
      - /var/log/mailserver/mail:/var/log/mail/
      - /var/log/mailserver/supervisor/:/var/log/supervisor/
      - ./config/:/tmp/docker-mailserver/
      # ホスト側にあるletsencryptの場所を指定する
      - /etc/letsencrypt/:/etc/letsencrypt/
    cap_add: [ "NET_ADMIN", "SYS_PTRACE" ]
    restart: always

volumes:
  maildata:
  mailstate:
  #  maillogs:

Fail2Banのログも、tmpfsに出力するように設定を変更します。./config/ にあるファイルを変更します。

./config/fail2ban-fail2ban.cf
# ログの出力先を指定
logtarget = /var/log/mail/fail2ban.log

ホスト側にフォルダを作っておきます。(作らなくてもvolumeのマウント時に自動で作ってくれるかもしれません。未検証)

# コンテナがログを出力するためのフォルダを作成
$ sudo mkdir /var/log/mailserver

※注: tmpfs上のフォルダ・ファイルはラズパイを再起動したら消えてしまいますので、ご注意。

アカウントの作成とコンテナの起動

./setup.sh で、アカウントを一つ作ってからコンテナを起動します。(アカウントはあとからでも良いかもしれません。忘れました。)

$ ./setup.sh email add xxxx@nosubject.io xxxxxxx
$ docker-compose up -d

setup.sh で、ユーザの追加やエイリアスの作成ができます。このあたりの使い勝手もシンプルですごい楽ですねー。setup.shの使い方は setup.shのガイド を見てください。

./setup.sh alias add hoge@nosubject.io xxxx@nosubject.io
./setup.sh alias add moge@nosubject.io xxxx@nosubject.io
./setup.sh alias add fuga@nosubject.io xxxx@nosubject.io

作成したユーザとエイリアスは、下記のファイルに記録されていてます。

./config/postfix-accounts.cf
./config/postfix-virtual.cf

これらのコンフィグを残しておけばdocker-compose down でコンテナを消しても、再度 up したときに同じものを作成してくれるスグレモノです。

Dockerのコンテナ起動後のポートの状態は、こんな感じです。

$ netstat -ltn
Active Internet connections (only servers)
Proto Recv-Q Send-Q Local Address           Foreign Address         State
tcp        0      0 0.0.0.0:993             0.0.0.0:*               LISTEN
tcp        0      0 0.0.0.0:587             0.0.0.0:*               LISTEN
tcp        0      0 0.0.0.0:143             0.0.0.0:*               LISTEN
tcp        0      0 0.0.0.0:80              0.0.0.0:*               LISTEN
tcp        0      0 0.0.0.0:8080            0.0.0.0:*               LISTEN
tcp        0      0 127.0.0.53:53           0.0.0.0:*               LISTEN
tcp        0      0 0.0.0.0:22              0.0.0.0:*               LISTEN
tcp        0      0 0.0.0.0:25              0.0.0.0:*               LISTEN
tcp        0      0 0.0.0.0:443             0.0.0.0:*               LISTEN
tcp6       0      0 :::80                   :::*                    LISTEN
tcp6       0      0 :::22                   :::*                    LISTEN
tcp6       0      0 :::443                  :::*                    LISTEN

ファイアーウォールの設定

ポート 25(smtp)、587(submission)、993(imaps)を開放します。⚠143(imap)は使わないので、開放しません。

$ sudo ufw limit smtp
$ sudo ufw limit submission
$ sudo ufw limit imaps

⚠追記:※後にポート143(imap)が開放されていることが判明し、追加の設定を行っています。下記の記事と同じ状況でした。大変参考になりましたありがとうございます。

参考:公開ホストのセキュリティがガバガバだった話
https://www.ryotosaito.com/blog/?p=492

これで、メールサーバの構築は完了です。

メールクライアントを設定すれば、外からでもメールの送受信ができるようになります。

おまけ

リレーチェック

スパムの踏み台になっていないか、Open Relay のチェックサイトで確認してみます。

open relay checker

Network Tools: DNS,IP,Email
DNS and Network troubleshooting and diagnostic tools integrated into one sweet interface.

Open Relay になっていなければOKです。Fail2Ban が動いていると チェックサイトが Banされてしまいますのでご注意。Fail2Ban がちゃんと動いていることの確認にはなりますが。

コンテナには setup.sh を使えば入れます。

$ cd ~/docker-mailserver
$ ./setup.sh debug login 

クライアントの設定

SMTP/IMAPSのユーザ名はドメイン名までを含むメールアドレス(xxxx@nosubject.io)になります。
パスワードは、setup.shで設定したものを設定すればOKです。

iPhone 標準のメールアプリだと

受信設定は
ホスト名:nosubject.io
ユーザ名:xxxx@nosubject.io
パスワード:xxxx
SSLを使用:ON
サーバーポート:993

送信設定は
ホスト名、ユーザ、パスワード、同上
SSLを使用:ON
認証:パスワード
サーバーポート:587
で接続できます。

EmacsのMewでも送受信ができました。😂

まとめ

docker-mailserver を使うとこんなにも楽に構築できるよ。というご紹介です。便利なものを作ってくれてありがたい。

わし
わし

Mewの設定も備忘録に書いておくかな。

Amazon.co.jp: ゲームウォッチ: ゲーム
ゲーム の優れたセレクションでオンラインショッピング。
ゲーム&ウオッチ スーパーマリオブラザーズ (【Amazon.co.jp限定】ゲーム&ウオッチ オリジナルピンズ 同梱)
ゲーム&ウオッチ スーパーマリオブラザーズ (【Amazon.co.jp限定】ゲーム&ウオッチ オリジナルピンズ 同梱)

コメント

タイトルとURLをコピーしました