メールリレー(Mail Relay)
概要
メールリレー(Mail Relay) は、MTA(Mail Transfer Agent)が受信したメールを宛先に直接配送するのではなく、別の MTA に中継・転送する仕組みです。RFC 5321(2008年)が SMTP におけるメールリレーの動作を定義しています。
メールリレーには 2 つの形態があります。1 つはドメイン間のメール転送で、送信側 MTA が受信側 MTA にメールを転送する、インターネットメールの基本的な動作です。もう 1 つは中継サーバー(リレーホスト)を経由する転送で、送信側 MTA が直接宛先に配送する代わりに、指定されたリレーサーバー経由でメールを送り出す構成です。
クラウド環境やオンプレミスのメールシステムでは、外部への送信をリレーサーバー経由に集約する構成が一般的です。SendGrid、Amazon SES、Mailgun などのメール配信サービスは、SMTP リレーサービスとして機能します。自社のアプリケーションサーバーから直接宛先に SMTP 接続するのではなく、配信サービスのリレーサーバーにメールを渡し、配信サービスが最終的な配送を行います。
仕組み
メールリレーは直接配送とリレー配送の 2 つの形態があり、リレーホストの認証設定とオープンリレーの防止が運用の要点です。
直接配送とリレー配送の違い
直接配送では、送信側 MTA が宛先ドメインの MX レコードを引き、宛先の MTA に直接 SMTP 接続します。リレー配送では、送信側 MTA はメールをリレーホスト(中継サーバー)に渡し、リレーホストが宛先の MTA への配送を代行します。
# 直接配送
送信 MTA → (MX ルックアップ) → 宛先 MTA
# リレー配送
送信 MTA → リレーホスト → (MX ルックアップ) → 宛先 MTA
リレー配送を使う理由は複数あります。OP25B(Outbound Port 25 Blocking)で直接送信できない環境、送信元 IP のレピュテーション管理を配信サービスに委託したい場合、DKIM 署名やバウンス処理をリレーサーバーに集約したい場合などです。
リレーホストの設定
Postfix でリレーホストを設定する場合、/etc/postfix/main.cf の relayhost パラメーターを使います。
relayhost = [smtp.relay-service.com]:587
角括弧 [] で囲むと MX ルックアップを行わず、指定したホストに直接接続します。ポート番号を :587 で指定しています。リレーサーバーが SMTP AUTH を要求する場合は、認証情報も設定します。
# /etc/postfix/main.cf
smtp_sasl_auth_enable = yes
smtp_sasl_password_maps = hash:/etc/postfix/sasl_passwd
smtp_sasl_security_options = noanonymous
smtp_tls_security_level = encrypt
# /etc/postfix/sasl_passwd
[smtp.relay-service.com]:587 apikey:SG.xxxxxxxxxxxx
オープンリレーの危険性
オープンリレーとは、認証なしで第三者からのメールを中継する MTA の設定状態です。インターネット初期には MTA がオープンリレーで運用されるのが一般的でしたが、スパム送信に悪用される深刻な問題が発生し、現在ではオープンリレーはセキュリティ上の重大な欠陥として扱われます。
オープンリレーの MTA が悪用されると、以下の被害が発生します。
- スパム送信の踏み台にされ、サーバーの IP アドレスが DNSBL(DNS ブロックリスト)に登録される
- DNSBL に登録されると、そのサーバーから送信する全てのメールが受信拒否される
- サーバーのリソース(CPU、帯域幅、ディスク)がスパム送信に消費される
- ISP からサーバーの停止を求められる場合がある
リレー制限の設定
Postfix でオープンリレーを防ぐ設定です。
# /etc/postfix/main.cf
smtpd_relay_restrictions =
permit_mynetworks,
permit_sasl_authenticated,
reject_unauth_destination
permit_mynetworks は mynetworks に定義されたネットワークからのリレーを許可します。permit_sasl_authenticated は SMTP AUTH で認証済みのクライアントからのリレーを許可します。reject_unauth_destination は上記の条件に該当しない場合、自ドメイン宛以外のメールのリレーを拒否します。
リレーとメール認証の関係
メールがリレーサーバーを経由すると、SPF の検証に影響が出ます。SPF はエンベロープ From ドメインの SPF レコードに送信元 IP が含まれているかを検証しますが、リレーサーバーの IP が SPF レコードに含まれていなければ SPF は fail します。
メール配信サービスを利用する場合は、サービスが提供する SPF の include メカニズムを自ドメインの SPF レコードに追加します。
v=spf1 include:sendgrid.net ~all
DKIM 署名はリレーサーバーで付与するのが一般的です。リレーサーバーが DKIM 署名を行うことで、途中のリレー経路に関係なく署名の検証が成功します。
設定例
Postfix の relayhost パラメーターでリレーサーバーを指定し、SMTP AUTH と TLS で認証・暗号化を行います。
SendGrid をリレーホストとして使う構成
SendGrid を SMTP リレーとして Postfix に設定する例です。
# /etc/postfix/main.cf
relayhost = [smtp.sendgrid.net]:587
smtp_sasl_auth_enable = yes
smtp_sasl_password_maps = hash:/etc/postfix/sasl_passwd
smtp_sasl_security_options = noanonymous
smtp_tls_security_level = encrypt
smtp_tls_CAfile = /etc/ssl/certs/ca-certificates.crt
header_size_limit = 4096000
# /etc/postfix/sasl_passwd
[smtp.sendgrid.net]:587 apikey:SG.xxxxxxxxxxxxxxxxxxxxxxxx
設定後、postmap でハッシュファイルを生成し、Postfix をリロードします。
postmap /etc/postfix/sasl_passwd
systemctl reload postfix
内部ネットワークからのリレーを許可する構成
社内のアプリケーションサーバーからメールを送信する場合、内部ネットワークの IP からのリレーのみを許可します。
# /etc/postfix/main.cf
mynetworks = 127.0.0.0/8, 10.0.0.0/8
relayhost = [smtp.sendgrid.net]:587
mynetworks に社内ネットワーク(10.0.0.0/8 等)を含め、外部からのリレーは拒否します。
確認方法
自サーバーがオープンリレーになっていないかテストするには、外部の IP から SMTP 接続を行い、リレーが拒否されることを確認します。
openssl s_client -starttls smtp -connect mail.example.com:25 -quiet
接続後に以下のコマンドを実行します。
EHLO test.example.net
MAIL FROM:<test@test.example.net>
RCPT TO:<external@gmail.com>
RCPT TO で 554 5.7.1 Relay access denied が返れば、オープンリレーではありません。250 OK が返ってしまう場合はオープンリレー状態であり、即座に smtpd_relay_restrictions を修正する必要があります。
リレーホスト経由のメール送信が正しく動作しているかは、テストメールを送信してメールログを確認します。
echo "Test relay" | mail -s "Relay Test" test@example.net
grep "relay=" /var/log/mail.log | tail -5
ログに relay=smtp.sendgrid.net[...]:587 と記録されていれば、リレーホスト経由で送信されています。
外部の視点からも確認したい場合は、Labee Dev Toolbox の Mail Auth API を使うと、送信ドメインの SPF レコードにリレーサーバーの情報が含まれているかを確認できます。
curl "https://labee.dev/api/mail-auth?domain=example.com"
{
"success": true,
"data": {
"spf": {
"record": "v=spf1 include:sendgrid.net ~all",
"exists": true
},
"dkim": {
"record": null,
"exists": false,
"selector": "default"
},
"dmarc": {
"record": "v=DMARC1; p=reject; rua=mailto:dmarc@example.com",
"exists": true
},
"bimi": {
"record": null,
"exists": false
}
},
"error": null,
"meta": { "responseTime": 120 }
}
data.spf.record に include:sendgrid.net(利用している配信サービスの SPF ドメイン)が含まれていれば、リレーサーバー経由の送信が SPF を通過する設定になっています。
よくある問題
メールリレーのトラブルは、オープンリレーによる DNSBL 登録、SPF の設定漏れ、認証情報の失効が代表的な原因です。
オープンリレーが発覚して DNSBL に登録された
オープンリレーの状態でスパムに悪用されると、サーバーの IP が Spamhaus や Barracuda などの DNSBL に登録されます。まず smtpd_relay_restrictions を修正してオープンリレーを停止し、原因のスパム送信を止めます。その後、各 DNSBL の解除申請を行います。DNSBL からの解除には数日〜数週間かかることがあります。
SPF がリレー経由で fail する
自社 MTA からリレーサーバー経由でメールを送信している場合、受信側が見る送信元 IP はリレーサーバーの IP です。自ドメインの SPF レコードにリレーサーバーの IP または include メカニズムが含まれていないと、SPF が fail します。リレーサービスが提供する SPF レコード情報を自ドメインの SPF に追加します。
リレーサーバーへの認証に失敗する
リレーサーバーへの SMTP AUTH が失敗すると、メールは送信キューに滞留します。Postfix のログに SASL authentication failed と記録されます。API キーの有効期限切れ、パスワードの変更、TLS 設定の不一致(smtp_tls_security_level が不適切)などが原因です。認証情報を更新し、postmap でハッシュファイルを再生成します。
リレーサーバーの送信制限に抵触する
メール配信サービスには送信量やレートの制限があります。SendGrid の無料プランは 1 日 100 通、Amazon SES のサンドボックス環境は 1 日 200 通です。制限を超えるとリレーサーバーが 450 または 550 でメールを拒否します。配信ログで制限到達のエラーが出ていないか確認し、必要に応じてプランのアップグレードや送信制限の緩和を申請します。