SSD Nodes Learn
ガイド Matt Connor著者 Matt Connor ・更新日 2026-07-24

VPSでmailcowを構築してGmailにメールを届ける方法

VPSでのmailcow構築時に、Gmailから550 5.7.25 PTR rejectionで拒否される問題を解決します。事前にoutbound port 25の疎通確認を行い、DNSのPTRレコードを正しく設定する手順を解説します。IPレピュテーションの確認も重要です。

構築するもの

自前のサーバー上に完全なメールサーバーを構築します。送信・受信用のSMTP、スマートフォンやノートPCと同期するためのIMAP、Webメールクライアント、そして送受信されるすべてのメッセージをスコアリングするスパムフィルタを備えます。mailcow-dockerizedは、Postfix、Dovecot、Rspamd、SOGo webmail、MariaDB、Redis、ACMEクライアントを一つのDocker Composeスタックにまとめています。そのため、ソフトウェア自体の導入は難しくありません。30分以内に稼働させることができます。

難しいのは、それ以外の周辺設定です。メールは、インターネット上の他のサービスとは異なり、新規サーバーが強く警戒されるサービスです。「正常に動作する」状態と「Gmailにすべてのメッセージが無視される」状態の差は、4つのDNSレコードと、完全に制御できない場合がある1つのIPレピュテーション設定によって決まります。サーバーを契約する前に、以下の前提条件を読んでください。もし、レピュテーションの管理が困難だと判断した場合は、それも正当な判断です。2026年に実際にセルフホストすべきものの一覧の「only if you mean it」セクションには、まさにこのような理由が記載されています。

前提条件がプロジェクトのすべてです

これらが一つでも欠けると、メールは届きません。以下は、よくある失敗の原因の頻度順です。

Outbound port 25 が開放されていること。 サーバーは TCP port 25 を使用して Gmail や Microsoft へメールを配信します。多くの VPS やクラウドプロバイダーは、スパム対策としてデフォルトで outbound 25 をブロックしています。このブロックはサイレントに行われます。起動時にエラーは出ず、システムの状態も正常に見えますが、メールはキューに残り続けます。インストール前に必ずテストしてください。ブロックされている場合、解決策はプロバイダーへ開放を依頼するサポートチケットを送ることのみです。古いアカウントに対してのみ開放される場合もあれば、一切開放されない場合もあります。

クリーンな IP と良好なレピュテーション。 再利用された VPS の IP は、以前の利用者のスパム行為によって既にブロックリストに載っていることがよくあります。設定前に Spamhaus lookup や mxtoolbox などのサービスで自身の IP を確認してください。リストに載っている IP では、プログラム側では解決できない拒否が発生します。

DNS の管理権限と正しい PTR record。 ドメインのゾーンにレコードを追加する必要があります。また、サーバーの IP からメールホスト名へ逆引き(PTR)ができる設定が必要です。PTR は DNS パネルには設定されていないことがほとんどです。IP の所有者が管理しているため、VPS プロバイダーのコントロールパネル、またはサポートチケットを通じて設定する必要があります。

6 GiB RAM と 2 vCPU が推奨される最小構成です。 mailcow のプライベートインストールにおける最小要件は 6 GiB RAM と 1 GiB swap です。ユーザー数が増えた場合は 8 GiB を推奨します。2.5 GiB を下回る場合、generate_config.sh ではカーネルによるコンテナの強制終了を防ぐため、ClamAV ウイルススキャナーを無効化するオプションがあります。まずは 20 GB の SSD を用意してください。

IP アドレスではなく、DNS name を使用すること。 mail.example.com のようなホスト名を選択してください。その名前が MAILCOW_HOSTNAME、TLS 証明書の Subject、PTR のターゲット、および SMTP banner になります。どこでも一貫した名前を使用してください。

Step 1 — アウトバウンドの port 25 が開放されていることを確認する

まずこれを行ってください。これが失敗する場合、他の作業はすべて無駄になります。新しい VPS から、実際のメールサーバーに対して SMTP セッションの開始を試行します。

sudo apt update && sudo apt install -y netcat-openbsd
nc -vz -w 5 gmail-smtp-in.l.google.com 25

成功した場合は、すぐに結果が返ります。

Connection to gmail-smtp-in.l.google.com (142.250.x.x) 25 port [tcp/smtp] succeeded!

ポートがブロックされている場合は、5秒間停止した後にエラーになります。

nc: connect to gmail-smtp-in.l.google.com port 25 (tcp) timed out: Operation now in progress

このタイムアウトがブロックの証拠です。これはプロバイダー側のネットワークフィルタによるもので、ローカルの firewall によるものではありません。そのため、ローカルの設定変更では解決できません。サポートチケットを作成してください。「私の VPS (<IP>) に対して、アウトバウンドの TCP port 25 を有効にしてください。正当な mail server を運用しています。」 この結果が "succeeded" になるまで mailcow をインストールしないでください。なお、インバウンドの 25(他のサーバーから自分への通信)は別の経路であり、通常は開放されています。プロバイダーが制限をかけるのはアウトバウンド側です。

Step 2 — DNSレコードの設定

DNSの変更が反映されるには時間がかかります。インストール前に可能な限りすべての設定を公開してください。ドメインが example.com、メールホストが mail.example.com、IPアドレスが 10.0.0.10 であると仮定します。ゾーンに以下を作成してください:

mail.example.com.        A      10.0.0.10
mail.example.com.        AAAA   2001:db8::10          ; only if you have IPv6
example.com.             MX  10 mail.example.com.
example.com.             TXT    "v=spf1 mx -all"
_dmarc.example.com.      TXT    "v=DMARC1; p=none; rua=mailto:postmaster@example.com"

SPFレコードは「このドメインのメール送信はMXレコードのみ許可し、それ以外は拒否する」という意味です。自身のメールが拒否されないよう、DMARCはまず p=none で開始してください。アライメントが確認できたら、p=quarantine、次に p=reject へと厳格化します。意図的に残している未設定のレコードが2つあります。DKIMはStep 6でmailcowが自動生成します。PTRは、プロバイダーの管理パネルで今すぐ設定してください。

10.0.0.10 のPTR(逆引きDNS)を mail.example.com に設定してください。これは MAILCOW_HOSTNAME の正確な値です。このレコードは多くの人が設定を忘れる項目であり、大手プロバイダーはこれが設定されていないとメールを拒否します。管理パネルにrDNSの入力欄がない場合は、サポートへ問い合わせてください。

Step 3 — Dockerのインストール

mailcowには、Compose v2 pluginを備えたDocker Engineが必要です。Ubuntuのdocker.ioパッケージにはCompose pluginが含まれていないため、それではなくDocker公式のconvenience scriptを使用してください。

curl -fsSL https://get.docker.com | sudo sh
sudo docker compose version

Docker Compose version v2.xという行が表示されるはずです。もしdocker compose versionを実行してdocker: 'compose' is not a docker commandと表示された場合、Docker Engineはインストールされていますが、Compose pluginがインストールされていません。その場合は、Dockerのリポジトリからpluginをインストールしてください。上記のスクリプトを再実行するか、Docker自身のaptリポジトリから両方をセットアップするDocker Composeの基本ガイドに従ってください。

Step 4 — mailcow のクローンと設定ファイルの生成

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

まず umask0022 を出力することを確認してください。ファイルマスクが正しくないと mailcow はビルドに失敗します。Ubuntu 24.04 の root シェルでは、デフォルトで 0022 が設定されています。次に、完全修飾ホスト名(FQDN)の入力を求められます。mail.example.com を入力してください。この値は A レコードおよび PTR レコードと完全に一致する必要があります。入力した値は、スタック全体が参照する唯一の環境ファイルである mailcow.conf に書き込まれます。Web ポート (HTTP_PORT, HTTPS_PORT) の変更や、リソースの少ないサーバーでの ClamAV の無効化が必要な場合は、このファイルを開いて編集してください。

MAILCOW_HOSTNAME=mail.example.com
HTTP_PORT=80
HTTPS_PORT=443
SKIP_CLAMD=n          # set to y to drop the virus scanner on a <2.5 GiB box

メモリ容量が少ないサーバーでは SKIP_FTS=y も重要です。全文検索は mailcow のドキュメントで次にメモリを消費する機能として挙げられています。これを無効にすると、Webmail での本文検索ができなくなります。

ホスト上の他のサービスと競合しない限り、HTTP_PORT=80HTTPS_PORT=443 はそのままにしてください。mailcow 内蔵の ACME クライアントが証明書を取得するには、インターネットから port 80 へのアクセスが必要です。そのため、同じサーバーで 別の nginx-plus-Certbot 設定 を実行しないでください。mailcow は内部で独自の TLS 発行・更新を行うため、別のサービスが 80/443 ポートを使用していると動作に支障をきたします。

Step 5 — スタックの起動とログイン

sudo docker compose pull
sudo docker compose up -d
sudo docker compose ps

pullにより約24個のimageが取得されます。完了まで数分かかります。docker compose psですべてのcontainerがrunning(またはhealthy)になったら、ブラウザでhttps://mail.example.comを開いてください。デフォルトのadminログイン情報は、usernameがadmin、passwordがmoohooです。Access → Administratorsから、直ちにpasswordを変更してください。ブラウザでNET::ERR_CERT_AUTHORITY_INVALIDと警告が表示される場合、ACME certificateがまだ発行されていません。不具合と判断する前に、後述のACME failureを確認してください。起動直後の1〜2分間は、self-signed placeholderが表示されるのが正常な動作です。

Step 6 — ドメインの追加、メールボックスの作成、および DKIM の公開

管理 UI で Mail Setup ページ (Configuration → Mail Setup) を開きます。Domains タブで Add domain をクリックし、example.com を入力してください。次に、Mailboxes セクションで Add mailbox をクリックし、パスワードを設定して you@example.com を作成します。これで、IMAP で利用可能なメールボックスが作成されました。

次に DKIM キーの設定を行います。Configuration → ARC/DKIM keys に移動してください。ドメイン追加時に mailcow が既にキーを生成している場合があります。生成されていない場合は、ここで作成してください。対象のドメインを選択し、selector に dkim を指定して、2048-bit を選択し、Add をクリックします。表示された長い TXT 値をコピーし、以下の形式で公開してください。

dkim._domainkey.example.com.  TXT  "v=DKIM1;k=rsa;t=s;s=email;p=MIIBIjANBgkqh...long-key...QAB"

mailcow の Domains ページには DNS ボタンがあります。これを使用すると、必要なレコードの一覧と、実際に公開されているかどうかのステータス(緑のチェックまたは赤のバツ印)を確認できます。これをチェックリストとして使用し、配信テストを行う前にすべての行を緑にしてください。公開後に DKIM の行が赤くなる場合は、TXT レコードの分割が正しく行われていない可能性があります。2048-bit キーは単一の TXT 文字列の制限である 255 文字を超えます。そのため、一つの論理的な値として貼り付け、DNS ホスト側で自動的に分割されるようにしてください。

Step 7 — 配信テストを行い、スコア10/10を目指す

mail-tester.com にアクセスし、表示されたランダムなアドレスをコピーしてください。新しいメールボックスからそのアドレスへメールを送信します。https://mail.example.com/SOGo の SOGo webmail にログインして送信してください。送信後、"Then check your score" をクリックします。

スコアは 10/10 を目指してください。よくある減点理由と原因は以下の通りです:

  • SPF not alignedMX/SPF レコードが不足しているか、送信 IP が含まれていません。SPF TXT レコードを再確認してください。
  • DKIM signature does not verifydkim._domainkey TXT が不足しているか、反映待ち、あるいは破損しています。これが最も一般的な原因です。
  • No PTR / PTR mismatch — 逆引き DNS が mail.example.com に解決しません。プロバイダー側で修正してください。
  • Listed on a blocklist — 送信 IP の過去のレピュテーションによるものです。解除申請を行うか、クリーンな IP を要求してください。

スコアが 10/10 になるまで、Gmail や Outlook への実際のメール送信は控えてください。低いスコアと新しい IP の組み合わせは、初日にドメインがフラグ立てされる原因となります。

Step 8 — 実際のメールクライアントを接続する

Thunderbird、Apple Mail、またはスマートフォンに以下の設定を入力してください。すべての設定において、サーバーホストは mail.example.com です。

  • IMAP: port 993, SSL/TLS (または 143, STARTTLS)
  • SMTP submission: port 465, SSL/TLS (または 587, STARTTLS)
  • Username: フルアドレス you@example.com
  • Password: 設定したメールボックスのパスワード

port 25 を使用してクライアントからメールを送信しないでください。このポートはサーバー間通信専用です。mailcow はこのポートでの認証付き送信を許可していないため、クライアントからの接続は拒否されます。もし Relay access denied というエラーが出る場合は、port 25 を使用しているか、認証が不足しています。465 または 587 に変更し、メールボックスの認証情報を使用してください。

Step 9 — 重要なデータのバックアップ

mailcowには、すべてのstateful volumeのスナップショットを作成するバックアップスクリプトが含まれています。外部ディスクまたはマウントされたリモート先に対して実行してください。

sudo MAILCOW_BACKUP_LOCATION=/opt/mailcow-backups \
  ./helper-scripts/backup_and_restore.sh backup all

allは以下の6つの要素をキャプチャします。これらを一つでも失うとデータが失われます:vmail(実際のメールボックス)、crypt(vmailを復号するための鍵。これがないとvmailは使用できません)、mysql(ドメイン、ユーザー、エイリアス、設定を保持するMariaDB)、redis(キューとキャッシュの状態)、rspamd(学習済みのspam/ham)、postfix(メールキュー)。このスクリプトはヘルパーコンテナ内で動作し、圧縮アーカイブを書き出します。そのため、スタックが稼働したままでもバックアップの整合性が保たれます。 nightlyのcronジョブで自動化し、古いセットを削除するには--delete-days 14を追加してください。リストアには、スナップショットの一覧表示と復元対象の選択ができるrestoreを使用します。テスト復元を行っていないバックアップは、バックアップではなく単なる「期待」に過ぎません。別のVPSなどで一度テスト復元を行ってください。

Step 10 — スケジュールに基づいたアップデート

mailcowは独自のスクリプトを通じてアップデートを行います。このスクリプトは、新しいコードの取得、mailcow.confのマイグレーション、イメージのプリフェッチ、およびコンテナの再起動を以下の順序で実行します。

cd /opt/mailcow-dockerized
sudo ./update.sh --check   # reports whether an update exists, changes nothing
sudo ./update.sh           # applies it

スキーマのマイグレーションは元に戻すことが困難なため、必ず先にバックアップ(Step 9)を行ってください。アップデートは頻繁にリリースされ、インターネットに公開されているデーモンへのセキュリティ修正が含まれます。メールサーバーを数ヶ月間アップデートしない状態にしないでください。アップデート後にコンテナがunhealthyになった場合、sudo docker compose logs --tail=50 <service>-mailcowに起動に失敗したデーモンの名前が表示されます。

ハードニングに関する注意点

mailcowは独自のnetfilterサービス (netfilter-mailcow) を実行しています。このサービスは、mailおよびwebmailポートへ連続してアクセスするIPをBANします。そのため、メール機能は標準状態で保護されています。ただし、ホスト自体のSSHは保護されていません。SSHは依然として公開されており、ブルートフォース攻撃の対象となります。この構成には、Fail2banによるSSH認証ログの監視と、鍵認証のみのログイン設定を併用してください。mailcowの管理UIには強力なパスワードを設定してください。理想的には、パブリックインターネットから隔離するか、VPNの背後に配置してください。

失敗パターンと正確な文字列

Mail queueに溜まり、送信されない。 sudo docker compose exec postfix-mailcow postqueue -pを実行するか、管理UIのmail queueを確認してください。以下のメッセージと共に保留(deferred)状態になります:

status=deferred (connect to gmail-smtp-in.l.google.com[142.250.x.x]:25: Connection timed out)

これはプロバイダーによってアウトバウンドのport 25がブロックされていることが原因です(Step 1)。設定変更では解決しません。サポートへ問い合わせてください。DNSやTLSの問題ではありません。リモートのMX(port 25)に対してtimed outという単語が表示されていれば、それが原因です。

Gmailですべてがスパム判定される、またはバウンスする。 Gmailでメッセージを開き、「Show original」から認証結果(auth results)を確認してください。dkim=failまたはdkim=noneは、dkim._domainkey TXTレコードが不足している、破損している、あるいは反映待ちであることを意味します。ARC/DKIMのページに表示されている内容を正確に再設定し、TTLの経過を待ってください。spf=failは、SPF/MXレコードが現在のIPをカバーしていないことを意味します。アライメント(Alignment)が重要です。チェックが1つでも失敗すると、スパムフォルダに振り分けられます。

接続時に大手プロバイダーによって拒否される。 バウンスメールまたはPostfixのログに、GmailによるPTR拒否が記録されます:

550-5.7.25 [10.0.0.10] The IP address sending this message does not have a PTR
550-5.7.25 record setup, or the corresponding forward DNS entry does not match
550 5.7.25 the sending IP. As a policy, Gmail does not accept messages from IPs
550 5.7.25 with missing PTR records.

550 5.7.25コードは、逆引きDNS(reverse DNS)の欠落または不一致を意味します。プロバイダーの管理画面で、IPのPTRレコードをmail.example.comに設定してください(Step 2)。正引き(Aレコード)と逆引き(PTRレコード)は一致している必要があり、両者はmailcowが他のサーバーに名乗るホスト名と同じである必要があります。

ブラウザで証明書の警告が消えない。 acme-mailcowコンテナが正規の証明書の取得に失敗しています。ログを確認してください:

sudo docker compose logs acme-mailcow | tail -n 40

Cannot validate any hostnames, skipping Let's Encrypt for 1 hour.のような行や、チャレンジの失敗は、インターネットからport 80にアクセスできないか、Aレコードがこのサーバーを指していないことを意味します。mail.example.comがこのサーバーのIPを解決しているか確認してください。ホストのファイアウォールで80および443ポートを開放し、他のプロセスがこれらのポートを使用していないことを確認してください。原因を解決した後は、1時間の待機時間を待つのではなく、sudo docker compose restart acme-mailcowでクライアントを再起動してください。

FAQ

セルフホストのメール運用に価値はありますか?

データの所有権、無制限のエイリアス、完全な制御が必要なら、価値はあります。mailcowはVPSのコストでプロフェッショナルなスタックを提供します。ただし、到達率の維持は継続的な作業です。IPレピュテーション、DNSアライメント、ブロックリストの監視は常に必要です。スパムフォルダへの混入が致命的なビジネス用途では、マネージドプロバイダーの利用が現実的です。利便性よりも制御を重視し、運用を継続できる場合にセルフホストを選択してください。

送信ポート 25 がブロックされているか確認する方法は?

サーバーから nc -vz -w 5 gmail-smtp-in.l.google.com 25 を実行してください。 "succeeded!" と表示されれば開いています。待機後に timed out が表示される場合は、プロバイダーによってブロックされています。これは、セルフホストサーバーがメールを受信できるのに送信できない最も一般的な原因です。解決策はプロバイダーにポートの開放を依頼することのみであり、ローカルの設定変更では解決しません。

なぜメールが Gmail のスパムフォルダに届くのですか?

ほとんどの場合、認証チェーンの不備が原因です。Gmail の「メッセージの原文を表示」を確認し、spf=passdkim=passdmarc=pass を見てください。dkim=fail は、dkim._domainkey TXT レコードの欠落または不備を示しています。PTR レコードの不一致や、送信履歴のない新しい IP も原因となります。まず mail-tester.com で 10/10 を取得してください。その後、初日から大量に送信するのではなく、1日あたり数通から徐々に送信量を増やして IP を warming してください。

バックアップすべき対象は何ですか?

backup_and_restore.sh backup all を実行し、生成された一式をサーバー外に保存してください。これには vmail (メールボックス)、crypt (復号用キー)、MariaDB データベース (ドメイン、ユーザー、エイリアス、設定)、Redis、Rspamd の学習データ、および Postfix のキューが含まれます。多くの人が crypt ボリュームを見落としがちですが、これがないと vmail のバックアップは復号できない暗号文のままとなります。少なくとも一度は、別の環境でリストアのテストを行ってください。

2 GB の VPS で mailcow を実行できますか?

快適な動作は困難です。generate_config.sh は、メモリが約 2.5 GiB 未満の場合に ClamAV を無効化することを提案しますが、それでも Rspamd、ClamAV、Dovecot、MariaDB がメモリを競合します。そのため、実際の負荷がかかると swap が発生し、OOM kill が発生します。安定したシングルユーザー環境の最低ラインは 6 GiB のメモリと 1 GiB の swap です。利用者が数名を超える場合は、すぐに 8 GiB へアップグレードしてください。

#mailcow#email#self-hosting#docker#dns