[Index] [Manner] [Admin] [Zakki] [link]

メーリングリストサーバーを作ろう!

美森勇気

もくじ

1 はじめに
2 メーリングリストサーバーとは?
3 いくつかの問題点
4 エラーメールのループ
5 sendmail
6 smtp にアクセス
7 ヘッダについて
8 プログラム
9 最後に

脚注

管理者のページに戻る

トップページに戻る


1 はじめに

現在、メーリングリストを作ろうと思えばfml、majordomoなどサーバー用の プログラムとしていいものがいろいろと出ています。 例えば fml なら makefml というコマンドを実行してそれぞれの質問に答えていくだけで 簡単にメーリングリストを設立できます。それはそれでいいことなんですが、 ある日突然メールが届かない、などのトラブルが起こった時にどう対処して いいのかわからなくなってしまうおそれがあるでしょう。事故の原因を 切り分けてつきとめるためには、メール伝送のしくみ、メーリングリストサ ーバーが何をやっているか、といったことをある程度知っておく必要があ ります。あるいは、悪意を持ったものがいたずらしてくるかも知れず、 少なくともその手口を推測出来るかどうかは重要でしょう。 そして、そのためにはメーリングリストサーバーを自分で作って みるのもいい勉強になるでしょう。

この章では簡単なサーバープログラムの製作を通して「メールがサーバー に入ってから出ていくまで」について述べていきたいと思います。

ちょっと難しい部分とか Perl を知らないと理解しづらい部分などもあり ますが、完全に理解できなくともなんとなく見ていただければまったく 知らないよりははるかによいでしょう。

もしどうしても面倒だ、という方でも最後(9)だけは 読んで下さい。


もくじへ


2 メーリングリストサーバーとは?

メーリングリストサーバーというと本来ならサーバーマシンなども 含んでいるんでしょうが、ここでは狭い意味で解釈します。 最低限以下の様な機能を持ったプログラムが必要だということがわかるでしょう。

(1) メールを受けとったら
(2) それをメンバー全員に送り出す

では、まずこれだけのことをするサーバーを作ってみましょう。 といっても、本当にこれしかしないのならプログラムを作る必要などありません。

サーバーのおいてあるマシン: mail.princess.moemoe.or.jp
メーリングリストのアドレス: 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

というメーリングリストを作るとしましょう。そうしたら、 mail.princess.moemoe.or.jpというマシンの /etc/aliases に、以下の様に書けば いいんです。

kerokero-request: mimori
kerokero: mimori, shoko@crystal.co.jp,

aochan@frog.transform.co.jp, leap@forest.ne.jp

これの意味は、メーリングリストサーバー(princess.moemoe.or.jp) が
* kerokero-request さん宛のメールを受けとったら(このマシンの) mimori に送る
* kerokero さん宛メールなら 「:」 のあとの4人に送る

ということです。書き換えたら newaliases というおまじないをとなえてお きましょう。

しかし、/etc/aliases は root しか書けない重要なファイルなので、メンバー の増減のたびにこれを書き換えるのはあまりお勧めできる方法ではありません。 kerokero-request の方はまだしも、メンバーの方だけでもメンバーリストの ファイルを別に作っておいてそれを読ませるようにしたい、と思うのは自然な ことです。そこで、次にはそれを実現してみましょう。

今、mimoriさんのホームディレクトリ(ログインしてすぐに pwd をするとわかる) が /home/mimori で、メーリングリスト用に xmldir というディレクトリを作った としましょう。メンバーリストのファイル名を members にしました。 つまりメーリングリストのメンバーのリストを書いたファイル名はフルパスだと /home/mimori/xmldir/members になります。このファイルには、

mimori, shoko@crystal.co.jp,
aochan@frog.transform.co.jp, leap@forest.ne.jp

と書いておきます。一方、/etc/aliases には

kerokero: :include: /home/mimori/xmldir/members

と書いておくと、 kerokero あてのメールの送り先を /home/mimori/xmldir/members から読み込んで(include)くれます。 : の数に注意。

こうしておくと、新しいメンバーの登録も比較的簡単です。例えば新しく shippo@kemushi.com という人を登録するには、先ほどのメンバーファイル に

mimori, shoko@crystal.co.jp,
aochan@frog.transform.co.jp, leap@forest.ne.jp,
shippo@kemushi.com

と付け加えてあげればいいわけです。


もくじへ


3 いくつかの問題点

これで一応メーリングリストが出来たわけですが、問題がないわけではありません。

(1) メールがエラーになると、ループしてしまう。

また、問題というわけではありませんが、「こうしてほしい」というような 要望が出るかもしれません。ユーザーは概してわがままなものです。

(2) メーリングリストのメールにリプライしたとき、ついうっかりと差出人に 返してしまうことがあるので、そうならないようにしてほしい。
(3) メーリングリストのメールであることをわかりやすくしてほしい。

まあ今の水準だとここまでやってメーリングリスト、ということかも知れません。 さらに要求は突き進んでいきます。

(4) 過去のアーカイブなどをコマンドメールで取り寄せたい。
(5) 自己紹介ファイルをおきたい。
(6) ftp mail をやってほしい。
(7) 過去のメールをhtmlにしてホームページで公開してほしい。

などなど。このあたりのことをやりたいのならもうあきらめてfmlやmajordomoを 使った方がいいです。

では、この(1)〜(3)を実現する方法を考えていきましょう。


もくじへ


4 エラーメールのループ

では、まず非常にクリティカルなエラーメールのループについてお話ししましょう。

あなたはエラーメール を受けとったことがありますか?もしないとしたら、 それは幸せなことかも知れません。

エラーメールは、何らかの理由でメールが意図した送り先に届かなかった時に 「届かなかったよ」と教えてくれます(さらに簡単な理由もつけてくれるので、 メーリングリスト管理人はエラーメールを読まないといけないです。簡単な 英語で説明が書かれているので、エラーメールを受けとったら読む習慣を つけましょう)。

さて、「届かなかったよ」というメールなんですから、そのメールを出した人の ところに戻っていくのが普通でしょう。そして、その差出人が普通の人ならいい んですが、先に述べたメーリングリストサーバーだと、そこに届いたメールは エラーメールだろうと何だろうとまたメンバー全員に配送されます。そして そのエラーになる送り先へもメールが届き、エラーメールが帰ってきて… (以下繰り返し)となるわけです。困りますね。

もし、「このメールは管理人が出したんだよ」と明示的に示してやることが出来 れば、エラーメールは管理人に帰っていくのでループして増殖することはあり ませんし、また管理人はエラーメールを見て対策を講じることも出来ます (普通は)。

突然話は変わりますが、メールの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 をユーザーが直接立ちあげる必要はまずないのですが、ヘッダを いじったりする必要があるメーリングリストサーバーではこれを直接起動する のがいいでしょう。


From: daresore
To: nobody
Subject: test
Date: today

test

例えば、上の様なファイル(名前をtestとしましょう)を作って

cat test | mail (あなたのアドレス)
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

となります。

#注意!

こういうメールが他人にいくと迷惑ですから (そして、不慮の事故で管理者などに届いてしまう可能性があります)、く れぐれも自分あてのテスト用として1回だけ行なうように。

さて、そのMTAに差出人(Envelope From)を指定してやるには、 -f オプションを使います。 つまり、

cat (メールファイル) | /usr/lib/sendmail -f (管理人) (送り先)

とすればいいわけですね。で、これを while か何かでループすればいいん ですが、そうすると sendmail をたくさん起動することになり、マシンに 対する負荷が馬鹿になりません。


もくじへ

6 smtp にアクセス (詳しくは RFC821

そこでメーリングリストサーバーに直接 SMTP で「話し」をさせてしまい ましょう。話しは telnet を使いますが、話し方を指定してあげます。

telnet [server] smtp

こうすればOK。もし smtp としてだめなら

telnet [server] 25

としてあげてください。それでも駄目ならそのマシンは smtp がしゃべれない ので、smtp のしゃべれる別のマシンとお話しすればいいのです。 プロバイダだと、 smtp server はこれにしてください、という通知がある のが普通のようです。

さて、次は話す内容です。とりあえずメールを出してみましょう (help とすると使えるコマンドが出てくるのでこれを見るのもいいでしょう)。 下のうち、赤で書いてあるところは実際に入力したところで、それ以外は コンピュータの答えです。

mimori[14] telnet princess.moemoe.or.jp smtp
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だよ。
.
250 JAA22749 Message accepted for delivery
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 ヘッダについて

ここで、ヘッダについてちょっと復習しておきましょう。 メーリングリストサーバーに関係あるのはこのあたりでしょう(詳しくは RFC822 とかをみてね)

ヘッダというのはメールのうち、最初の改行だけの行までをいいます。 ヘッダにはおおよそ以下の様な情報が書かれています(メールによってはいくつかが ないものもあります)。

Return-Path: エラーなどのときに返るアドレスで、 Envelope fromと同じものがMTAによって挿入されます。
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 (引用情報)などがあります。

また、"X-" で始まるヘッダは自由に使っていいことになっています。 よく X-Mailer: Microsoft Internet Mail 4.70.1161 とか書いてありますね :-)

そこで、このあたりのヘッダに関しては以下のようにします(fmlやhmlに近い 書き方)。もし嫌いなら変更するのもそれほど難しくないでしょう。

1) 送られてきたメールに Reply-To があればそれを残し、なければ Reply-To: メーリングリストのアドレス を付加する。
2) メーリングリストの名前、番号は X-ML-Name, X-Mail-Count に書く。 サーバーの名前を X-MLServer に書く。
3) Subject に [メーリングリストの名前: メーリングリストのカウント] をつける。

具体的にはこんなふうになります。

Return-Path: hoge-request@princess.moemoe.or.jp
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 プログラム

では、実際のプログラムです。Perlで書いてあります。 出来る限りコメントをつけてわかりやすいようにしてますが、Perlをまったく 知らない人にはそれでも難しいかもしれません。まあこんなもんか、と思うか ラクダ本を買うかしてください :-)

ぷろぐらむ


もくじへ

9 最後に

今までのことを見て頂ければおわかりのように、ヘッダには重要な情報がのってい るにもかかわらず簡単に偽造することが出来ます。From の偽造は明示的に From を 書いて sendmail から送ればいいわけですし、-f option までつければ Envelope from (メールの受けてから見える部分としてはReturn-Path) まで偽造することができ、つまり他人になりすましてメールを出すことなど悪意あ るものにとっては簡単に出来るということになります。このようなメールシステム の欠点を知っておいてください。


もくじへ


脚注

/etc/aliases: HPなどのOSでは /usr/lib/aliases となっています。

hogehoge-request: メーリングリストの管理人アドレスは hogehoge-admin などいろいろなパターンがありましたが、 RFC2142 でこの形(hogehoge-request)とすることが推奨されています。 ラクダ本: O'REILLYから出ている一連のシリーズ。ちょっと大きな書店にはあるはず。 ちょっと高い。


管理者のためのページに戻る


Copyright 1996-97 by Mimori Yuuki
Correspond to mimori@puni.net