No.124 2002/03/09
メーリングリストの大事故

 私は、ソフトウェア工学関係の200人ほどの研究会のメーリングリストを運用しています。パソコンの使い方やネチケットについての理解力が若い人ほど高くない年配の人がかなりいることと、全体の人数も多くてコミュニケーションが活発なことから、いろんな問題が生じています。私は、なるべく問題を起こさないようにシステム側にいろんな工夫を盛り込んできて、それをきまぐれノートでも紹介してきました。改めてそれらを挙げますと…
 ここまでやったおかげで、メーリングリストはかなり平穏を保ってきました。ある会員が別の会員へファイル添付のメールを送ろうとして、送りたい相手がメーリングリストに流していたメールを見つけ出してそれに返信するという操作をしたために、全会員に流れてしまったこともあります。しかし、巨大なデータが200人に送り付けられて配送事故が起こることは防御されました。「気を付けないと情報漏洩になりますよ」と注意してあげるくらいですみました。システム側で防御していなければ、「添付ファイルはやめてくれと言ったでしょ!」と怒鳴らなければならなかったところでした。

 しかし、2002年3月6日、どうしても未然に防御できない大事故が起こってしまいました。メールの無限ループです。
 ある会員が、受信アドレスから別のアドレスへ転送をしかけていました。その転送先のメールサーバで「受取人不明」のエラーが起こりました。これはよくある事故です。普通は、そのエラー通知は「差出人エンベロープアドレス」(第105回参照)へ返されます。メーリングリストで配信されるメールの場合、差出人エンベロープアドレスはメーリングリスト管理者のアドレスになるので、メーリングリスト管理者がエラー通知を受けることになります。
 ところが、今回エラー通知を送ってよこしたメールサーバは、差出人エンベロープアドレスへ送り返すのでなく、エラーになったそのメールに返信するという動作をしていました。つまり、エラーになったメールにReply-To(返信先)ヘッダがあればそこへ(なければFromヘッダのアドレスへ)返信するという動作をしたのです。これはきわめて迷惑な動作です。メーリングリストで配信されたメールには、メーリングリストへ返信させるためのReply-Toヘッダが付けられています。そのため、エラー通知はメーリングリストに投げられ、そのメールはくだんの会員にも配信され、それがまたエラーになってメーリングリストへ投げられるという、決して自動的には止まらない無限ループが起こってしまったのです。

 悪いことに、私は、メールサーバにPostfixという新しいメール転送プログラムを使っていました。
 世界で広く使われている伝統的なsendmailというプログラムは、多数の宛先へ配信するメールを一ドメインずつ順番に送るので、メーリングリストの配信に時間がかかります。あるドメインとの通信に時間がかかると、それだけ配信完了が遅延するので、約200人への配信に1時間以上かかることはよくありました。一方、Postfixは、多数のドメインへ並行して配信するので、配信は1分半ほどで終わってしまいます。通信に時間がかかるドメインがあっても、それはほかのドメインへの配信に影響しません。
 Postfixのこの優れた特徴があだになりました。配信が速いから、エラーメールのループも速く、結果的に26分で約80通ものエラーメールが配信されてしまったのです。配信の遅いsendmailだったら、気付いてから対処完了までに数回のループで済んだでしょう。

 メールのループが始まったのは13時45分、事務局長から電話が入ったのが14時ころでした。その時、私は会社で打ち合わせを終えて席に戻ったばかりでした。私はただちに、会社の業務をほったらかして、インターネット経由で自宅のサーバにログインして対処しました。
 Postfixを停止。そのメーリングリストとは無関係の人からのメールも受信できなくなってしまいますが、やむを得ません。
 そして、転送をしかけていた会員のアドレスをリストから削除。
 スパムメール防御策のノウハウを利用して、エラーメールを拒絶する設定をPostfixに追加して、Postfixを再起動。実は、設定を間違えたため、ブロックできていませんでした。その原因を調べている時間はありません。再度Postfixを停止。相手サーバのIPアドレスに基づいて、ルータのIPフィルタでエラーメールの受信をブロックするようにしました。
 サーバの中を調べているうちに、すでに多量のメールが送信待ちに入ってしまっており、Postfixを再起動したら会員への迷惑が続くということがわかりました。Postfixの仕組みを詳細には知らないまま、後の誤動作のリスクを覚悟して、送信待ちのメールの削除を始めました。単純に全部消すわけにはいきません。ほかの重要なメールがあるかもしれないからです。256個のディレクトリの中のファイルを探し、一つ一つ中身を見て、送信待ちになっているエラーメールを消しました。
 そしてPostfixを再起動。別の原因によるもの以外に送信待ちのメールがなくなったことを確認したのは、16時少し前。約2時間がかりでした。
 対処中にも、会員から会社に電話が入ってきました。
「○○会の○○ですが…」「対処中です。」
「○○会の○○ですが…」「対処中です。」
 こういう時には連絡対応者が別にほしい…
 今回は、私がすぐに自宅のサーバにログインできる状況だったからまだ幸いでした。こんなことが起こるようでは、私はおちおち外出も寝ることもできません。
 そこで、また新しい仕掛けを作りました。私よりも早くメールのループに気付いた会員が、私のウェブサーバにアクセスしてメーリングリストを緊急停止させるというものです。
 その研究会のホームページに「メーリングリスト緊急停止」というリンクを設けます。それをクリックして、会員専用のパスワードを入れると、緊急停止の案内ページに入ります。そこで「停止」というリンクをクリックして、もう一度パスワードを入れます(同じパスワードでよいのですが、ブラウザに記憶されたパスワードは自動的に出ないように仕組んでいます。誤操作を防ぐためです)。そうすると、スクリプトが動いて、アドレスリストファイルの名前を変更します。これにより、メーリングリストで配信されようとするメールを「アドレスリストファイルがない」というエラーに落としてメールのループを食い止めます。後で私が連絡を受け、原因を調べて対処してから復旧させます。
 電車の乗客が押す非常停止ボタンのようなものです。私一人では即刻対処できないリスクをカバーするために、緊急時にメーリングリストのシステム設定を“破壊”する権限をあえて全会員に委ねたのです。

 この仕掛けは、大事故が発生した日のうちに作りました。ところが、さっそく翌日に“副作用”が起こってしまいました。
 ある会員が、翌日メールを開いた時、エラーメールが次々にダウンロードされたのを見てパニックに陥りました。メールの順番が入れ違って届いていたので、緊急停止の仕掛けを説明した私のメールがエラーメールの洪水の途中に入っていました。それを見て、今ダウンロードされつつあるエラーメール(すでにその人の会社のメールサーバにまで届いてしまっているものです)がそれで止まるのだと勘違いして、緊急停止を操作してしまったのです。「おお、止まった。便利なものを作ってくれたなあ」当たり前です。もう止まっていたのですから。
 その人は、事故が起こったのは前日であって、すでに私が止めていたということには気付かなかったようです。そして、メーリングリストを緊急停止させたら全員にメールが配信されなくなってしまうのだから私に連絡しなければならないということにも思い至らなかったようです。さらに、緊急停止の案内ページに「停止したら必ずメーリングリスト管理者に連絡してください」と大きな文字で書いてあるのも、緊急停止した時にスクリプトによって英語で「<deo@gabacho-net.jp>に知らせよ」と出力されるメッセージも読まなかったようです。よほどあわてたのでしょうか。
 すぐに連絡を入れてくれていたなら、「それはあなたの勘違いです。以後気を付けてください」で済んだのですが、誰かが停止させてほったらしたことに気付いた時には、故意の運用妨害と思ってしまいました。

 ユーザーがシステムの知識の欠如で使い方を誤解するというミスは、起こっても不思議はないと思います。でも、いくらわかりやすいように説明しても読まないというユーザーのミスを防ぐためには、私はいったいどうしたらいいのでしょう。



(2002/03/10追記) 「ええい、これでもか!」という工夫をさらに思いつきました。緊急停止の案内ページにアクセスしたら自動的にメーラーを起動して連絡用の送信メールを用意するという仕掛けです。<HEAD>タグの後に次の例のようなMETAタグを入れればよいということがわかりました。Internet Explorer 6.0で動作確認済みです。

<META HTTP-EQUIV="refresh" CONTENT="0; URL=mailto:ml-admin@mydomain.jp?Subject=I stopped the mailing list.">

 これによって次に予想されるトラブルは、メーリングリストを停止していないのに連絡メールを誤送信することです。しかし、停止したのに連絡しないというトラブルよりはましです。

目次 ホーム