FreeBSD 4-STABLE と sendmail 8.12



FreeBSD 4.6-RELEASE にむけての作業が始まる 2002年3月25日、RELENG_4 ブランチの sendmail が 8.12 系列に置き換えられました。多くの Web サイトや雑誌記事にもあるようにこの 8.12 では sendmail の役割をネットワークデーモンとローカル配送(スプール書き込み)という2つに分割し、それに伴い定義ファイルの書式も変更になりました。

一応、これまでの sendmail 8.11.x 用のcf ファイルも利用できるということになっていますが、重要なのが sendmail バイナリそのものが setuid root されなくなったことです。これによりソースからコンパイルしたのではなく、make world によってバイナリのバージョンが上がった場合に、スプールのパーミッションやアカウントなどの準備が充分でないと sendmail が permission denied のエラーを出したり、場合によってはスプールに書き込めなくてメールをロストする危険性もあります。

/usr/src/UPDATING を一部要約すると(今日のひとことから転載)

sendmail を 8.12.2 に変えた(20020325 のところを見てください)ので sendmail を set-gid で動かすためのユーザとグループが必要になります。ですが、make installworld するときにその新しいユーザで /var/spool/clientmqueue の所有者とグループを設定する必要があります。つまり installworld するまえにそのユーザをあらかじめ作成しておかなければなりません。mergemaster -p という機能を使えばたぶんあなたが望む結果が得られるでしょう。ただし、古いバージョンからアップデートする場合、mergemaster を make しなおしておいてください。


たしかにこの注意事項も重要なのですが、ユーザ smmsp、グループ smmsp を作成しても、mergemaster で /etc/mail/sendmail.cf と /etc/mail/submit.cf という sendmail の定義ファイルが消されてしまうことがありました。

原因を深く追及できない私は結局 sendmail.8.12.3.tar.gz を anonymous FTP からとりよせソースを展開し、cf/cf ディレクトリにある generic-bsd4.4.mc ファイルをコピーして sendmail.mc ファイルを作成し、make sendmail.cf でファイルを作成しました。submit.mc ファイルは配布物に含まれているので、sendmail デーモンを smmsp ユーザで動かすための定義を加えて、make submit.cf としてファイルを作成します。

いずれのファイルもインストールする場所は /etc/mail ですので、root になり、必要なら現行ファイルのバックアップを取っておいてコピーします。



もう一つ重要なのが、sendmail の機能が2分割されたことで、ネットワークからのメールを受信するマシンでは2つデーモンを起動することになります。私の知る限り /stand/sysinstall や、これから生成される /etc/rc.conf などはまだこの手法に対応していないようです(そのうち変わるかもしれません)。確実を期するには、/stand/sysinstall(/etc/rc.conf)では sendmail を起動せず、/usr/local/etc/rc.d に sendmail を2つ起動する簡単なシェルスクリプトを置いておくとよいと思われます。



それでは、具体的な手順を追ってみましょう。2002/5/31 現在の sendmail の最新バージョンは 8.12.3 です。8.12.2 や 8.12.0 にはセキュリティホールが見つかっていますので、必ず最新版を使用します。FreeBSD の STABLE や CURRENT で利用している人は、バイナリの更新については心配する必要はありません。

アーカイブを取って来たら /usr/local/src にでもばらまきます。バイナリのコンパイルをするのであれば先にやっておいてください。あ、もちろん、uid 25, gid 25 は作ってからですよ。

では cf で定義を作ります。今回は、自身は PC の POP対応メーラとの通信を受け付けるサーバだが、配送経路の末端であり特殊な配送はしないとします。まず最初は cf/README に目を通しておきましょう。

ソースを展開したディレクトリ sendmail.8.12.3 の中の cf/cf ディレクトリに入ります。FreeBSD の場合には generic-bsd4.4.mc がありますから、これを sendmail.mc という名前にでもコピーして編集します。コメント部分を抜いて、一部ホスト固有の情報を伏せたものが以下のようになりました。
                                                                                
 1:divert(-1)
 2:
 3:divert(0)dnl
 4:VERSIONID(`$Id: generic-bsd4.4.mc,v 8.10 1999/02/07 07:26:02 gshapiro Exp $')
 5;OSTYPE(bsd4.4)dnl
 6:DOMAIN(generic)dnl
 7:FEATURE(`access_db', `hash -T<TMPF> -o /etc/mail/access')dnl
 8:FEATURE(`accept_unresolvable_domains')dnl
 9:FEATURE(`relay_mail_from')dnl
10:FEATURE(`nouucp',`reject')dnl
11:define(`confDOMAIN_NAME',`xxxx.xxxxxxxxxxxx.xx.jp')dnl
12:define(`LOCAL_MAILER_PATH', /usr/libexec/mail.local)dnl
13:define(`LOCAL_MAILER_FLAGS', LOCAL_MAILER_FLAGS`'SP)dnl
14:MAILER(local)dnl
15:MAILER(smtp)dnl

1〜6行目はそのまま。7行目は他のホストにメールを送るのに必要。8は自分でDNSの登録を忘れていた時に文句を言われないため(苦笑)。9はPCから外部へメールを送るのは転送になるので必要。10はuucpは使っていないので。11はなくても動くかもしれません。12・13が落とし穴で、これがないとローカルスプールのロックができなくてメールが受け取れません。

さらに、submit.mc も編集します。

                                                                                
 1:divert(-1)
 2:
 3:divert(0)dnl
 4:VERSIONID(`$Id: submit.mc,v 8.6 2002/03/26 03:30:58 ca Exp $')
 5:define(`confCF_VERSION', `Submit')dnl
 6:define(`__OSTYPE__',`')dnl dirty hack to keep proto.m4 from complaining
 7:define(`_USE_DECNET_SYNTAX_', `1')dnl support DECnet
 8:define(`confTIME_ZONE', `USE_TZ')dnl
 9:define(`confRUN_AS_USER', `smmsp')dnl
10:FEATURE(`msp')dnl
ほとんどこちらは変える必要はありませんが、9行目でローカルスプールに書き込むプログラムの実行ユーザを smmsp に指定しておきます。

これで
                                                                                
% make sendmail.cf
% make submit.cf
とやると sendmail.cf, submit.cf が生成されます。デバッグモードなどを使ってルールのテストをして、問題がなければ /etc/mail の下に配置します。

しかし、これではまだ配送ができません。

このホストが受け取るドメイン・アドレスを指定する local-host-names というファイルが /etc/mail に必要です。これは、例えばこのマシンが hoge.foo.jp だとして、このマシン自身と www.foo.jp と baz.bar.jp のアドレスを受け取りたいとすれば、
                                                                                
hoge.foo.jp
www.foo.jp
baz.bar.jp
のように、1つのあて先につき1行で書き込んでおきます。

さらに、メールのリレーを受け付けるアドレスを /etc/mail/access に記述します。たとえば、このメールサーバを利用する PC クライアントが 192.168.2.0/24 と 192.168.3.0/24 だとすれば、
                                                                                
127.0.0.1 RELAY
192.168.2 RELAY
192.168.3 RELAY
のように記述します。しかし、sendmail はこのファイルを直接参照はしません。指定アドレスが増えた時のためにハッシュ化されたテーブルを持って管理しています。テーブルの更新は、
                                                                                
# makemap hash /etc/mail/access.db < /etc/mail/access
を実行すればよいでしょう。

これでいよいよ起動します。まず、/etc/rc.conf で sendmail_enable="NONE" (注:NO ではだめ。二重起動してしまう)になっていることを確認しましょう(後優先ということを忘れずに)。で、手動であれば
                                                                                
/usr/sbin/sendmail -L sm-mta -bd -q15m
/usr/sbin/sendmail -L sm-msp-queue -Ac -q15m
上がネットワークデーモン、下がローカル用デーモンです。ローカルのスプール管理はデーモンとしてではなく cron で動かしてもかまいません。

では、動作したかどうか確認してみましょう。netstat -a で smtp に絡むタスクが2つあれば二重起動されています。rc.conf をチェックしてください。

                                                                                
% netstat -a | grep smtp
tcp4       0      0  *.smtp                 *.*                    LISTEN
% ps -ax | grep sendmail
  117  ??  Ss     0:00.29 sendmail: accepting connections (sendmail)
  120  ??  Is     0:00.04 sendmail: Queue runner@00:15:00 for /var/spool/client
  205  p0  R+     0:00.00 grep sendmail
% sockstat -4l | grep sendmail
root     sendmail   117    4 tcp4   *:25                  *:*
root     sendmail   117    5 tcp4   *:587                 *:*

メールの転送テストなどが完了すれば、自動で sendmail を起動するスクリプトを /usr/local/etc/rc.d/sendmail.sh とでもして用意します。

                                                                                
#!/bin/sh
case "$1" in
start)
        /usr/sbin/sendmail -L sm-mta -bd -q15m
        /usr/sbin/sendmail -L sm-msp-queue -Ac -q15m
        ;;
stop)
        kill `head -1 /var/spool/clientmqueue/sm-client.pid`
        rm -f /var/spool/clientmqueue/sm-client.pid
        echo -n " sendmail-smclient stopped. "
        kill `head -1 /var/run/sendmail.pid`
        rm -f /var/run/sendmail.pid
        echo -n " sendmail-mta stopped. "
        ;;
*)
        echo "Usage: `basename $0` {start|stop}" >&2
        exit 64
        ;;
esac

exit 0

あとは /var/log/maillog をよく注意してみておくことですね。うまくいったようでもチェック洩れは必ずあります。



参考にさせていただいたページ


● 梅本 さんの FreeBSD Press の記事 (http://www.imasy.or.jp/~ume/published/sendmail-milter/)

● fkimura さんの sendmail 8.12 の解説 (http://www.fkimura.com/sendmail-cf10.html)

● ksakai さんの解説 (http://www.kt.rim.or.jp/~ksakai/sendmail.html)

● MKPLAN の技術メモ (http://www.mkplan.net/kura/memo/FreeBSD/sendmail-8.12.0.html)

たいへん有用なドキュメントでした。ありがとうございます。



戻る