はじめに
メールはとても奥が深く、SPF、DKIM、DMARC など。いきなり難しい用語にぶつかって戸惑ってしまいがちです。
私自身もまさにその状態で、ドメイン認証の仕組みの理解に悩むなかで
「そもそもメールってどうやって送られているの?」「SMTP って何?」という根本に立ち返ることにしました。
この記事は、メールの基本中の基本である「メールメッセージの構造」と「SMTPプロトコルの仕組み」を、Telnet を使って実際に手を動かしながら理解してみた記録です。
メールの仕組みを基本からしっかり整理してみたい方の入り口になれば嬉しいです。
SMTP とは
メールオブジェクトを、送信者から受信者へ配送するための専用プロトコルです。
メールオブジェクトは以下で構成されます:
- SMTP エンベロープ(配送のための外装)
- SMTP コンテンツ(実際の手紙)
SMTP コンテンツはさらに、以下に分かれます:
- ヘッダーセクション(件名、差出人、宛先など)
- 本文(メッセージ本体)
私たちが普段、受信箱で目にするのは SMTP コンテンツ 部分です。
SMTP プロトコルは、TCP プロトコル上で動作するため、まずはコネクションを確立させるところから始まります。
そしてコネクションの確立後も、まるでトランシーバーのように、1ステップずつ交互に通信しながら慎重に進みます
イメージ:
「こちら example.net、応答願います、どうぞ」
「こちら MailHog、example.net さん、こんにちは、どうぞ」「omochi@example.net を送信元とします、どうぞ」
「了解、送信元OK、どうぞ」
Telnet で SMTP クライアントになりきって、MailHog にメールを出してみる
MailHog は、SMTP のテスト用に使える簡易メールサーバーです。
ローカル環境で気軽に試せるので、学習用途にぴったりです。GUI でメールの受信内容も確認できます。
SMTP の動きを理解するために、Telnet で、サーバーからの応答を待ちながら 1 ステップずつ進む様子を確認してみました。
ここで再現しているのは、ローカルのメールクライアント(MUA) が、最寄りの郵便ポストにメールを投函する ── そんな工程に相当します。
たとえば Gmail の場合であれば、Gmail のクライアントが SMTP 経由で Gmail の送信サーバーにメールを渡すイメージです。
※ 実際の Gmail 等の商用 SMTP サーバーは、認証や暗号化を必須としているため、Telnet では通信できません。
telnet localhost 1025
Trying ::1...
Connected to localhost.
Escape character is '^]'.
220 mailhog.example ESMTP MailHog
# クライアント(私):
HELO spoofed.net
# サーバー(MailHog):
250 Hello spoofed.net
# クライアント(私):
MAIL FROM:<bounce@spoofed.net>
# サーバー(MailHog):
250 Sender bounce@spoofed.net ok
# クライアント(私):
RCPT TO:<omochi@example.com>
# サーバー(MailHog):
250 Recipient omochi@example.com ok
# クライアント(私):
DATA
354 End data with <CR><LF>.<CR><LF>
Subject: Mission Report
From: Bruno Bucciarati <bucciarati@example.com>
To: Omochi<omochi@example.com>
Content-Type: text/plain; charset=UTF-8
I will complete the mission.
I will protect my team.
Doing both... that’s the burden of a leader.
Are you ready?
I already am.
.
# サーバー(MailHog):
250 Ok: queued as SOSr6KfoksPi9_hqm9PFAgxCQH3IIshtWp95bHlgCe8=@mailhog.example
# クライアント(私):
QUIT
# サーバー(MailHog):
221 Bye
Connection closed by foreign host.
SMTP の配送は “ホップ” の連続
Telnet での実験では、私がメールクライアント(MUA) となり、MailHog という最初のメールサーバー(MTA) にメールを渡すところまでを体験しました。
実際のメール配送では、このあと複数の MTA(メールサーバー)を経由して相手に届きます。
これを「ホップ」と呼びます。
たとえば Gmail から Yahoo! メールにメールを送るとき、
- Gmail クライアント → Gmail の送信サーバー(最初の MTA)
- Gmail の MTA → Yahoo! の受信サーバー(別の MTA)
というように、SMTP を使って メールサーバー同士がリレーのようにメールを転送していきます。
受信メールのヘッダーセクションで Received:
を見てみよう
実際のメールには「このメールはどこを通ってきたか」を示す Received:
ヘッダーが ホップの回数だけ積み重なっています。
Received: from mail-sor-f69.google.com ...
Received: from smtp01-hn4-sp1.mta.example.com ...
フィールドの説明と使い分けのポイント
フィールド | SMTP 的役割 | 見た目の役割 | 説明 |
---|---|---|---|
MAIL FROM |
バウンスの返送先(Return-Path) | 見えない | SPF 検証の対象 |
From: |
表示される差出人 | 見える | 見た目のなりすましが可能 |
RCPT TO |
配送対象のアドレス | 見えない | 配送制御のために使われる |
To: |
表示される宛先 | 見える | Bcc の場合は、RCPT TO にだけ含め、To: には含めない |
SMTP のスタンス
ただし、上記のフィールドの値はすべて「自称」です。
中身の正しさはもちろん確認しませんし、MAIL FROM
と From:
や、RCPT TO
と To:
がバラバラでもまったく気にしません。
「私は儀式にはうるさいですが、送るだけです。中身には関知しません」というのが SMTP のスタンスです。
→ SMTP は、あくまで「配達人」。差出人の正体も、手紙の中身も、一切気にせず運びます。
これでは詐称し放題では!? と不安になりますが、このような仕様になった理由には、SMTP 誕生の背景が絡みます。
SMTP プロトコルが誕生した頃の時代
SMTP が作られたのは古き良き 1982年(RFC 821)──
- インターネットは信頼のネットワークだった(通信相手は大学や研究機関ばかり)
- なりすまし・迷惑メール・詐欺なんて想定されていなかった
- ただし、ネットワークや機器がまだまだ不安定だった時代、1 ステップずつ成功確認しながら進める必要があった
時代は変わり、インターネット全盛期
ガラケーのメールで、自分のアドレスから自分宛に迷惑メールが届いてびっくり!という体験をしたことがある方も多いのでは?(それなりに年齢がいっている方 限定で)
SMTP の中身は信用できない。そして、平文のため経路で誰が通信傍受しているか分からない。
だから、身元を保証する仕組み、そして本文を暗号化する仕組みが必要になった。
次回(未定)は、その「身元を保証する仕組み」──
受け取る側のメールサーバーが、「本当に差出人と同一人物か?」を確認するための仕組み SPF, DKIM, DMARC あたりの正体に迫る、かもしれません。
番外:師匠に一蹴される
「メールが難しくて全然分かりません……」
ドメイン認証に溺れかけた私に、師は静かに告げました。
「まずは、歴史を追って。メールメッセージの形式、SMTP プロトコルの概要から。」
プロトコルすら知らずにメールを語るな──
(※そこまでは言われていない)
ということで、今回はその第一歩。SMTP の基礎から改めて整理してみました。
「あ~、それたぶん DMARC で落ちてますね」と、のけぞりながら言える日が来るまで頑張ります。