Skip to content

Instantly share code, notes, and snippets.

@akira-kuriyama
Last active January 30, 2016 15:04
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save akira-kuriyama/4fd6ae8a2f8129db5621 to your computer and use it in GitHub Desktop.
Save akira-kuriyama/4fd6ae8a2f8129db5621 to your computer and use it in GitHub Desktop.

基本

メール送信の基本的な仕組みはメールサーバーを挟みメッセージのやり取りをする。 送信者はメールサーバーへメッセージを送信し、受信者はメールサーバーへメッセージを取りに行く。

MTA (Mail Transfer Agent)

メールサーバーが持つ、メール転送サーバソフト パソコンから送られてきたメールを受け取り、それをあて先へ送信する。あて先側のメールサーバーがそれを受け取る。

MUA (Mail User Agent)

ユーザが使うパソコンのメールソフト。 メールの送受信だけではなく、メールの作成、表示、保存、アドレスの管理ができる。

MDA (Mail Delivery Agent)

MDAはMTAにとどいたメールを個人別に振り分ける役割

メールアドレスはあて先のメールボックスを指す

メールアドレスの@の前がメールボックスの名前を指す。この部分を「ローカル部」と呼ぶ。 メールアドレスの@の後はメールアボックスのあるドメイン つまりメールアドレスは「ローカル部@ドメイン」という構成。

別名

1つのメールボックスを複数のメールアドレスで指し示す。

メールングリスト・メールグループ

1つのメールアドレスで、複数のメールボックスを指し示す。

どうやってドメインからメールアドレスサーバーを割り出すか

DNSのMXレコード(Mail eXchange Record)を使用し、メールボックスがあるメールサーバーを示す。 障害対策で、一つのMXレコードに複数のメールサーバーアドレスを指定でき、優先度を指定できる。

メールの送信、受信にはMTAを経由する

送信者は送信者用のメールサーバーにメールを送る。受信者のメールサーバーには直接送らない。 つまり作成したメールはMUAに設定されている送信用MTAに送ることになる。 送信用MTAは、多くの場合、プロバイダのメールサーバーだったり会社のメールサーバーだったりする。 メールが送られた送信用MTAは、ドメインをもとにメールを受信用MTAに送る。 受信者は受信用MTAからメールを取り出す。

SMTP (Simple Mail Transfer Protocol)

MUAからMTA、MTAからMTAへメールを「送る」プロトコル メールを送信する側がSMTPクライアント。受信側がSMTPサーバー。 MUAからMTAの場合は、送信PCのMUAがクライアント、MTAがサーバー。 MTAからMTAの場合は、クライアントからサーバー。 SMTPはトランスポート層のプロトコルとしてTCPを使用する。 サーバーが使用するポートはWell-Knownポートの25番ポートを使う。 SMPTはASCIIコードの文字をベースにメッセージのやり取りを行い、通常はコマンド・レスポンスの終了を改行コードCRLFで示す。

コマンドは「コマンド パラメータ」の順に書かれる。 コマンドとパラメータの間はスペースで分割される。 レスポンスは「レスポンスコード 文字列」という形で記述される。 レスポンスコードと文字列はスペースで分割される。 レスポンスコードは3桁の数字で、HTTPステータスコードと似ている。

SMTPコマンド

「コマンド」「空白」「パラメータ」「改行」とう形式

コマンド パラメータ 意味
HELO ホスト名(ドメイン名) 自身の名前を通知し、SMTPサーバーと接続を開始する
EHLO ホスト名(ドメイン名) HELOの拡張。SMTPサーバーは使用可能な拡張機能を通知する。ESMTPで使用されるコマンド。
MAIL FROM:<メールアドレス> 送信元メールアドレスを通知する
RCTP TO:<メールアドレス> あて先メールアドレスを通知する。複数のメールアドレスを指定したい場合は、RCTPコマンドを複数送る。
DATA なし このコマンド以降から「ドット改行」まではメール本文
QUIT なし SMTPの接続を終了する
NOOP なし サーバーはOKの応答を返す。応答確認などに使う。
VRFY ユーザ名 そのユーザ名のメールアドレスが存在するか問い合わせる
EXPN メーリングリスト そのメーリングリストが存在するか問い合わせる
AUTH 認証方式 SMTP Authで使用する。ユーザ認証の方式の問い合わせ
RSET なし いままで送信したコマンドをなかったものとする

SMTPのレスポンス

「レスポンスコード」「空白」「フレーズ」という形式

ステータスコード 意味 説明
1xx 肯定先行 正しいコマンドを受け付けて処理中である
2xx 肯定完了 正しいコマンドを受け付けて処理を完了した。
3xx 肯定中間 正しいコマンドを受け付けて、次に別のコマンドを要求する
4xx 一時否定完了 誤ったコマンドを受け付けた。再送を望む。
5xx 否定完了 サーバーの状態によりコマンドを受け付けることができない。

代表的なレスポンスコード

コード フレーズ 説明
220 ready サーバーへ接続され、コマンドを待ち受けている
221 closing connection コネクションを切断する
250 OK 正常にリクエストを受け付け、終了した
354 Enter Mail メール本文の入力要求

ESMTP (SMTP Service Extensions)

時代の要求に合わせてSMTPで追加機能を利用できるようにしたもの。 だが、全てのサーバーがESMTPに対応しているわけではないし、 対応していたとしても全ての機能を使えるとは限らない。 そこで、最初のHELOを送る代わりに、EHLOを送る。 そうすると、サーバーはレスポンスで使用できる機能一覧を送る。

代表的なESMTPの拡張機能

|コマンド|機能| |:------|:-----------|:------| |8BITMIME|8ビットのメッセージの送信| |AUTH|SMTP Authが使用可能| |SIZE|受信可能なメールサイズの通知| |PIPELINING|パイプライン処理可能| |STARTTLS|TLSによる暗号化可能|

※メモ TLSは、SSLを標準化したもの。SSLはHTTPなどでの使用が前提だが、それを他のプロトコルでも利用可能にしたのがTLS。

ディレクトリハーベストアタック(Directory Harvest Attack)

スパムメールを送るために、サーバーにVFRYコマンドを使ってアドレスが存在するか確認する方法。 なので、VFRYとEXPNのコマンドを利用できないようにしているサーバーも多い。

エンベロープ

HELO(EHLO)、MAIL、RCPT、メッセージの後ろにQUITという一連のコマンドを部分をエンベロープと呼ぶ。つまりDATA部分を抜かした部分。

メール本体であるメッセージだが、複数のメールヘッダとボディで構成されている。

メールヘッダは、「ヘッダ名 : ヘッダ値 改行」で記述されている。 メールヘッダはなくても送信できる。基本的にヘッダはメッセージのためのデータ。

メールヘッダのFromとToは送信元とあて先のユーザ名とメールアドレスを指すが、エンベロープのMAIL、RCPTと一致する必要はない。

メールヘッダの種類

代表的なメールヘッダ

|ヘッダ|値の意味| |:------|:-----------|:------| |From|メールの送信者氏名とメールアドレス| |To|あて先氏名とメールアドレス| |Reply-To|メールの送信先| |Cc|カーボンコピー。同一のメールを送信するあて先メールアドレス| |Bcc|ブラインドカーボンコピー。同一のメールを送信するあて先メールアドレス| |Date|メール作成日時| |Message-ID|MUAかMTAが生成するメールを識別するユニークな値| |Subject|メールの件名(必須)| |Received|トレース情報(?)| |MIME-version|使用しているMIMEのバージョン| |Content-type|ボディのメディアタイプ| |Content-Transfer-Encoding|ボディのエンコード情報| |X-Mailer|使用しているMUAの名前|

POP3 (Post Office Protocol)

IMAP4 (Internet Mail Access Protocol)

MUAがMTAからメールを「取り出す」プロトコル 取り出す際にどちらかのプロトコルを選んで取り出す。

MIME (Multiourpose Internet Mail Extensions)

メールデータに対するプロトコル

ヘッダ

MUA・MTAが送信前と送信後につけるもの。役割はメッセージの情報

Received ヘッダ

メールの伝送経路を追跡するための情報。メールを受け取ったMTAがその情報をReceivedとしてヘッダに追加する。 「誰が」「誰から」「いつ」「誰宛の」メールを受け取ったかが記される。 例

Received: from smtp16.mail.bbt.yahoo.co.jp (smtp16.mail.bbt.yahoo.co.jp [202.93.83.109])
        by example.com with SMTP id 6122A25ED23
        for <00000@example.com>; Tue, 13 Sep 2005 15:06:59 +0900 (JST)
Received: from unknown (HELO PC NAME) (219.110.000.00 with poptime)
  by smtp16.mail.bbt.yahoo.co.jp with SMTP; 13 Sep 2005 06:06:43 -0000

第三者中継(Third Party (Mail) Relay)

MTAは中継サーバーとも呼ばれる。 スパムメールは中継サーバーを挟んで送信されることが多く、それにより送信元が隠蔽できる。 MTAは「自分のドメインあてのメールならば接続を許可」「他のドメインあてのメールならば(中継になるため)接続を拒否」する設定にすることで、スパムメールを中継しなくできる。 一般的にこの設定をするがしていないサーバーを第三者中継サーバーと呼ぶ。

DNSBL(DNS based BlackList)

スパムメール受け取り防止のために第三者中継サーバーを経由するメールは受け取らないということもできる。 この考え方でDNSBLと呼ばれるリストを使って、メールの受信を禁止しているサーバーもある。

SMPT Auth

IPアドレスやドイメイン名以外でメールを送信するユーザを識別する方法の一つ。 大きく分けて2つある。POP Before SMTP と SMPT Auth SMTP AuthはESMTPによる拡張機能の一つで、STMPに認証機能を追加したもの。 これにはSASL(Simple Authentication and Security Layer)プロトコルを使用している。 SASLはユーザ認証や暗号化のプロトコル。 クライアントとサーバー間でまずAUTHコマンドで使用する認証方式を送る。 たとえばチャレンジアンドレスポンス方式(CHAM-MD5)が選べる。

主な認証方式

|認証方式| 説明| |:------|:-----------|:------| |LOGIN| ユーザIDとパスワードを複数行で平文で送信する| |PLAIN| ユーザIDとパスワードを1行で平文で送信する| |CHAM-MD5| チャレンジアンドレスポンス方式でユーザIDとパスワードを送信する| |DIGEST-MD5| CHAM-MD5を拡張したもの|

★他にもある?

OP25B (Outbound Port 25 Blocking)

プロバイダが、プロバイダの中から外へメールが送られるときに、プロバイダのメールサーバー以外のサーバーを通してメールを送信することを禁じる設定。 プロバイダのメールサーバーを中継してもらいプロバイダの外へ出て行くメールはOK。 ただし例外が2点あり、1つはプロバイダと契約している企業のメールサーバー。これはOP25Bの影響をうけない。 もう1つが、プロバイダのユーザがプロバイダ以外で契約しているメールサーバーを使いたい場合。 例えばフリーメールのメールサーバーなどを使いたい場合。この場合はOP25Bで送られなくなってしまう。 そこでサブミッション方式をつかう。 つまり、プロバイダが用意した中継用メールサーバーを通してのみメールを外に送信することができる方式。 このサブミッションのメールサーバーは、ポート番号587を使うのが一般的。もちろん第三者中継にならないようにSMTP Authが必須。

POPの基礎

POP1,2は既に使われていない。POPといえばPOP3を指す。 POP3はTCPのポート110番を使う。 POPはクライアントからのコマンドとサーバーからのレスポンスでやり取りする。 POPのやり取りは3つの手順に分類することができる。 Authentication(認証)とTransaction(処理)とUpdate(更新)。

認証(Authentication)

まずPOPのレスポンスは”+OK”と”-ERR”の2種類しかない。 HTTPやSMTPのようにステータスコードがない。

認証の仕方は、ユーザIDとパスワードにより、サーバーに接続してきたユーザの身元の確認を行う。 コマンドはUSERでユーザIDを送り、PASSでパスワードを送る。 SMTPはもともと認証機能を持っておらず拡張機能であるSMTP Authで行ったが、POPは元から認証機能をもっている。 ただしUSERとPASSは平文で送信している。 なので盗聴を防ぐために、チャレンジアンドレスポンス方式のAPOPを使用することができる。

メールの取り出し(Transaction)

メールの取り出しコマンドは、STAT、LIST、RETR、DELEの4コマンド。 1, STATでは”メールの数”と”メールの総バイト数”が返ってくる。

2, LISTでは、メッセージ番号とそのメールのバイト数のリストが返ってくる。

3, RETRで、メールのメッセージ番号を指定しメールを得る。 メッセージのボディは”.”で終了

4, DELE でLISTで取得したメールに削除マークをつける。 RETRとDELEをメールの数だけ繰り返す。

更新 (メールの削除)(UPDATE)

QUITコマンドで、メールを削除し、終了(TCPコネクションが切断)する。 RESTコマンドを送ると、削除マークを消すことができ、QUITでメールが削除されずメールボックスに残ることになる。

POP Before SMTP

SMTPでユーザ認証をする方法の一つ。 POP Before SMTPはメールボックスがあるサーバーと送信用MTAが同一のサーバーの時に使用される。 手順はまずPOPで認証を通して、その後SMTP通信をする。

メールボックスの管理とIMAP

POPの欠点として、メールボックスにあるメールをみるためにはMUAにメールを移動させないとならない。

MUAへメールを移動しつつ、メールボックスにメールを残すやり方として、 UIDLコマンドをつかって、現在メールボックスにあるメールにつけられたメールのIDのリストを取得する。 IDはメールサーバーがつける番号のことで、メールごとに異なる番号が付けられる。 RETRでメールを取得し、RESTを使って削除マークを消しておく。 また取得したメールのIDを記憶しておく。 次回のアクセスの際もUIDLコマンドでメールIDを取得し、前回取得していないIDを持つメールだけを取得するようにする。

IMAP (Internet Message Access Protocol)

現在使われているバージョンは4。IMAP4と呼ばれてる。 POPはたったひとつのメールボックスしか持てないが、 IMAPは複数のメールボックスの使用と管理ができる。 たとえば「受信ボックス」「送信済みボックス」「Draftボックス」などを一人で使える。

POPのメールボックスはクライアントのMUAに保存するまでの一時的な保管場所 IMAPではメールボックスはサーバー上にあり、それを操作する。 メールは基本的にサーバー上のメールボックスに保存される。

IMAPの機能は多彩で、「認証」「メールの同期」「自由なメール閲覧(特定のメールを閲覧するだけではなく、添付ファイルだけ閲覧、添付ファイルなしの閲覧、メールの一覧など可能)」「メールの検索」などが可能。

IMAPはPOPと同じクライアント・サーバーのやりとり。 クライアントからの「リクエスト」、サーバーからの「レスポンス」をやりとりする。その特徴としてあげられるのはタグを付けること。 タグはリクエストに対するレスポンスを示すもの。たとえば「1234」というタグがついているリクエストがあればそれに対するレスポンスにも「1234」というタグがついている。これはIMAPが並列処理を行うことができるが故に必要。

リクエストは「タグ コマンド パラメータ」から、レスポンスは「タグ ステータス レスポンスコード メッセージ」からなる。 代表的なリクエストのコマンド

|コマンド| 説明| |:------|:-----------|:------| |LOGIN| ログイン| |AUTHENTIACTE| 認証方法の選択| |LIST| メールボックスの一覧| |SELECT| 使用メールボックスの選択| |FETCH| メールの取得| |SEARCH| メールの検索| |CREATE| メールボックスの作成| |APPEND| メールの追加| |STORE| フラグの変更| |COPY| メールのコピー|

|フラグ| 説明| |:------|:-----------|:------| |\Seen| 既読メール| |\Answered| そのメールの返信メールを作成したことがある| |\Flagged| マークを付ける(重要なメールなど)| |\Deleted| 削除マークをつける(完全に削除はEXPUNGEコマンドで行う)| |\Draft| 下書きのメール| |\Recent| 新着メール|

整理すると メールを転送するSMTP メールボックスから取り出すPOP メールボックスを管理するIMAP

MIME (Multipurpose Internet Mail Extensions)(マイム)

MIMEはその「やりとりされるメールの中身」についてのプロトコル。

まずメールではUS-ASCII以外の符号化データを運ぶことはできない。 US-ASCIIは7ビットの文字。 US-ASCIIしか運べないメールで多言語や添付ファイルを運ぶための仕組みがMIME

BASE64 … 6ビットごとに区切ってそれを英数字記号に変換する。これによりどんなビット列でも英数字記号になる。

マルチパート… 本文はテキストでUS-ASCII、添付ファイルはバイナリでBASE64で符号化されているとしよう。つまりメールの部分ごとに符号化が異なる。このように異なる符号化で構成されるメールをマルチパート・メールという。

ちなみにUS-ASCIIのみを使ってメールを送る場合、MIMEは必要ない。

MIMEヘッダ

MIMEについての情報を記述する。これは、メールのボディに対してと、メールの部分ボディごとに記述される。 メールは1つのボディをもっており、そのボディをの中に複数の部分ボディをもてる。 なので1つのメールに対して複数のMIMEヘッダがありうる。 メールデータ全体としては、まずメールヘッダがありその中にMIMEヘッダがある。 メールボディには1つ以上の部分ボディがあり、部分ボディごとにMIMEヘッダがある。

メールヘッダ内のMIMEヘッダの一番最初につくのがMIME-Versionヘッダ。 ただversionは1.0しかないので MIME-Versionヘッダは「MIME-Version:1.0」に必ずなる。 そして、メディアタイプと符号化をあらわすMIMEヘッダがその後に続くことになる。

メディアタイプは以下の形式で指定される Content-Type: <メディアタイプ>/<サブタイプ>; パラメータ

メディア・タイプ サブタイプ 説明
text plain(テキストファイル), html テキストデータ。パラメータとしてcharsetで文字コードを指定する
image jpeg, gif など 画像ファイル
video mpeg, quicktime など 動画ファイル
application octet-stream, pdf, ms-word など なんらかのアプリケーションで使われているファイル
message rfc822, (RFC822規格のメール)など メールメッセージなど
multipart mixed(複数のメディアタイプが混在しているマルチパートメール) マルチパートメールであることを示す。パラメータにboundaryを指定
model vrml など 2Dや3Dのグラフィックモデルデータ

符号化は以下の形式で指定される Conent-Transfer-Encoding: <符号化タイプ>

変換 符号化タイプ 説明
なし 7bit 7ビットの符号化のテキストデータ。US-ASCIIやISO-2022-JPなどの7ビットの文字コードで書かれているテキストなど。デフォルトの符号化タイプ
なし 8bit 8ビットの符号化テキストデータ。通常では使えず、ESMTPで拡張されている場合のみ使える。
なし binary 7bit, 8bit以外のバイナリデータ。通常は使えない。ESMTPで拡張されている場合のみ使える。
あり quoted-printable US-ASCIIにあるものはそのまま、ないものは「=」をつけて表現する。US-ASCII以外の欧米文字で使われる。
あり base64 BASE64で符号化されたデータ。ファイル、ISO-2022-JP 以外の日本語など

※7bit と base64 以外は日本ではほとんど使われない。

ISO-2022-JPでは半角カタカナや機種依存文字が使えない。 それらを使う場合は、テキストではなく、バイナリ扱いにしてBASE64に変換する。

メールヘッダの多言語化

MIMEヘッダはボディで何を記述しているかを示している。なのでメールヘッダにはMIMEヘッダをつけられない。 しかしそのためにメールヘッダ用のMIMEの記述方法がある。 これは「=?」で始まり、「?=」で終わる書き方をする。 SubjectやFrom、添付ファイル名なども、この書き方で記述する。

S/MIME

S/MIMEは メールの暗号化とメッセージ認証を行う手法。 SMTPはサーバー間のやりとりはESMPでTLSを使って通信経路上で暗号化できる。 しかしメールサーバーが必ずTLSを必ず使っているとは限らない。 そこで、メールのボディを暗号化できる技術としてS/MIMEを使う。MUAでメールを開くときに複合化される。

S/MIMEは、暗号化とメッセージ認証のどちらかまたは両方が使用できる。 暗号化は「2つの暗号化の組み合わせ」方法を使用する。 共通鍵暗号化でデータを暗号化して、その共通鍵を公開鍵で相手に渡す方法。 メッセージ認証は電子書名を使用する。 これは公開鍵暗号化方式を使った、メッセージ認証。さらに電子書名を使用することで、メッセージ認証だけではなく送信者のユーザ認証も可能になる。

公開鍵暗号化方式を使うので、 電子署名には送信者の電子証明書が、 暗号化にはあて先の電子証明書が必要になる。これがS/MIMEを使うための条件。

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment