debian-squeeze-kfreebsd-amd64 sendmailからpostfixへ

※実際には10/10のネタです。

■kfreebsd-amd64カーネルDebian Squeezeにsendmailを導入したが、
 syslogにSTARTTLSのエラーが出ていた。
 送信自体に影響は無いが、デーモンの再起動をする度、
 読み込み失敗のタイムアウトを待っている(ログ上では23)なので、精神衛生上良くない。

$ tail -f /var/log/syslog | grep "Error"
Oct 9 22:40:01 kfreesqueeze sm-msp-queue[7873]: STARTTLS: Error: missing random file definition
Oct 9 22:44:24 kfreesqueeze sm-mta[8049]: STARTTLS: Error: missing random file definition

■telnet localhost 25で確認するも、250-STARTTLSは見つからなかった。

ehlo localhost
250-kfreesqueeze.bsd.vm Hello localhost [127.0.0.1], pleased to meet you
250-ENHANCEDSTATUSCODES
250-PIPELINING
250-EXPN
250-VERB
250-8BITMIME
250-SIZE
250-DSN
250-ETRN
250-AUTH DIGEST-MD5 CRAM-MD5
250-DELIVERBY
250 HELP
quit

■ランダムファイルの定義が見当たらないとの事。

$ ls -l /dev/*random
crw-rw-rw- 1 root root 0, 6 Oct 10 18:20 /dev/random
lrwxr-xr-x 1 root root 6 Oct 10 18:20 /dev/urandom -> random

■/dev/urandomがシンボリックリンクなのは、FreeBSDのお作法の様子。

http://ja.wikipedia.org/wiki//dev/random

■EGDを使うか、chroot環境で/dev/random、/dev/urandomを別に作るかだが、
 そもそもSTARTTLSを使っていない。

http://www.sendmail.org/~ca/email/starttls.html

■confRAND_FILEをsendmail.mcに指定、m4と再読み込みをすると、不適切だというエラーが出る。
 これではEGDを使えばどうにかなるとも思えない。

☆define(`confRAND_FILE', `/dev/urandom')dnl
$ sudo tail -f /var/log/syslog | grep STARTTLS | cut -c 16- | sed s/":"/"\n"/g
kfreesqueeze sm-mta[16651]
STARTTLS
Error
no proper random file definition /dev/random
kfreesqueeze sm-msp-queue[16658]
STARTTLS
Error
missing random file definition

☆define(`confRAND_FILE', `/dev/random')dnl
$ sudo tail -f /var/log/syslog | grep STARTTLS | cut -c 16- | sed s/":"/"\n"/g
kfreesqueeze sm-msp-queue[16686]
STARTTLS
Error
missing random file definition
kfreesqueeze sm-mta[16752]
STARTTLS
Error
no proper random file definition /dev/urandom

■同様の症状でバグ報告があった。しかし古い(May 05, 2006; 10:30am)上に、回答もないようだ。

http://old.nabble.com/Bug-366087%3A-sendmail%3A-should-define-HASURANDOMDEV-on-GNU-kFreeBSD-td4240053.html

■コンパイルオプションを確認

$ /usr/lib/sendmail -bt -d0.1
Version 8.14.3
Compiled with: DNSMAP LDAPMAP LDAP_REFERRALS LOG MAP_REGEX MATCHGECOS
MILTER MIME7TO8 MIME8TO7 NAMED_BIND NETINET NETINET6 NETUNIX
NEWDB NIS NISPLUS PIPELINING SASLv2 SCANF SOCKETMAP STARTTLS
TCPWRAPPERS USERDB USE_LDAP_INIT XDEBUG

============ SYSTEM IDENTITY (after readcf) ============
(short domain name) $w = kfreesqueeze
(canonical domain name) $j = kfreesqueeze.bsd.vm
(subdomain name) $m = bsd.vm
(node name) $k = kfreesqueeze
========================================================

ADDRESS TEST MODE (ruleset 3 NOT automatically invoked)
Enter <ruleset> <address>
> 3.0 bsd.vm
canonify input: bsd . vm
Canonify2 input: bsd . vm
Canonify2 returns: bsd . vm
canonify returns: bsd . vm
> 3.0 kreesqueeze.bsd.vm
canonify input: kreesqueeze . bsd . vm
Canonify2 input: kreesqueeze . bsd . vm
Canonify2 returns: kreesqueeze . bsd . vm
canonify returns: kreesqueeze . bsd . vm
> 3.0 labunix@kfree.bsd.vm
canonify input: labunix @ kfree . bsd . vm
Canonify2 input: labunix < @ kfree . bsd . vm >
Canonify2 returns: labunix < @ kfree . bsd . vm >
canonify returns: labunix < @ kfree . bsd . vm >
> ?
Help for test mode:
? :this help message.
.Dmvalue :define macro `m' to `value'.
.Ccvalue :add `value' to class `c'.
=Sruleset :dump the contents of the indicated ruleset.
=M :display the known mailers.
-ddebug-spec :equivalent to the command-line -d debug flag.
$m :print the value of macro $m.
$=c :print the contents of class $=c.
/mx host :returns the MX records for `host'.
/parse address :parse address, returning the value of crackaddr, and
the parsed address.
/try mailer addr :rewrite address into the form it will have when
presented to the indicated mailer.
/tryflags flags :set flags used by parsing. The flags can be `H' for
Header or `E' for Envelope, and `S' for Sender or `R'
for Recipient. These can be combined, `HR' sets
flags for header recipients.
/canon hostname :try to canonify hostname.
/map mapname key :look up `key' in the indicated `mapname'.
/quit :quit address test mode.
rules addr :run the indicated address through the named rules.
Rules can be a comma separated list of rules.
End of HELP info
>/quit

■ソースを読む。
 MSP中のSTARTTLSを切るかRandFileを指定する。。。と。

$ grep STARTTLS: -A 10 sendmail/SECURITY
STARTTLS: If sendmail is compiled with STARTTLS support on a platform
that does not have HASURANDOMDEV defined, you either need to specify
the RandFile option (as for the MTA), or you have to turn off
STARTTLS in the MSP, e.g.,

DAEMON_OPTIONS(`Name=NoMTA, Addr=127.0.0.1, M=S')
FEATURE(`msp')
CLIENT_OPTIONS(`Family=inet, Address=0.0.0.0, M=S')

The first option is used to turn off STARTTLS when the MSP is
invoked with -bs as some MUAs do.
■というかドキュメントにもあるし。
 MSPを使うというのは、smmspグループのユーザモードで起動することになるのか。

$ zcat /usr/share/doc/sendmail-cf/sendmail/SECURITY.gz | grep RunAsUser: -A 8
RunAsUser: FEATURE(`msp') sets the option RunAsUser to smmsp.
This user must have the group smmsp, i.e., the same group as the
clientmqueue directory. If you specify a user whose primary group
is not the same as that of the clientmqueue directory, then you
should explicitly set the group, e.g.,

FEATURE(`msp')
define(`confRUN_AS_USER', `mailmsp:smmsp')
■バグではないにせよ。。。
 要は、小さな変更で動くレベルではないということですね。
 ここでこれ以上の時間を取られるのも困るので、postfixに変更します。

■sendmailを止めてpostfixをインストール

$ sudo /etc/init.d/sendmail stop
$ ps -ef | grep sendmail | grep -v grep
$ sudo apt-get install postfix

$ ps -ef | grep postfix | grep -v grep
postfix 24360 24353 0 22:35 ? 00:00:00 qmgr -l -t fifo -u
postfix 24359 24353 0 22:35 ? 00:00:00 pickup -l -t fifo -u -c
root 24353 1 0 22:35 ? 00:00:00 /usr/lib/postfix/master

■telnetで確認。250-STARTTLSが居ますね。

$ telnet localhost 25
Trying 127.0.0.1...
Connected to localhost.
Escape character is '^]'.
220 kfreesqueeze.bsd.vm ESMTP Postfix (Debian/GNU)
ehlo localhost
250-kfreesqueeze.bsd.vm
250-PIPELINING
250-SIZE 10240000
250-VRFY
250-ETRN
250-STARTTLS
250-ENHANCEDSTATUSCODES
250-8BITMIME
250 DSN
quit

■10通のメールを出してみる。
 ※引数が無い場合は「$1」には何も入らないようにしているので、
  引数をつける場合、「" chars"」というように、はじめにスペースを入れる。

$ cat telnetmail.sh
#!/bin/sh -x

TDATE=`date '+%Y/%m/%d %H:%M'`
TFQDN=`hostname -f`
TUSER=`whoami`
PORT=25
THOST=`hostname -s`

(sleep 2; echo "EHLO ${THOST}";
sleep 1; echo "MAIL FROM: ${TUSER}@${TFQDN}";
sleep 1; echo "RCPT TO: ${TUSER}@${TFQDN}";
sleep 1; echo "DATA"
sleep 1; echo "From: MAIL ${TUSER} <${TUSER}@${TFQDN}>"
echo "Subject: mail from ${TUSER}$1"
echo "To: MAIL <${TUSER}@${TFQDN}>"
echo "${TDATE}"
echo "."
sleep 1; echo "QUIT"
sleep 1; echo; ) | telnet $TFQDN $PORT

$ for num in `seq -w 1 10`;do ./telnetmail.sh " $num / 10";done

■受信時の件名の後ろに付きます。

$ mail
Mail version 8.1.2 01/15/2001. Type ? for help.
"/var/mail/labunix": 10 messages 10 new
>N 1 labunix@kfreesque Mon Oct 10 22:42 15/637 mail from labunix 01 / 10
N 2 labunix@kfreesque Mon Oct 10 22:42 15/637 mail from labunix 02 / 10
N 3 labunix@kfreesque Mon Oct 10 22:43 15/637 mail from labunix 03 / 10
N 4 labunix@kfreesque Mon Oct 10 22:43 15/637 mail from labunix 04 / 10
N 5 labunix@kfreesque Mon Oct 10 22:43 15/637 mail from labunix 05 / 10
N 6 labunix@kfreesque Mon Oct 10 22:43 15/637 mail from labunix 06 / 10
N 7 labunix@kfreesque Mon Oct 10 22:43 15/637 mail from labunix 07 / 10
N 8 labunix@kfreesque Mon Oct 10 22:43 15/637 mail from labunix 08 / 10
N 9 labunix@kfreesque Mon Oct 10 22:43 15/637 mail from labunix 09 / 10
N 10 labunix@kfreesque Mon Oct 10 22:44 15/637 mail from labunix 10 / 10

■ログ解析のpflogsummも導入。
 基本的に、smaも「/var/log/mail.log」を取り込んでいるだけなので、
 どっちでも良さそうですが、sendmailの場合、「stat=Sent」になるのに対し、
 postfixだと、「status=sent」になるという違いがあります。
 という事でしばらくは両方とも動かします。

$ sudo apt-get install pflogsumm

$ cat pflogsumm_report
#!/bin/bash
MAILLOG=`mktemp`
for log in `ls /var/log/mail.*|sort -r`;do
cat $log >> $MAILLOG
done
REPORT=`mktemp`
pflogsumm --problems_first --verbose_msg_detail --mailq -d yesterday $MAILLOG > $REPORT
cat $REPORT | mail -s "`head -1 $REPORT` in `uname -n`" postmaster
rm -f $MAILLOG $REPORT

■root権限が無いと、「/var/log/mai.*」は読めないので。
 初回実行と1時間置きの実行が済んで落ち着いたら、「/etc/cron.dairy」に移動します。
 sma同様、「crontab」に書いても良いですが、
 smaの設定があるcrontab の設定は消す方針なので、間違えて消さないようにということで。

$ sudo chown root:root pflogsumm_report
$ sudo chmod 700 pflogsumm_report
$ sudo cp -pi pflogsumm_report /etc/cron.hourly/
$ sudo ./pflogssumm_report

■追記

以前に書いたので、割愛しますが、postfixでSTARTTLSが使えるように設定しても、
「random file」のエラーはありませんでした。
デフォルトの自己証明書でも、作成した自己証明書でも。。。

debian-lenny amd64版でも問題無いので、kfreebsd-amd64版だけの問題かな。。。