はじめに
メールをちゃんと送ったのに届かない——よくある話だ。
原因の多くは認証設定の不備だ。SPF・DKIM・DMARCが揃っていないと、受信サーバーに迷惑メールと判定される。
この記事では:
- SPF・DKIM・DMARCの仕組み(設定しないと何が起きるか)
- 自前サーバー(Postfix / sendmail)での設定方法
- AWS SESでの設定方法
- 両者の違いと選び方
を順番に整理する。
メール認証の基礎
メールが「本物かどうか」を受信側が確認するための仕組みが3つある。
SPF(Sender Policy Framework)
「このドメインから送っていいIPはこれだ」とDNSに宣言する。
受信サーバーは From ヘッダのドメインのDNSを引き、送信元IPと照合する。一致しなければ失敗(fail)扱いになる。
DNSに設定するTXTレコード例:
example.com. IN TXT "v=spf1 ip4:203.0.113.1 include:amazonses.com -all"
| トークン | 意味 |
|---|---|
ip4:203.0.113.1 |
このIPからの送信を許可 |
include:amazonses.com |
SESのIPも許可(SES経由で送る場合) |
-all |
上記以外はすべて拒否(fail) |
👉 -all(hard fail)と ~all(soft fail)がある。本番では -all を推奨。
DKIM(DomainKeys Identified Mail)
送信サーバーが秘密鍵でメールのヘッダ・本文に署名し、受信側がDNS上の公開鍵で検証する。
- 改ざん検知(署名後に本文が書き換えられたかどうかわかる)
- 送信元の正当性確認(秘密鍵を持つサーバーが送ったと証明できる)
DNS上の公開鍵レコード例:
mail._domainkey.example.com. IN TXT "v=DKIM1; k=rsa; p=MIGfMA0GCSqGSIb3DQEBA..."
👉 セレクタ(mail の部分)は任意の名前をつけられる。複数の鍵を使い分けるときに区別する。
❌ DKIM署名があっても、メールが「どのドメインから送られたか(From)」を証明するわけではない。それはDMARCの役割。
DMARC(Domain-based Message Authentication, Reporting & Conformance)
SPF・DKIMの結果を受け取り、失敗したときどう処理するかをポリシーとして宣言する。
DNSに設定するTXTレコード例:
_dmarc.example.com. IN TXT "v=DMARC1; p=quarantine; rua=mailto:dmarc@example.com"
| パラメータ | 意味 |
|---|---|
p=none |
何もしない(モニタリングのみ) |
p=quarantine |
迷惑メールフォルダへ振り分け |
p=reject |
受信を拒否 |
rua= |
集計レポートの送信先メールアドレス |
👉 最初は p=none でレポートだけ収集し、問題がないことを確認してから quarantine → reject へ段階的に上げるのが安全。
自前サーバー編(Postfix / sendmail)
Postfix
現代のLinux環境で最も広く使われているMTA。設定ファイルが読みやすく、ドキュメントも充実している。
/etc/postfix/main.cf の基本設定:
myhostname = mail.example.com
mydomain = example.com
myorigin = $mydomain
inet_interfaces = all
inet_protocols = ipv4
# TLS(送信側)
smtp_tls_security_level = may
smtp_tls_loglevel = 1
# TLS(受信側)
smtpd_tls_cert_file = /etc/letsencrypt/live/mail.example.com/fullchain.pem
smtpd_tls_key_file = /etc/letsencrypt/live/mail.example.com/privkey.pem
smtpd_tls_security_level = may
設定変更後は postfix reload で反映する。
OpenDKIMの設定(/etc/opendkim.conf):
Mode sv
Domain example.com
KeyFile /etc/opendkim/keys/example.com/mail.private
Selector mail
Socket inet:8891@localhost
PostfixにOpenDKIMをmilterとして組み込む(main.cf):
milter_protocol = 6
milter_default_action = accept
smtpd_milters = inet:localhost:8891
non_smtpd_milters = inet:localhost:8891
鍵の生成:
opendkim-genkey -D /etc/opendkim/keys/example.com/ -d example.com -s mail
生成された mail.txt の内容をDNSのTXTレコードに登録する。
sendmail
歴史的に広く使われてきたMTA。設定は sendmail.cf(直接編集は難解)と m4 マクロで行う。
/etc/mail/sendmail.mc(m4マクロ)の基本設定:
OSTYPE(`linux')
DOMAIN(`generic')
define(`confDOMAIN_NAME', `mail.example.com')
define(`confCACERT', `/etc/ssl/certs/ca-bundle.crt')
define(`confSERVER_CERT', `/etc/letsencrypt/live/mail.example.com/fullchain.pem')
define(`confSERVER_KEY', `/etc/letsencrypt/live/mail.example.com/privkey.pem')
MAILER(`local')
MAILER(`smtp')
m4からcfファイルを生成:
m4 /etc/mail/sendmail.mc > /etc/mail/sendmail.cf
systemctl restart sendmail
dkim-milterの設定(/etc/mail/dkim-filter.conf):
Domain example.com
KeyFile /etc/dkim/keys/mail.private
Selector mail
Socket inet:8891@localhost
sendmail.mc にmilterを追加:
INPUT_MAIL_FILTER(`dkim-filter', `S=inet:8891@localhost')
👉 現代の新規構築ではPostfixを選ぶのが無難。sendmailは設定の複雑さと可読性の低さがネックになりやすい。既存環境の保守目的で使うことが多い。
共通:DNSレコードのまとめ
自前サーバーを使う場合、以下のDNSレコードをすべて手動で設定する。
| レコード種別 | ホスト名 | 値 |
|---|---|---|
| TXT(SPF) | example.com |
v=spf1 ip4:<サーバーIP> -all |
| TXT(DKIM公開鍵) | mail._domainkey.example.com |
v=DKIM1; k=rsa; p=<公開鍵> |
| TXT(DMARC) | _dmarc.example.com |
v=DMARC1; p=quarantine; rua=mailto:dmarc@example.com |
| PTR(逆引き) | <IPの逆引き> |
mail.example.com |
👉 PTRレコード(逆引きDNS)はVPSやクラウドプロバイダーのコンソールで設定する。設定しないとスパム判定されやすい。
送信元IPの注意点
自前サーバーの場合、サーバーのグローバルIPが送信元IPになる。
- 新規IPはレピュテーション(信用スコア)がゼロからスタート
- 過去にスパム送信に使われたIPを割り当てられることがある(VPSなどで注意)
- 大量送信する場合はウォームアップ(徐々に送信数を増やす)が必要
❌ 認証設定(SPF・DKIM・DMARC)が完璧でも、IPのレピュテーションが低いと届かないことがある。
AWS SES編
AWS SESはメール送信に特化したマネージドサービス。MTAの管理・鍵管理・IPレピュテーション管理をAWSが担う。
SES固有の概念
サンドボックス状態
初期状態では検証済みのメールアドレスにしか送れない。
本番環境で使うには「プロダクションアクセス」の申請が必要(AWSコンソールのSES → Account dashboardから申請)。
送信制限
| 状態 | 1日あたりの上限 | 送信レート |
|---|---|---|
| サンドボックス | 200通 | 1通/秒 |
| プロダクション | 50,000通〜 | 14通/秒〜 |
👉 プロダクション移行後もリクエストに応じて上限は引き上げられる。
送信元IP:共有IP vs 専用IP
| 共有IP | 専用IP(Dedicated IP) | |
|---|---|---|
| コスト | 無料 | $24.95/月/IP |
| IPレピュテーション | 他ユーザーと共有 | 自分で管理 |
| 向いている用途 | 一般的な用途 | 大量送信・ブランド保護 |
👉 共有IPは他ユーザーのスパム行為で評価が下がるリスクがある。大量送信や重要な通知メールには専用IPを検討する。
ドメイン検証
- AWSコンソール → SES → Verified identities → Create identity
-
Domain を選択して
example.comを入力 - SESが表示するCNAMEレコードをDNSに追加する
# SESが生成するCNAMEレコード例(3件)
_amazonses.example.com. CNAME verification-token.dkim.amazonses.com.
xxxxxxxxxx._domainkey.example.com. CNAME xxxxxxxxxx.dkim.amazonses.com.
yyyyyyyyyy._domainkey.example.com. CNAME yyyyyyyyyy.dkim.amazonses.com.
DNS伝播後、コンソール上のステータスが Verified になれば完了。
DKIM設定
ドメイン検証時に Easy DKIM を有効にすると、SESが自動で署名してくれる。
- 秘密鍵の生成・保管・ローテーションはSESが担う
- OpenDKIMのセットアップは不要
- DNSにCNAMEを3件追加するだけで完了(ドメイン検証時に追加したもの)
❌ 「DKIM設定が必要か」と思うかもしれないが、Easy DKIMを有効にした時点でSESが自動的に署名するため、追加作業は不要。
SPF
SESのSMTPエンドポイント経由で送ると、エンベロープFromが amazonses.com になるため、amazonses.comのSPFが自動的に通る。
独自ドメインのFrom(from:user@example.com)に対してSPFを通したい場合は:
example.com. IN TXT "v=spf1 include:amazonses.com ~all"
👉 SESではSPFよりDKIMとDMARCの組み合わせで認証を担保するのが一般的。
SMTPインターフェース接続
アプリケーションやPostfixからSESのSMTPエンドポイントに向けることで、既存の送信コードをほぼ変えずにSESを使える。
SESのSMTP設定値(東京リージョンの例):
| 項目 | 値 |
|---|---|
| ホスト | email-smtp.ap-northeast-1.amazonaws.com |
| ポート |
587(STARTTLS)または 465(TLS) |
| 認証方式 | PLAIN / LOGIN |
| ユーザー名 | IAMのSMTP認証情報(アクセスキーとは別) |
| パスワード | 同上 |
SMTP認証情報の生成:
SESコンソール → SMTP settings → Create SMTP credentials → IAMユーザーが作成され、ユーザー名・パスワードが表示される。
PostfixからSESに向ける設定(main.cf):
relayhost = [email-smtp.ap-northeast-1.amazonaws.com]: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
/etc/postfix/sasl_passwd:
[email-smtp.ap-northeast-1.amazonaws.com]:587 SMTP_USER:SMTP_PASSWORD
postmap /etc/postfix/sasl_passwd
postfix reload
比較まとめ
| 観点 | 自前サーバー(Postfix/sendmail) | AWS SES |
|---|---|---|
| 送信元IP | 自サーバーのIP(レピュテーション管理が必要) | 共有IP or 専用IP(AWSが管理) |
| DKIM署名 | OpenDKIMを自前で設定・鍵管理 | SESが自動署名(CNAMEを置くだけ) |
| SPF | 自サーバーIPをDNSに記載 |
include:amazonses.com を追加 |
| DMARC | 自前でDNSレコードを設定 | 同左(SES固有の差異なし) |
| 管理コスト | 高い(MTA・TLS・鍵管理・ログ監視) | 低い(インフラ管理はAWS任せ) |
| コスト | サーバー費用のみ(大量送信に有利) | 従量課金(少量なら安価) |
| 到達率 | IP評価次第 | 高め(AWSの実績あるIP) |
| 初期設定の手間 | 多い | 少ない(サンドボックス解除が手間) |
どちらを選ぶか
SESを選ぶケース:
- 新規構築でメール送信基盤を一から作る
- 到達率を重視する(マーケティングメール・重要な通知)
- インフラ管理の工数を減らしたい
自前サーバーを選ぶケース:
- すでにPostfix/sendmailの運用実績がある
- 大量送信でSESのコストが無視できない規模になる
- IPアドレスを完全にコントロールしたい(特定のIPレンジからの送信が要件)
👉 新規構築でどちらか迷ったら、まずSESを選んでおくのが無難。管理コストが低く、到達率も安定している。