連載:インターネット・プロトコル詳説(5)
SMTP(Simple Mail Transfer
Protocol)〜前編
梁瀬介次
2001/5/2
■シンプルで複雑なプロトコル「SMTP」
|
||||||||
| 表1 SMTPの歴史年表 |
SMTPは、一般にインターネットメールの送信プロトコルとして知られている。メーラからメールサーバへメールを送信する際に使用するのがSMTPだ。名前どおり、本連載で扱うプロトコルでも1、2位を争うシンプルなプロトコルであると同時に、最も複雑な動作を強いられるプロトコルでもあるのだ。
|
||||||||||||||||||
| 表2 SMTP関連の標準仕様 |
シンプルかつ複雑とはどういう意味なのか? その答えはSMTPと切っても切れない「メール・ルーティング」というメールサーバにおける隠れた機能にある。
■メール・ルーティングにおけるSMTP
メーラからメールを出す際に、メールサーバへSMTPを用いてメールを送信することは分かってもらえるだろう。では、その後メールはどのようにして相手に届くのか。そこにも何らかの仕組みが存在しているはずだ。そうした仕組みを「メール・ルーティング」と呼ぶ。下の図を見てほしい。
![]() |
| 図1 メール・ルーティングにおける配信と転送処理 |
これは、メーラとメールサーバを含めた、メール・ルーティングの構造図だ。実はメールサーバというのは、通常幾つかの機能から成り立っている。大きく分けると「メール配信(Delivery)」機能と「メール転送(Transfer)」機能だ。
メール配信機能とは、サーバのローカルでユーザーのメールボックスへ間違いなくメールを届ける機能のことだ。通常、メールサーバには、登録されているユーザーのメールを保存しておく、ユーザーごとのメールボックスがある。メールサーバは、自分にどういう名前のユーザーが登録されているか、そのユーザーがどのメールボックスを使用しているかを管理し、あて先メールアドレスから判別して、間違いなく配達する必要がある。これが配信だ。この配信機能は、メールサーバ・アプリケーション固有の機能で、アプリケーションにより動作が異なる。例えばsendmailなどでは、UNIXのユーザー登録の仕組みを利用してメールボックスも管理している。Microsoft Exchange ServerやLotus Notes/Dominoなどでは、別のユーザー管理の仕組み(Active Directory/Domino Directory/LDAPなどのディレクトリ機能)を利用することになる。
もし、メールに示されたあて先がメールサーバ・アプリケーション自身の管理するユーザーでない場合、そのメールをほかのメールサーバへと送信する必要がある。これが転送だ。単にメール・ルーティングといった場合には、この転送だけを指す場合もある。そしてこの転送で、ほかのメールサーバとの通信に使用されるのがSMTPである。
また細かく見れば、メール転送は送信機能と受信機能にも分かれる。あるいは、送受信メールを一時的に保管し、実際の転送に備えるキューイングと呼ばれる機能を持つこともある(このための領域を「メールキュー」と呼ぶ)。メールサーバによっては、これらの機能がまったく別々のプログラムによって実装されていたり、同一のプログラムですべて処理していることもある。メーラはこれらの機能を利用させてもらっているというわけだ。つまり、メールの転送依頼が終了すると、その後のメールのルーティングの責任はメールサーバに移行する。これを「配送責任(Responsibilities)」と呼ぶ。
こうしたメール配信や転送機能を受け持つプログラムを総称して「MTA(Mail Tranfer Agent)」と呼ぶ。メールサーバといわれるものは、このMTAとして定義されている機能を実装したサーバのことだ。厳密には、相手サーバに接続するためのクライアント機能も持つ、複合的なプログラムまたは一連のプログラム群だ。sendmailやqmailがこれに該当する。
逆にこうした機能はいっさい持たず、MTAに依存してユーザーのフロントエンドとしてメールの作成や表示に専念するプログラムをMUA(Mail User Agent)と呼ぶ。いわゆるメーラがこれに該当する。
古くには、MTAとMUAはもともとは1つのプログラムだった。最も初期のころのメールプログラムでは、同じマシン内のユーザーにのみ送受信を行うような代物だったのだ。SMTPというプロトコルの出現は、メールプログラムに遠く離れたユーザーにもメールを送受信できるという力を与えた代わりに、先に述べたような転送のためのさまざまな機能を必要とした。結果、プログラムは膨大なものとなり、MTAとMUAという2階層に分離するのが最も効率的な運用となったのである。
■メールアドレスとルーティング
では、MTAがどのようにメール・ルーティングを行うのかを見てみよう。この送信処理は、次の段階に分けられる。
|
(1)
|
MUAからMTAへメール送信を依頼 |
|
(2)
|
あて先メールアドレスから送信先MTAを決定する |
|
(3-a)
|
送信先MTAが自身であった場合には、「配信」処理を行う → 送信終了 |
|
(3-b)
|
送信先MTAへSMTP接続を行い、送信 |
|
(4)
|
送信先MTAが「配信」処理を行う → 送信終了 |
MUAから送信を依頼されたメールは、MTAによって「配信」か「転送」かが判別される。判別の根拠となるのが、メールアドレスだ。メールアドレスは一般に次のような書式をとっている。
ユーザー名@メールサーバ名またはドメイン名
右辺が自分自身を指していれば、自身で管理しているユーザーへメールを配信すればよいし、違うなら該当するMTAへと転送する必要がある。端的に説明すると、左辺が配信に、右辺が転送にかかわっていると思ってもよい。
ここで、メールサーバ名(FQDN*1)とドメイン名はまったく別物だということに注意してほしい。本来、メールアドレスは右辺にメールサーバ名を有する書式が一般的だった。歴史的経緯によるものだが、ある特定サーバに存在するユーザーは完全にユニーク性を保持できるため、あいまいさはない。この場合は、単にこのメールサーバに接続し、メールを転送すればよい。
ただし、メールサーバ名は比較的長くなる傾向があるとともに、組織内で管理しているサーバ名やサブドメイン名を外部に漏らしてしまう傾向にある。また、何より「不格好」だという印象が強いと考えられた。そこで、DNSドメイン名を右辺に定義できる仕組みが考案された。DNS MXレコードを使用する方法で、RFC974(STD14)に定義されている。
本稿では、DNSについて詳しく述べないが、DNSではドメインにおいてMX(Mail eXchange)と呼ばれる種類のレコードで複数のMTAが関連付けられるとともに、各MTAへの「距離*2」が示される。そのドメインあてのメールが転送される場合には、この距離が最も小さく近いMTAがそのドメインの「代表MTA」として、送信元MTAによって選択される決まりになっている。
![]() |
| 図2 送信先MTAの決定 |
例えば、上記の例のようなMXレコードでは、最初のMTAが代表MTAとなる。また、距離がまったく同じMXレコードが登録されていることもある。この場合距離は同じなので、どのMTAを選択してもよい。送信元MTAの実装次第だが、ランダムや順番に選択されれば、一種の負荷分散として機能することになる。また、選択されたMTAに何らかの原因で接続できない場合には、次に距離が短いMTAが選択される。つまり、簡易なフェイルオーバーとして機能させることもできる。
MTAにおけるメール・ルーティングにはもう1つ、複数メールの転送という複雑な動作も伴う。例えば、あて先やCc(カーボンコピー先)として複数のアドレスが指定されていた場合だ。メールのデータから、あて先やCc、Bcc(ブラインド・カーボンコピー)を解析し、上記のようなロジックから転送すべきMTAをすべて洗い出さなければならない。そして、それぞれの転送先ごとにメールを転送するわけだ。
そのほか、MTAとして動作するためには、送信時に接続に失敗した際の遅延送信や、受信時のためにキューイングを管理して多数のリクエストがあった場合の処理の効率化を図ったり、ユーザー管理を行うためのディレクトリへのアクセス機能なども必要となる。SMTP自身は非常にシンプルなプロトコルでしかない。だが、その役割の実現のためには、こうした複雑な仕組みの実装が必要となるのだ。
|
|
■SMTPコマンド
では、実際のSMTPのプロセスについて見てみることにしよう。
SMTPも、HTTPなどとよく似たプロトコル構造をしている。まずメールを転送(送信)したい側である転送元MTAから転送先MTAへ接続した後、転送元から「コマンド」と呼ばれる要求文字列が送信される。接続元はこのコマンドに応じて、毎回「レスポンス・メッセージ」を返答する。レスポンスの先頭には3ケタの「リプライコード」が含まれ、このコードによって、成功/不成功が判別できるようになっている。これらもやはり文字列である。
●コマンドの書式
コマンド[コマンドごとのオプションキーワードや引数など]
●レスポンスの書式
リプライコード[空白]任意のリプライ・メッセージ
いずれもASCIIコードで示され、文字列の終端はCR(0x0d)+LF(0x0a)である。つまり行のイメージを持っているのもHTTPと同様だ。これら文字列は、MIMEの回でも出てきた7ビットコードである。原則的にSMTPでは7ビットコードしか使用されない。理由はMIMEの回でも述べたとおりだが、通常のSMTPサーバでは8ビットは文字化けを起こしたり(データ欠損)、動作を不安定にする可能性がある。
![]() |
| 図3 SMTP通信の例 |
上記は実際のSMTP通信例だ。簡単に見えるが、実際にほとんどの場合、以上のような流れだけで通信は完結してしまう。HTTPとは異なり、接続後、複数回のメッセージのやりとりが行われるのが普通だ。また、レスポンスは複数行をとることもあるが、その際、次にも行が続く場合には、リプライコードとリプライ・メッセージの間は空白ではなく、-(ハイフン)を用いる。ただし、できる限りレスポンスは1行に収めることが推奨されている。また、1行の最大文字数は512までにしなければならない。
まず最初に、グリーティングと呼ばれる「自己紹介」が行われる。接続先MTAが220リプライコードを用いて自分を名乗ると、接続先MTAはHELOコマンドを用いて、やはり自身を名乗る。次に接続先MTAが250リプライコードを返せば、接続は完了する。これは互いに相手のサーバ名などを確認する作業だ。レスポンス・メッセージでは通常、正常時に250リプライコードを返答することになっているが、コマンドによってはほかのコードが正常終了時に返ることがある。
次に送信側は、MAIL FROMコマンドとRCPT TOコマンドでメールの送信者とあて先を送信先へ通知する。送信先MTAでは、RCPT TOコマンドで伝えられたアドレスに配信できるかどうかを、通常はこの時点で判断する必要がある。ローカルで受け取るユーザーが存在しているかどうかを調べ、存在していないのであれば、この時点でエラーを返答する。同じMTA上の複数のユーザーにメールを送る場合には、このRCPT TOコマンドは複数回繰り返されることになる。
次にDATAコマンドを送信し、その後メール・データを送信することを伝える。このメール・データが、前回まで出てきた「インターネットメール・フォーマット」または「MIME」に準拠したメールそのものである。メール・データの最後は必ず.(ピリオド)のみを含んだ行で終結しなくてはならない。こうした行を送信先MTAが検出すると、レスポンス・メッセージを返答する。最後に、QUITコマンドを用いて切断を行う。
こうした通信内容は、もちろんMUAからの送信依頼時でも何ら変わることはない。そのほかSMTPで用いられるコマンドは別表にまとめたが、SMTP通信ではほとんどの場合、上記コマンドとレスポンスで事足りてしまう。まさに“Simple”メール・プロトコルだ。
|
| 「SMTP〜後編」へ |
| 「Master of IP Network総合インデックス」 |
TechTargetジャパン
- 実機では測定できない性能を測定? (2012/2/7)
システムの完成前に、達成し得る性能値や必要なサーバリソースを知るには? その解となる「性能シミュレーション技法」を解説 - 性能チューニング個所の検討 (2012/1/30)
アプリのチューニングや環境増強で、どの程度改善が見込める? 今回からは「実際に活用できる性能対策」を解説します - 遅いところを直すだけでいいのですか? (2012/1/24)
負荷が集中したときの性能ボトルネックを改善するのに、アプリケーションサーバとDB、どちらを優先すべきでしょう? - cloudfoundry.comを使ってみよう (2012/1/19)
VMwareが提供するPaaSプラットフォーム「CloudFoundry」。注目を集めるこの基盤を活用してPaaSを構築!
|
|
キャリアアップ
スポンサーからのお知らせ
- - PR -
イベントカレンダー
- - PR -



