1. はじめに
SNS で、Cloudflare のサービスを組み合わせることで、独自ドメインのメールシステムを構築できるという投稿を見かけました。
普段、メールサービスとしては Gmail や Outlook などを利用していますが、メールの送受信に関する仕組みについては、あまり理解できていない部分もありました。
そこで今回は、DNS やメール配送の仕組みについて理解を深めることも兼ねて、Cloudflare を利用したメールシステムを構築してみることにしました。
最終的には、以下の機能を持つ Web メールシステムを目指しています。
- 独自ドメインでメールを送受信できる
- 受信したメールを Cloudflare 上に保存する
- ブラウザからメールの閲覧・送信ができる
- メールの閲覧・送信機能は認証されたユーザーのみ利用できる
- ドメイン費用を除き、Cloudflare の無料枠内で運用する
ただし、最初からすべての機能を実装するのは大変なので、今回は
「独自ドメインでメールを受信し、Cloudflare Workers で処理できるところまで」
を目標とします。
2. 今回のシステム構成
今回利用するサービスは以下です。
| サービス | 用途 |
|---|---|
| gen.xyz | ドメイン取得・登録管理 |
| Cloudflare DNS | DNS管理 |
| Cloudflare Email Routing | メール受信 |
| Cloudflare Workers | 受信メールの処理 |
| Workers Observability | 実行ログの確認 |
今回の構成は以下のとおりです。
送信元メールアドレス
|
| SMTP
v
Cloudflare Email Routing
|
| ルーティングルール
v
Cloudflare Workers
|
| email() ハンドラー
v
Workers Logs
受信したメールは、Email Routing を通して Workers へ渡し、宛先とサイズをログに出力する形とします。
なお、今回はメールの受信を確認するだけなので、メール本文の保存処理は実装しません。
また、セキュリティ面を考慮し、受信 Worker については HTTP での公開を行わない構成を目指します。
3. 独自ドメインの取得と DNS 設定
3.1 ドメインの取得
まず、メールアドレスとして利用する独自ドメインを取得します。
今回はgen.xyzから、●●●.xyz のドメインを取得しました。
検証用として費用を抑えたかったため、取得費用が安かった .xyz ドメインを選んでいます。特にそれ以外に理由はありません。
(取得後にスパムなどへの悪用事例があると知ったのですが、まぁ、今回は個人学習用なので、そのまま使ってみることにしました)
取得後、登録者メールアドレスの認証を行い、ドメインが Active になったことを確認しました。
これで Cloudflare の設定へ進めると思っていましたが、ここで少しつまずくことになります。
3.2 Cloudflare でドメインが選択できない
Cloudflare の Email Routing でドメインを選択しようとしたところ、以下のメッセージが表示されました。

メールルーティング用の利用可能なゾーンが見つかりません
ドメインは取得できているため、そのまま利用できると考えていましたが、どうやら Cloudflare 側で DNS を管理するための設定が必要なようです。
調べてみると、ドメインの登録とDNSの管理は、それぞれ別の役割を持っています。
今回の場合、ドメインの登録・更新管理は gen.xyz で行いますが、DNSレコードの管理は Cloudflare に任せたいと考えています。
そのため、Cloudflare に DNS ゾーンを作成し、ドメインのネームサーバーを Cloudflare 指定のものへ変更する必要がありました。
3.3 ネームサーバーの変更
Cloudflare に取得済みドメインを追加し、Free プランを選択すると、以下のネームサーバーが指定されました。
celeste.ns.cloudflare.com
rene.ns.cloudflare.com
続いて、gen.xyz の管理画面から、以下のメニューを開きます。
My Domains > Manage > Nameservers
変更前のネームサーバーは以下でした。
parking1.gen.xyz
parking2.gen.xyz
これを Cloudflare 指定のネームサーバーへ変更します。
celeste.ns.cloudflare.com
rene.ns.cloudflare.com
設定画面で Use custom nameservers を選択し、変更内容を保存しました。

なお、ネームサーバーを変更する際、既存の DNSSEC 設定がある場合は、旧 DS レコードの扱いについても確認する必要があります。
この変更により、ドメインの登録・更新は引き続き gen.xyz で管理しつつ、DNS の問い合わせには Cloudflare の権威 DNS サーバーが応答する構成になります。
3.4 DNSが反映されていない?
ネームサーバーの変更後、Cloudflare 側のステータスを確認したところ、Pending のままでした。
DNS の設定変更には反映まで時間がかかることもあるため、まずは PowerShell から現在のネームサーバーを確認してみることに。
nslookup -type=ns ●●●.xyz 1.1.1.1
結果は以下となりました。
*** ●●●.xyz には利用できる
name server (NS) レコードがありません
想定していたCloudflareのネームサーバーが取得できていません。
いわゆる「DNSの浸透待ち」なのかと思いましたが、実際にどの段階まで反映されているか確認してみることにしました。
3.5 権威DNSへの問い合わせ
通常、DNSリゾルバーは取得したDNSレコードを一定期間キャッシュします。
そのため、権威DNS側で設定が変更されていても、DNSリゾルバーが古い情報を返す場合があります。
そこで、.xyzの権威DNSサーバーへ直接問い合わせてみました。
nslookup -type=ns ●●●.xyz x.nic.xyz
結果は下記が出力されました。
●●●.xyz nameserver = parking1.gen.xyz
●●●.xyz nameserver = parking2.gen.xyz
こちらでも変更前のネームサーバーが返ってきました。
つまり、今回の時点では、DNS リゾルバーのキャッシュ以前に、.xyzの親ゾーン側でも変更前の情報が案内されている状態でした。
この確認を通じて、DNS の反映については下記を分けて考える必要があると理解しました。
| 確認箇所 | 確認する内容 |
|---|---|
| レジストラ | 変更した NS が保存されているか |
| 親ゾーンの権威DNS | 新しい NS への委任が反映されているか |
| DNSリゾルバー | キャッシュを含め、どのNSを返しているか |
これまでは、DNS の変更が反映されない場合は単純に時間がかかるものと考えていましたが、問い合わせ先を変えることで、問題の切り分けができることを理解できました。
その後、gen.xyz 側で変更が保存されていることを確認し、しばらく時間を置いたところ、Cloudflare 側でも Active になっていました。
これで、Cloudflare による DNS 管理へ移行できました。
4. DNSレコードの確認
4.1 作成した覚えのないAレコード
Cloudflare の DNS 設定を確認したところ、下記 A レコードが存在していることがわかりました。
A @ 54.67.87.110
A www 54.67.87.110
A * 54.67.87.110
いずれも自分で作成した覚えがなかったため、何のための設定なのか確認します。
調査の結果、Cloudflare にはドメイン追加時に既存の DNS レコードをスキャンして取り込む機能があります。
今回のドメイン取得直後には gen.xyz のパーキングページが表示されていたため、パーキングページ向けに設定されていた A レコードが、Cloudflare へのドメイン追加時に取り込まれた可能性があります。
Aレコードは、ドメイン名と IPv4 アドレスを対応付けるための DNS レコードです。
今回のように同じ IP アドレスが設定されていれば、ルートドメインや対象サブドメインから、同じ接続先を参照する構成になります。
一方、メールの配送先には後述する MX レコードを使用します。
今回は Web サイトを公開する予定がなく、これらのAレコードも利用していないため、3件とも削除することにしました。
4.2 公開した覚えがないのにアクセスが発生している
ちなみに、A レコードを削除する前に Cloudflare の Analytics を確認したところ、直近24時間で868件の HTTP リクエストが記録されていました。

特に気になったのは、下記パスにアクセスが発生していたことです。
/xmlrpc.php
/2018/wp-includes/wlwmanifest.xml
/blog/wp-includes/wlwmanifest.xml
いずれも WordPress に関連するパスですが、今回 WordPress は構築していません。
これらは、WordPress の設置状況などを機械的に探索するスキャンによるものと考えられます。
また、5xxエラーも441件発生しており、その多くは 521 Origin Down でした。
これは Cloudflare が接続先のオリジンサーバーと正常に接続できなかったことを示します。今回の場合、パーキングページ向けの接続先が正常に応答していなかった可能性が考えられます。
最近のセキュリティ情勢を踏まえると、こうしたアクセス自体は珍しくないのでしょうが、ドメイン取得後すぐにこれだけのアクセスが発生するとは思っていなかったので、恐怖を感じます。。
ただし、今回のように Web サイトを公開するつもりがなくても、不要な A レコードが残っていれば、意図しない接続先へアクセスが発生する可能性もあります。
このため、今回は不要なAレコードを削除し、メール受信に必要な DNS レコードだけを残す方針としました。
5. Email Routingの設定
DNS管理の移行が完了したので、ここからメール受信の設定を行います。
Cloudflare Dashboardから、下記のメニューを開きます。
Email Service > Email Routing
対象ドメインを選択し、Email Routing を有効化しました。
今回の設定では、Cloudflare によってメール受信用の DNS レコードが追加されました。
5.1 MXレコードの確認
追加された MX レコードは下記のとおりです。
route1.mx.cloudflare.net
route2.mx.cloudflare.net
route3.mx.cloudflare.net
MX レコードは、対象ドメイン宛てのメールをどのメールサーバーへ配送するか指定するものです。
例えば、mail.me@●●●.xyz にメールを送信する場合、送信側のメールサーバーは ●●●.xyz の MX レコードを問い合わせます。
今回の場合、Cloudflare のメールサーバーが案内されるため、メールはCloudflare Email Routing へ配送されます。
送信側メールサーバー
|
| MXレコードを問い合わせ
v
DNS
|
| Cloudflareのメール配送先を取得
v
Cloudflare Email Routing
また、メール認証に利用する SPF・DKIM の TXT レコードも追加されていました。
なお、MX レコードがメールの配送先を指定するのに対し、SPF はドメインからの送信を許可するサーバーを示し、DKIM は電子署名によって送信元ドメインやメッセージの正当性を検証するために使用されます。
今回 Cloudflare が追加した SPF・DKIM レコードは、Email Routing によるメールの転送・配送を認証するためのものであり、MX レコードとは役割が異なります。
最終的に Email Routing のステータスが「有効」になったことを確認しました。

6. Email Workerの作成
次に、受信したメールを Cloudflare Workers で処理します。
今回は、メールを受信した際にログを出力するだけのシンプルな Worker を実装しました。
6.1 Workerの作成
Email Routing の「宛先 Workers」から、新しいWorkerを作成します。
スターターには「自分で作成」を選択しました。
当初、Worker 作成画面に表示されているコードを直接編集しようとしましたが、ここではスターターのプレビューが表示されているだけでした。
そのため、今回は一度 Worker をデプロイし、その後、作成した Worker のコードエディターから処理を変更しています。
6.2 受信処理の実装
実装したコードは下記のとおりです。
export default {
async email(message, env, ctx) {
console.log("Email received", {
recipient: message.to,
size: message.rawSize,
});
},
};
今回は受信の確認が目的なので、処理は最小限にしています。
email() は、Email Routing からメールを受信した際に実行されるハンドラーです。
HTTP リクエストを処理する場合にはfetch()を使用しますが、今回のようなメール受信ではemail()を使用します。
また、message.to から受信先アドレス、message.rawSize からメールのサイズを取得できます。
今回のコードでは、これらの情報を console.log() に出力しています。
なお、今回実装したのは受信したメールの宛先とサイズをログに出力する処理のみであり、メール本文の保存や別のメールアドレスへの転送は行っていません。
このため、Worker でメールを受信できても、後からメールの内容を閲覧することはできません。
6.3 HTTP公開を無効化する
今回の構築では、昨今の情勢を踏まえセキュリティ面を考慮したく、不要な HTTP アクセス経路は設けない方針としました。
Cloudflare Workers には、workers.devなどを利用してHTTP経由でWorkerを呼び出す仕組みがあります。
しかし、今回必要なのはメール受信イベントの処理だけです。
このため、Worker のドメイン設定で下記を確認しました。
| 項目 | 設定 |
|---|---|
| Production URL | 無効 |
| Preview URL | 無効 |
| Custom Domain | 未設定 |
| HTTP Route | 未設定 |
これにより、HTTP 用の公開ルートを用意せず、Email Routing を経由して Worker を実行する構成になります。
ただし、外部からメールを受信する以上、メールそのものを介した入力は受け付けるため、完全に外部から隔離された環境になるわけではありません。
今後、メール本文や添付ファイルの解析を実装する際には、不正な入力を想定した処理も必要になります。
6.4 ルーティングルールの作成
Worker の作成後、Email Routing から受信アドレスと Worker を紐づけました。
今回の設定は下記のとおりです。
| 項目 | 設定 |
|---|---|
| 受信アドレス | mail.me@●●●.xyz |
| Action | Send to a Worker |
| Worker | 作成したEmail Worker |
| Status | Enabled |
これにより、指定したメールアドレス宛てにメールが届くと、Worker のemail()が呼び出されるようになります。
7. メール受信の動作確認
設定が完了したので、実際にメールを送信してみます。
7.1 テスト内容
動作確認にあたり、まずは Worker の Observability から Workers Logs を有効化しました。
これにより、Worker 実行時に出力される console.log() の内容を、Cloudflare Dashboard 上から確認できるようになります。
今回は社用メールアドレスから、下記テストメールを送信しました。
To: mail.me@●●●.xyz
Subject: Cloudflare受信テスト
Email Workerの動作確認です。
送信後、Worker の Observability を開いてログを確認します。
7.2 実行結果
Email received
{
recipient: "mail.me@●●●.xyz",
size: 5961
}
また、Observability 上では成功イベントが2件、エラーが0件となっていました。
今回のログから、下記処理が正常に実行されたことを確認できました。
社用メールアドレス
|
| メール送信
v
Cloudflare Email Routing
|
| ルーティングルール
v
Cloudflare Workers
|
| email() 実行
v
Workers Logs
|
v
受信成功
これで、今回の目標としていた
「独自ドメインでのメール受信と、Workerによる受信処理」
を実現できました。
8. おわりに
今回は、独自ドメインの取得から Cloudflare へのDNS管理の移行、Email Routing の設定、Workers によるメール受信までを実施しました。
今回の対応で特に興味深かったのは、DNS の管理とメール配送の仕組みです。
これまで DNS レコード自体業務で扱う機会がなく、ネームサーバーの変更や、その反映状況を権威 DNS へ直接問い合わせて確認することなどはあまりありませんでした。
今回、実際に NS の変更が反映されない状況に遭遇したことで、単純に DNS の浸透待ちと判断するのではなく、どの段階で変更が反映されていないかを確認する重要性を理解できました。
また、Cloudflare Workers についても、HTTP リクエストだけでなく、Email Routing を経由したメール受信イベントで実行できる点は新しい発見でした。
今回は HTTP の公開エンドポイントを設けず、メール受信処理だけを動かす構成にしましたが、今後Webメール画面を構築する際も、必要な機能だけを公開することを意識して進めたいと思います。
なお、現状では受信したメールの宛先とサイズをログへ出力するだけなので、メールサービスとして利用できる状態ではありません。
今後、実際にメールシステムとして利用するためには、受信したデータを保存・管理する仕組みが必要になります。
このため、次回は Cloudflare R2 を利用し、受信したメールを保存できる仕組みを実装する予定です。
最終的には、Cloudflare の無料枠を活用しながら、独自ドメインでメールの送受信・閲覧ができる Web メールシステムを目指します。



