このページは、まだ未完成です。。。

nicotalk&キャラ素材配布所 http://www.nicotalk.com/charasozai_kt.html (2024年5月16日)

この記事を作った動機

 最近、Google (Gmail) とかに深く関係があるのは嫌であることや、中央集権的な SAAS サービスへの不信がある。そこで、自前のメールサーバを持ちたいと思い、Mailcow を使おうとしたので不完全でいいので作業過程の記録を取りたい。

前提条件

  • Arch Linux 環境で作業を行い、Mailcow 公式サポートはない状態である
  • 専用の物理 PC を割り当てる
  • クリーンインストールで、Gnome デスクトップ環境や最低限のパッケージが入った、Arch Linux 環境
  • スリープを無効化している。-> gnomeの設定のメモ ⚙
  • firewalld は導入していないこと -> Prepare your system - mailcow: dockerized documentation
  • できれば yayコマンド を導入する
  • NetworkManager を使っている。
  • DNS サーバにクラウドフレアを使っている。

設定要件

  • 自分の LAN (VPN) 環境のみからメールの送信を受け付け、グローバル IP 空間からはメールの送信を受け付けない
  • メールの受信についての対策は、Mailcow 標準に頼りたい
  • 利用者は自分や自分が許可した少数の身内のみ
  • メールサーバ自体は直接グローバル IP 空間には晒さず、VPN や LAN のネットワーク空間を転送するようにして利用する。

ネットワーク構成

 ネットワーク構成としては、通常のメールサーバではグローバル空間に配置してファイヤウォールに必要な分だけ慎重に穴を開けるなどのスタンスを取ると考えられるが、今回のはセキュリティーの観点から、そうはしなかった。

 基本的には、メールサーバは直接グローバル空間には晒さず、かつNAT環境下にある自宅の専用に用意したサーバを使うという観点から、別の専用にグローバル空間とつながっていて固定IP持っている中継サーバ(VPS)で、ポート転送などを行うという形態を取った。また、セキュリティの観点から メールを送受信したり、サーバを管理できるユーザは、VPNによって自宅のLAN内にアクセスできる人間のみとし、グローバル空間からは、SMTPポートだけ、晒して、メールは送受信できるようにしつつ、外部の人間は今回構築するメールサーバに対して、リレーとして使ったり、送信を命令することはできないようにしている。メールを送信できる人は、メールサーバと同じLANに属しているユーザだけであり、メールの受信はどこからでもスパムでないこと、不正でないことを前提に、スパムフィルターで弾かれなかったものが受け付けられるという形態を取る。

 中継には VPS を使い、メールサーバとVPS間は専用に用意したVPNネットワークで接続される。これにより、NAT超えも実現しながら、メールサーバを直接グローバル空間に晒さずに済むというものである。注意点としてはメールサーバ側のルーティングや、VPS側のファイヤウォール、転送設定がを間違っていると、セキュリティリスクになる点を留意する。

イメージ用の図いろいろ

ネットワーク構成の概要

ネットワーク構成の概要

大まかなルート構成

VPSにおけるポート転送と特別なルーティング(nftables)で成立
VPSにおけるポート転送と特別なルーティング(nftables)で成立
通常のSMTPとして成立するルート
通常のSMTPとして成立するルート

外部のメールサーバからの見え方

外部のメールサーバからの見え方

メール送受信のためのフロントエンドアクセスが出来る範囲

メール送受信のためのフロントエンドアクセスが出来る範囲

SMTP 関連パケットのルーティングについて

メール受信時の経路
メール受信時の経路
メール送信、SMTP における応答通信時における経路
メール送信、SMTP における応答通信時における経路
不正な SMTP パケットの経路
不正な SMTP パケットの経路

ネットワーク設定

VPS プロバイダの設定

VPS の設定

メールサーバ本体の設定

説明用の仮定

メールアドレス

  • xxxx@your.domain.comのようにする。

メールサーバについて

  • mx.your.domain.comにホストすることにする。
  • IPアドレスを160.251.xxx.xxxとして仮定する。

Mailcow のインストール

docker 環境の導入

# 必要なパッケージのインストール (jq は mailcow の依存関係)
yay -Sy docker docker-compose jq
# sudo pacman -Sy docker docker-compose jq

# サービスの有効化
sudo systemctl enable --now docker

# 必要であれば管理用ユーザを docker グループに追加し、権限を付与する
sudo usermod -aG docker [targetUser]

# 念のため再起動
sudo systemctl reboot

IP アドレスの固定

 今回は、NetworkManager を Gnome 環境に組み合わせた状態なので、Gnome の GUI から設定を行った。

IP固定
IP固定

Mailcow のインストール

 以下は公式ドキュメントの引用である。設定を生成するスクリプトによって、聞かれる設定については、今回は HostName を mx.your.domain.com のようにした。

su
umask 0022
cd /opt
git clone https://github.com/mailcow/mailcow-dockerized
cd mailcow-dockerized
./generate_config.sh

Mailcow の起動 (su 環境)

docker compose pull
docker compose up -d

動作確認

 別の PC から、Mailcow のフロントエンドを開き、ログインすることで動作確認する。Mailcow におけるデフォルトの管理者の情報は以下のとおりである。-> ログイン情報の出典

初期ログイン情報

  • ユーザ名
    admin
  • パスワード
    moohoo

フロントエンドにアクセスする

※ 初回起動時は、一定時間待たないとフロントエンドが出てこないので注意する。

  1. 任意のブラウザを開き、Mailcow がインストールされた PC にアクセスする。設定を厳密にはしていないので証明書のエラーが出るがここでは動作確認を目的としているのでとにかく進める。

    動作確認

  2. 管理者ログインページに遷移し、ログインする。

    動作確認1
    動作確認2

  3. ダッシュボードが表示される。

    動作確認3

DNS 設定をする

/opt/mailcow-dockerized/mailcow.conf

# Enable DNS-01 challenge (instead of HTTP-01)
ACME_DNS_CHALLENGE=y

# Specify your DNS provider plugin (see provider list below)
# Example: dns_servercow for Servercow, dns_cf for CloudFlare, dns_aws for AWS Route53
ACME_DNS_PROVIDER=dns_cf

# Email address for ACME account registration
ACME_ACCOUNT_EMAIL=your@Valid.emali.com

/opt/mailcow-dockerized/data/conf/acme/dns-01.conf

CF_Token        = "Your secret token"
CF_Account_ID   = "Your secret ID"

Cloudflare において、アカウントIDを確認する

 ホーム画面から、workers のところを押すと以下のように見える。

Cloudflare アカウントIDを確認する1
Cloudflare アカウントIDを確認する2

Cloudflare において “Please verify your email” で API トークンを生成できないとき

 本人確認ができていないということで、拒絶されているので何かしらの形で本人確認をしたことにする必要がある。正式な方法は分かっていないが、以下のようにして、ドメイン登録など本人確認が必要な操作をしようとすると出てくる、“Verify your account"の項目を使って、本人確認をした状態で、API キーを取得しようとすることはできることが分かった。

Cloudflare APIトークンが生成できない様子
Cloudflare 本人確認の様子

Email Routing の無効化

 Cloudflare では単に、Email routing の設定に移動して、disable という赤いボタンを押すだけでは、十分にロックされた MX レコードを削除しきれない。
 以下の画像に示されるように、赤く囲った部分に対象のドメインが無い状態にしないと、DNS レコードの画面から、自分でドメインを設定できる状態に持ち越せない。

EmailRouting無効化方法について

DNS レコードを追加

メールサーバまでの経路を作成

メールサーバ自体にルーティング
  • 名前
mx.your.domain.com
  • タイプ
    A
  • 内容
160.251.xxx.xxx
メールサーバに誘導
  • 名前
your.domain.com
  • タイプ
    A
  • 内容
mx.your.domain.com

認証系 (要確認)

SPF

 だれがメールをyour.domain.comとして送信して良いかを IP や ドメイン名で設定する。今回はドメインを指定する例を示す。

  • 名前
your.domain.com
  • タイプ
    TXT
  • 内容
"v=spf1 a:mx.your.domain.com -all"
DMARC

 認証に失敗したメールをどう扱うか示す。p=noneで破棄して送信失敗の通知だけする、p=quarantineでスパムとして扱う、p=rejectで配送しないになる。

  • 名前
_dmarc.your.domain.com
  • タイプ
    TXT
  • 内容
"v=DMARC1; p=quarantine"
DKIM

 メールが配送過程で改ざんされていないか確かめる。名前に、dkim._domainkeyの接頭辞が必要である。内容は例示として簡略化したものを示し、各自適切に設定する必要がある。Mailcow における設定値については、mailcow-にて-dkim-を確認取得するを参照する。

  • 名前
dkim._domainkey.your.domain.com
  • タイプ
    TXT
  • 内容
"v=DKIM1;k=rsa;t=s;s=email;p=..."

逆引きホスト名の修正

 以下のように双方向に名前解決して、それらが一致するようにする。VPS の管理画面などから設定する。(反映に時間がかかるため数日ほど放置してみること)

  • イメージ
mx.your.domain.com. -> 160.251.xxx.xxx
160.251.xxx.xxx -> mx.your.domain.com.
  • 設定内容の例
mx.your.domain.com.
  • 設定の検証
# mx.your.domain.com. -> 160.251.xxx.xxx
 dig mx.your.domain.com.

# ; <<>> DiG 9.20.19 <<>> mx.your.domain.com.
# ;; global options: +cmd
# ;; Got answer:
# ;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 6491
# ;; flags: qr rd ra; QUERY: 1, ANSWER: 1, AUTHORITY: 0, ADDITIONAL: 1
# 
# ;; OPT PSEUDOSECTION:
# ; EDNS: version: 0, flags:; udp: 1232
# ;; QUESTION SECTION:
# ;mx.your.domain.com.		IN	A
# 
# ;; ANSWER SECTION:
# mx.your.domain.com.	300	IN	A	160.251.xxx.xxx
# 
# ;; Query time: 248 msec
# ;; SERVER: 192.168.24.1#53(192.168.24.1) (UDP)
# ;; WHEN: Sun Aug 09 05:57:27 JST 2026
# ;; MSG SIZE  rcvd: 65
# 160.251.xxx.xxx -> mx.your.domain.com.
dig -x 160.251.xxx.xxx

# ; <<>> DiG 9.20.19 <<>> -x 160.251.xxx.xxx
# ;; global options: +cmd
# ;; Got answer:
# ;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 58919
# ;; flags: qr rd ra; QUERY: 1, ANSWER: 1, AUTHORITY: 0, ADDITIONAL: 1
# 
# ;; OPT PSEUDOSECTION:
# ; EDNS: version: 0, flags:; udp: 1232
# ;; QUESTION SECTION:
# ;127.185.xxx.xxx.in-addr.arpa.	IN	PTR
# 
# ;; ANSWER SECTION:
# 127.185.xxx.xxx.in-addr.arpa. 86400 IN	PTR	mx.your.domain.com.
# 
# ;; Query time: 59 msec
# ;; SERVER: 192.168.24.1#53(192.168.24.1) (UDP)
# ;; WHEN: Sun Aug 09 05:57:33 JST 2026
# ;; MSG SIZE  rcvd: 91

おまけ

Mailcow にて DKIM を確認(取得)する

 DNS の値として設定すべき DKIM の値は既に Mailcow が生成しているのでそれを使う。その値について確認する方法を以下に画像で示す。確認には、Mailcow のフロントエンドを利用する。

DKIM DNS設定の取得
DKIM DNS設定の取得
DKIM DNS設定の取得
DKIM DNS設定の取得
DKIM DNS設定の取得

mailcow/unbound コンテナにおいて、unhealthyとなり、メールが一切送受信できなくなる問題について (追記 2026/8/31)

 以下に示す github の issue にも書かれているが、私の環境においても IPv6 による名前解決が unbound の設定においてデフォルトで有効になっており、それが障害を起こしていたという事例が確認された。

 具体的には以下のような経過を辿った。

  1. 通常どうりメールが送受信でき何も問題なさそうに見える
  2. しばらく数週間後くらいして、例えばヤフーのメール認証のメールが10分くらい送れて届くなど障害が現れてくる
  3. それから2日後、メールが送受信できないことが発覚し、調査することになった。

具体的な修正内容

 /opt/mailcow-dockerized/data/conf/unbound/unbound.conf の設定内容を IPv6 を使わないように修正する。以下は、設定ファイルの一部を例に示す。

  • 設定前
server:
  verbosity: 1
  interface: 0.0.0.0
  interface: ::0
  logfile: /dev/console
  do-ip4: yes
  do-ip6: yes
  do-udp: yes
  do-tcp: yes
  • 設定後
server:
  verbosity: 1
  interface: 0.0.0.0
  #interface: ::0
  logfile: /dev/console
  do-ip4: yes
  do-ip6: no
  do-udp: yes
  do-tcp: yes

調査において見られた症状

  • docker ps において、unbound コンテナが、unhealthyステータスになっている。
  • Mailcow のフロントエンドの管理者画面において、Poxtfix などで MX レコードに関する名前解決が失敗している旨のログが散見される。
warning: Unable to look up MX host mx.your.domain.com for Recipient address main@your.domain.com: Temporary failure in name resolution
warning: Unable to look up MX host xxxxxxx.in.tmems-jp.trendmicro.com for Recipient address xxxxxx@xxxxxx.xxxxxxx.ac.jp: Temporary failure in name resolution
  • sudo tcpdump -i any port25 を実行すると、メール送信時に、パケットが送信された様子がすぐに見られない。

関連する記事

使った画像とか

参考にしたサイトとか