Plan 9

メールサーバの設定

2009年10月20日更新

各種ファイルの設定

/mail/lib以下のファイルを書き換えます。

これらはuid=upas gid=upasなので、 upasグループに所属させておく。

smtpd.conf

smtpdの基本的な設定を書きます。 このうち、verifysenderdomは使われてないような。。

defaultdomain lufia.org
norelay on
verifysenderdom off
saveblockedmsg off
ournets xxx.xxx.xxx.xxx/xx
ourdomains wisp.lufia.org, lufia.org

rewrite(rewrite.directからコピーしたものを編集)

初期状態ではrewriteが存在しないので、 同じ場所にあるrewrite.directをコピーしてそれを書き換えます。 通常であれば、以下の部分だけ書き換えればいいと思います。

# your local names
\l!(.*)   alias   \1
\l\.lufia.org!(.*)  alias  \1
lufia.org!(.*)  alias  \1

上記の、\l\.lufia.org!(.*)は、\lがホスト名に置き換えられます。

names.local

これはエイリアスファイルです。 最初のカラムに別名を書き、次のカラムに転送するユーザ名を書きます。 無ければとくに変更は不要です。

postmaster	glenda
webmaster	glenda

remotemail

fd=lufia.org

/cron/upas/cron

mailserverとなっている部分を実際のサーバ名で置き換えます。 cronの書式はUnixとほとんど同じみたい。 cron.dailyみたいなものはありません。

# kick mail retries (replace mailserver with your system)
0,10,20,30,40,50 * * * *	wisp		/bin/upas/runq -a /mail/queue /mail/lib/remotemail

# clean up after grey list
47 4 * * *	wisp	rm -rf /mail/grey/tmp/*/*

テストして正しく送れていれば正解。

  • user→外部
  • 外部→user
  • 外部→webmaster

メールの転送

転送したいアドレスを/mail/box/$user/forwardに書きます。 1行目だけ有効で、複数に転送する場合は空白で区切って書き、 また、メールボックスにも残しておく場合は、local!$userを加えます。

glenda@anonymous.com local!glenda

スパム対策

Plan 9のsmtpdでは、グレーリスト法が使えます。 listen監視下のtcp25に、-gオプションを加えるだけです。 whitelistなど必要なファイルはインストール時において すでに作られているので、特に気にしなくても問題ありません。

#!/bin/rc
#smtp serv net incalldir user

user=`{cat /dev/user}
exec upas/smtpd -g -n $3

あとは、適当なフリーメールなどから送信テストして、 /mail/grey/x.x.x.x/y.y.y.y/$userが作成されていれば完了。 詳しくはスパム対策を参考に。

Outbound Port 25 Blocking

tcp!*!25とtcp!*!587でupas/smtpdが動いている状態を作ります。 また、SMTP Authが必要なので、smtpdに-aオプションを与えます。

% cat /cfg/$sysname/service/tcp587
#!/bin/rc
user=`{cat /dev/user}
exec upas/smtpd -a -g -n $3

serviceに実行権を付けたファイルを追加すれば、自動的に反映されます。 Plan 9サーバの再起動は必要ありませんし、起動コマンドも必要ありません。

送信者確認の流れ(メモ)

  1. upas/smtpdが/mail/lib/validatesenderをfork&exec
  2. validatesenderは、データを送らないモードでupas/smtpを実行
  3. 送信者メールアドレスが無効の場合、upas/smtpがエラーを返す

upas/smtpの中はだいたいこんな感じ

  1. ndb/dnsquery $domain mx => $hosts
  2. ndb/dnsquery ^ ($hosts) ^ ip => 見つからなければ$hostsから削除
  3. dial /net/tcp! ^ ($hosts) ^ !smtp

トラブルシューティング

外部から受信したメールがconnection timed outする

/sys/log以下のsmtpd, smtp.fail, smtpd.mxあたりに connection timed outが記録されている場合。

cpurcなどでndb/dns実行より前にlistenしてしまうと、 smtpdから見える名前空間に/net/dnsが存在しないため、 このようなエラーになることがあります。

この場合、/cfg/$sysname/cpurcで、 listenより先にndb/dnsを動かせばいいです。

当時、困ってた時のメモ。

デバッグのために、/mail/lib/validatesenderから呼ばれている upas/smtpに-dオプションを与えたかったが、 配布ファイルのためになるべく書き換えたくなかった。 これはbindすればごまかせる。

デバッグオプションを加えると、ログ(/sys/log/smtpd.mx)に

mxlookup returns nothing

というログが出る。

/proc/$smtpd/nsをみると、 /lib/namespaceから実行しているはずの mount -a /srv/dns /netが見当たらない。 でもbootesからは/srv/dnsが見える。 パーミッションは666なので問題ない。

IPアドレスで送受信できない

テストのとき、メールの開通確認が終わらないうちに DNSが新サーバを参照してしまうと困るので、 MXレコードには現行のサーバのIPのままにしておいて user@xx.xx.xx.xxのようにIPアドレスで直接テストしていたのですが、 smtpd.confのourdomainsにIPが登録されていなかったために /sys/log/smtpdにBad Forwardエラーが吐かれていました。 この場合、たぶんforwardにもIP直打ち規則を登録しないといけない。

/sys/log/cronに、upasの転送エラーが記録される

upas:  can't call mailserver: cs: can't translate service

/cron/upas/cronから、 mailserverとなっている部分をメールサーバ名に置き換えます。

smtpdを動かすつもりがないなら、runqの行を消すか、無効にする。 bootesからbind upascron /cron/upas/cronでも大丈夫。

whitelist.starterに追加しても反映されない

ソースを読んでも使われていないようなので、 直接whitelistに追加するといいかもしれません。 tip9ugメーリングリストはFreeMLを使っています。 その場合はこのように。

% cat >>/mail/grey/whitelist
210.157.23.0/24 *.gmo-media.jp
211.125.95.0/24 *.gmo-media.jp
^D