美森勇気
1 はじめに
現在、メーリングリストを作ろうと思えばfml、majordomoなどサーバー用の
プログラムとしていいものがいろいろと出ています。
例えば
fml なら
makefml というコマンドを実行してそれぞれの質問に答えていくだけで
簡単にメーリングリストを設立できます。それはそれでいいことなんですが、
ある日突然メールが届かない、などのトラブルが起こった時にどう対処して
いいのかわからなくなってしまうおそれがあるでしょう。事故の原因を
切り分けてつきとめるためには、メール伝送のしくみ、メーリングリストサ
ーバーが何をやっているか、といったことをある程度知っておく必要があ
ります。あるいは、悪意を持ったものがいたずらしてくるかも知れず、
少なくともその手口を推測出来るかどうかは重要でしょう。
そして、そのためにはメーリングリストサーバーを自分で作って
みるのもいい勉強になるでしょう。
この章では簡単なサーバープログラムの製作を通して「メールがサーバー
に入ってから出ていくまで」について述べていきたいと思います。
ちょっと難しい部分とか Perl を知らないと理解しづらい部分などもあり
ますが、完全に理解できなくともなんとなく見ていただければまったく
知らないよりははるかによいでしょう。
もしどうしても面倒だ、という方でも最後(9)だけは
読んで下さい。
メーリングリストサーバーというと本来ならサーバーマシンなども
含んでいるんでしょうが、ここでは狭い意味で解釈します。
最低限以下の様な機能を持ったプログラムが必要だということがわかるでしょう。
(1) メールを受けとったら
では、まずこれだけのことをするサーバーを作ってみましょう。
といっても、本当にこれしかしないのならプログラムを作る必要などありません。
サーバーのおいてあるマシン: mail.princess.moemoe.or.jp
というメーリングリストを作るとしましょう。そうしたら、
mail.princess.moemoe.or.jpというマシンの
/etc/aliases に、以下の様に書けば
いいんです。
kerokero-request: mimori これの意味は、メーリングリストサーバー(princess.moemoe.or.jp) が ということです。書き換えたら newaliases というおまじないをとなえてお
きましょう。
しかし、/etc/aliases は root しか書けない重要なファイルなので、メンバー
の増減のたびにこれを書き換えるのはあまりお勧めできる方法ではありません。
kerokero-request
の方はまだしも、メンバーの方だけでもメンバーリストの
ファイルを別に作っておいてそれを読ませるようにしたい、と思うのは自然な
ことです。そこで、次にはそれを実現してみましょう。
今、mimoriさんのホームディレクトリ(ログインしてすぐに pwd をするとわかる)
が /home/mimori で、メーリングリスト用に xmldir というディレクトリを作った
としましょう。メンバーリストのファイル名を members にしました。
つまりメーリングリストのメンバーのリストを書いたファイル名はフルパスだと
/home/mimori/xmldir/members になります。このファイルには、
mimori, shoko@crystal.co.jp,
kerokero: :include: /home/mimori/xmldir/members
と書いておくと、 kerokero あてのメールの送り先を /home/mimori/xmldir/members
から読み込んで(include)くれます。 : の数に注意。
こうしておくと、新しいメンバーの登録も比較的簡単です。例えば新しく
shippo@kemushi.com という人を登録するには、先ほどのメンバーファイル
に
mimori, shoko@crystal.co.jp,
これで一応メーリングリストが出来たわけですが、問題がないわけではありません。
(1) メールがエラーになると、ループしてしまう。
また、問題というわけではありませんが、「こうしてほしい」というような
要望が出るかもしれません。ユーザーは概してわがままなものです。
(2) メーリングリストのメールにリプライしたとき、ついうっかりと差出人に
返してしまうことがあるので、そうならないようにしてほしい。
まあ今の水準だとここまでやってメーリングリスト、ということかも知れません。
さらに要求は突き進んでいきます。
(4) 過去のアーカイブなどをコマンドメールで取り寄せたい。
などなど。このあたりのことをやりたいのならもうあきらめてfmlやmajordomoを
使った方がいいです。
では、この(1)〜(3)を実現する方法を考えていきましょう。
では、まず非常にクリティカルなエラーメールのループについてお話ししましょう。
あなたはエラーメール
を受けとったことがありますか?もしないとしたら、
それは幸せなことかも知れません。
エラーメールは、何らかの理由でメールが意図した送り先に届かなかった時に
「届かなかったよ」と教えてくれます(さらに簡単な理由もつけてくれるので、
メーリングリスト管理人はエラーメールを読まないといけないです。簡単な
英語で説明が書かれているので、エラーメールを受けとったら読む習慣を
つけましょう)。
さて、「届かなかったよ」というメールなんですから、そのメールを出した人の
ところに戻っていくのが普通でしょう。そして、その差出人が普通の人ならいい
んですが、先に述べたメーリングリストサーバーだと、そこに届いたメールは
エラーメールだろうと何だろうとまたメンバー全員に配送されます。そして
そのエラーになる送り先へもメールが届き、エラーメールが帰ってきて…
(以下繰り返し)となるわけです。困りますね。
もし、「このメールは管理人が出したんだよ」と明示的に示してやることが出来
れば、エラーメールは管理人に帰っていくのでループして増殖することはあり
ませんし、また管理人はエラーメールを見て対策を講じることも出来ます
(普通は)。
突然話は変わりますが、メールのcontentsは本文とヘッダでなりたっている、と良くい
いますが、Message全体としてはそれ以外に envelope と呼ばれるMTA
(Mail Transfer Agent, メールを実際に配送する
プログラム)
が解釈する部分、郵便でいえば郵便屋さんが読む
表の宛名とか差出人住所にあたる部分があります。そして、メールはそれに
したがって配送されるのであって、ヘッダの From とか To とかにどう書いて
あろうとMTAはそれを読んでません。そして、エラーメールが返る先はその
差出人住所(Envelope From という)の部分です。よって、もしもEnvelope Fromを
管理人のアドレスにすることが出来れば(つまりMTAに「これは私が出した
メールなんだよ」と教えてあげれば)一件落着です。
ここで sendmail というものが登場します。
5 sendmail
sendmail とはMTAの一種であり、その名の通りメールを送ったり受けとったり
するプログラムで普通 DAEMON (一種の常駐プログラムと考えて下さい)で
動いてます(詳しくは man 8 sendmail してください)。
メールを送るプログラムとしてはmailなどがありますが、
mail コマンドなどは基本的に人間が書いたメールにヘッダなどをつけて体裁
を整えるコマンドであり、それを郵便局、つまり sendmail に渡している、
と考えて下さい。一方、sendmail は SMTP(Simple Mail Transfer Protocol)
という「言葉」を使って他のマシンと話しをし、メールを転送します。
ちょっと脱線しますが、メールに限らずインターネット上で他のマシンと
「話し」、つまりアクセスするには必ず何らかのプロトコルを使います。
一番基本的なのが TCP/IP (Transmission Control Protocol /Internet Protocol)、
ホームページの転送なら HTTP (Hyper Text Transfer Protocol)、
ファイル転送の FTP (File Transfer Protocol)というのも有名ですね。
これらはそれぞれ一種の「言葉」だと思っておいてください。
この sendmail をユーザーが直接立ちあげる必要はまずないのですが、ヘッダを
いじったりする必要があるメーリングリストサーバーではこれを直接起動する
のがいいでしょう。
例えば、上の様なファイル(名前をtestとしましょう)を作って
cat test | mail (あなたのアドレス)
こういうメールが他人にいくと迷惑ですから
(そして、不慮の事故で管理者などに届いてしまう可能性があります)、く
れぐれも自分あてのテスト用として1回だけ行なうように。
さて、そのMTAに差出人(Envelope From)を指定してやるには、
-f オプションを使います。
つまり、
cat (メールファイル) | /usr/lib/sendmail -f (管理人) (送り先)
とすればいいわけですね。で、これを while か何かでループすればいいん
ですが、そうすると sendmail をたくさん起動することになり、マシンに
対する負荷が馬鹿になりません。
そこでメーリングリストサーバーに直接 SMTP で「話し」をさせてしまい
ましょう。話しは telnet を使いますが、話し方を指定してあげます。
telnet [server] smtp
telnet [server] 25
としてあげてください。それでも駄目ならそのマシンは smtp がしゃべれない
ので、smtp のしゃべれる別のマシンとお話しすればいいのです。
プロバイダだと、 smtp server はこれにしてください、という通知がある
のが普通のようです。
さて、次は話す内容です。とりあえずメールを出してみましょう
(help とすると使えるコマンドが出てくるのでこれを見るのもいいでしょう)。
下のうち、赤で書いてあるところは実際に入力したところで、それ以外は
コンピュータの答えです。
mimori[14]
telnet princess.moemoe.or.jp smtp
これはテストメールなんだよ。
ここで、ヘッダについてちょっと復習しておきましょう。
メーリングリストサーバーに関係あるのはこのあたりでしょう(詳しくは
RFC822
とかをみてね)
ヘッダというのはメールのうち、最初の改行だけの行までをいいます。
ヘッダにはおおよそ以下の様な情報が書かれています(メールによってはいくつかが
ないものもあります)。
Return-Path: エラーなどのときに返るアドレスで、
Envelope fromと同じものがMTAによって挿入されます。
また、"X-" で始まるヘッダは自由に使っていいことになっています。
よく X-Mailer:
Microsoft Internet Mail 4.70.1161 とか書いてありますね :-)
そこで、このあたりのヘッダに関しては以下のようにします(fmlやhmlに近い
書き方)。もし嫌いなら変更するのもそれほど難しくないでしょう。
1) 送られてきたメールに Reply-To があればそれを残し、なければ
Reply-To: メーリングリストのアドレス を付加する。
具体的にはこんなふうになります。
Return-Path: hoge-request@princess.moemoe.or.jp
(* はメーリングリストサーバーが付加したり変更したりしたヘッダ)
では、実際のプログラムです。Perlで書いてあります。
出来る限りコメントをつけてわかりやすいようにしてますが、Perlをまったく
知らない人にはそれでも難しいかもしれません。まあこんなもんか、と思うか
ラクダ本を買うかしてください :-)
今までのことを見て頂ければおわかりのように、ヘッダには重要な情報がのってい
るにもかかわらず簡単に偽造することが出来ます。From の偽造は明示的に From を
書いて sendmail から送ればいいわけですし、-f option までつければ Envelope from
(メールの受けてから見える部分としてはReturn-Path)
まで偽造することができ、つまり他人になりすましてメールを出すことなど悪意あ
るものにとっては簡単に出来るということになります。このようなメールシステム
の欠点を知っておいてください。
/etc/aliases: HPなどのOSでは /usr/lib/aliases となっています。
hogehoge-request: メーリングリストの管理人アドレスは hogehoge-admin
などいろいろなパターンがありましたが、
RFC2142
でこの形(hogehoge-request)とすることが推奨されています。
もくじ
2 メーリングリストサーバーとは?
3 いくつかの問題点
4 エラーメールのループ
5 sendmail
6 smtp にアクセス
7 ヘッダについて
8 プログラム
9 最後に1 はじめに
2 メーリングリストサーバーとは?
(2) それをメンバー全員に送り出す
メーリングリストのアドレス: kerokero@princess.moemoe.or.jp
管理用アドレス : kerokero-request@princess.moemoe.or.jp
管理人の本当のアドレス : mimori@princess.moemoe.or.jp
メンバーのアドレス : mimori@princess.moemoe.or.jp
shoko@crystal.co.jp
aochan@frog.transform.co.jp
leap@forest.ne.jp
kerokero: mimori, shoko@crystal.co.jp,
* kerokero-request さん宛のメールを受けとったら(このマシンの) mimori に送る
* kerokero さん宛メールなら 「:」 のあとの4人に送る
aochan@frog.transform.co.jp, leap@forest.ne.jp
aochan@frog.transform.co.jp, leap@forest.ne.jp,
shippo@kemushi.com3 いくつかの問題点
(3) メーリングリストのメールであることをわかりやすくしてほしい。
(5) 自己紹介ファイルをおきたい。
(6) ftp mail をやってほしい。
(7) 過去のメールをhtmlにしてホームページで公開してほしい。
4 エラーメールのループ
From: daresore
To: nobody
Subject: test
Date: today
test
cat test | /usr/lib/sendmail (あなたのアドレス)
とすると、違いがよくわかるでしょう。前者では
Return-Path: <mimori@usa.net>
Received: (省略)
Date: Thu, 5 Jun 1997 14:37:34 +0900 (JST)
From: Mimori Yuuki <mimori@usa.net>
Message-Id: <199706050537.OAA22198@usa.net>
To: mimori@usa.net
From: daresore
To: nobody
Subject: test
Date: today
test
Return-Path: mimori@usa.net
Received: (省略)
Message-Id: <199706050537.OAA22203@usa.net>
From: daresore@usa.net
To: nobody@usa.net
Subject: test
Date: today
test
もくじへ
6 smtp にアクセス (詳しくは
RFC821)
Trying xxx.xxx.xxx.xxx ...
Connected to princess.moemoe.or.jp.
Escape character is '^]'.
220 princess.moemoe.or.jp ESMTP Sendmail 8.8.5; Wed, 11 Jun 1997 02
:36:56 +0900 (JST)
HELO princess.moemoe.or.jp
250 princess.moemoe.or.jp Hello mimori@princess.moemoe.or.jp
[xxx.xxx.xxx.xxx], pleased to meet you
MAIL From: <mimori@princess.moemoe.or.jp>
250 <mimori@princess.moemoe.or.jp>... Sender ok
RCPT To: mimori@usa.net
250 mimori@usa.net... Recipient ok
RCPT To: error@princess.moemoe.or.jp
550 error@princess.moemoe.or.jp
550 error@princess.moemoe.or.jp... User unknown
#エラーはこうなる。
RCPT To: leap@forest.ne.jp
250 leap@forest.ne.jp... Recipient ok
DATA
354 Enter mail, end with "." on a line by itself
From: Mimori <mimori@usa.net>
To: Leap <leap@forest.ne.jp>
Subject: smtp no test
SMAPぢゃないよ、SMTPだよ。
.
QUIT
221 princess.moemoe.or.jp closing connection
Connection closed by foreign host.
こうすると、mimori@usa.net と leap@forest.ne.jp に以下のようなメールが
いきます。
Return-Path: mimori@princess.moemoe.or.jp
Date: Wed, 11 Jun 1997 02:37:20 +0900 (JST)
Message-Id: <199706110037.JAA22749@princess.moemoe.or.jp>
From: Mimori <mimori@usa.net>
To: Leap <leap@forest.ne.jp>
Subject: smtp no test
これはテストメールだよ。
SMAPぢゃないよ、SMTPだよ。
7 ヘッダについて
Received: このメールが途中、どういう経路でここまで来たのかが(MTAによって)
書かれています。
From: メールを書いた人の名前とアドレスです。
Sender: メール差出人の名前、アドレスです。
Fromがなんらかの理由(グループの代表アドレスを使っているとか1人で複数の
メールアドレスを使い分けてるとか)で実際にメールを出そうとしているアドレスと
Fromとが一致しない場合に本当の差出人がsender に書かれることになっています。
Message-Id: このメールのIDで、(つけるならば)uniq なものをつけなければなりません。
普通 <番号/記号@マシン名> となってます。
To: 送り先です。
Cc: カーボンコピーと呼ばれ、To 以外に参考までに送ったりするときに使います。
Bcc: ブラインドカーボンコピーで、機能は Cc: と同じようなものですが、
この行は受取人に送られないので相手に気づかれずにメールを送ることが出来ます。
Date: メールを出した日付。
Subject: メールのサブジェクト。
Reply-To: メールの返送先です。
Precedence: メールの配送方法を示します。メーリングリストの場合には bulk にしておくのがいいよう
です。
他に In-Reply-To:, References (引用情報)などがあります。
2) メーリングリストの名前、番号は X-ML-Name, X-Mail-Count に書く。
サーバーの名前を X-MLServer に書く。
3) Subject に [メーリングリストの名前: メーリングリストのカウント]
をつける。
Date: Tue, 10 Jun 97 09:40:01 +900
From: mimori@usa.net (Mimori Yuuki)
Reply-To: hoge@princess.moemoe.or.jp *
Subject: [hoge-ML:01557] New member *
To: hoge@princess.moemoe.or.jp
X-ML-Name: hoge-ML *
X-Mail-Count: 01557 *
X-MLServer: Mariko-d v1.0 *
Message-ID: <19970610.01557@usa.net>
Precedence: bulk *
もくじへ8 プログラム
もくじへ9 最後に
もくじへ
脚注
Copyright 1996-97 by Mimori Yuuki
Correspond to mimori@puni.net