自分で運用しているFreeBSD+PostfixのメールサーバーからGmailへメールを送ったところ、次のようなエラーが返ってくるようになりました。
550-5.7.1
Our system has detected that this message is likely unsolicited mail.
簡単に言えば、
「迷惑メールの可能性があるため、Gmail側で受信を拒否した」
ということです。
以前は自前のPostfixから普通にメールを送信できていても、現在は「メールが送信できる」というだけでは不十分です。
Gmailなどへ安定してメールを届けるためには、
- SPF
- DKIM
- DMARC
- 正引き・逆引きDNS
- TLS
などを正しく設定することが重要になっています。
この記事では、FreeBSD+PostfixからGmailへメールを送信することを目的として、SPF・DKIM・DMARCの設定方法を整理します。
Gmailの送信者要件
Googleは2024年2月から、Gmailへメールを送信する送信者に対して認証などの要件を設けています。
通常の送信者では、少なくともSPFまたはDKIMによる認証が必要です。
さらに、Gmailへ1日5,000通を超えるメールを送信する一括送信者については、
SPF+DKIM+DMARC
が必要です。
自前のメールサーバーを運用するのであれば、送信数にかかわらず、
SPF・DKIM・DMARCをすべて設定しておく
ことをおすすめします。
今回の環境
私の環境では、FreeBSD上でPostfixとCyrus IMAPを使用しています。
また、1台のメールサーバーで複数のドメインを扱っています。
説明用として次の構成を想定します。
メールサーバー
mail.example.com
メインドメイン
example.com
仮想ドメイン
example.jp
送信メールアドレス
user@example.jp
つまり、
user@example.jp
↓
mail.example.com
↓
Gmail
という形でメールを送信します。
今回の目的は、
user@example.jpから送ったメールを、正規のメールとしてGmailに認証してもらうこと
です。
最初にSPF・DKIM・DMARCの違いを理解する
設定を始める前に、それぞれの役割を理解しておくと分かりやすくなります。
SPF
SPFは、
「このドメインのメールを、このIPアドレスのメールサーバーから送ってよい」
という情報をDNSで公開する仕組みです。
DKIM
DKIMはメールサーバーが秘密鍵でメールに電子署名を付けます。
受信側はDNSに登録された公開鍵を使って署名を検証します。
これによって、
「このドメインが管理する鍵で署名されたメールである」
ことを確認できます。
DMARC
DMARCはSPFとDKIMの認証結果を利用して、
「From:に書かれているドメインと認証されたドメインが一致しているか」
を確認し、認証に失敗したメールをどう扱うかという方針をDNSで公開する仕組みです。
重要:送信側SPFと受信側SPFは別の話
ここは非常に重要です。
以前の記事ではpolicyd-spfをPostfixへインストールしていました。
しかし、
自分のメールをGmailにSPF認証してもらうだけなら、policyd-spfは必要ありません。
送信側で必要なのは、
自分のドメインのDNSへSPF TXTレコードを登録すること
です。
policyd-spfやpyspf-milterは、自分のPostfixが受信したメールのSPFを検証するために使用します。
つまり、
自分 → Gmail
のSPF対策はDNS設定。
インターネット → 自分
のメールをSPF検証する場合にpolicyd-spfなどを使用します。
目的が違います。
この記事では「Gmailへ送信する」ことが目的なので、まず送信側の設定を説明します。
1. SPFを設定する
SPFはDNSのTXTレコードとして登録します。
たとえば、メールサーバーのグローバルIPアドレスが、
203.0.113.10
だったとします。
example.jpのDNSへ、
example.jp. IN TXT "v=spf1 ip4:203.0.113.10 -all"
を登録します。
これで、
example.jpのメールは203.0.113.10から送信する
ということを宣言できます。
※203.0.113.10は説明用のIPアドレスです。実際には自分のメールサーバーのグローバルIPアドレスを指定してください。
SPFを確認する
DNSへ登録したら、
% dig TXT example.jp
などで確認します。
正常なら、
"v=spf1 ip4:203.0.113.10 -all"
が取得できます。
SPFの「-all」と「~all」
よく見かけるのが、
-all
と、
~all
です。
-allは、
「ここまでの条件に一致しない送信元はSPF Fail」
という比較的厳しい指定です。
一方、
~all
はSoftFailです。
自分のドメインからメールを送信するサーバーを完全に把握できているのであれば、最終的には-allを使用できます。
ただし、Webサーバーや外部メール配信サービスなどからもメールを送っている場合、それらもSPFに含める必要があります。
2. DKIMを設定する
続いてDKIMです。
DKIMでは、
秘密鍵 → メールサーバー
公開鍵 → DNS
という構成にします。
Postfixからメールを送信するときに秘密鍵で署名し、GmailはDNSから公開鍵を取得して署名を検証します。
OpenDKIMをインストールする
私はFreeBSDのportsを使用しています。
# cd /usr/ports/mail/opendkim
# make install clean
pkgを使用する場合は、その環境で提供されているパッケージを利用してください。
DKIMの鍵を作る
鍵を保存するディレクトリを作成します。
# mkdir -p /var/db/dkim/example.jp
# chown -R mailnull:mailnull /var/db/dkim
セレクタを、
202608
として鍵を作成します。
# opendkim-genkey \
-D /var/db/dkim/example.jp \
-d example.jp \
-s 202608
すると、
202608.private
202608.txt
が作成されます。
202608.privateが秘密鍵。
202608.txtにはDNSへ登録する公開鍵が記述されています。
DKIMのセレクタとは?
セレクタは、
「どのDKIM鍵を使っているかを識別する名前」
です。
今回、
202608
というセレクタにしたので、公開鍵は、
202608._domainkey.example.jp
というDNS名で公開します。
日付をセレクタにしておくと鍵を交換するときにも分かりやすくなります。
DKIM公開鍵をDNSへ登録する
生成された、
202608.txt
を確認します。
概ね次のような内容になります。
202608._domainkey IN TXT (
"v=DKIM1; k=rsa; p=xxxxxxxxxxxxxxxx..."
)
これをDNSへ登録します。
p=以降が公開鍵です。
こちらは公開して問題ありません。
一方、
202608.private
は秘密鍵なので絶対に公開しないでください。
OpenDKIMを設定する
複数ドメインを扱う場合は、
KeyTable
SigningTable
TrustedHosts
を利用すると管理しやすくなります。
/usr/local/etc/mail/opendkim.conf
を設定します。
AutoRestart yes
Canonicalization relaxed/simple
ExternalIgnoreList refile:/usr/local/etc/mail/opendkim/TrustedHosts
InternalHosts refile:/usr/local/etc/mail/opendkim/TrustedHosts
KeyTable /usr/local/etc/mail/opendkim/KeyTable
Mode sv
SigningTable refile:/usr/local/etc/mail/opendkim/SigningTable
Socket local:/var/run/milteropendkim/socket
Syslog yes
SyslogSuccess yes
UMask 007
UserID mailnull
SigningTable
/usr/local/etc/mail/opendkim/SigningTable
に、
*@example.jp 202608._domainkey.example.jp
と記述します。
これは、
「@example.jpから送信するメールには、このDKIM設定を使う」
という意味です。
KeyTable
/usr/local/etc/mail/opendkim/KeyTable
には、
202608._domainkey.example.jp example.jp:202608:/var/db/dkim/example.jp/202608.private
と記述します。
これで、
example.jp
↓
selector = 202608
↓
202608.private
という関係ができます。
TrustedHosts
/usr/local/etc/mail/opendkim/TrustedHosts
には、DKIM署名を行う内部ホストなどを指定します。
たとえば、
127.0.0.1
::1
mail.example.com
とします。
必要以上に広いネットワークを登録しないようにします。
PostfixとOpenDKIMを接続する
Postfixのmain.cfへ設定します。
smtpd_milters = unix:/var/run/milteropendkim/socket
non_smtpd_milters = $smtpd_milters
milter_protocol = 6
milter_default_action = accept
ここで、
non_smtpd_milters
も重要です。
smtpd_miltersはPostfixのSMTPサーバー経由で入ってきたメールに適用されます。
一方、non_smtpd_miltersはsendmailコマンドなど、SMTPサーバーを経由せずPostfixのキューへ入るメールにもMilterを適用するための設定です。
Webアプリケーションなどからメールを送る場合には特に確認しておきたい項目です。
OpenDKIMを起動する
# service milteropendkim enable
# service milteropendkim start
Postfixも再起動します。
# service postfix restart
DKIMを確認する
DNSへ公開鍵を登録したら、
# opendkim-testkey \
-d example.jp \
-s 202608 \
-vvv
などで確認できます。
DNSから公開鍵を正常に取得できることを確認します。
3. DMARCを設定する
DMARCは基本的にDNSへTXTレコードを登録することで送信ドメイン側の設定を行います。
ここも重要なポイントです。
Gmailへ送った自分のメールをDMARC認証してもらうためだけなら、
自分のPostfixへOpenDMARCをインストールする必要はありません。
OpenDMARCは主に、
自分のメールサーバーが受信したメールのDMARCを検証する
ために使用します。
DMARCレコードをDNSへ登録する
DMARCは、
_dmarc.example.jp
という名前のTXTレコードとして登録します。
最初は、
_dmarc.example.jp. IN TXT "v=DMARC1; p=none"
程度から始めるとよいでしょう。
p=noneは、
DMARC認証結果を確認するが、認証に失敗してもDMARCポリシーとして隔離や拒否を要求しない
という監視向けの設定です。
DMARCレポートを受け取る
DMARCの大きなメリットの一つがレポート機能です。
たとえば、
v=DMARC1; p=none; rua=mailto:dmarc@example.jp
とします。
これによってDMARC集約レポートの送付先を指定できます。
ただし、DMARCレポートはXML形式で届くことが多いため、メールが大量に届く環境では専用の解析サービスやツールを使用した方が管理しやすいでしょう。
DMARCポリシーを強化する
動作確認ができたら、
p=none
から、
p=quarantine
さらに、
p=reject
へ変更することを検討します。
大まかには、
p=none
↓
p=quarantine
↓
p=reject
という順番で強化していくと安全です。
いきなりp=rejectにすると、設定漏れのある正規メールまで拒否される可能性があるので注意します。
DMARCで重要な「アライメント」
DMARCを理解するうえで重要なのが、
アライメント(Alignment)
です。
たとえばメールのFrom:が、
user@example.jp
なら、DMARCでは基本的にexample.jpとSPFまたはDKIMで認証されたドメインとの関係を確認します。
単に、
SPF = pass
DKIM = pass
になっていれば何でもよい、というわけではありません。
From:ドメインとのアライメントが重要です。
これがDMARCで特につまずきやすい部分です。
4. 正引き・逆引きDNSを確認する
SPF・DKIM・DMARCだけで終わりではありません。
Gmailへ送信するメールサーバーでは、正引き・逆引きDNSも重要です。
たとえば、
mail.example.com
↓ A
203.0.113.10
となっている場合、
203.0.113.10
↓ PTR
mail.example.com
という逆引きも正しく設定されていることを確認します。
逆引きPTRレコードは、自分が管理している通常のDNSゾーンではなく、サーバーや回線を提供している事業者側で設定するケースが多いので注意してください。
5. TLSも確認する
現在のGmail送信者要件では、メール送信にTLSを使用することも求められています。
Postfixのログを確認して、GmailとのSMTP通信がTLSで行われているか確認しておきます。
6. 実際にGmailへ送信して確認する
すべて設定したら、実際にGmailへメールを送信します。
Gmailで受信したメールのヘッダーを確認します。
理想的には、
spf=pass
dkim=pass
dmarc=pass
となります。
Gmailではメールの「メッセージのソースを表示」から認証結果を確認できます。
最終的な構成
今回の設定を整理すると、
DNS
│
┌──────────────┼──────────────┐
│ │ │
SPF DKIM DMARC
│ │ │
送信IPを公開 公開鍵を公開 ポリシー公開
│
│
user@example.jp │
│ │
▼ │
┌──────────────────────┐
│ FreeBSD + Postfix │
│ + OpenDKIM │
└──────────┬───────────┘
│
│ DKIM署名付きメール
▼
Gmail
│
├─ SPF確認
├─ DKIM署名確認
└─ DMARC確認
という関係になります。
policyd-spfとOpenDMARCは不要なのか?
不要というわけではありません。
用途が違います。
Gmailへ送信するために必要なのは、
SPF → DNS
DKIM → OpenDKIM+DNS
DMARC → DNS
です。
一方、自分のPostfixで受信するメールを検証するのであれば、
SPF検証 → policyd-spf / SPF Milterなど
DKIM検証 → OpenDKIM
DMARC検証 → OpenDMARC
といった構成が考えられます。
「送信ドメイン認証」と「受信メールの検証」を分けて考えると、とても分かりやすくなります。
まとめ
Gmailへメールを確実に届けるためには、単にPostfixが正常に動作しているだけでは不十分になっています。
最低でも確認しておきたいのは、
SPF
送信を許可するメールサーバーをDNSで公開する。
DKIM
OpenDKIMなどを使ってメールへ電子署名を付け、公開鍵をDNSへ登録する。
DMARC
SPF・DKIMとFrom:ドメインの関係を確認するためのポリシーをDNSへ公開する。
正引き・逆引きDNS
メールサーバーのホスト名とIPアドレスを正しく対応させる。
TLS
メールサーバー間の通信を暗号化する。
という点です。
特に重要なのは、
SPFとDMARCは、Gmailへ送信するためだけならPostfixへ専用ソフトをインストールする必要はなく、基本的にはDNS側の設定である
ということです。
私自身、最初に設定したときは「SPFを使うのだからPostfixにもSPFのソフトが必要だろう」と考えていました。
しかし、
送信メールを認証してもらう設定
と、
受信メールを自分のサーバーで検証する設定
は別物です。
ここを理解すると、SPF・DKIM・DMARCの関係がかなり分かりやすくなります。
自前でFreeBSD+Postfixのメールサーバーを運用していて、
「Gmailに届かない」
「迷惑メールに入ってしまう」
「550-5.7.xのエラーが返ってくる」
という場合は、まずSPF・DKIM・DMARC、正引き・逆引きDNS、TLSを順番に確認してみることをおすすめします。
