%%Title: sendmail の使い方

%%Created: Wed Aug 20 12:00:00 JST 1997
%%Updated: Fri Sep 29 12:00:00 JST 2000

巷では sendmailが使いにくいと評判なんだけど、なんでだろう?
FreeBSDやNetBSDでは /usr/share/sendmailの下にドキュメントいっぱいあるし、
M4で設定も簡単にできるから、評判ほど使いにくいとは思わないけどなぁ。
ドキュメントが日本語化されてないから?

  1. milterを使う
  2. sendmail.8.11.1
  3. sendmail.8.9.1 / sendmail891+3.1W.patch
  4. sendmail.8.8.7 / sendmail.8.8.7+2.7Wbeta7.patch
  5. sendmail.8.8.7 をインストールするための準備
  6. sendmail.cfの設定
  7. CFによるsendmail.cfの設定
  8. sendmailのオプション


o milterを使う
	http://www.sendmail.com/partner/resources/development/milter_api/api.html

	libmilter/READMEをさくっと読む
	devtools/Site/site.config.m4 に以下を定義する
	APPENDDEF(`conf_sendmail_ENVDEF', `-DMILTER')


o sendmail.8.12.0
	INSTALLをさくっと読む。

	IPv6喋らすには以下を devtools/Site/site.config.m4 に定義しとく。
	define(`confENVDEF', `-DNETINET6')

	sh Build で make する。


o sendmail.8.11.1
sendmail と WIDE版パッチは、例えば
	ftp://ftp.kyoto.wide.ad.jp/sendmail/
	から拾って来る。

	ディレクトリ構成が変わった
		:
	% cd sendmail-8.11.1/sendmail
		:

	FreeBSD4.2-RELEASEで使うと
		mail.local: lockmailbox /var/mail/user2 failed; error code 75
	ってエラーがでて mqueueには溜るけど /var/mail に書き込んでくれない。

	http://www.jp.FreeBSD.ORG/QandA/HTML/1729.htmlを参照。
	要するに CFに以下を足す。

		LOCAL_MAILER_FLAG_ADD='S'


o sendmail.8.9.1 / sendmail891+3.1W.patch
	% gunzip -c /var/tmp/sendmail.8.9.1.tar.gz | tar xvf -
	% cd sendmail-8.9.1/src
	% gunzip -c /var/tmp/sendmail891+3.1W.patch.gz | patch -p1
	まず、../READ_ME, READ_ME, RELEASE_NOTES.WIDE を適当に読む。
	% sh Build
	% cd obj.FreeBSD.2.2.7-RELEASE.i386
	% make install BINDIR=/usr/local/sbin UBINDIR=/usr/local/bin \
			MANROOT=/usr/local/man/cat HFDIR=/usr/local/share/misc


o sendmail.8.8.7 / sendmail.8.8.7+2.7Wbeta7.patch
	以降の作業は全て /var/tmp/sendmail 以下で行うとする。
		% mkdir /var/tmp/sendmail

	- いずこから sendmail と WIDE版パッチを拾ってくる。
	例えば、
	  ftp://ftp.kyoto.wide.ad.jp/sendmail/sendmail.8.8.7.tar.gz
	  ftp://ftp.kyoto.wide.ad.jp/sendmail/sendmail.8.8.7+2.7Wbeta7.patch.gz

	% cd /var/tmp/sendmail
	% gunzip -c sendmail.8.8.7.tar.gz | tar xvf -
	% cd sendmail-8.8.7/src
	% patch -p1 < ../../sendmail.8.8.7+2.7Wbeta7.patch
	res_close() が2重定義されてると怒られるので、変更を加える。
	正しい解決方法は不明。

	% sh Patch-makefiles
	まず、../READ_ME, READ_ME, RELEASE_NOTES.WIDE を適当に読む。
	プラットフォームに合った Makefile を編集する。
	例えば Sun の場合
	% vi Makefiles/Makefile.SunOS
		を編集。
		DBMDEF= -DNEWDB 
		ENVDEF= -DNEEDPUTENV=2                 <-- SunOS4.1.x はsetenv(3) が無いので
		BINDDIR=../../../bind-4.9.3
		NEWDBDIR=../../../db.1.85/PORT/sunos.4.1.4
		LIBS=   -ldb -lresolv -l44bsd
	% sh makesendmail clean
	% sh makesendmail
	% cd obj.SunOS.4.1.4.sun4
	% mv /usr/lib/sendmail /usr/lib/sendmail.orig  <-- 必要ならば
	% sh makesendmail install

	makemap を作る。
	% cd makemap
	% ln -s ../src/safefile.c .
	% ln -s ../../db.1.85/PORT/sunos.4.1.4/include .
	% ln -s ../../db.1.85/PORT/sunos.4.1.4/include sys
	% cc -I../src -I./include -DNEWDB -DNOT_SENDMAIL -O -c safefile.c
	% cc -I../src -I./include -I. -DNEWDB -DNOT_SENDMAIL -O -c makemap.c
	% cc -O -o makemap makemap.o safefile.o -ldb


o sendmail 8.8.7 を作るための準備
	以降の作業は全て /var/tmp/sendmail 以下で行うとする。
		% mkdir /var/tmp/sendmail

	- groff を入れる。
		マニュアルが作れないだけなので、飛ばしてもよし。

	- New Berkeley DB パッケージを突っ込む
		馬鹿でかい alises を使っていると処理が早くなるらしい。
		SunOS 4.1.4 で NDBM を使って sendmail を make すると
		NEWDB を使えと言われた。これ以上の深入りはしてないです。(^^;

	
	- いずこから db.1.85 を拾って来る。
		例えばftp://vortex.ce.nihon-u.ac.jp/pub/network/sendmail/db.1.85.tar.gz

		% cd /var/tmp/sendmail
		% gunzip -c db.1.85.tar.gz | tar xf -
		% cd db.1.85/PORT
		% ln -s sunos.4.1.1 sunos.4.1.4
		% cd sunos.4.1.4
		% make
		% cp lib44bsd.a /usr/lib
		% ranlib /usr/lib/libdb.a

	- lib44bsd.a と libresolv.a を作る。
		sendmail を make する際に、__dn_skipname が無いと怒られたので。

	- いずこから bind を拾ってくる。
		今回は
		ftp://ftp.kyoto.wide.ad.jp/pub/bind/4.9.3/bind-4.9.3-REL.tar.gzを使用。

		% cd /var/tmp/sendmail
		% gunzip -c bind-4.9.3.tar.gz | tar xf -
		% cd bind-4.9.3/compat/lib
		% make
		% cp lib44bsd.a /usr/lib
		% ranlib /usr/lib/lib44bsd.a
		% cd ../../res
		% make
		% cp lib44bsd.a /usr/lib
		% ranlib /usr/lib/lib44bsd.a


o sendmail.cfの設定
	${CFDIR}/README をよく読むべし
	(FreeBSDの場合は /usr/share/sendmail/cf/README)

	基本的には設定ファイル hoge.mc を作って
		# m4 ${CFDIR}/m4/cf.m4 hoge.mc > hoge.cf
	として hoge.cf を作る。これを新しい sendmail.cf として使う。

	FreeBSDの場合は /etc/mail の下に hoge.mc を作って、
		# make hoge.cf

	access, mailertable, accesstableを変更したら/etc/mail で make する。
		# make maps
	Makefileの中では
		# makemap hash /etc/mail/access < /etc/mail/access
	とかしている。
	sendmailを restartする必要なし。

	以下設定例

	- dnl は無駄な改行を省きたい場合に使う。

	- v6/v4両方使うには
		DAEMON_OPTIONS(`Name=MTA-v4, Family=inet')
		DAEMON_OPTIONS(`Name=MTA-v6, Family=inet6')

	- サーバのホスト名に別名がある場合
		FEATURE(`use_cw_file')
		を定義して /etc/mail/local-host-names に別名を列挙する。
		ファイル名を変えたい時は以下のようにする。
		define(`confCW_FILE', `-o /etc/mail/local-host-names')
	
	- Message Submission Agent(RFC2476)を使わない
		FEATURE(`no_default_msa')

	- smtp relay の設定。デフォルトは禁止。
		mc に
			FEATURE(`access_db', `hash -o /etc/mail/access')
		と書いて、/etc/mail/accesss には以下のように書いとく。

			2001:200:101                    RELAY

		すると、200:200:101 からのメールは配送可能になる。
		第2引数の意味は以下の通り。詳しくはREADMEを読むべし。
			RELAY		配送許可
			REJECT		受信不可
			ERROR:"hage"	hageとメッセージを出力する。

	- envelope from を使ったアクセス制御
		mc に
			FEATURE(`access_db', `hash -o /etc/mail/access')
			FEATURE(`relay_mail_from')
		と書いて、/etc/mail/accesss には以下のように書いとく。

			From:sakane@ydc.co.jp	RELAY

		すると、メールヘッダ(SMTPヘッダじゃない)が

			From: 

		なメールは転送可になる。

	- envelope from に書かれたドメインが存在しなくてもメールを受け付けるには
		FEATURE(`accept_unresolvable_domains')

	- 転送等の設定は mailertable を編集する。
		mc に
			FEATURE(`mailertable', `hash -o /etc/mail/mailertable')
		と書いて、/etc/mail/mailertable には以下のように書いとく。

			wide.ydc.co.jp          local:

			Feb  5 12:04:23 papa sendmail[393]: g15343c00387: SYSERR(root): MX list for tanu.org. points back to papa.tanu.org

		とか怒られるのは mailertable に tanu.org が無いから。

	- To:やCc:フィールドがない場合の制御
		To: undisclosed-recipients:; を追加する。
		define(`confNO_RCPT_ACTION', `add-to-undisclosed')

	- 基本的な mc
		
		VERSIONID(`$Id: nymph.mc,v 1.3 2001-07-02 12:24:09+09 sakane Exp $')
		OSTYPE(`bsd4.4')dnl
		DOMAIN(`generic')dnl
		FEATURE(`access_db', `hash -o /etc/mail/access')
		FEATURE(`blacklist_recipients')
		FEATURE(`local_lmtp')
		FEATURE(`mailertable', `hash -o /etc/mail/mailertable')
		FEATURE(`relay_based_on_MX')
		FEATURE(`virtusertable', `hash -o /etc/mail/virtusertable')
		DAEMON_OPTIONS(`Name=MTA-v4, Family=inet')
		DAEMON_OPTIONS(`Name=MTA-v6, Family=inet6')
		define(`confCW_FILE', `-o /etc/mail/local-host-names')
		define(`confPRIVACY_FLAGS', ``authwarnings,noexpn,novrfy'')
		define(`confNO_RCPT_ACTION', `add-to-undisclosed')
		define(`confMAX_MIME_HEADER_LENGTH', `256/128')
		MAILER(`local')
		MAILER(`smtp')
		

	- accesstable の例
		
		% cat /etc/mail/access
		From:sakane@ydc.co.jp           RELAY
		ydc.co.jp                       RELAY
		2001:200:101                    RELAY
		3ffe:501:481d                   RELAY
		202.249.27                      RELAY
		

	- mailertableの例
		
		% cat /etc/mail/mailertable
		wide.ydc.co.jp          local:
		ydc.co.jp               smtp:mail.ydc.co.jp

		wide.ydc.co.jp 宛のメールは local spoolに貯める。
		ydc.co.jp 宛のメールは mail.ydc.co.jp へ転送する。
		


o CF-3.7Wpl2
	howto-CF.html

o CF-3.6Wbeta7
	howto-CF.html


o sendmail のオプション
	% man sendmail

	キューに溜ったメールの吐き方
	# sendmail -q

	キューディレクトリを指定して吐き出す方法
	# sendmail -OQueueDirectory=/export/backup-mine/mqueue.old -q


o sendmail の debug

	対話形式でデバッグできる。
	# sendmail -bs

	ログファイルの指定
	# sendmail -X /var/tmp/mail.log

	メールアドレスのテスト
	# sendmail -bt

	# sendmail -bD -C sendmail.cf
	-C	sendmail.cfを指定する。
	-bD	sendmail をフォアグランドで動かす。

o sendmail.cf の使い方

	※相当昔にメモったので、もう古いかも

コマンド		
	マクロ定義		Dx値				マクロxに値を設定する。
	クラス定義		Cc語1[語2[...]]			クラスcに語1[語2[...]]を設定する。
				Fcファイル			クラスcにファイルを読み込む。
	オプション設定		Oo値				オプションoに値を設定する。
	信頼するユーザ設定	Tユーザ1[ユーザ2[...]]		ユーザ1[ユーザ2[...]]を信頼する。
	優先順位設定		P名前=番号			名前の優先順位を指定する。
	メーラ定義		M名前,[フィールド=値]		メーラ名を定義する。
	ヘッダ定義		H[?mフラグ]名前:形式		ヘッダの形式を定義する。
	ルール・セットの設定	Sn				番号nのルール・セットを開始する。
	ルール定義		Rlhs rhs コメント		lhsパターンを rhs形式に書き換える。

マクロ
	Dコマンドを用いて定義される。
	マクロの前に$を付けて参照する。

	a	RFC822形式で表した発生日付
	b	RFC822形式で表した現在日付
	c	ホップカウント
	d	UNIXのctime形式で表した日付
	e	SMTPの初期メッセージ			De$j Sendmail $v ready at $b
	f	発信者のfromアドレス
	g	受信者に相対的な発信者アドレス
	h	受信者のホスト
	i	待行列の識別子
	j	サイトの公式なドメイン名		Dj$w.$D
	l	UNIXのFrom行の形式			DlFrom $g $d
	n	エラーメッセージに使用される名前	DnMAILER-DAEMON
	o	アドレスの中で用いられる演算子の集合	Do.:%\@!^=/
	p	sendmailのプロセス番号
	q	デフォルト発信者アドレスの形式		Dq$g$?x ($x)$.
	r	使用されたプロトコル
	s	発信者のホスト名
	t	現在時の数値表現
	u	受け取るユーザ
	v	sendmailのバージョン番号
	w	このサイトのホスト名
	x	発信者の氏名
	z	受信者のホームディレクトリ

パターン表現
	$*	0個以上のトークンとマッチする。
	$+	1個以上のトークンとマッチする。
	$-	厳密に1個のトークンとマッチする。
	$=x	クラスxに属する任意のトークンとマッチする。
	$~x	クラスxに属さない任意のトークンとマッチする。
	$x	マクロxの中の全トークンとマッチする。

オプション
	Oコマンドを用いて定義される。

	Aファイル	aliasファイル名を定義する。
	aN		N秒間だけ @:@ を待ち、aliasファイルを再構築する。
	Bc		空白の置換文字を定義する。
	c		高価なメーラの待行列にメールを入れる。
	D		aliasのデータベースを再構築する。
	db		background modeで配送する。
	di		対話的に配送する。
	dq		次回の待行列の実行の時に配送する。
	ee		エラーメッセージを発信し、常に終了ステータスの0を返信する。
	em		エラーメッセージを返信する。
	ep		エラーメッセージをプリントする。
	eq		終了ステータスだけを返信し、エラーメッセージを発信しない。
	ew		エラーメッセージを書き戻す。
	Fn		temporaryファイルのモードをnにセットする。
	f		UNIXスタイルのFrom行を保持する。
	gn		メーラのデフォルトのグループ識別番号をnにする。
	Hファイル	SMTPヘルプファイル名を定義する。
	I		どのホスト名もBINDのネームサーバを使用して解決する。
	i		着信メッセージ内のドットを無視する。
	Ln		ロギングをnレベルにする。
	Mx値		マクロxに値を設定する。
	M		ホームネットワーク名を定義する。
	m		自分にもメールを送る。
	Nネット		ホームネット名を定義する。
	o		古い形式のヘッダを受理する。
	Qdir		待行列ディレクトリ名を定義する。
	qn		ジョブを待行列へ入れる時刻を決定する要素nを定義する。
	rt		読み取りのタイムアウト時間をtに設定する。
	Sファイル	統計のログファイル名を定義する。
	s		配送を試みる前に、常に待行列ファイルを作成する。
	Tt		待行列のタイムアウトをtに設定する。
	un		メーラのデフォルトのユーザ番号をnに設定する。
	v		冗長モードで実行する。
	Wワード		remote debug に使用されるパスワードを設定する。
	Xl		負荷平均(load average)がlを越えたら、SMTP接続を拒否する。
	xl		負荷平均(load average)がlを越えたら、メッセージを待行列へ入れる。
	Y		待行列にあるジョブを全て別々のプロセスで配送する。
	yn		全ての受信者のジョブの重要度をnだけ下げる。
	Zn		ジョブの実行のたびに、その重要度をnだけ下げる。
	zn		優先順位とともにメッセージの重要度を決定するために使用される因子

重要な記号
	Dq$g$?x ($x) $| ($y) $.
		D	マクロ定義コマンド
		q	定義するマクロ名
		$g	gに設定された値を参照すると言う意味
		$?x	マクロxに値が設定されているか検査する。 
			もし設定されていれば直後の文字が評価される。
		$|	else
		$.	条件区の終わりを意味する。

		例えば、
			Dgfoge@hage.com
			DxFOO
		ならば、
		Dq$g$?x ($x)$. の結果、$q は foge@hage.com (FOO) となる。
							  ↑
						ここに空白が入ることに注意。
	$[ホスト名$]
		ネームサーバへ渡して解決させる。
		例えば、
			$[[202.249.27.1]$]
		は、dclwide.dcl.co.jp と変換される。
	$>n
		ルールセットnに移行の文字を評価した値を渡す。	
		例えば、
			$>9$l%$2
		は、ルールセット9に、マクロlと文字%と$2の内容が渡される。
	$#error$:メッセージ
		ユーザへエラーメッセージを送信する。