メールのドメイン認証まとめ

最終更新日:

すでに枯れた技術なのにミドルウェアの設定がめんどくさいメールサーバー。
メールサーバーを作るとき、色々見ながら設定はするけどよくわからんドメイン認証。
新年度ということもあり、初心者でもメールサーバーを構築するにあたって使うであろうドメイン認証の一覧を簡単な説明を載せて書いておく。
各技術はそれ相応に深いもので、本ページだけでの理解は難しいため、適宜色々な解説サイトやRFCを読み込んで仕様を理解してほしい。

ドメイン認証とは

メールの送付元ドメインが “本物” であることをチェックする為に使われている技術。
これはメールの仕様上、メールの送信元をユーザー側から見たときにある程度詐称できることからきている。
送信元メールサーバーから送付先メールサーバーに届けられるメールの中には宛先・送信者にまつわる2つの重要なデータが存在している。
それが エンベロープヘッダー
上記の言葉については様々なサイトで解説しているので割愛するが、基本的にヘッダーを書き換えることでなりすましができる。
以下のプログラムは、なりすましメールを作ることができるもの。

#!/usr/bin/env python3

###########
### 免責事項 
###########
#
# 本プログラムは検証・勉強用途のみに利用すること。
# 本プログラムを利用して発生したいかなる事象に対し著者は一切の責任を持たない。  
#

from smtplib import SMTP
from email.mime.text import MIMEText

# Envelope
ENVELOPE_TO   = "realreceiver@to.example.com"
ENVELOPE_FROM = "realsender@from.example.com"

# Header (Fake)
HEADER_TO   = "fakereceiver@fake.to.example.com"
HEADER_FROM = "fakesender@fake.from.example.com"

# SMTP Server
SMTP_HOST = "smtp.example.com"
SMTP_USER = "exampleuser"
SMTP_PASS = "examplepass"

# Header and Body
body = "hogehoge"
msg = MIMEText(body, "html")
msg["Subject"] = "Fake Email"
# 以下のTo, Fromを書き換えればなりすましが可能(メールヘッダー)
msg["To"] = HEADER_TO
msg["From"] = HEADER_FROM

MESSAGE = msg.as_string()

mail_serv = SMTP(SMTP_HOST)
mail_serv.set_debuglevel(True)
mail_serv.ehlo()
mail_serv.starttls()
mail_serv.ehlo()
mail_serv.login(SMTP_USER, SMTP_PASS)
mail_serv.sendmail(ENVELOPE_FROM, ENVELOPE_TO, MESSAGE)
mail_serv.quit()

上記のような例の場合、

  • エンベロープ

    • To(受信側): realreceiver@to.example.com
      • 改ざん不可能: メールはこの宛先のメールサーバーへと飛ぶため、改ざん不可能。
    • From(送信側): realsender@from.example.com
      • 改ざん可能: メールが送付できなかった場合、リターンメールがこのメールアドレス宛に飛ぶ。それを無視してもよいなら改ざんできる。
  • ヘッダー

    • To(受信側): fakereceiver@fake.to.example.com
      • 改ざん可能: ほとんどのメールクライアントはここに書かれているものを受信者として表示する。
    • From(送信側): fakesender@fake.from.example.com
      • 改ざん可能: ほとんどのメールクライアントはここに書かれているもの送信者として表示する。

という形になる。
上記のプログラムでメールを送付した場合、fakesender, fakereceiverというFromヘッダーが改ざんされたメールが送付される。

1件、個人で持っているメールアドレス宛に、ある種いい例といえるなりすまし迷惑メールが来ていたので紹介する。
ゴミカスscam野郎

赤く塗りつぶしている部分はすべて私が利用している同一のメールユーザーを示すもの。
上記のスクリーンショットは以下の点がおかしいといえる。

  • Fromが自分のメールアドレスになっており、謎の経由地が存在する。
  • 送信元が明らかに三菱UFJではない。

これはいわゆるメールによるフィッシング詐欺というもの。邪悪。
これはヘッダーFromを私のメールアドレスに書き換えて送付してきている。

なりすましメール自体は今に始まったものではなく、かなり歴史が古い。
しかしながら今回言及していくドメイン認証技術の一般的な普及により、なりすましメールを送付すること自体がそもそも難しくなってきているのが現状。

具体的なドメイン認証のやり方

複数個あるので以下に一覧として簡単にまとめていく。
以下に書く手法は1つだけやっておけばOK!というものではなく、基本全部設定することを推奨する。
全部やればなりすまし判定が極めてされにくい
(ここで「なりすまし判定がされない」と断言したいところだが、メールサーバーにはレピュテーションという隠れスコアがあって闇が深い。)
実際のところ、送信側での設定でSPFだけ入れときゃ問題なく送れるサーバーもあるし、DKIM, DMARKまできっちり設定しても受信側で迷惑メール判定が長い間続くサーバーも存在する。

PTRレコードの設定 (難易度: Very Easy)

だいぶ昔からある設定方式のはず。初出はいつなのかわからない。
送信側メールサーバーに設定されるA, AAAAレコードのFQDNと送信元メールサーバーのIPアドレスに紐づけられるPTRレコードの値が一致するかどうかで検証する。(ヘッダー、エンベロープも見てるのかはMTAによるのかも、情報不足) 送信側メールサーバーの逆引きレコード(PTRレコード)を設定すればOK。
設定方法はサーバーをどこで契約しているかによる。
GMO ConoHaをはじめとしたVPSなんかは管理画面から簡単に設定できるパターンが多いし、AWSも最近サポートへの起票無しでPTRレコードの設定をすることができるようになった。
クラスメソッド: [UPDATE] 申請なしでElastic IPの逆引き設定ができるリージョンが増えました [ついに東京、大阪も!!]

サーバー側での設定がなく、設定するうえで失敗する理由がほとんどないため難易度をVery Easyとした。

SPFレコードの設定 (難易度: Easy)

RFC7208によって定義されている。策定は2014年4月。
受信側メールサーバーがメール送信側のIPアドレスを確認し、メールを送信してきたFQDNに登録されているTXTレコード(SPF)に照らし合わせてチェックすることで、送信元のサーバーが妥当なものであるか検証する。
一見すると上記のPTRレコード方式と似ているが、より設定に自由度が増えた認証の方式である。
メールを送付するFQDNにDNS上のTXTレコードで設定を投入すればOK。
設定の内容だが、メールサーバーのIPアドレスを指定するもの、MXレコードを読み込ませる設定にするもの、設定を外部から引っ張ってくるものなど柔軟な設定ができる。
設定方法は様々なサイトに乗ってるため割愛。

[注意事項]

SPFレコードを編集するときにやらかす例が大手でもちらほらある。


なにをやらかしたか?というとSPFレコードは同じFQDN上で2個以上設定してはいけないところにある。
上記のツイートのような設定をすると、SPF Permerrorとなり、SPFによるドメイン認証が無効となる。(つまり@docomo.ne.jp発のメールが送りにくくなる!)
SPFの設定はFQDNにつきレコードの数は1つしか許されていないが、各設定項目の数は可変であるため、include: aspmx.pardot.comの設定を下の奴にねじ込んでおけば済んだはず。
インフラエンジニアあるあるだけど、軽微な追加・変更作業が致命的な問題に繋がることも多いのでちゃんとレビューなどを徹底したほうがいい。
個人的なファイトスタイルだが、やらかすと問題が大きくなりそうなドメインの場合、設定前に一時的にTTLを60~120秒にしておくと良いと思う。
上記のドコモの場合、ツイートでも言及していたが、TTLキャッシュが最大86400秒(24時間)残るため、どこかのユーザーは最大1日メールが届かなくなる恐れがある。
これをTTL120秒にしておけば120秒間隔で問題にカタがつけられるため、TTLのコントロール技術も学ぶといい。
(ドコモのようなクラスになってくるとDNS問い合わせによるネットワーク/DNSサーバーへの負荷もすごそうだが…。)
話がすごく脱線しているが、DNSもメールと密接に紐づいているため、DNSも勉強しような。

サーバー側の設定がなく、設定自体も簡単なため難易度をEasyとした。

DKIMレコードの設定 (難易度: Medium)

RFC 6376によって定義されている。策定は2011年9月。
送信側メールサーバーはRSAで電子署名したメールのデータをメールヘッダーに付与し送付する。
受信側メールサーバーは受信したメールにあるDKIMのデータが格納されているメールヘッダー(DKIM-Signature)を確認し、そこに記載されているセレクタ情報を確認した後、DNSに問い合わせを行い、公開鍵を取得する。
取得した公開鍵と秘密鍵が一致するならば署名検証が行えるため、検証ができる。

何言ってるかよくわからんけど、メールの耐改ざん性を獲得したドメイン認証技術。
DNSレコードの登録のみではなく、サーバー上でOpenDKIMや秘密鍵、セレクタの設定やMTAの設定を行う必要があり、少し難易度が上がる。
とはいえ、強いエンジニアたちが皆構築ログをあげているため、構築で大きなつまづきをすることはないと思う。

サーバーの設定もあるが、情報は多く出回っているため難易度をMediumとした。

DMARCレコードの設定 (難易度: Easy)

RFC 7489によって定義されている。策定は2015年3月。 DMARCは前述のドメイン認証とは少し異なり、それ自体ではドメイン認証の効力を持っているとは言い難い。
DMARCの本質的な効力は"受信側サーバーがなりすましメールを受け取った"ときに効果を発揮する。
DMARCはなりすましメールを受信したメールサーバーがその後の対応内容を決める為に利用されるものだからだ。 DMARCの設定では、DMARCの認証に失敗したメールを受信側でリジェクトしてもらうもの、迷惑メールに隔離してもらうもの、DMARCの認証に失敗したメールのレポート送付先を指定できるものがある。
対応内容はメールで利用するドメインの頭に_dmarcを入れ、そのFQDNにTXTレコードを入れる形。
私が普段設定するときは迷惑メールに隔離してもらったうえ、レポートの送付は特に利用しない設定にしている。
私個人からすればDMARCは正直そこまで設定する必要のある設定とは思っていなかった。やりすぎではないかと思っていた。
しかし、以下の記事ではPaypalではDMARC導入後では70%, MicrosoftのOutlookでは50%以上のなりすましメールを削減できたとある。
https://dmarc.org/press/release-20140218/

めっちゃ重要じゃん、DMARC…

サーバー側の設定がなく、設定自体も簡単なため難易度をEasyとした。

インフラエンジニアとしての個人のお気持ち

最初にメールは枯れた技術、みたいなことを書いてしまったが、今もアップデートが続いている技術である。
SPFの話を少し長めに書いたのも、その辺りに少し思うところがあるため。
難易度が低い?設定が単純?それはそうだけど、設定変更時に一文字ミスったら認識されずTTLが切れるまで地獄を見ることになるかもしれない。そもそも重要な仕様を把握していなくてやらかすかもしれない。
よくわかってないIT担当者がめちゃくちゃにいじって大爆死している例をみたことはある?その後の爆弾処理を押し付けられる係には?
これを見てくれたみんなはミスをやらかして時すでに時間切れかつ致命的な致命傷になる前に色々打てる手段はちゃんと打ってくれな!
あとそろそろPPAPも廃止しようね。

  • Q: なんで難易度がMediumまでしかないんですか?Hardはどこに行ったんです?
  • A: インフラの安定運用をするのがVery Hard、はっきりわかんだね。