1998年8月9日初版発行、1999年2月5日第二版発行、2001年3月16日第三版改訂中
この文書はメイルにおける Message-ID に対する考察を行ったものである。ニューズに関しては行っていないことをあらかじめ考慮していただきたい。 この議論の叩き台として、メイルのメッセージの形式を定めた RFC 2822 "Internet Message Format" を読むことを勧める。 原文を読むのが辛い方向けに RFC 2822 の "3.6.4. Identification fields"の邦訳 をしたので必要ならご覧下さい。 なお、RFC 2822 は RFC 822 の改訂版であり、2001年3月に公開されたものである。これにより RFC 822 は obsolete になったため、RFC 2822 を前提に議論を勧める。
ここで、簡単な用語説明を行う。
Message-ID フィールド(以降、単に Message-ID と記述する)とはメイルやニューズのメッセージの識別子を記述するため場所であり、各メッセージの Message-ID はそれぞれ唯一無二(ユニーク)でなければならない。
Message-ID はその性質(ユニーク)により、メッセージの重複を防いだり、"In-Reply-To", "Referrence" フィールドと併せてスレッドを生成することが可能である。また、本文中で参照する Message-ID を記述して、参照元のメッセージを特定することもできる。このため、メイリングリストやニューズには欠かすことのできないものである。
RFC 2822 では 'every message SHOULD have a "Message-ID:"'(どのメッセージも"Message-ID:"を持つべきである)という記述があるため、Message-ID は付けるべきものである。ちなみに、RFC 822 では Message-ID は optional-field として定義されている。
Message-ID に関する議論になると必ずといっていいほど、MUA が付けるべきか MTA が付けるべきかという話になる。まず、MTA の役割と Message-ID を付けることに関して考えてみる。次に RFC ではどうなっているかを考えてみる。
過去及び現在において MTA として最も多く使われている「高機能で、複雑な配送でもOK、そのかわり設定も複雑」な sendmail は Message-ID を付ける。一方、sendmail と置き換わるべきものとして作られた「安全で、信頼性も高く、簡潔で、高速な配送を行う」 qmail では Message-ID は付けない。MTA としての本来の役割を考えてみると、エンヴェロープの情報に基づきホストからホストへメッセージを配送するのが仕事であり、基本的には(経路情報のヘッダーを付ける以外)メッセージそのものには関与しない。MTA が Message-ID を付けるということはヘッダーを解析し、Message-ID がすでにあるかどうか調べるということであり、余計な処理が必要になるということである。つまり、MTA としての役割から見た場合、(親切な行為なのか余計なお世話なのかはともかくとして)必要なこと以上のことを行っているのである。qmail でも Message-ID を付ける方法があるが、これに関しては「qmail とヘッダーの補完に関して」に記述する。なお、RFC821 の改定案の"6.3 Compensating for Irregularities"では受け取ったメッセージが Message-ID や Date を欠いていれば MTA でそれらを追加してよい"MAY"となっている。ただし、そのようなメッセージを生成した MUA を"these weak SMTP clients"と呼んでいることからも、本来は MUA で生成すべきだという考えが読み取れると思う。また、将来的には欠いているヘッダは Message Submission Agent (MSA) で補完されるようになるかも知れない(RFC 2476 "Message Submission"を参照)。
ユーザーが作成するメッセージの形式は RFC 2822 に規定されていて、MUA はこの RFC 2822 に従ったメッセージを生成する必要がある。よって、Message-ID はこの RFC 2822 に規定されていることから MUA が生成すべきものであることがわかる。Return-Path や Received などの経路情報のヘッダーも RFC 2822 に記述されているのではないかという意見もあると思うが、"Further restrictions may be applied to the syntax of the trace fields by standards that provide for their use, such as [SMTP]." との記述があるので例外である。
この項目の結論として、MUA が Message-ID を生成すべきである。ただし、Message-ID が欠けているメッセージを受け取った MTA でも Message-ID を生成することは可能である(決して、MTA が Message-ID を生成すべきだというわけではない)。
まず、Message-ID の形式を見てみる。RFC822 では <local-part "@" domain> で unique であることが要求されている。
次に具体的に考えてみる。Message-ID として要求されるのは「世界中で唯一無二の識別子」"a globally unique identifier"であることである。これを実現する方法として、"@" の右側にはメッセージが作成されたドメイン名(FQDN)あるいはドメインリテラル([202.224.39.39] のような IP アドレスの記述方法)を記述し、その左側にはそのドメインにおいてユニークになるように保証された文字列(例えば、生成日時、プロセスID、生成番号などの組み合わせ)を記述する。つまり、FQDN は世界中でユニークであるから、そのホストにおいてユニークな文字列であれば、その組み合わせの Message-ID はユニークとなる。なお、ドメインリテラルを用いる場合は、パブリックな IP アドレスである必要がある。
以上のことは RFC 2822 の "3.6.4. Identification fields"(邦訳) に詳しく解説されているので参考にしてほしい。
クライアントマシンの多くはファイアーウォールの内側でプライベートなIPアドレスを持つかあるいはダイアルアップホストのようにIPアドレスを持たない。そのため、Message-ID で使用すべき FQDN を持つことができない。先の項目で述べたように、Message-ID は MUA が生成すべきであるのだが、使用すべき FQDN がない。さて、どうしたものだろうか?
まず、Message-ID を生成する MUA の FQDN の実装例をまとめてみると次のようなものが挙げられる。
1.の場合は、そのマシンがグローバルな IP アドレスを持つ場合は、正しい FQDN であるため全く問題ない。正式なドメインを持っている組織がファイアウォールの内側をプライベートな IP アドレスのサブドメインとして構成している場合は、正式な FQDN ではないもののユニークであることが保証される。正式なドメインを持たない組織およびダイアルアップホストの場合は、契約している ISP の下に仮想的なサブドメインを設定すればごまかしの FQDN は生成できるが、必ずしもユニークであることは保証されない。ただし、これらの前提として各クライアントの TCP/IP の設定 が正しく行われている必要がある。しかし、「Windows における TCP/IP の設定」で述べるように必ずしもまともに設定がされているとは限らない。
2.の場合は、サーバ名は FQDN であるが、同じサーバを利用している他のマシンも同じ FQDN になってしまうので、何らかのユニークな文字列を生成する必要がある。そのサーバの利用者においてユニークであることが保証される文字列はユーザ名(ログイン名)であるのでこれを利用する。3.の場合も、ユーザ名とドメイン名の組み合わせでユニークとなる。ユーザ名をそのまま Message-ID に表示したく無い場合は、何らかの規則(例えばハッシュ関数等)でユーザ名を変換すればよい。各 MUA が同一の生成規則を持っているわけではないので、他のユーザと衝突する可能性が全くないわけではない。しかし、日時の情報、プロセスID、生成番号、MUA 固有の情報などを組み合わせれば、Message-ID を利用した機能を使う上では実効上ほぼ問題ない程度にユニークな Message-ID を生成できる。
「グローバルな IP アドレスを持ったクライアント PC はほとんどない」「ユーザの設定は信用できない」という前提においてまとめると、Message-ID の FQDN には MUA がメイルサーバ名やメイルアドレスなどから勝手に判断して付け、ユニークな文字列にユーザ名(あるいは相当する文字列)、日時の情報、プロセスID、生成番号、MUA 固有の情報などを組み合わせれば、ほぼユニークな Message-ID を生成することが可能である。
なお、この結論と似たような考え方の Message-ID の生成方法が Internet-Drafts として提案された。(ただし、現在、このドラフトは期限切れで削除されているため、そのコピーをここに置いておく。)
MTA としての qmail はヘッダーの補完はしない。経路情報のヘッダーを追加するだけである。しかし、Message-ID を付ける方法がないわけではない。付属文書のFAQ 5.5. "How do I fix up messages from broken SMTP clients?"がそれだ。サーバー内部でローカル配送を行わせることによりヘッダーの補完を行う方法である。具体的に説明すると、qmail のパッケージの中には MUA の送信部分の役割を果たす qmail-inject という(RFC822 の形式に補完してキューに送信する)プログラムがある。MTA としてメイルを受け取ったら、まず仮想ユーザーのメイルボックスに配送し、そしてそのメイルボックスから本来の宛先へ配送する。このメイルボックスからの配送には qmail-inject が使われるため、ヘッダーが補完されるわけである。しかし、この FAQ のタイトルで "broken SMTP clients" と書かれているように、この方法が必要なクライアントというのは決して好ましいのものではない。
また、FQDN を持つことができず、 Message-ID を生成できないために SMTP クライアントにはなれないと割りきってしまえば、qmail の作者 DJB の提案する OFMIP(Old-Fashioned Mail Injection Protocol)クライアントとして考えることができる。mess822というパッケージに含まれる ofmipd というプログラム(25番以外のTCPのポートを使用)を使用する。このデーモンはクライアントからのメッセージを受取ると、ヘッダーを RFC822 に従うように修正し、MTA のキューに配送してくれる。
歴史的に見て、インターネットメイルは自前で MTA を持つ UNIX をプラットホームとして発展してきた。MUA がそのマシンのキューにメッセージを放り込めば MTA がそのメッセージを送信してくれる。そのため、自前で MTA を持たない Windows の MUA がメッセージを送信するときの専用のプロトコルは特に定義されていなく、中継メイルサーバに対して SMTP client として働いているのが現実である。しかし、不完全なメッセージを出力する MUA の問題や不正中継の問題などのため、MTA が MUA からメッセージを受け取る際に様々な問題が生じている。これらのことを背景にしたかは確かではないが、RFC 2476 "Message Submission" が公開された。この RFC は MUA から送信されたメッセージを受け取る Message Submission Agent (MSA) というのを MTA の代わりに設け、認証や不完全なエンヴェロープやヘッダーに対する補完を行う機能を受け持つことを提案している。
基本的に SMTP と同じプロトコルを用いるためポート番号を 25 から 587 に変更する(MSA と MTA の使い分けができれば 25 のままでもよい)だけで、MUA は対応できる(認証関連を追加する必要がある)と思う。認証に関しても POP before SMTP や SMTP-AUTH は一部では実装されている。サーバ側に関しても MSA をサポートしたものもある。
ダイアルアップホストの場合、ダイアルアップアダプターと TCP/IP のプロトコルドライバさえインストールすれば、ISP の DHCP によって TCP/IP の設定をせずに使える。しかし、MUA でメッセージを書いているときは基本的にオフラインであるから、DHCP がまったく働いていない状態である。この状態では、ホスト名としてコンピュータ名(NetBIOS名)が使われる。ドメイン名は付かない。このコンピュータ名の問題は、OEM インストールされた初期状態は "default" など、メーカーが設定した名前が付けられており、また、名前を付け変えたとしても、日本語を含めホスト名として使ってはいけない文字が使えてしまう点である。このようなダイアルアップホストでも、ホスト名/ドメイン名を付けることは可能である。ネットワークの設定における「TCP/IPのプロパティ」の「DNSの設定」で行える。 なお、使用している PC がどのような FQDN が付けられているかは winipcfg.exe を実行すればわかる。使用しているマシンがどのような FQDN が付けられているか知らない方は実行して確認してもらいたい。
組織などでファイアウォールの内側の LAN を DHCP で運用しているところは多いと思う。この場合、ホスト名/ドメイン名の設定を何もしなければ、ドメイン名は DHCP サーバにより与えられるが、ホスト名はコンピュータ名(NetBIOS名)が使われてしまう。ダイアルアップホストと同じ問題が起こりえる。ホスト名/ドメイン名の設定をすれば確実なのだがそれでは DHCP を使うメリットがなくなってしまう。そのため、正しいコンピュータ名を設定する必要がある。
これらの設定に関して、一般のユーザの大半はネットワークの知識がないため、ほとんど設定しないと思う。組織のおいてはパワーユーザや管理者がいれば設定してもらえるが、いない場合や個人ユーザの場合はどうしようもない。そのため、メイリングリストで <********@default> のような Message-ID をよく見かけるわけである。