
「メールを送る」とは、最終的にメールアドレスの示すメールボックスにメッセージを送り込むことである。このとき、2つのホスト間でメールを転送するのに使われるプロトコルが「SMTP」だ。
メール転送の手順とは?
SMTPは「Simple Mail Transfer Protocol」の略で、インターネットのホスト間でメールを交換するために使われてきた古いプロトコルである。もともとRFC821で定義されていたが、ヘッダのRFC2822と同様、さまざまな拡張の必要に迫られてRFC2821に置き換えられた経緯がある。
図1はSMTPの概要を表わしたものである。メールの送信側がSMTPクライアントで、メールを受信する側がSMTPサーバとなる。SMTPサーバのポート番号はインターネット標準で「25」が割り当てられており、メール送信はクライアントからサーバのポート25へTCPコネクションを確立することから始まる。
無事TCPセッションが確立すると、サーバ側からSMTPのリプライコード220がクライアントへ返される。続いてクライアントは、サーバにSMTPの通信開始を宣言するEHLOまたはHELOコマンドをサーバに送る。
サーバがこれに応答すると、クライアントはMAILコマンドをサーバに送信する。MAILコマンドはメールの送信開始を意味するコマンドだが、パラメータにはエラーメールを返すための返信先アドレスを添えて送る。サーバにコマンドが受理されるとリプライ250が返される。続いてメールの宛先を伝えるRCPTコマンドがサーバへ送られる。RCPTのパラメータは受取人のメールアドレスで、複数の受取人へ送るメールであればメールの受取人の数だけRCPTコマンドを繰り返し送信する。サーバがRCPTコマンドを受信すると、その応答を返す。
このとき、メッセージヘッダにも宛先アドレスフィールドなどの宛先や送信元情報があることに気付く人もいるだろう。実はここにSMTPの特徴がある。メッセージ上はFromフィールドやToフィールドにメールアドレスを記述している。しかしSMTPでは、これらは「便せん」の一部であって、内容には直接関与しないようになっている。その代わり、MAILコマンドとRCPTコマンドをメールのエンベロープ(Envelope、封筒)と考え、実際の配送メールアドレスを示すわけだ。このMAILコマンドのメールアドレスを「エンベロープFrom」、RCPTコマンドのメールアドレスを「エンベロープTo」と呼ぶ習慣がある。
メールメッセージの送信は、DATAコマンドでサーバに通知する。サーバはリプライコード354で「メッセージの入力を開始し、<CRLF>.<CRLF>で終了せよ」と応答する。以降、クライアントはサーバに向けてメッセージを送信する。
メッセージの終了を表わすパターンをサーバが受信すると、リプライコード250を返し、メッセージの受信が完了となる。クライアントはQUITコマンドを送信し、TCPコネクションを切断する。
サーバはこのようにしてメッセージを受信するが、そのメッセージがサーバの持つメールボックス宛であれば、バッファ(スプールともいう)に受信しているメッセージをメールボックスに移動して終了となる。一方、受信したメッセージをさらに別のメールサーバに転送する場合は、今度は自身がSMTPクライアントとなって、バッファに受信した情報を使いメッセージの送信を行なう。これが基本的なメッセージ送信の流れである。
SMTPのコマンド
RFC2821には、SMTPコマンドとリプライコードのほか、コマンドとそのコマンドの処理が成功した場合及び失敗した場合に返すリプライコードの対応が示されている。まずは表1に示すコマンドから解説していこう。

表1●SMTPのコマンド
メール送信に先立って最初に使うのがEHLOまたはHELOである。EHLOは「Extended Hello」、HELOは「Hello」を意味している。EHLOを使うかHELOを使うかの選択はSMTPのサービス拡張機能をサポートしているか否かによる。RFC2821ではEHLOコマンドを標準とし、SMTPサービス拡張機能をサポートしていないサーバにアクセスした場合、HELOコマンドによって再びメール送信手順を実行することになっている。
MAILコマンドはメール送信の開始を表わすとともに、エラーが発生した場合の返信先をパラメータとして指定する。このコマンドをサーバが受信すると、サーバは返信経路バッファ、転送経路バッファ、そしてメールデータバッファをクリアし、コマンドで通知された返信先(reverse-path)情報を返信経路バッファに保存する。つまりMAILコマンドはサーバ側に用意されている3つのバッファをクリアする契機となるコマンドである。
RCPTコマンドはメールデータの受取人を示すために使われ、DATAコマンドはメッセージ送信開始をサーバに告げるコマンドである。この2つはすでに前で述べたとおりだ。
RSETコマンドは、現在のメール送信処理が中止されたことを示す。このコマンドをサーバが受信すると、すべてのバッファや制御のための状態テーブルなどの情報をクリアしなければならない。ただし、このコマンドではTCPのコネクションは閉じない。TCPコネクションを閉じるのは、QUITコマンドの役割である。
VRFYコマンドは与えられた引数の文字列に一致するユーザー、またはメールボックスを応答するコマンドである。このコマンドは他のコンピュータからメールボックスやユーザーのアカウントを調べるために悪用される可能性があり、通常は使えないよう運用上規制がかけられる。
EXPNコマンドは、パラメータに指定したメーリングリスト(エイリアス)を調べ、一致する情報があればそれを返すコマンドである。このコマンドもVRFYと同様に悪用される可能性があり、通常は使えないよう運用上規制がかけられる。
HELPコマンドは、ヘルプ情報を表示するコマンドである。メールサーバの管理者がTelnetクライアントなどを用いてSMTPサーバにアクセスしたような状況で使われる。
NOOPコマンドは、まったく何の影響も与えない(何もしない)コマンドとして用意されている。これは「SMTPサーバ用のping」と考えるとよい。このコマンドを使えば、SMTPサーバが動作しているかどうか応答を得ることができる。
SMTPのリプライコード
続いて表2のリプライコードについて説明しよう。応答コードは3桁の数字で表わされ、それぞれの桁に意味を持たせている。左から最初の数字が応答の種類を示し、真中の数字がカテゴリを示し、最後の数字がカテゴリ中のより詳しい意味を表わす。

表2●リプライコード
本記事は、ネットワークマガジン2007年12月号の特集1「電子メールプロトコル再入門」を再編集したものです。内容は原則として掲載当時のものであり、現在とは異なる場合もあります。 |

この連載の記事
-
第9回
ネットワーク
いろいろな場所で同じメールを読めるIMAPの仕組みとは? -
第8回
ネットワーク
メールクライアントの動作からPOPのやりとりを見てみよう -
第7回
ネットワーク
メールの受信用に作られたPOPを学ぶ -
第6回
ネットワーク
SMTPの拡張機能を確かめる「EHLOコマンド」を知ろう! -
第4回
ネットワーク
メールの添付ファイルを実現するMIMEのマルチパートとは? -
第3回
ネットワーク
メール誕生からある「7ビットの制約」を越えるMIMEとは? -
第2回
ネットワーク
メールの宛名はどこにある?ヘッダを理解する -
第1回
ネットワーク
電子メールを基礎の基礎から学んでいこう -
ネットワーク
電子メールプロトコル再入門<目次> - この連載の一覧へ