CloudflareのEmail Workersで正規表現許可リストを使って複数宛先に受信メールを転送する

CloudflareのEmail Routing機能を使うと、受信アドレスごとに転送先を振り分けることができるんですが、Email Workersという機能を使えばスクリプトでもっと細やかな制御ができるようです。

たとえばどこかのサービス登録に使うアドレスは、そのサービスのドメインからのメールしか受信しないようにするとか。

Email Workersには、許可されたアドレスからのメールだけを転送するAllowlist sendersというテンプレートがあるんですが、そのままだと正規表現が使えないのでメールアドレスをフルで決め打ちする必要があるし、転送先が1つしか書けません。なので、これを改造してみることにしました。

とはいえスクリプトの文法がよくわからないので、いろいろなAIに頼んでみました。

それでEmail Workersでちゃんと動くコードが返ってきたのが、Claudeだけ。中国語の文法のわからないことを聞いてもかしこい答えを返すなあとふだんから感心していたんですが、コード生成でも優秀です。そもそもほかのAIは、Email Workersのコードを何の言語で書けばいいのかわかってなかったです。

で、そのClaudeの生成したものに若干手を加えてできたのが以下。

// Cloudflare Email Workers Forwarding Script with Regex Filtering

export default {
  async email(message, env, ctx) {
    // Regular expression patterns for allowed From addresses
    const allowedFromPatterns = [
      /^.*@aaa\.com$/i,
      /^.*@.*\.aaa\.com$/i,
      /^.*@bbb\.com$/i,
      /^.*@.*\.bbb\.com$/i
    ];

    // Forwarding destination email addresses
    const forwardToAddresses = [
      "xxx@xxx.com",
      "yyy@yyy.com"
    ];

    // Check the From address
    const from = message.from;

    if (allowedFromPatterns.some(pattern => pattern.test(from))) {
      // Forward the message to each destination address
      for (const forwardTo of forwardToAddresses) {
        // Forward the original message without modification
        await message.forward(forwardTo);
        console.log(`Forwarded email from ${from} to ${forwardTo}`);
      }
    } else {
      // Reject the email if it doesn't match the allowed patterns
      message.setReject("Address not allowed");
      console.log(`Set to reject email from ${from}. Reason: Address not allowed`);
    }
  }
}

aaa.combbb.comのメールアドレス(サブドメイン含む)がFromにあったら、 xxx@xxx.com yyy@yyy.com に転送して、それ以外のメールは拒否するというコードです。
( xxx@xxx.com yyy@yyy.com は、事前にCloudflareのダッシュボード上でEmail > Email Routing > Destination addressesに登録しておく必要があります。)

この正規表現からすると、Fromの末尾が厳密にaaa.combbb.comになっていないと転送されないように見えるんですが、メールヘッダ上“AAA” <aaa.com>のような形式のFromのメールでもちゃんと転送対象になります。さすがにそのあたりちゃんとわかってくれてます。

Email Workersの注意点

Email Workersはいろいろできておもしろそうなんですが、ちょっと注意点が。

Cloudflareのダッシュボード上、Email Workersで転送されたメールは、Email RoutingActivity LogResultDroppedになってしまうんです。Forwardedでなく。

転送されずにRejectされたメールはDelivery Failedとなるので区別はつくんやけど。

ちなみに複数の転送先のうち転送できたところとできなかったところが混ざっていた場合もDelivery Failedでした。

追記 2024-11-24

Email Workersで転送されたメールのActivity LogでのResultが最近DroppedからForwardedに変わっていました。

ただ、たとえば1通の受信メールを4アドレスに転送した場合、Email Routing summaryでは

Total received: 5
Forwarded: 4
Dropped: 1
Other: 0

のようにカウントされています。

独自ドメインで無料でメール送受信する環境を作る

独自ドメインを使ってGoogle Workspaceをおためししていましたが、そろそろ無料期間が終わるので解約することにしました。

Google SitesのHTTPSでのwwwなしアクセスもGoogle Workspaceなしで無料でできることがわかったし、独自ドメインでのメール送受信も無料でできることがわかったので。

無料でのメール送受信

メール受信(転送)は、CloudflareのEmail Routing機能を使えば無料でできるということにはこの前ふれました。

で、無料での送信はどうやるか。

これにはMailgunというサービスを使うことにしました。このサービスの提供するSMTPサーバを使って送信する設定をGmailに入れて使います。1日100通までの送信なら無料。広告配信とかするのでなければこれで十分かな。

Mailgunは無料アカウントだと1ドメインしか管理できないので、生ドメインとそのサブドメインをいっしょに扱うことはできません。
(アカウント作成時にSMS認証があるので、2アカウント作る場合は電話番号が2つ必要かも。SMS認証しなくても各種設定はできるけど、実際のメール送信はできませんでした。)

さっきのプラン比較のページによると、“Authentication Protocols (SPF, DKIM, CNAME, DMARC, BIMI, etc.)“はFreeプランだと使えないことになっているんですが、SPF・DKIM・DMARCはなぜか問題なく使えて、受信側の検証もちゃんと通っています。

SPF・DKIM・DMARC非対応ドメインのブロックがGmailで始まったから、広く開放することにしたんかな?

しかもDKIMは2048ビットの鍵長にも対応しているので、そのあたりもGoogle Workspaceと遜色ないです。

ちなみに上位プランでしか使えないほかの機能へのアクセスにはちゃんとUpgradeの案内が出るので、おためし期間中だから全機能利用できてるみたいな感じではないです。そもそもおためし期間じゃないし。

DNS設定

DNS側の設定ですが、送信だけの目的なら、Mailgunの管理ページの

Send > Sending > Domains > (ドメイン名) > DNS Records

に書かれてあるSending recordsの2レコードだけ書けばいいです。
(わかりにくいけど、1つ目がDKIMで、2つ目がSPFです。)

SPF・DKIMレコードはSimpleLoginのと共存可能なので、Mailgunの設定を入れても送信はSimpleLoginでも問題なくできます。
(SPFはちゃんと1行に混ぜて書く必要があるけれど。)

Receiving recordsはMXレコード。受信メールをどのサービスに受け取らせるか。今回受信はCloudflareがやるので使いません。サブドメイン運用なしなら、Cloudflareでなくこっち使うのもありかも。正規表現でのメールの振り分けとか、複数宛先転送もできるみたいやし。

Tracking recordsって何やろ?と思ったんですが、送信メールに埋め込む既読検知用のビーコンとかUnsubscribeリンクとかのURLがこのドメインで書かれるみたいです。自分は使わないけど。

ちなみにこの送信メールに埋め込むUnsubscribeリンク、クリックされるとその後その宛先に一切メール送信ができなくなります。

「まちがってクリックしてしまった人のために戻す方法を提供してほしい!」というリクエストが2017年にフォーラムに出ていたんですが、まだ対応されてないようです。

このせいで、送信テスト用に使っているアドレスにまったく送れなくなってこまったので、Mailgunの設定でドメイン自体を消して登録しなおしたら送れるようになりました。DKIMキーも作り直し。

なぜかそれでも、Dashboardの統計データとかは消えずに引き継がれました。

Google SitesをHTTPSでwwwなし独自ドメインアクセスできるようにする方法

この前○○○.earthという独自ドメインを取ったけれど、このドメインのWebサイトを1ページだけでも作っておくことにしました。

名刺に

Web: ○○○.earth

みたいに書くことを想定して。

Webサーバ選定

Webサイトでは、コンテンツをごりごり作り込もうとかは考えてないので、機能は最低限でいいです。

無料で広告も出ないところはないかと調べたら、やっぱりGoogle Sitesがよさげでした。

Google Sitesに独自ドメインでアクセスできるようにする

Google Sitesで作ったサイトを独自ドメインで表示させるのはこの手順で。これで、

http://www.○○○.earth
https://www.○○○.earth

でアクセスさせることができるようになりました。

せっかくドメイン名がシンプルなのだから、いっそのことwwwなしでもアクセスできるようにしたいです。

wwwなし(ネイキッドドメイン)URLでアクセスできるようにする

サイトをwwwなしURLでアクセスできるようにする機能は、個人用のGoogle Sitesにはないんですが、Google Workspaceのにはありました。Google Workspaceは無料ではないけれど。

設定はこの手順で。これで、

http://○○○.earth

でアクセスさせることができるようになりました。
(“https://www.○○○.earth"にリダイレクトされます。)

でもHTTPSの"https://○○○.earth"だとつながりません。ブラウザをHTTPS強制設定にしてる人もいるし、この状態だと名刺に「Web: ○○○.earth」とは書けないです。

wwwなしURLにHTTPSでアクセスできるようにする

HTTPでしか接続できなかったものを無理やりHTTPSで接続できるようにするといえば、CloudflareのProxyモード。以前BlueskyのリダイレクトURLでお世話になりました。

“○○○.earth"のAレコードとAAAAレコードでProxyモードをONにすれば、

https://○○○.earth

でも無事につながるようになりました。
(リダイレクト先の"www.○○○.earth"のCNAMEレコードでは、ProxyモードをOFFにする必要がありました。あと、SSL/TLS encryption設定で、encryption modeをFlexibleにもしています。)

Google Workspaceを使わずwwwなしURLでアクセスできるようにする

wwwなしURLにアクセスするのに有料のGoogle WorkspaceのGoogle Sitesを使うという方法をさっき書いたけれど、Cloudflare(無料プランでOK)を使うとその必要もなくなりました。

ふつうのお行儀のいいDNSだと、RFCという業界標準の仕様上wwwなしのネイキッドドメインにはCNAMEレコードが書けないんですが、

CloudflareはCNAME flatteningという特殊な挙動で技術的な制約をかわしてくれるので、ネイキッドドメインにもCNAMEレコードが設定できます。

“○○○.earth"のCNAMEレコードに"www.○○○.earth"と書いてProxyモードをONにしておけば、個人用Google Sitesを使っていても、

http://○○○.earth
https://○○○.earth

というURLで

https://www.○○○.earth

にリダイレクトさせることができました。ホスト名のかぶる生ドメインのMXレコードの動作にも影響しません。

追記 2024-11-13

CNAME flatteningを使うとGoogle Workspaceでなく個人用のGoogle Sitesにネイキッドドメインでアクセスできるようになるんですが、

Google Workspaceの管理コンソール > アカウント > ドメイン > ドメインの管理 > 対象ドメインのリダイレクトを変更

でネイキッドドメインのwwwへのリダイレクト設定は有効にしたままである必要があるようです。これはGoogle Workspaceのサブスクリプションが切れていても問題ないので、試用期間でこの設定を入れてしまえばいいです。
(この設定がないと、ネイキッドドメインアクセスでGoogleが"HTTP 404"を返してしまいます。)

追記 2024-11-18

PorkbunのURL Forwarding機能(無料)を利用すれば、CNAME flatteningやGoogle Workspaceの管理コンソールのリダイレクト設定に頼ることなく

http://○○○.earth
https://○○○.earth

というURLから

https://www.○○○.earth

にリダイレクトさせることが可能です。SEO的にどうとかはわかりませんが。

追記 2025-05-03

CloudflareのRedirect Rulesを利用すれば、CNAME flatteningにもGoogle Workspaceの管理コンソールのリダイレクト設定にもPorkbunのURL Forwarding機能にも頼ることなくリダイレクトすることができました。

スポーツの秋

すずしくなってきたので、2か月ぶりにインラインスケートに行ってきました。

道の駅 発酵の里こうざき

まずお気に入りの神崎の道の駅でお昼を食べてからと思ったら・・・

IMG20240926104054

2月からレストラン オリゼが木曜定休になってる(>_<)

IMG20240926104340

IMG20240926104416
ということで、イートインのあるパンやさん(はっこう茶房)でコロッケパンをいただくことに。ここ気になってたけど、入るのは初めてです。

このコロッケパン、最後の1つだったんですが、

IMG20240926105328

帰りがけに売り場を見てみたら、別の焼きたてパンが補充されていました。

あ、こっちもおいしそうやったなー。

夏の終わりあるある

IMG20240926112208

夏の間に、自転車道の脇の草がすっかり伸びていました。

IMG20240926114432

草刈りが済んでいるところもあるけれど・・・

IMG20240926123613

刈った草がまだ路面に放置されているところも。まぎれた小石に足を引っかけてしまって危なかったです。

夏の運動不足がたたって、体力的にちょっときつめでした。