next up previous contents
Next: G.2.3 Other Setting Up: G.2 メイル環境の設計 Previous: G.2.1 sendmail.cf generator -

G.2.2 ハブホストに集中、内側は直接配送の設定

MX レコードに指定されたドメイン・マスターへ全てのメイルが届き、 それを内部へ 再配送する。内部から外部へメイルを送る場合は、 ドメイン・マスターへ送り、 ドメイン・マスターが外部へ配送を行う。内部配送の場合には直接 /etc/mail/aliases に従って配送を行う。
\epsfile{file=mail-relay}

この場合、ドメイン・マスターに届いたメイルは、ドメイン・マスターの sendmail.mx がローカルの aliases map を参照して適切なスプール・ホストに 再配送することになる。 従って、ドメインマスターの /etc/mail/aliases に各メンバーごとの aliases が 記述されていなければならない。

        # /etc/mail/aliases
        #    中略
        member01:member01@mail1.summer00.wakhok.ac.jp
        member02:member02@mail2.summer00.wakhok.ac.jp
        member03:member03@mail3.summer00.wakhok.ac.jp
        member04:member04@mail4.summer00.wakhok.ac.jp
        ...

用意すべき sendmail.cf は、ドメインのマスター用と その他の内部用の2種類です。

m4 での cf の書き方の基本は、

VERSIONID
OSTYPE
DOMAIN
FEATURE
ローカルなマクロの定義、再定義
MAILER
LOCAL_RULE_*
LOCAL_RULESETS

の順になっています。特に、MAILER は必ずこの位置になければなりません。 一方、マクロの定義では、FEATURE の前になければ(FEATUREで利用されるような場合) ならない場合もあります。一般的には、FEATURE で上書きされてしまわない 限りは、前に書いても問題ないでしょう。

divert(-1)
# ドメインマスターの設定
# DNS + HUB,SPOOL
# created by N.Kanayama
divert(0)dnl
dnl # this is a comment for mc
VERSIONID(`$Id: FreeBSD, v8.12 2001/08/08 DNS,HUB,SPOOL$')
dnl # we are using FreeBSD
OSTYPE(bsd4.4)dnl
Dwmail1 dnl # my name

Dmsummer00.wakhok.ac.jp
dnl # $j FQDN
define(`confDOMAIN_NAME', `$w.$m')dnl
dnl # 
LOCAL_DOMAIN(`$m')dnl
dnl # replace from:
MASQUERADE_AS(`$m')dnl
dnl # replace header mail from:
FEATURE(`masquerade_envelope')dnl
dnl # without root
EXPOSED_USER(`root')dnl
dnl # accept mail from DNS unresolvable domain
FEATURE(`accept_unresolvable_domains')dnl
dnl # use LMTP transfer mode for local mailer
FEATURE(`local_lmtp')dnl
dnl # don't use many command: ex. expn,vrfy, etc.
define(`confPRIVACY_FLAGS',`goaway')dnl
dnl # aliases database auto rebuild, don't set on domain master
define(`confAUTO_REBUILD', `AutoRebuildAliases')dnl
dnl # don't use IDENT protocol
define(`confTO_IDENT', `0s')dnl
dnl # reveal my sendmail version
define(`confSMTP_LOGIN_MSG', `$j Sendmail R8/cf1.0; $b')dnl
dnl # also reveal on received header
define(`_REC_BY_', `$.by $j (R8/cf1.0)$?r with $r$. id $i$?{tls_version}')dnl
dnl # OK, all definition is set
dnl #
MAILER(`local')dnl
MAILER(`smtp')dnl

dnl # ドメインマスター以外のメイルサーバの追加設定
dnl # DNS , inner client SMTP server
dnl # relay to outside mail server
define(`SMART_HOST', `esmtp:mail1.summer00.wakhok.ac.jp')dnl
LOCAL_NET_CONFIG
R$* < @ $* .$m. > $* $#smtp $@ $2.$m. $: $1 < @ $2.$m. > $3
dnl #
dnl # if you want to use smtp then use this instead of above one
dnl define(`SMART_HOST', `smtp:mail1.summer00.wakhok.ac.jp')dnl
dnl LOCAL_NET_CONFIG
dnl R$* < @ $* .$m. > $* $#esmtp $@ $2.$m. $: $1 < @ $2.$m. > $3

以下、主に書き換えが必要な項目について解説する。

divert

m4 マクロでは、divert(-1) から divert(0)で囲まれた部分は一切出力しない。 つまり、mc に何か説明を書き、それを cf に出力したくないような場合に 使う。必ず、divert(0)で終らないと、まったく何も出力されない点に 注意が必要である。(つまりは、出力抑制とその回復の命令)

dnl

dnl は、"delete through newline" で次の改行までを削除するという命令 である。つまり、dnl が行頭にあれば、その行は mc のコメント行として 使え、行の途中にあればそれ以降がコメントとして使えるが、生成される cf において本当に改行をしないので使い方を誤ると行がつながってしまう 場合がある。

Dwmail1 の後ろに空行があるのはそのためで、これがないと次の Dmsummer00.wakhok.ac.jp がつながってしまい、生成された cf に おいては、
Dwmail1 Dmsummer00.wakhok.ac.jp
となってしまう。このために空行を入れているのだが、全体としては m4 では 行の途中からコメントを入れる書き方は止めた方が良く、次のようにコメント行 にした方が良いであろう。

dnl # My name
Dwmail1
dnl # My domain
Dmsummer00.wakhok.ac.jp

一方、m4 のマクロ命令などでも m4 は忠実に改行は改行のまま出力するので、 必要のない空行が生まれる。これを抑制するために、 FEATURE(`masquerade_envelope')dnl のように行末に dnl を サンプルでは挿入しているが、別に空行が余分に出るだけなので、 全くなくても害はない。

sendmail.cfのコメント

行頭の # は sendmail.cf のコメントを表す文字である。m4 は基本的には マクロ以外はそのまま生成する cf に出力をする。従って、行頭に dnl を つけずに書いたコメントは本当のコメントになるのだが、ここで注意は 行頭に # があっても、それは m4 自体の解釈の対象になる点である。 例えば、次のように mc に書いたとする。

# $x is macro

ところが、$x m4 の解釈の対象となって いるために、展開されてしまう のである。もし、cf に上の通りにコメントとして出力したい場合には、 m4 の解釈を抑制するために、バッククォートとシングルクォートで囲って 次のように書かなければならない。

# `$x' is macro

同様に、以下に出てくるマクロ命令の引数などに関しても、m4 に解釈されたく なければ、`' で囲む必要があり、そのためにサンプルの 各所にこれがあるのである。

VERSIONID

cf に埋め込まれるバージョン識別文字列である。RCS,CVS,SCCS などのバージョン 管理ツールで管理できるように考えられているが、それらを利用しないので あれば、別になくても良い。ちなみに、SMTPのgreeting message(後述) とは全く関係がなく、単なるコメント行となっている。

OSTYPE

使用している OS の種類を指定する。指定出来る名前は、../ostype 以下に あるos-name.mc の os-name が利用できる。 FreeBSD は、bsd4.4 を指定する。 なお、../ostype/bsd4.4.mc を読めば分かる通り、OS 毎のローカルメーラの 位置や、オプションなどを定義した、OSの違いを吸収するためのものである。 README を読めば分かるが、非常に多くの設定がこれでなされるようになって いる。

# ls ../ostype
aix2.m4                 hpux10.m4               riscos4.5.m4
aix3.m4                 hpux11.m4               sco-uw-2.1.m4
aix4.m4                 hpux9.m4                sco3.2.m4
altos.m4                irix4.m4                sinix.m4
amdahl-uts.m4           irix5.m4                solaris2.m4
aux.m4                  irix6.m4                solaris2.ml.m4
bsd4.3.m4               isc4.1.m4               solaris2.pre5.m4
bsd4.4.m4               linux.m4                solaris8.m4
bsdi.m4                 maxion.m4               sunos3.5.m4
bsdi1.0.m4              mklinux.m4              sunos4.1.m4
bsdi2.0.m4              nextstep.m4             svr4.m4
darwin.m4               openbsd.m4              ultrix4.m4
dgux.m4                 osf1.m4                 unixware7.m4
domainos.m4             powerux.m4              unknown.m4
dynix3.2.m4             ptx2.m4                 uxpds.m4
gnu.m4                  qnx.m4

Dwmail1

cf におけるホスト名の定義で、FQDNではなく、必ず一語ホスト名を 書く。 通常これは自動的に生成されるのだが、 うまく動作しない場合もあるので、通常は 陽に指定する。 D は cf マクロにおける Define(定義)の意味で、続く一文字の w がマクロ変数名、その後の文字列が代入される文字列である。 C言語風に書くと、w = "mail1" となる。 m4 では、これは全体が単なる文字列なので、そのまま cf に出力される。

ここに定義するホスト名が、DNS やローカルの /etc/hosts と同じでないと sendmail が正常に動作しないので、注意が必要である。

Dmsummer00.wakhok.ac.jp

Dw と同じであるが、ドメイン名を定義している。

define(`confDOMAIN\_NAME', `\$w.\$m')

define はm4 のマクロ命令で、define(A,B) でマクロA に 値B を設定する。m4 では、マクロはそれを読んだ段階で直ちに 展開してしまうので、通常は ` ' で括って展開を抑制しなければ ならない。ここでは、ホストの FQDN を設定しており、生成される cf に おけるFQDN を表す変数に $w.$m を埋め込む役割を果たしている。 sendmail.cf のマクロでは、変数は全て一文字で、それを引用するには $ をつけて $w のように使う。先の Dwmail1 で、 マクロ変数 w には 'mail1' が設定されており、同様に $m もドメイン名が設定されているので、 結果的にはこれは 'mail1.summer00.wakhok.ac.jp' を設定している事になる。出力される cf では、これは Dj$w.$m と 表記される(つまり、cf のマクロ変数 $j は FQDN を意味する)。

MASQUERADE\_AS(`\$m')

次に重要なのが、From 行のアドレスの指定方法である。デフォルトでは、 $j が指定されるので、[host name].[domain name] の ように設定される。従って、mail1.summer00.wakhok.ac.jp のように From 行の アドレスが設定されるが、これをドメイン名のみに書き換えたい場合は、 $m を指定すれば良い。 なお、一語ホスト名が From行に使われている場合であっても、書き換えは 行われる。勿論、次のように陽に設定しても良い。
MASQUERADE_AS(`summer00.wakhok.ac.jp')
ちなみに、MASQUERADE_AS マクロは、../m4/cfhead.m4 で定義されている。

FEATURE(`masquerade\_envelope')

MTAのヘッダーであるエンベロープの MAIL FROM: の発信者アドレス も MASQUERADE_AS で指定したものに置き換える。 FEATURE は、cf であらかじめ用意されているマクロで、../feature/ にある。

# ls ../feature/
accept_unqualified_senders.m4   no_default_msa.m4
accept_unresolvable_domains.m4  nocanonify.m4
access_db.m4                    nodns.m4
allmasquerade.m4                notsticky.m4
always_add_domain.m4            nouucp.m4
bestmx_is_local.m4              nullclient.m4
bitdomain.m4                    promiscuous_relay.m4
blacklist_recipients.m4         rbl.m4
delay_checks.m4                 redirect.m4
dnsbl.m4                        relay_based_on_MX.m4
domaintable.m4                  relay_entire_domain.m4
generics_entire_domain.m4       relay_hosts_only.m4
genericstable.m4                relay_local_from.m4
ldap_routing.m4                 relay_mail_from.m4
limited_masquerade.m4           smrsh.m4
local_lmtp.m4                   stickyhost.m4
local_procmail.m4               use_ct_file.m4
loose_relay_check.m4            use_cw_file.m4
mailertable.m4                  uucpdomain.m4
masquerade_entire_domain.m4     virtuser_entire_domain.m4
masquerade_envelope.m4          virtusertable.m4

主なものは READMEで解説されているが、解説されていないものも あるので注意が必要である。 疑問がある場合には、本山の http://www.sendmail.org/m4/readme.html を参照する必要がある。 MASQUERADE_ENVELOPE の場合は、 _MASQUERADE_ENVELOPE_ マクロ変数をonにしているだけで、 実際にはこのマクロ変数がon になっていると、 ../m4/proto.mc で直接 cf マクロを書き換えるようになっている。

define(`confPRIVACY\_FLAGS',`goaway')

sendmail のコマンドなどに制限を加える設定を行うための定義で、 様々な値があり、以下にそれらを掲げる。

public
制限をしない。
needmailhelo
MAIL コマンドの前に HELO,EHLO を要求する。
needexpnhelo
EXPN コマンドの前に HELO,EHLO を要求する。
needvrfyhelo
VRFY コマンドの前に HELO,EHLO を要求する。
noexpn
EXPN コマンドの禁止。
novrfy
VRFY コマンドの禁止。
restrictmailq
mailq コマンドの一般ユーザの使用禁止。
restrictqrun
sendmail -q コマンドの一般ユーザの使用禁止。
noreceipts
DSN(Delivery Status Notification)をサポートしない(RFC1891)。
noetrn
ETRN コマンドの使用禁止(8.9以降)。
noverb
VERB コマンドの使用禁止(8.9以降)。
nobodyreturn
DSN を伴った本文を返さない(8.10以降)。
goaway
noreceipts, restrictmailq, restrictqrun, noetrn, nobodyreturn 以外の全てのオプションを指定したのと同じ。
authorwarnings
発信者アドレス偽造の可能性に関する情報を付加する (X-Authentication-Warning)。

デフォルトでは authorwarnings になっている。複数のオプションを指定する場合 にはカンマ(,)で区切る。最初はデフォルトのままでテストした方が良いが、 配送など問題がないことを確認したら、外部向けのメイルサーバでは、goaway を 指定するのが通常となりつつある。

define(`confAUTO\_REBUILD', `True')

alias file (/etc/mail/aliases) はテキストファイルであり、sendmailは 高速動作のためにこれらテキストファイルからデータベースを作成し、それら を利用するようになっている。このデータベースの作成は newaliases コマンド で行われるが、もし /etc/mail/aliases を編集した場合には再度 newaliases を実行しなければ、データベースは更新されない(つまり、データベースに その変更が反映されない)。これを防ぐために、自動的にデータベースを 再構築するように指示するのがこの設定である。但し、最初のみは手動で newaliases を実行しなくてはならない。

一方、デフォルトでこのオプションが False に設定されているのは、これが DoS (Denial of Service attack)攻撃に利用される可能性があるからである。 従って、外部から直接メイルを受け付ける公式メイルサーバ上では、この定義 はしない方が良い。

define(`confTO\_IDENT', `0s')

IDENT認証と呼ばれる認証方式がsendmailではサポートされていますが、 あまり使われておらず、Firewall によっては IDENT を積極的に切っている 場合さえあります。標準では、IDENT認証を使わない相手の場合、5secは 待つためにその時間が無駄になります。0sec に設定すると実質的にIDENT認証は 使われません。(TO は TimeOut の意味です、タイプミスに注意して ください)

TimeOut に関する項目は非常にたくさんあり、ここでは全てを紹介出来ません ので、sendmail.org のページを参照してください(生成したsendmail.cf にも 簡単な解説はついています。O Timeout.xxxx の項目を見てください)。 ただ、TimeOut で用いられ れる記法と単位は共通で、s(sec),m(min),h(hour),d(day) がそれぞれ使えます。 従って、ここでは 0s ですから、0秒と指定している訳です。

define(`confSMTP\_LOGIN\_MSG', `\$j Sendmail R8/cf1.0; \$b')

SMTP でアクセスした際に出る Greeting Massage には、標準ではsendmailの バージョンと cf のバージョンが出るようになっている。すなわち、デフォルトは Sendmail $v/$Z になっているが、両方とも sendmail のバージョンに 同じなので、これを見ると sendmail のバージョンが分かる事になり、もし、 このバージョンの sendmail にセキュリティホールが見付かれば、このバージョン 番号を元に攻撃される可能性があるので、これを書き換えている。

特に、$Z については、変更が出来ないような書き方になっているので (../m4/version.m4を書き換えれば別ですが)、使わないようにしている。 それでも、生成された cf には DZ8.12.8 が入ってしまうが、引用 していないので問題ないだろう。気になる人はsendmail.cfから、 この行を削除すれば良い。

define(`\_REC\_BY\_', `\$.by \$j (R8/cf1.0)\$?r with \$r\$. id \$i\$?{tls\_version}')

上と同じであるが、こちらは Received: ヘッダにつく方である。これも、 標準では $.by $j ($v/$Z) になっているので、そこを書き換えている。

ところが実は、これはあくまでもヘッダーや greeting message だけの問題で、 help コマンドを実行されるとバージョン番号は必ず分かってしまうようになって います。これは、sendmail 自体のバグと思われます。気になる方は、 sendmail/srvrsmtp.c の 4198行目と4239行目を以下のように変更すれば良いでしょう。

       message("502 5.3.0 Sendmail R8 -- HELP not implemented");
       ...
       message("214-2.0.0 This is Sendmail version R8");

但し、version.c 自体を書き換えると、ログにバージョンが残らなくなるので あまり感心しません。

LOCAL\_DOMAIN(`\$m')

デフォルトでは、$j (つまりは、mail1.summer00.wakhok.ac.jp) 宛のみを受け取るようになっているために、ドメイン名のみのメイルを 受け取る事はできない。これを受け取るためには、LOCAL_DOMAIN(`$m') を設定する。複数のドメイン宛のメイルを受け取りたい場合には、それらを 全てここに列挙しなければならない。

MASQUERADE\_AS(`\$m')

デフォルトでは送信者のアドレス(From: 行)はFQDNがつくようになっている。しかし、 このままでは特定のサーバへ返信が戻る事になるので、ドメイン名に書き換える。 Reply-To: ヘッダも対象となる。

FEATURE(`masquerade\_envelope')

envelope の送信者についてもFQDNが用いられるので、それについても MASQUERADE_AS で設定したものに書き換える。Return-Path: ヘッダもそれに応じて書き換えられる。

EXPOSED\_USER(`root')

MASQUERADE_ASの対象外となる user の定義。root は対象外に しておいたほうが良いだろう。

FEATURE(`accept\_unresolvable\_domains')

これを設定するかどうかは迷うところであるが、通常、MAIL FROM: の ホスト部分がDNSで見付からない場合、そのメイルは受け取らないように なっている。ところが、相手のMTAがFirewallの内側で、NAT などで変換 されているような場合や、ダイアルアップ、あるいは常時接続だがIPが 変わるような場合には、これがないと受け取らなくなってしまう。

FEATURE(`local\_lmtp')

sendmail ではローカル配送では、mail.local を呼び出し、mail.local が ユーザのスプールファイル(/var/mail/[user])に書き込むようになっている。 古くはmail.localにはSUID をつけて書き込んでいたが、現在ではLMTP (RFC2033 Local Mail Transfer Protocol)を用いており、直接特定の uid/gid で 書き込むようになっているのでSUID は必要がないのだが、 デフォルトではそのための設定がされていないので、この設定が必要である。 ちなみに、FEATURE の説明で先にディレクトリの一覧を掲載したが、そこに local_lmtp.m4 はある。

define(`SMART\_HOST', `esmtp:mail1.summer00.wakhok.ac.jp')

外に直接接続させないメイルサーバの場合は、外に発信しても良いメイルサーバ に集中させて、そこで処理を行うようにする。SMART_HOST は自分以外の ドメインに送る場合には、指定したサーバに指定した方法(今の場合はesmtp)で 送る。mailer に smtp を使いたい場合には、smtp に置き換えるだけで良い。


next up previous contents
Next: G.2.3 Other Setting Up: G.2 メイル環境の設計 Previous: G.2.1 sendmail.cf generator -
Noriyo Kanayama