PostfixとMailmanを使ってバーチャルドメインでメーリングリストを管理する

引っ越し予定のサーバでは、fmlを使ってメーリングリストを管理していた。メーリングリストのメールアドレスは、普通のメールアドレスと同じドメインで運用していたので、このままだとGoogle Appsに移行するのが面倒だ。そこで、メーリングリスト用に専用ドメインを用意して、バーチャルドメインメーリングリストを管理することにした。
MTAはPostfixを使うので、Postfixのバーチャルドメインに対応しているメーリングリストドライバとしてGNU Mailmanを使うことにする。FreeBSDメーリングリストにも使われてるので、実績も十分だし安心そう。

インストール

portsで一発。mail/mailman

バーチャルドメイン

PostfixMailmanでバーチャルドメインを実現する方法は、6.1.2 Virtual domainsに書いてある。ただ、この方法だとmlname@ml.example.comをmlname@localhostに配送してから、mailmanコマンドを実行してメーリングリストの処理を行うことになる。何が気になるかというと、メーリングリスト名のローカルアカウントを使うこと。せっかくバーチャルドメインにしてるんだから、ローカルアカウントとメーリングリスト名の重複を気にするのは面倒だ。
というわけで、代替案としてPostfix and Mailman Integrationというスクリプトを見つけた。これならローカルアカウントを汚染せずにメーリングリストを処理できる。仕組みとしては、relay_domainsを使って@ml.example.comを受け付けた後、transport_mapsを使ってこのスクリプトにメールを渡し、メーリングリストの処理を行うというもの。

Postfix to Mailmanの設定

postfix-to-mailman-2.1.pyをダウンロードして、/usr/local/mailmanに設置する。スクリプト中のpythonのパス、MailmanHomeとMailmanOwnerを適切に変更して、実行権限を付与する。

# cp /some/where/postfix-to-mailman-2.1.py /usr/local/mailman
# chmod 755 /usr/local/mailman/postfix-to-mailman-2.1.py
# vi /usr/local/mailman/postfix-to-mailman-2.1.py

以下を適切に書き換える

#! /usr/bin/env python

MailmanHome = "/var/mailman"; # Mailman home directory.
MailmanOwner = "postmaster@example.com"; # Postmaster and abuse mail recipient.

Postfixのtransportとして使えるように、master.cfに設定を追加する。

mailman   unix  -       n       n       -       -       pipe
  flags=FR user=mailman:mailman
  argv=/usr/local/mailman/postfix-to-mailman-2.1.py ${nexthop} ${user}

transport_mapsに使うmapを作成する。postmapするのを忘れずに。

# vi /usr/local/etc/maps/transport

ml.example.com    mailman:

# postmap /usr/local/etc/maps/transport

最後にmain.cfでrelay_domainsとtransport_mapsを指定する。

relay_domains = ml.example.com
transport_maps = hash:/usr/local/etc/maps/transport

postfix reloadして、mlname@ml.example.comにテストメールを送ってみよう。メーリングリストを作成することをお忘れ無く。

fmlによる既存メーリングリストの移行

メーリングリストの移行は、メンバー、アーカイブ、シーケンス番号を引き継げば問題ない。
メンバーはfmlのmembersとactivesから引き継ぐ。
アーカイブについては、fmlのアーカイブはMH形式、Mailmanアーカイブはmbox形式なので、packfなんかを使って変換する。
シーケンス番号は、fmlのseqで最終のシーケンス番号を確認してから、Mailmanのシーケンス番号を変更する。Mailmanのシーケンス番号は、これから付与されるシーケンス番号なので、fmlのseqに+1する必要があることに注意。以下は1281に変更した例。

# /usr/local/mailman/bin/withlist メーリングリスト名
Loading list LIST (unlocked)
The variable `m' is the LIST MailList instance
>>> m.Lock()
>>> m.post_id
1.0
>>> m.post_id = 1281
>>> m.post_id
1281
>>> m.Save()
>>> (Ctrl +Dを入力)
>>> (Ctrl +Dを入力)
Unlocking (but not saving) list: LIST
Finalizing