sendmail には、 コンパイル時にのみ指定できる FFR (For Future Release) オプション での追加機能があります。 新しいバージョンでは正式機能に昇格しているものもあります。
$Id: sendmail_ffr.html,v 1.3 2009-12-22 11:49:35+09 kabe Exp $
まずソースのdevtools/Site/site.config.m4
に、
必要な -D
コンパイル引数を書き込みます。
... APPENDDEF(`conf_sendmail_ENVDEF', `-D_FFR_BLOCK_PROXIES -D_FFR_TLS_1') ...
あとは普通に cd sendmail; sh ./Build -c にてコンパイル。
コンパイル済の sendmail などは、-d
デバッグオプションで
設定を吐かせます。
sendmail/conf.c に個別に記載が必要なので全部出てくる保証はないですが、
大抵は大丈夫でしょう。
% sendmail -bt -oQ/dev/null -d0.13 < /dev/null | grep FFR FFR Defines: _FFR_BLOCK_PROXIES _FFR_TLS_1 % _
HTTPのproxy要求に見えるものを拒否します。 HTTP proxy経由でむりやり接続しようとした際に発生します。
% telnet 127.0.0.1 25 Trying 127.0.0.1... Connected to localhost4. Escape character is '^]'. 220 mail.host.name ESMTP mail GET http://www.yahoo.com/ HTTP/1.0 421 4.7.0 mail.host.name Rejecting open proxy localhost4 [127.0.0.1] Connection closed by foreign host. % _
Sendmail 8.14.0 では正式対応。
SSL (STARTTLS) 機能を強化します。
SSLv2 を無効にするための
CipherList
オプションを使うために必要。
紛らわしいですが、 SSLv3/TLSv1 はこの FFR をつけなくても
使えます。
O CipherList=cipherlist
O DHParameters512=param
TLSSrvOptions
オプション文字に C
が使えるようになります。自分側のサーバー証明書の設定が無しでも
設定エラーにしません。(何に使うんだ?)
sendmail.cf: O CipherList=DEFAULT:!SSLv2:!MD5
設定する文字列は openssl ciphers
(1) を参照。
なお、sendmail.mc
の専用defineは無いので、
*.mc に入れたいなら地で直接書く (とsendmail.cfでは変な場所に入る)
か、
sendmail.mc: define(`confSERVER_KEY', `/etc/mail/server.key # CipherList support needs -D_FFS_TLS_1 in devtools/Site/site.config.m4 O CipherList=DEFAULT:!SSLv2:!MD5 ')dnlのような姑息な書き方が必要。
無効証明書の検査のための、単一ファイルの
O CRLFile=
に加え、
ハッシュディレクトリ O CRLPath=/usr/ssl/crl.d
を使えるようにします。OpenSSL 0.9.7以降が必要。
/* Turn all errors into temporary errors */
O SoftBounce=True
オプションを追加。
5xx 5.x.x ステータスを返すところを、問答無用で
4xx 4.x.x ステータスに書き換えます。
Sendmail 8.14.0 では正式対応。
/* runtime option for "MaxNOOPCommands" */
O MaxNOOPCommands=20
を追加します。
NOOPとVERBが発行された回数を数え、デフォルトは20回となっている
攻撃緩衝ロジックの回数を調整できます。
Oct 22 17:17:10 mail sendmail[1000]: n9M8GtSJ001000: localhost6 [IPv6:::1]: possible SMTP attack: command=NOOP, count=20
Sendmail 8.14.0 では正式対応。
FEATURE(`greet_pause', `5000') で SMTPバナーの
遅延をかけているとき、クライアントが待たずに何秒後に喋りだしたかを
ログに記録します。
1秒単位、四捨五入。
計時のための gettimeofday(2) は軽くないシステムコールなので、
デフォルトでは計時しない模様。
Sendmail 8.14.0 では正式対応。
/* deliver first TA in background, then queue */
O DeliveryMode=o
を使えるようにします。
SMTPで受信している複数の宛先のメールについて、1人目は即配送、
2人目以降はqueueに取り込んで遅延配送します。
DeliveryMode
(d) は
i
(即配送、デフォルト),
q
(一旦queueに取り込む) などに設定できますが、
o
にすると1人目は i
,
2人目以降は q
動作になります。
大量配信メーリングリストはqueueに取り込んでバッチ配送、
通常の一対一メールは即配送、という設定ができる。
サーバ全体に対する設定なので注意。(alias毎の設定ではない)
SMTP受信用ポートとして、TCPではない UNIX ソケットを使えるようにします。 F[amily]=local を指定します。
O DaemonPortOptions=Name=MTA-local, Family=local, Addr=/var/run/submit.sock
単独ではあんま用途ないですが、 127.0.0.1:25へのbindもしたくないとか、 そもそも TCP/IP スタックを持ってないとか、 milterを重ねるような使い方で有用?
SMTP DATA 受信後の、
250 2.0.0 qUEuE1D Message accepted for delivery
のメッセージ部分をカスタマイズできるようにします。
デフォルトはO MessageAccept=$&i Message accepted for delivery
相当。
-D_FFR_MAX_SLEEP_TIME=86400
などとすると、
内部で使われる sleep()にこれを超える値が渡された際に
警告ログを出します。(sleep動作は行われる。)
GreetPauseに外部マップなどを使用していて、おかしな値が来る可能性の
ある時などの保険やデバッグ用と思われます。
RunAsUser と DefaultUser オプションの読み込み時に、
ユーザ名にドットが入っている場合に対応。
デフォルトでは":"と同様、グループ指定との区切りになる。
(一般ユーザへの配送はこのFFRがなくても問題ない、はず)
あんまり O DefaultUser=sendmail.runner:smmsp
とかは
指定しないでしょうが、
devtools/OS/MPE-iX で指定があるのでそういうOSのためでしょう。
O RefuseLowMem=number
: これ以下の空きメモリでSMTP拒否
O QueueLowMem=number
: これ以下の空きメモリで即配送せずqueue投入
O MemoryResource=string
: 何の値を参照するか
この機能を使うためには、FFRの他に以下の #define (-DUSESWAPCTL=1など) が必要です。 OSによって自動選択とかは全くやってくれないので、 各自で調べて選んで site.config.m4 に書き込む必要あり。
USESWAPCTL
USEKSTAT
O MemoryResource=freemem
で、
kstat_data_lookup(3KSTAT) で取り出す値を指定できる。
デフォルトは "freemem"
USEPROCMEMINFO
O MemoryResource=SwapFree
あたりが適当?
ただ、UNIX系のOSでは空きメモリはディスクキャッシュに使われるので、 「空きメモリ」がほとんどない状態が正常です。 あんまり役に立たないかも。
O PrivacyOptions=noactualrecipient
を使えるようにします。
エラーメールに X-Actual-Recipient: ヘッダを追加しません。
Sendmail 8.14.0 では正式対応。
O HeloName=helo.host.name
オプションを追加。
HELOで名乗るホスト名を明示できます。
(sendmail 8.14.0では正式機能に昇格)
メール送信時、メッセージ長が 宛先サーバの EHLO 応答の SIZE 値より大きかったら 送信をあきらめます。 (つまりデフォルトではSIZEは見てない。) 巨大電文を無駄に送ってしまうのを避けられます。
** NOTE: _FFR_CLIENT_SIZE is untested.とあるので、実験段階?
EHLO ではない素の HELO で、SMTPオプション応答があった場合に ログに記録します。 昔のsendmailとかで複数行のSMTPバナーを出している相手の検出用?
配送完了時だけでなく、配送試行毎に ", ntries=回数" の ログを出力します。 配送エラー率の高い宛先の状況を見るのに有用かも。 (Y!Jとか…)
SMTP の DATA送信時、まだ終了の ".\r\n"
を送っていないのに
MTAが何らかのステータスを返してきたら、ステータス値にかかわらず
エラー扱いします。
電文の終了をちゃんと確認しない他MTAの検出用と思われますが、 変な他MTAのデバッグ用か。 実用性は不明。
queueを処理するときは、通常は頭から順番に (場合によっては何個かおきに) 処理しますが、 メッセージ単位ではなく宛先ドメイン単位で数えます。 特定の宛先ドメインに大量のメールが滞留する場合に、 他の宛先まで遅延してしまうのを緩和できる、かもしれない。
複数のメールを queue に投入するときは、宛先のホスト名で 並べ替えた順で投入しますが、 ホスト名の末尾からの比較で並べ替えるようにします。 つまり *.co.jp 宛が隣同士になる。 配送性能のチューニングに使えそうですが、
/* XXX maybe compare hostnames from the end? */なので、効果のほどはさだかではないかも。
通常、queueファイルは RunAsUser (smmspなど) の所有で、 それ以外のownerになっていると色々な警告が出ますが、 aliases の加工などを行う TrustedUser の所有では警告しないようにします。 TrustedUser が滞留 queueの出し入れをするなど、 直接に操作することを想定。
DATAの受信後、check_eom
ルールセットを起動します。
引数: メッセージ長
MaxMessageSize による制限チェックの後に起動されます。
Sendmail 8.14.0 では正式対応。
$&{mail_from}
マクロを使えるようにします。
要するに envelope from ですが、$&f
と違い
SMTPのMAIL FROM: の値がそのまま参照できます。
(毒入りの可能性があるので注意!)
aliases を索く際、map指定にて %0 はユーザ名に置換されますが、 %1 をホスト名に置換できるようにします。 LDAPでaliasesを索くときに役に立つかもしれません。
-D_FFR_LDAP_VERSION=3
で
LDAPの接続プロトコルバージョンのデフォルト値を指定。
ldap mapでバージョン指定 -w3
を
毎回明示したくない場合、とか。
** The LDAP database map code in Sendmail 8.12.10, when ** given the -1 switch, would match only a single DN, ** but was able to return multiple attributes for that ** DN. In Sendmail 8.13 this "bug" was corrected to ** only return if exactly one attribute matched.
sendmail 8.12.10 のLDAP索きバグの互換動作。
LDAPを索いた際、(同一属性名で)複数マッチをさせず
値が1つだけ欲しいときは ldap map の-1
オプションを
使いますが、
8.12.10 では 単一の dn: からは複数返すことができました。
この旧動作が欲しい、dn: をまたぐものは欲しくない、
という場合に、この FFR を入れると -2
オプションが
使えるようになります。
O Milter.macros.maxdatasize=65535
オプションを追加。
milterへ書き出すバッファの最大長を調整します。
デフォルトは 65535。
O MaxForwardEntries=0
オプションを追加。
.forward
の転送先の数を制限します。
デフォルトは 0 (制限無し)
DSN (エラーメール、差出人が<>) の宛先が alias で、 owner-recipient のaliasも存在する場合は、 メンバーに配信せず owner- に配送します。
DSN (Delivery Status Notification) が通常のメーリングリストに 届くことはない、はず、です。 メーリングリストなら必ず owner-listname: の aliasも作ってあるはずので、 配信時は差出人は owner- に書き換わっており、 エラーは owner- に戻るはず。
素のlistnameに差出人が空のメールを出すのは spamだけだと想定し、配信しない、と。
配送メーラー起動時に、 setsid(2)+setlogin(2) にて 制御端末をsendmailから切り離します。 全メーラーに適用。
O DaemonPortOptions=DeliveryMode=[qdib]
が使えるようにします。
daemon毎に、DeliveryMode
が変更できます。
Sendmail 8.14.0 以降は正式対応。
なお _FFR_DM_ONE を定義しても o
は使えません。
(sendmail/daemon.cをちょこっと改造すればOK)
Sendmail 8.14.2 では正式対応。
O DaemonPortOptions=T=[ip]
で、
Daemon毎に O SuperSafe
オプション相当が指定できます。
"S"
は SndBufSizeSize として使われているので、
"T"
で指定。
Interactive と PostMilter だけが指定できます。
O DeliveryMode=i[nteractive]