メールの仕組みをまとめてみた

#初期の電子メール

送受信間でTCPコネクションを確立し電子メールを配送していた。
下図のようにインターネットが繋がっていないと送受信ができない。

<img width="737" alt="スクリーンショット 2020-06-22 0.50.36.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/156096/4a6fa187-d428-8b97-e42f-44dfebe1bec2.png">

#現在の電子メール

電源を切らないメールサーバを経由する。
また、メールの受信に**POP**というプロトコルを使用する。

![スクリーンショット 2020-10-06 17.05.28.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/156096/5defa19d-4184-4c0b-29ac-907a49b39d10.png)

① メールソフトの設定に従い、メールサーバAにメールが送信される。
② DNSのMXレコードをひき、メールサーバBにメールを送信する。
③ メールソフトの設定に従い、メールサーバBからメールを受信する。




#SMTP(Simple Mail Transger Protocol)

**SMTP**とは電子メールを送信するアプリケーションプロトコル。TCPのポート番号は25番。
SMTPは1つのTCPコネクションを確立して、メッセージの転送を行う。クライアントはテキストコマンドで要求を出し、サーバは3桁の数字で応答する。
コマンドや応答の最後には必ず改行(CR,LF)が付加される。

###代表的なSMTPのコマンド

| コマンド | 内容 |
|:-:|:-:|
| HELO <domain>  | 通信開始  |
|  EHLO <domain> |  通信開始(拡張版HELO) |
| MAIL FROM:<reverse-path  | 送信者  |
| RCPT TO:<forward-path>  | 受信者の指定(Receipt to)  |
| DATA  | 電子メールの本文の送信  |
|  RSET | 初期化  |
| VRFY <string>  |  ユーザー名の確認 |
|  EXPN <string> | メーリングリスト名をユーザー名へ展開  |
| NOOP  | 応答の要求(NO Operation)  |
| QUIT  | 終了  |

###代表的な応答コード

200番台は成功。
300番台はコマンドは受け入れられたが追加の情報を待っていることを表す。DATAコマンドへの応答に354が使われる。
400番台は一時的エラー。
500番台は永続的エラー。

| 応答コード | 内容 |
|:-:|:-:|
| 211  | システムの状態やHELPの応答  |
| 220 <domain>  |  サービスの開始 |
| 221 <domain>  | サービスの終了  |
| 354  | 電子メールのデータの入力開始  |
| 421  |  サービスの提供ができないため、コネクションの終了 |
| 500 |  文法の誤り |

#POP(Post Office Protocol)

SMTPはメールを配送するプロトコルであるのに対し、POPはメールを受信するためのプロトコルである。SMTPのみだと受信側のコンピュータが_初期の電子メール_のように常時電源が入っていなければならない。

送信先からSMTPによって常時電源が入っているPOPサーバにメールが送られ、クライアントはPOPによってPOPサーバに保存されたメールを受信する。

POPもSMTP同様に1つのTCPコネクションを利用する。
コマンドはASCII文字列で表され、応答メッセージは正常を表す`+OK`とエラーを表す`-ERR`の二つしかない。

###代表的なPOPのコマンド

| コマンド | 内容 |
|:-:|:-:|
| USER name  | ユーザー名の送信  |
| PASS string  | パスワードの送信  |
| QUIT  |  通信終了 |
| APOP name digest  | 認証  |
|  RETR msg | メールのメッセージの取得  |


#メールアドレスの仕組み

インターネットのメールアドレスは`hoge@example.com`のような形式である。
`hoge`が名前で`example.com`が住所。この場合、`hoge`がメールを受信するコンピュータのホスト名かメール配送用のサブドメインで、`example.com`が組織名を表す。

###DNS(Domain Name System)

電子メールの配送先の管理はDNSによって行われる。
DNSにはメールアドレスとそのメールアドレス宛のメールを送信すべきメールサーバのドメイン名を登録できる。これを`MXレコード`という。`IN MX 10 mx1.example.com`というような記述方法で設定されてい

例えば_hoge.com_のMXレコードに_IN MX 10 mx1.hoge.com_を指定すると、_hoge.com_で終わるメールアドレス宛のメールは全て_mx1.hoge.com_に転送される。

1つのメールアドレスに複数のサーバが指定されているときMXレコードに記されている数字が小さいものを優先して送信する。

MXレコードが_IN MX 10 mx1.hoge.com_, _IN MX 20 mx2.hoge.com_のとき
_10_の方が小さいので_mx1.hoge.com_に優先して送られる。_mx1.hoge.com_に送信できなかったとき_mx2.hoge.com_に送信される

#MIME(Multipurpose Internet Mail Extensions)

Webサーバとブラウザの間でやり取りされるデータのファイル形式。
ヘッダ+本文(データ)の2つから成る。
ヘッダと本文は空行で区別される。
MIMEヘッダの`Content-Type`で`Multipart/Mixed`を指定し、`boundary = `の後に書いた文字列で区切ると1つのMIMEメッセージをMIMEメッセージとして定義できる。これを**マルチパート**と呼ぶ。`Content-Type`はヘッダに続く情報がどのような種類のデータなのかを示す。

###MIMEの代表的なContent-Type

| Content-Type | ファイル種類 |
|:-:|:-:|
|  text/plain |  テキスト |
| message/rfc822  |  MIMEと本文 |
|  multipart/mixed | マルチパート  |
| application/postscript  | PostScript  |
|  application/octet-stream | バイナリファイル  |
| image/gif  |  GIF |
|  image/jpeg | JPEG  |
| audio/mpeg  | MP3  |
| video/mpeg  |  MPEG |
|  message/external-body | 外部にメッセージがある  |
| application/pdf |  PDF |

その他はhttps://www.iana.org/assignments/media-types/media-types.xhtml を参照

##MIMEの書き方

###簡単な例

以下の例が最もシンプルな例である。
FromからContent-Typeの行までがヘッダで、その後に空行があり、本文がある。
本文とヘッダの間には必ず空行を入れる。

```text
From: temp@exampl.com
To: hoge@example.com
Subject: This is a MIME message
MIME-Version: 1.0
Content-Type: text/plain; charset=ISO-2022-JP

ハロー MIME!
```

###再帰的な構造

`Content-Type`にMultipart/Mixedを指定する。
`boundary =`の後に区切り文字を設定する。

以下の場合だと**Sample-Boundary**が区切り文字。
`--Sample-Boundary`を境界として入力し、最後にはマルチパートの最後を表す`--Sample-Boundary--`がある。


```text
From: temp@exampl.com
To: hoge@example.com
Subject: This is a MIME message
MIME-Version: 1.0
Content-Type: Multipart/Mixed; boundary = Sample-Boundary
Content-Transfer-Encoding: 7bit

ハロー MIME!

--Sample-Boundary           ← 境界
Content-Type: Text/Plain; charset=US-ASCII
Content-Transfer-Encoding: 7bit

Hello, MIME!

--Sample-Boundary           ← 境界
Content-Type: Text/Plain; charset=ISO-2022-JP
Content-Transfer-Encoding: 7bit

はろー　MIME!

--Sample-Boundary--         ← 最後の境界
```

#IMAP(Internet Message Access Protocol)

IMAPはPOPと同様、メッセージを受信するためのプロトコルである。
POPは電子メールの管理をクライアント側で行うのに対し、IMAPはサーバ側で管理する。
外出先でもスマートフォンやタブレットで自宅のパソコンと同じようにメールの確認ができる。


##POP VS IMAP

###POP
####メリット
パソコン等に保存したメールの削除・移動等を素早く処理でき、端末の容量が許す限りメールを保存できる。


####デメリット
複数のパソコン等でのメール利用は使い勝手が悪い場合があります。また、同時に複数台の端末で受信を行うことができない

###IMAP
####メリット

サーバ上でメールを管理するので複数の端末での利用に優れている。複数の添付ファイルがあるときどれか一つを受信するといったことができる。

####デメリット

メールサーバーの容量制限に達した場合、不用なメールをサーバ上から削除しなければ、新規に送られたメールを閲覧することができなくなる。

#実践

##Telnet

telnetコマンドは基本的に以下のような書式である。

```text
telnet ホスト名 ポート番号
```

例えば

```text
telnet localhost 25
```

現在telnetは推奨されておらず、SSHの使用が推奨されている。

##MXレコードを検索する

`dig`コマンドはDNSサーバに問い合わせることで、ドメイン名からIPアドレスを調べるコマンド。（逆も可能)
MXレコードを引いてGmailのメールサーバを調べてみる。

```terminal
% dig gmail.com mx +short
30 alt3.gmail-smtp-in.l.google.com.
10 alt1.gmail-smtp-in.l.google.com.
20 alt2.gmail-smtp-in.l.google.com.
5 gmail-smtp-in.l.google.com.
40 alt4.gmail-smtp-in.l.google.com.
```