sendmailでメールサーバー設定

最近の sendmail は、ずいぶんとセキュリティーが強化され、CFやm4 を利用することで設定も楽になってきました。とはいっても、後発の qmail 等に比べるとまだまだ面倒な設定ファイルである sendmai.cf と格闘しなくてはなりません。そこで、何処をどうすればどんな設定ができるかまとめてみます。


なるべく新しい sendmail を導入

なるべく、セキュリティーが強化されていてバグの少ないバージョンの sendmail の利用をお勧めします。コンパイルはさほど難しくないので、 http://www.sendmail.org/ からソースをダウンロードしてコンパイル/インストールしてください。おまけにコンパイル手順を簡単に説明しています。

sendmail に付属のコマンドについて

sendmail パッケージをインストールした後は、必ず newaliases コマンドは実行してください。newaliases コマンドは、aliases データーベースの構築以外に、設定ファイルのパーミッションやディレクトリのパーミッションの問題のある部分を警告します。

    # newaliases

以下のコマンドは実行しておくことが必要です。

    # chmod go-w / /etc /etc/mail /usr /var /var/spool /var/spool/mqueue
    # chmod root / /etc /etc/mail /usr /var /var/spool /var/spool/mqueue

ローカルメール送信に、 sendmail に付属の smrsh を使用する場合の注意。メーリングリストや .forward などでフィルタープログラムを利用する場合、フィルタープログラムを利用できるように smrsh で許可を与える必要があります(フィルタープログラムを所定の場所に登録する)。

例えば、/usr/local/filter/mailselect というプログラムを .forward で利用する場合:
RedHat 6.0 では

    # cd /etc/smrsh
    # ln -s /usr/local/filter/mailselect mailselect
sendmail 標準インストールでは
    # cd /usr/adm/sm.bin/
    # ln -s /usr/local/filter/mailselect mailselect

設定ファイル sendmail.cf の動作テスト

いきなりですが、始めに、作った sendmail.cf がきちんと動作するかテストする方法を記述します。以降で CF について記述しますが、CF によって作られた sendmail.cf は以下の方法でテストしてください。-C オプションに作成した sendmail.cf を指定し、-bt オプションも指定します。 CF ファイルがデフォルトのパスにある場合、-C は省略できます。また、sendmail では詳細なデバックモード(-d35.9など) があります。

● ユーザー名が moto 、ドメイン名が foobar.co.jp として例を説明しています。

    # /usr/lib/sendmail -C/etc/mail/sendmail.cf -bt
    ADDRESS TEST MODE (ruleset 3 NOT automatically invoked)
    Enter <ruleset> <address>
    >
    > 3,0 moto
    rewrite: ruleset   3   input: moto
    rewrite: ruleset   3 returns: moto
    rewrite: ruleset   0   input: moto
    rewrite: ruleset   0 returns: $# local $: moto
    >
    > 3,0 moto@foobar.co.jp
    rewrite: ruleset   3   input: moto @ foobar . co . jp
    rewrite: ruleset  96   input: moto < @ foobar . co . jp >
    rewrite: ruleset  96 returns: moto < @ foobar . co . jp >
    rewrite: ruleset   3 returns: moto < @ foobar . co . jp >
    rewrite: ruleset   0   input: moto < @ foobar . co . jp >
    rewrite: ruleset  97   input: moto
    rewrite: ruleset   3   input: moto
    rewrite: ruleset   3 returns: moto
    rewrite: ruleset   0   input: moto
    rewrite: ruleset   0 returns: $# local $: moto
    rewrite: ruleset  97 returns: $# local $: moto
    rewrite: ruleset   0 returns: $# local $: moto
    >
● 外部(INTERNET)へのメール配送を自分自身で行う設定の場合:
    > 3,0 shin@baz.com
    rewrite: ruleset   3   input: shin @ baz . com
    rewrite: ruleset  96   input: shin < @ baz . com >
    rewrite: ruleset  96 returns: shin < @ baz . com >
    rewrite: ruleset   3 returns: shin < @ baz . com >
    rewrite: ruleset   0   input: shin < @ baz . com >
    rewrite: ruleset  88   input: < smtp : baz . com > . shin < @ baz . com >
    rewrite: ruleset  88 returns: $# smtp $@ baz . com . $: shin < @ baz . com >
    rewrite: ruleset   0 returns: $# smtp $@ baz . com . $: shin < @ baz . com >
    >
● 外部(INTERNET)へのメール配送を別のホスト(mail.foobar.co.jp)に依託する設定の場合:
    > 3,0 shin@baz.com
    rewrite: ruleset   3   input: shin @ baz . com
    rewrite: ruleset  96   input: shin < @ baz . com >
    rewrite: ruleset  96 returns: shin < @ baz . com >
    rewrite: ruleset   3 returns: shin < @ baz . com >
    rewrite: ruleset   0   input: shin < @ baz . com >
    rewrite: ruleset  88   input: < smtp : [ myhost . foobar . co . jp ] > . shin < @ baz . com >
    rewrite: ruleset  88 returns: $# smtp $@ [ myhost . foobar . co . jp ] $: shin < @ baz . com >
    rewrite: ruleset   0 returns: $# smtp $@ [ myhost . foobar . co . jp ] $: shin < @ baz . com >
    >

moto@foobar.co.jpや moto はローカル内に存在するユーザーなのでローカルメールとして処理しています。shin@baz.com は外部のユーザーなのでインターネットメールとして処理します。

● メールのリレーやスパムに関するチェック方法:

以下は、mx.baz.com という名前で IP アドレスが 202.101.202.101 のホストが SMTP 接続をしてきた際に user@baz.com というアドレスを持つユーザーからのメールを受信するかどうかテストをする場合の例です。

    > CheckDebug,check_relay mx.baz.com $| 202.101.202.101
    rewrite: ruleset 171   input: mx . baz . com $ | 202 . 101 . 202 . 101
    rewrite: ruleset 171 returns: mx . baz . com $| 202 . 101 . 202 . 101
    rewrite: ruleset 173   input: mx . baz . com $| 202 . 101 . 202 . 101
    rewrite: ruleset 172   input: 202 . 101 . 202 . 101
    rewrite: ruleset 172 returns: 202 . 101 . 202 . 101
    rewrite: ruleset 173 returns: OK
    > 
    > .D{client_name}mx.baz.com
    > .D{client_addr}202.101.202.101
    > check_mail user@baz.com
    rewrite: ruleset 196   input: user @ baz . com
    rewrite: ruleset 190   input: user @ baz . com
    rewrite: ruleset 190 returns: user @ baz . com
    rewrite: ruleset   3   input: user @ baz . com
    rewrite: ruleset  96   input: user < @ baz . com >
    rewrite: ruleset  96 returns: user < @ baz . com >
    rewrite: ruleset   3 returns: user < @ baz . com >
    rewrite: ruleset 189   input: user < @ baz . com > $| baz . com
    rewrite: ruleset 189   input: user < @ baz . com > $| com
    rewrite: ruleset 189 returns: user < @ baz . com >
    rewrite: ruleset 189 returns: user < @ baz . com >
    rewrite: ruleset 194   input: user < @ baz . com >
    rewrite: ruleset 193   input: user < @ baz . com >
    rewrite: ruleset 193 returns: OK
    rewrite: ruleset 194 returns: OK
    rewrite: ruleset 196 returns: OK
    >
    > .D{client_name}mx.baz.com
    > .D{client_addr}202.101.202.101
    > .Dfuser@baz.com
    > check_rcpt user@foobar.co.jp
    rewrite: ruleset 188   input: user @ foobar . co . jp
    rewrite: ruleset   3   input: user @ foobar . co . jp
    rewrite: ruleset  96   input: user < @ foobar . co . jp >
    rewrite: ruleset  96 returns: user < @ foobar . co . jp >
    rewrite: ruleset   3 returns: user < @ foobar . co . jp >
    rewrite: ruleset 186   input: user @ baz . com $| user @ foobar . co . jp
    rewrite: ruleset   3   input: user @ baz . com
    rewrite: ruleset  96   input: user < @ baz . com >
    rewrite: ruleset  96 returns: user < @ baz . com >
    rewrite: ruleset   3 returns: user < @ baz . com >
    rewrite: ruleset   3   input: user @ foobar . co . jp
    rewrite: ruleset  96   input: user < @ foobar . co . jp >
    rewrite: ruleset  96 returns: user < @ foobar . co . jp >
    rewrite: ruleset   3 returns: user < @ foobar . co . jp >
    rewrite: ruleset 186 returns: user < @ baz . com > $| user < @ foobar . co . jp >
    rewrite: ruleset 184   input: user < @ baz . com > $| user < @ foobar . co . jp >
    rewrite: ruleset 184 returns: OK
    rewrite: ruleset 188 returns: OK
    >
    > .D{client_name}mx.baz.com
    > .D{client_addr}202.101.202.101
    > .Dfuser@baz.com
    > check_rcpt user@momo.com
    rewrite: ruleset 188   input: user @ momo . com
    rewrite: ruleset   3   input: user @ momo . com
    rewrite: ruleset  96   input: user < @ momo . com >
    rewrite: ruleset  96 returns: user < @ momo . com >
    rewrite: ruleset   3 returns: user < @ momo . com >
    rewrite: ruleset 186   input: user @ baz . com $| user @ momo . com
    rewrite: ruleset   3   input: user @ baz . com
    rewrite: ruleset  96   input: user < @ baz . com >
    rewrite: ruleset  96 returns: user < @ baz . com >
    rewrite: ruleset   3 returns: user < @ baz . com >
    rewrite: ruleset   3   input: user @ momo . com
    rewrite: ruleset  96   input: user < @ momo . com >
    rewrite: ruleset  96 returns: user < @ momo . com >
    rewrite: ruleset   3 returns: user < @ momo . com >
    rewrite: ruleset 186 returns: user < @ baz . com > $| user < @ momo . com >
    rewrite: ruleset 184   input: user < @ baz . com > $| user < @ momo . com >
    rewrite: ruleset 184 returns: $# error $@ 5 . 7 . 1 $: 553 Relay operation rejected
    rewrite: ruleset 188 returns: $# error $@ 5 . 7 . 1 $: 553 Relay operation rejected
    >

最後の部分が OK または error になるかでスパムのチェックがきちんと設定されているか確認できます。foobar.co.jp は自分のドメインなので受信しますが、momo.com は違うので受信拒否しています。

動作テストモードから抜けるのは、/quit^D をタイプしてください。


sendmail.cf と CF 編

日本では、sendmailの設定ファイルである sendmail.cf の設定には CF を利用することが一般的です(基本的には sendmail 8.9 まで、動作保証や新しい機能は利用できないが CF で作成した cf ファイルのレベル[V9/Berkeley]を変更することで sendmail 8.11 までは利用することができる)。


CFを利用するのは非常に簡単で、アーカイブを展開してツールやサンプルを作成したら準備完了です。通常、Perl を利用するように設定されていますが、シェルを利用することも可能です。

* CF のセットアップ

% gunzip -dc CF-3.7Wpl2.tar.gz | tar xvf -
% cd CF-3.7Wpl2/Master
% patch < CF-3.7Wpl2-smtpcheck.patch1
% patch < CF-3.7Wpl2-smtpcheck.patch2
% cd ..
% make cleantools
% make tools
% make samples

* CF を利用するには

CF を利用するには、def ファイル(マクロのようなもの)を作成し cf ファイルに変換するという手続きをとります。def ファイルの雛形として、Standards sendmail-8.9.xを利用する場合、v8 とついている雛形ファイルを用います。その際、メールサーバとして利用するには sendmail-v8.def、それ以外でスプールを共用するには null-v8.def を使用します。とはいっても、変更する部分がさほど多くなければ、変更点だけを記述した defファイルを新規に作成するだけでも構いません。

% cp Standards/sendmail-v8.def hostname.def
% <Editor> hostname.def
% make hostname.cf
MASTERDIR=./Master TOOLDIR=./Tools \
./Tools/Configure hostname.def > hostname.cf.tmp
mv -f hostname.cf.tmp hostname.cf
%

エディタで、必要な変更を行った def ファイルをもとに make コマンドを実行します。細かい設定については doc/MANUAL.jpn に記述されています。その中でも、必要な設定や重要と思われることを以下に記述します。

* sendmail のバージョンなどを定義

# sendmail のバージョンを指定 Ver. 8.9.X の場合 R8V8
CF_TYPE=R8V8
 
# sendmail.cf のバージョン
VERSION=3.7Wpl2 
VERSION_SEPARATOR=/
LOCAL_VERSION=`date +%y%m%d%H`

* OS のタイプを定義

# OS に依存する内容が記述された Master/OSTYPE の下にあるファイルのいずれかを選ぶ
OS_TYPE=solaris2

* 基本部分の定義

# MX (Yes/No) 
#
MX_SENDMAIL=yes
 
# ドメイン名の指定 (自動的にセットされるので記述不要)<Dm>
MY_DOMAIN=foobar.co.jp
 
# ホスト名の指定 (自動的にセットされるので記述不要)<Dw>
MY_NAME=myhost
 
# Official SMTP Host Name (hostname.domain: myhost.foobar.co.jp) <Dj>
OFFICIAL_NAME='$w.$m'
 
# ホストが複数の名前を持つ場合に、その別名を指定する
#    メールの配送時に OFFICIAL_NAMEに書き換えが行われるのを防ぐには
#    ACCEPT_ADDRや、ALIAS_REWRITE=no を指定する。
MY_ALIAS=mail.foobaz.co.jp
 
# canonicalization の設定 (MX:one, Non MX:no)
CANON=one

* アドレス設定

# 送信時の From: のアドレスにホスト名を入れない
FROM_ADDRESS='$m'
# To: Cc: のアドレスも上記に同じ設定にしたい場合
RECIPIENT_GENERIC=yes
 
# アドレスの書き換えに関する設定
#    @MY_NAME や @OFFICIAL_NAME でも @FROM_ADDRESS へ書き換えを行ないたい場合に yes
#   lower を指定すると @*.MY_DOMAIN に対しても @FROM_ADDRESS への書き換えを行なう。
REWRITE_GENERIC_FROM=yes
REWRITE_GENERIC_TO=yes
 
# From: にホスト名を入れるユーザ(どのホストユーザーか区別が必要な場合)
LOCAL_USERS='uucp nobody'
 
# 受け取るアドレスの設定
#   受け取るべきアドレスの指定(Gatewayなどで、メールをリレーするだけの場合コメントアウト)
ACCEPT_ADDRS='$m'

* その他

#デフォルトの配送先に関する設定
#   all:        全て直接配送を行なう
#   none:       全て DEFAULT_RELAY に転送する
#   ドメイン名: 指定したドメインは直接配送し、それ以外は DEFAULT_RELAY に転送する
#   ファイル名: ドメイン名が列挙されたファイルのフルパスを指定する。
DIRECT_DELIVER_DOMAINS=foobar.co.jp
DEFAULT_RELAY='smtp:[myhost.foobar.co.jp]'
 
# ハブホストの指定
#   メールを集中的に受信・転送するホストが用意されているような場合に利用
HUB_HOST=hubhost.foobar.co.jp
 
# スプールホストの指定
#   ローカルにはスプールを持たない時や POP利用のためにメールを特定のホストに集約したい
#   場合に利用
SPOOL_HOST=spoolhost.foobar.co.jp
 
# BITNET宛のメールの配送方法を指定
BITNET=no
 
# user@[12.34.56.78]形式のアドレスをネームサーバーの逆引きを利用して変換する。
RES_NUMERIC=no
 
# NUMERIC表記(user@[ip-addr])のアドレスの配送
#   直接配送は yes
#   送り先のホストが、IP アドレス表記を解釈できない場合 strip
DELIVER_NUMERIC=strip
 
#  エラーが発生した時のメールのヘッダ部分をおくるべきユーザの指定。
COPY_ERRORS_TO=postmaster
 
# SMTPコマンドに関する制限の設定
#  public        制限なし 
#  needmailhelo  SMTP/MAIL コマンドの発行前に HELO を要求する 
#  needexpnhelo  SMTP/EXPN コマンドの発行前に HELO を要求する 
#  needvrfyhelo  SMTP/VRFY コマンドの発行前に HELO を要求する 
#  noexpn        SMTP/EXPN コマンドの使用禁止 
#  novrfy        SMTP/VRFY コマンドの使用禁止 
#  restrictmailq mailq コマンドの一般ユーザ使用禁止 
#  restrictqrun  sendmail -q の一般ユーザの使用禁止 
#  noreceipts    Return-Receipt-To: の解釈抑制 
#  noetrn        ETRN コマンドの使用禁止 (8.9以降) 
#  noverb        VERB コマンドの使用禁止 (8.9以降) 
#  goaway        needmailhelo,needexpnhelo,needvrfyhelo,noexpn,novrfy,
#                authwarnings,noreceipts,noetrn,noverb
#  authwarnings  発信者アドレスの偽造可能性に関する情報をヘッダに付加
PRIVACY_FLAGS='goaway'

* メールの転送制限 [smtpcheck] - SPAMメールのリレーホストとして利用されないようにする必要な設定例

MAIL_RELAY_RESTRICTION=yes
# SMTP 接続を受け付ける発信元ホストのアドレスを指定
#CHECK_HOST_ALLOW='foobar.co.jp'
# SMTP 接続を拒否する発信元ホストのアドレスを指定
#CHECK_HOST_DENY=
# 上記で指定されなかった発信元ホストのアドレスに対するデフォルトの動作を指定
CHECK_RELAY_DEFAULT=allow
 
# 無条件で受信/中継を許可するホストの IPアドレスのリスト
LOCAL_HOST_IPADDR='192.168.0'
# 無条件で受信/中継を許可するホストのドメインのリスト
LOCAL_HOST_DOMAIN='foobar.co.jp'
 
# smtpサーバーとして利用可能なクライアントの IPアドレス
#CLIENT_HOST_IPADDR='192.168.0'
# smtpサーバーとして利用可能なクライアントのドメイン名
#CLIENT_HOST_DOMAIN='foobar.co.jp'
# クライアントから送られるメールの送信者アドレスとして書かれているべきドメイン名を指定
#CLIENT_FROM_DOMAIN='foobar.co.jp'
 
# mail from: で渡される発信者(sender)のドメイン部分がない場合に受け取りを拒否
NEED_SENDER_DOMAIN=yes
# mail from: で渡される発信者(sender)のドメイン部分が FQDNでない場合に受け取りを拒否
CHECK_FROM_FQDN=yes
# mail from: で渡される発信者(sender)のドメイン部分を DNSで引いてみて存在を確認
USE_SENDER_DNS_CHECK=yes
 
# メールを受信するドメイン名のリストを定義
ALLOW_RECIPIENT_DOMAIN='foobar.co.jp'
# 中継を許可するメールのFrom, Toドメインを限定するリストを指定
#ALLOW_RELAY_FROM='foobar.co.jp'
ALLOW_RELAY_TO='foobar.co.jp'

* ファイルやディレクトリのパーミッションに関する設定 [.foward に関する部分のみ記述]

# GroupWritableForwardFileSafe 
#        - グループ書き込み可の .forward ファイルを許可
# ForwardFileInGroupWritableDirPath 
#        - グループ書き込み可のディレクトリー内にある .forward ファイルを許可
# ForwardFileInUnsafeDirPath 
#        - 安全でないディレクトリ内の .forward ファイルを許可
# ForwardFileInUnsafeDirPathSafe 
#        - 上記 .forward に記述されたプログラムの実行を許可
#   ここで言うディレクトリーは .forward が存在するディレクトリーだけでなく
#   トップディレクトリーから全部チェックされるので注意してください
DONT_BLAME_SENDMAIL='ForwardFileInUnsafeDirPath,ForwardFileInUnsafeDirPathSafe'

* ここまでいろいろ説明しましたが最も簡単なメールサーバーの def ファイルの例を挙げておきます。

通常のメールゲートウェイ 自分では受けずリレーするだけのメールゲートウェイ
# Version
CF_TYPE=R8V8
VERSION_SEPARATOR='-'
LOCAL_VERSION=a1.6
#
# OS Type
OS_TYPE=linux-redhat
#
MX_SENDMAIL=yes
MY_DOMAIN=foobar.co.jp
MY_NAME=myhost
OFFICIAL_NAME='$w.$m'
 
DIRECT_DELIVER_DOMAINS=all
 
# Address
FROM_ADDRESS='$m'
RECIPIENT_GENERIC=yes
ACCEPT_ADDRS='$m'
LOCAL_USERS='uucp nobody'
 
# other
CANON=one
BITNET=no
RES_NUMERIC=no
DELIVER_NUMERIC=strip
COPY_ERRORS_TO=postmaster
PRIVACY_FLAGS='goaway'
 
# smtpcheck
MAIL_RELAY_RESTRICTION=yes
LOCAL_HOST_IPADDR=192.168.0
LOCAL_HOST_DOMAIN=foobar.co.jp
NEED_SENDER_DOMAIN=yes
CHECK_FROM_FQDN=yes
USE_SENDER_DNS_CHECK=yes
ALLOW_RECIPIENT_DOMAIN=foobar.co.jp
# Version
CF_TYPE=R8V8
VERSION_SEPARATOR='-'
LOCAL_VERSION=a1.6
#
# OS Type
OS_TYPE=linux-redhat
#
MX_SENDMAIL=yes
MY_DOMAIN=foobar.co.jp
MY_NAME=myhost
OFFICIAL_NAME='$w.$m'
 
DIRECT_DELIVER_DOMAINS=all
STATIC_ROUTE_FILE=relay.txt
 
# Address
FROM_ADDRESS='$m'
RECIPIENT_GENERIC=yes
# 自分では何も受けないので設定しない
##ACCEPT_ADDRS='$m'
LOCAL_USERS='uucp nobody'
 
# other
CANON=one
BITNET=no
RES_NUMERIC=no
DELIVER_NUMERIC=strip
COPY_ERRORS_TO=postmaster
PRIVACY_FLAGS='goaway'
 
# smtpcheck
MAIL_RELAY_RESTRICTION=yes
LOCAL_HOST_IPADDR='192.168.0 192.168.1.1'
NEED_SENDER_DOMAIN=yes
CHECK_FROM_FQDN=yes
USE_SENDER_DNS_CHECK=yes
ALLOW_RELAY_TO=foobar.co.jp
   
  relay.txt - リレー先を指定する
 
GW:  relay:[192.168.1.1]
DOM: foobar.co.jp

* SPAM 対策としてブラックリストの作成やメールのリレーに関する設定

上記のメールの転送制限で簡単に記述していますが、ここではもう少し詳しく CF を利用して説明します。

    # ソースルーティングを指定した中継を拒否します。(user%somehost@myhost形式のアドレス)
    REJECT_SOURCE_ROUTE_RELAY=yes
 
    # メールの転送制限を行なうかどうかを設定します。
    # no に設定すると、以降で説明するマクロをいくら設定しても無視されます。
    MAIL_RELAY_RESTRICTION=yes
 
    # 接続元IPアドレス/ドメインによるアクセス制限の設定。
    # 通常は、CHECK_RELAY_DEFAULTが allowの時は例外を CHECK_HOST_DENY に記述し、
    #         CHECK_RELAY_DEFAULTが deny の時は例外を CHECK_HOST_ALLOWに記述する。
    # globalなネットワークに接続されていてMXが向いているホストでは
    # CHECK_RELAY_DEFAULTをallowにしなければならない。
    # SMTP 接続を許可するホストの IP アドレス/IP アドレスを記述したファイル名を指定します。
    CHECK_HOST_ALLOW=/etc/mail/sendmail.host.allow
    # SMTP 接続を拒否するホストの IP アドレス/IP アドレスを記述したファイル名を指定します。
    CHECK_HOST_DENY=/etc/mail/sendmail.host.deny
    # 上の2つに該当しなかったときの動作を規定します。(allow/deny)
    CHECK_RELAY_DEFAULT=allow
 
    # ローカルの(ローカルとみなす)IPアドレス/ドメインの一覧をリストする。(直接指定またはファイル)
    # 一般的には、自社サイト内の IP アドレスをリストしておく。
    # 192.168.1 と記述した場合、 192.168.1.0/24 を意味します。
    #   192.168.1
    #   192.168.2.123
    LOCAL_HOST_IPADDR=/etc/mail/sendmail.localip
    # LOCAL_HOST_IPADDR と同様だが、IP アドレスではなく「ホスト名」、「ドメイン名」をリストします。
    # localdomain.name と記述した場合、 *.localdomain.name を意味します。
    #   localdomain.name
    LOCAL_HOST_DOMAIN=/etc/mail/sendmail.localdomain
 
    # メールの受信/中継を許可するSMTP接続ホストのIPアドレス/ドメインの設定。(直接指定またはファイル)
    # この設定で受信/中継を許可したサイトには後述のALLOW_*によるチェックがかからない。
    # また、上述のLOCAL_HOST_*と違い、CLIENT_FROM_DOMAINによる発信者アドレスに対するドメインチェックを
    # かけることができる。
    # CLIENT_FROM_DOMAINを設定すると SMTP接続ホストでglobalなメーリングリストが運用されていると
    # トラブルが発生する可能性があるので注意。
    # 一般的には、自社サイト内のクライアントを含むように設定する
    # CLIENT_HOST_IPADDR でリストされた IP アドレスを持つホストまたは
    # CLIENT_HOST_DOMAIN でリストされたドメイン名を持つホストからのメールで、
    # その FROM が CLIENT_FROM_DOMAIN にリストされたドメインとマッチするメールは中継が許可されます。
    CLIENT_HOST_IPADDR=/etc/mail/sendmail.client.hostip
    CLIENT_HOST_DOMAIN=/etc/mail/sendmail.client.hostdomain
    CLIENT_FROM_DOMAIN=/etc/mail/sendmail.client.fromdomain
 
    # 自社サイト外のSMTP接続ホストから、自社サイトのアドレスを発信者アドレスに付けたメールの発信を
    # 許可する場合に設定。(直接指定またはファイル)
    # 一般的には、自宅のクライアントなどを含むように設定する
    # ROAM_HOST_IPADDR でリストされた IP アドレスを持つホストまたは
    # ROAM_HOST_DOMAIN でリストされたドメイン名を持つホストからのメールで、
    # その FROM が ROAM_USERS にリストされたユーザーとマッチするメールは中継が許可されます。
    ROAM_HOST_IPADDR=/etc/mail/sendmail.roam.hostip
    ROAM_HOST_DOMAIN=/etc/mail/sendmail.roam.hostdomain
    ROAM_USERS=/etc/mail/sendmail.roam.users
 
    # SPAM_LIST にリストされたユーザー/ドメイン/アドレスからのメールは受け取りを拒否します。
    SPAM_LIST=type:/etc/mail/sendmail.junklist
    SPAM_REGEX='^[0-9]+@(aol|msn)\.com'
    # type には、hash(NEWDB), btree, dbm(NDBM) が指定可能。省略時は hash
    #   ファイルを書き換えたあと以下のコマンドを実行します。dbm を利用している場合、
    #   makemap dbm sendmail.junklist < sendmail.junklist
    #
    #     user1@domain1.jp        any comment
    #     domain2.jp              discard
    #     123.45                  any comment
    #     12.34.56                errmsg 451 Message rejected
    # any comment は、なにか書いておかないと makemap がエラーを出すので書いておく
    # discard は、受信したメールはどこにも配送されずに消滅する
    # errmsg 以降は、エラーメールに残されるメッセージとなる
 
    # mail from: で渡される発信者のドメインの制限
    # mail from: で渡される発信者(sender)のドメイン部分がない場合に受け取りを拒否します。
    NEED_SENDER_DOMAIN=yes
    # mail from: で渡される発信者(sender)のドメイン部分がFQDNでない場合に受け取りを拒否します。
    CHECK_FROM_FQDN=yes
    # mail from: で渡される発信者(sender)のドメイン部分をDNSで引いてみて存在確認をする
    USE_SENDER_DNS_CHECK=yes
 
    # rcpt to: で渡される受取人ドメインの制限(直接指定またはファイル)
    # ALLOW_RECIPIENT_DOMAIN は、メールサーバが受理する宛先ドメイン名のリストを指定します。
    ALLOW_RECIPIENT_DOMAIN=/etc/mail/sendmail.acceptdomain
    # ALLOW_RELAY_FROM は、指定された FROM を持つメールに関しては無条件に中継を許可します。
    ALLOW_RELAY_FROM=/etc/mail/sendmail.relay.from
    # ALLOW_RELAY_TO は、指定された TO を持つメールに関しては無条件に中継を許可します。
    ALLOW_RELAY_TO=/etc/mail/sendmail.relay.to
    # RELAY_MAP は、上記の ALLOW_* の代りにDB 形式で記述できる
    RELAY_MAP=type:/etc/mail/sendmail.releymap
    # type には、hash(NEWDB), btree, dbm(NDBM) が指定可能。省略時は hash
    #   ファイルを書き換えたあと以下のコマンドを実行します。dbm を利用している場合、
    #   makemap dbm sendmail.releymap < sendmail.relaymap
    #
    #     # foo@domain.jp 宛のメールを中継
    #     .!domain.jp             allow
    #     !domain.jp              allow
    #     # foo@*.domain.jp 宛のメールを中継
    #     .!.domain.jp            allow
    #     !.domain.jp             allow
    #     # foo@sub.domain.jp 宛のメールを拒否する
    #     .!sub.domain.jp         deny
    #     # foo@friend.jp 宛のメールを中継
    #     .!friend.jp             allow
    #     !friend.jp              allow
    #     # しかし、foo@spam.jp から foo@friend.jp への中継を拒否する
    #     spam.jp!friend.jp       deny
    # deny 以外に以下のものも記述できる
    # discard は、受信したメールはどこにも配送されずに消滅する
    # errmsg 以降は、エラーメールに残されるメッセージとなる
    #
    # 中継を拒否する受信者アドレスのドメインのリストを指定します。
    CLIENT_DENY_TO=/etc/sendmail.deny.to
 
    # REJECT_EXTERN_SRR に yes を指定すると、自社サイト外から送られてくるメールに関して
    # ソースルーティングを拒否できます。(user%otherhost@hostや @host:userother@host形式のアドレス)
    REJECT_EXTERN_SRR=yes
 
    # 「@」のないMessage-Idだったら配送を拒否する
    HDR_REJECT_BADMID=no
 
    # To/Ccヘッダに特定のアドレスが書かれていたら配送を拒否する(直接指定またはファイル)
    # 'anonymous foo@public.jp' と指定した場合、anonymous@*, foo@public.jp が拒否される
    HDR_REJECT_RCPTADDRS=/etc/sendmail.hdrrejaddr
    # errorはエラーメールを返し、discardは無視する(/dev/null)
    HDR_REJECT_ACTION=error

CF では、今まで記述した項目以外にもさらに細かい sendmail.cf の設定が行えるようになっています。もっともっと sendmail を細かく制御したい時や詳しく知りたい場合、MANUAL.jpn をお読みください。また、WEB 上ではより詳しい情報が数多く見つかることでしょう。


sendmail.cf と m4 編

もともと sendmail のパッケージには、sendmail.cf を作成するためのテンプレートが用意されています。そのテンプレートは、m4 マクロで書かれており、そのテンプレートを修正し m4 コマンドを利用して sendmail.cf を作ることが出来ます。CF が対応する sendmail のバージョンの問題で、sendmail 8.10 以降は CF ではなく m4 マクロを利用する方がよい。


* m4 を利用するには

m4 マクロで書かれたテンプレートは、sendmail/cf/cf ディレクトリーにあります。ここにあるサンプル(.mc)を参考にし、設定するシステムにあわせ修正を施します。通常は sendmail/cf/cf/tcpproto.mc をそのままコピーして利用すれば良いでしょう。sendmail/cf/cf/ に移動して tcpproto.mchostname.mc としてコピーし、OSTYPE(unknown) の "unknown" を自分のシステムに合わせて書き換えます。これは、展開したソースの cf/ostype ディレクトリーにあるマクロファイル (メイルコマンドのパスやタイムゾーンの設定などOSに依存する定義)を引用するための設定なので、このディレクトリーにないシステムは自分で作成しておく必要があります。

例えば Solaris 2 の場合:

    OSTYPE(solaris2)

その他の設定はサンプルを用いて...その前に、m4 は、 # 以降をコメントと解釈しないので、記述しないか dnl (delete through newline) を利用する。また、詳細は sendmail/cf/README を参照してください。

    divert(-1)
    #
    # Copyright (c) 1998, 1999 Sendmail, Inc. and its suppliers.
    # All rights reserved.
    # ...
    #
 
    divert(0)dnl
    VERSIONID(`$Id: hostname.mc 8.11 1999/08/03 15:26:50 JST Exp $')dnl # mcファイルの ID
    OSTYPE(solaris2)dnl               # OS は Solaris 2 (cf/ostype)
    DOMAIN(generic)dnl                # ドメイン名の定義は /etc/mail/local-host-names を参照
    FEATURE(`always_add_domain')dnl   # local配送時も FQDNを付与
    MASQUERADE_AS(`foobar.co.jp')dnl  # アドレスのドメイン部の書き換え
    MASQUERADE_DOMAIN(`foobar.co.jp')dnl
    FEATURE(`masquerade_entire_domain')dnl
    FEATURE(`masquerade_envelope')dnl
    FEATURE(`access_db',`hash -T<TMPF> -o /etc/mail/access')dnl # メール中継用データベースの指定
    FEATURE(`blacklist_recipients')dnl
    FEATURE(`nouucp',`reject')dnl     # uucpアドレスはreject
    undefine(`UUCP_RELAY')dnl
    undefine(`BITNET_RELAY')dnl
    define(`confPRIVACY_FLAGS', `goaway')dnl            # SMTP コマンドのプライバシーフラグ設定
    define(`confSMTP_LOGIN_MSG', `$j Sendmail; $b')dnl  # メッセージのバージョン表示を隠す
    define(`confMAX_MESSAGE_SIZE', `5242880')dnl        # 受信メールの最大バイト数を指定 5 MB
    MAILER(local)dnl                  # local mailer の設定 (cf/mailer)
    MAILER(smtp)dnl                   # smtp mailer の設定 (cf/mailer)

mc ファイルを作成したら、m4 コマンドを使用して .cf ファイルを作成します。

    ./Build hostname.cf

または、

    m4 ../m4/cf.m4 hostname.mc > hostname.cf

ここで生成した hostname.cf は、/etc/mail/local-host-names, /etc/mail/relay-domains に記述したドメインを持つメールのみ受け付ける設定になっています。POP/IMAPクライアントからメイル送信を行うには、 relay-domains ファイルに該当する PC が属しているドメイン名や IPアドレスを記述しておく必要があります。

* 定義ファイルmc のマクロについて

mc ファイルの記述方法は、基本的に以下のオーダーで記述します。 しかし、この順序には若干の例外があり、FEATURE の前に define を指定しなければならないものもあります。

VERSIONID cf ファイルにコメントとして記述される定義ファイルのバージョンID。
OSTYPE OSの指定。展開したソースの cf/ostype ディレクトリーのある定義を取り込みます。
DOMAIN ドメインの設定に関する定義。展開したソースの cf/domain ディレクトリーにある定義を取り込みます。
FEATURE 特定の機能に関する定義。展開したソースの cf/feature ディレクトリーにある機能について設定します。
local macro definitions 個別にマクロを設定。define, undefine など
MAILER メールの配送に必要なエージェントを指定。展開したソースの cf/mailer ディレクトリーにある定義を取り込みます。
LOCAL_RULE_* 個別に配送ルールを定義。
LOCAL_RULESETS 個別に配送ルールセットを定義。

設定する値についてはバックシングルクォーテーション(`)と シングルクォーテーション(')で囲まれている必要があります。また、# 記号はコメントとしては利用できないので dnl (Delete through New line) を使用する。 また、不要な情報を cf ファイルに書き出さないようにするためにもマクロの最後には dnl を指定するとよい。

最もよく利用するものだけを挙げて説明します。

マクロ 説明

divert(-1)
コメント
divert(0)dnl

定義ファイルの初めに記述する divert(-1) から始まり divert(0) で囲まれた内容は、cf ファイルには出力されません。この囲まれた内容は、定義ファイルのコメントとして扱われます。# 記号がコメント行として扱われないので、定義ファイルの詳細を記述しておくには便利なフィールドです。
VERSIONID(`<SCCS,RCS version id>') 定義ファイルのバージョンを記述します。RCS, SCCS といったリビジョンコントロールシステムで利用されるリビジョン番号を挿入することが一般的です。
OSTYPE(linux)

どのタイプの OS を利用するか cf/ostype ディレクトリーにリストされている OS を選択します。ここでリストされているファイルは、各OS に依存する部分が定義されています。sendmail が動作しうる OS はほとんど用意されているが、なければ使っている環境に近い OS を元に作成します。

DOMAIN(generic) ドメインに関する情報を指定します。通常、cf/domain ディレクトリーにある generic.m4 を利用するが、デフォルトの状態で支障があればドメイン名などを利用したファイル名で作成しなおします。
MAILER(local)
MAILER(smtp)
sendmail で使用するメーラーを指定します。ローカル配信と SMTP 配信の双方を指定するが、通常 cf/mailer にある local.m4, smtp.m4 を利用する。この定義は、必ず設定ファイルの最後に記述されていなければなりません。
FEATURE(`always_add_domain')

宛先のアドレスにユーザー名のみを指定したときに、ユーザー名にローカルのドメインを付加します。

MASQUERADE_AS(`foobar.co.jp') メールの From: 行に指定されたアドレスのドメイン部分をここで指定したドメインに置き換えます。アドレスのドメイン部分にホスト名が含まれているとき、この指定でドメイン部分をドメイン名だけに置き換えることができます。
MASQUERADE_DOMAIN(`foobar.co.jp') メールの From: 行に指定されたアドレスが、ここで指定したドメインに含まれる場合 MASQUERADE_AS の対象になります。MASQUERADE_DOMAIN(`foo.co.jp bar.co.jp') の場合、From: 行のドメイン部が指定(foo.co.jp, bar.co.jp)されたものに含まれれば MASQUERADE_AS で指定されたドメインであるかのように中継時に書き換えられて配送されます。
FEATURE(`masquerade_entire_domain') MASQUERADE_AS, MASQUERADE_DOMAIN が設定されている場合、ドメイン全体を完全に隠すようにアドレスの書換えが行なわれます。MASQUERADE_DOMAIN(`foo.co.jp bar.co.jp') の場合、From: 行のドメイン部が *foo.co.jp, *bar.co.jp に含まれれば MASQUERADE_AS で指定されたドメインであるかのように中継時に書き換えられて配送されます。
MASQUERADE_EXCEPTION(`foobar.co.jp') 変換されるのを除外したいドメインを指定します。
FEATURE(`limited_masquerade') MASQUERADE_DOMAINに、記述されたドメインのみ MASQUERADE_AS の対象になります。
FEATURE(`masquerade_envelope') 通常は、ヘッダアドレスだけが書き換えられるが、エンベロープも同様に書き換えたいたい場合に指定します。
define(`confCW_FILE',`/etc/mail/local-host-names')

受信したいドメインを記述するファイルを指定します。これは、デフォルトで設定されているので指定する必要はありません。

  foobar.co.jp
define(`confCR_FILE',`/etc/mail/relay-domains')

転送を許可するドメインや IP Address を記述するファイルを指定します。これは、デフォルトで設定されているので指定する必要はありません。

  foo.co.jp
  bar.co.jp 
FEATURE(`access_db')
FEATURE(`access_db', `hash -o /etc/mail/access')

メール中継の許可/拒否が登録されたデータベースを指定します。データベースのタイプは、hash(Berkeley DB), btree, dbm(NDBM) などを選択できるがデフォルトの場合 hash になります。データベースの作成方法は、テキストで以下のような内容のファイルを作成し makemap コマンドでデータベースを構築します。access.db というデータベースが作成されます。makemap コマンドで、データベースを作成したものは sendmail を再起動する必要がありません。

# cat /etc/mail/access
localhost         RELAY
foobar.co.jp      RELAY
foo.co.jp         RELAY
bar.co.jp         RELAY
spam.com          REJECT
192.168.212       REJECT
<>                REJECT
spam@aol.com      ERROR:550 Spam not accepted
 
# makemap hash /etc/mail/access < /etc/mail/access
FEATURE(`blacklist_recipients')

この指定をすることで、受信者のアドレスやサブドメイン名のスパム対策が設定できるようになります。

# cat /etc/mail/access
 ...
anonymouse@       REJECT
subscription@     REJECT
host.foobar.co.jp ERROR:550 That host does not accept
FEATURE(`dnsbl')
FEATURE(`dnsbl', `relays.ordb.org')
メール中継の拒否に、不正中継を行うホストをブラックリストとして管理しているサーバを利用する際にこれを指定します。サーバーを明示的に指定しない場合、cf/feature/dnsbl.m4 に登録されたサーバーが利用されます。
FEATURE(`accept_unqualified_senders') デフォルトで、発信者のアドレスにドメイン名が含まれていない場合SMTP セッションの MAIL FROM: コマンドが拒否されます。その機能を無効にしたい場合、これを指定します。
FEATURE(`accept_unresolvable_domains') デフォルトで、発信者のアドレスのドメイン名が DNS によって解決できない場合、SMTP セッションの MAIL FROM: コマンドが拒否されます。その機能を無効にしたい場合、これを指定します。
FEATURE(`mailertable')

ドメイン名によって転送するサーバーを指定したり、外部のメールサーバーから内部のスプールサーバーに転送を行うなど、スプールサーバーを変更したい場合にはこれを指定します。配送ルールは、/etc/mail/mailertable ファイルに以下のように記述します。このファイルも、makemap コマンドでデータベースを構築します。[ ] で囲まれたホストは MX レコードを検索しません。

# cat /etc/mail/mailertable
foobar.co.jp      smtp:[192.168.0.1]
sub.foobar.co.jp  smtp:[192.168.0.2]
.foo.co.jp        smtp:[%1.foo.co.jp]
define(`SMART_HOST', `mailer:hostname') ファイヤーウォール内のスプールホストから、外部のリレーサーバーに転送したいなど、リレーサーバーを指定したい場合にはこれを指定します。define(`SMART_HOST', `smtp:[192.168.30.1]:[192.168.30.2]') といった具合に複数指定があった場合、最初に指定したホストに配送を試みて配送できないときに次のホストに配送されます。FEATURE(`mailertable') を指定してさらにこれを指定した場合、mailertable のデータにマッチしなかったらこの設定が適用されます。
define(`confCF_VERSION', `hostname.mc-1.2') Received: に記録される cf のバージョンを設定します。
define(`confSMTP_LOGIN_MSG', `$j Sendmail; $b') SMTP コネクション時のグリーティングメッセージを設定します。
define(`DATABASE_MAP_TYPE', `hash') デフォルトのデータベースのタイプを設定します。デフォルトで hash が設定されています。
define(`ALIAS_FILE', `/etc/mail/aliases') エイリアスファイルを設定します。newaliasesコマンドにより、aliases.db が作成されます。
define(`confMAX_MESSAGE_SIZE', `5120000') 受信可能なメールの最大サイズを設定します。サイズはバイト単位で指定します。デフォルトは、未定義で無制限です。
define(`confPRIVACY_FLAGS',`goaway') SMTPコマンドに関するプライバシーフラグを設定します。

FEATURE(`nouucp',`reject')
undefine(`UUCP_RELAY')
undefile(`BITNET_RELAY')

UUCP や BITNET 形式のアドレスを無効にします。最近は、uucp などあまり利用されていないので、セキュリティー強化のために指定しておくとよい。

詳細は、sendmail/cf/README を参照してください。メイルの中継制限に関する機能については sendmail/cf/README の ANTI-SPAM CONFIGURATION CONTROL に記述されています。


おまけ:sendmail-8.11.2 のインストール

Solaris 8 for Intel にインストールする例を記述しています。何かと便利なので、bind-8.2.2-P7 の BIND ライブラリーと Berkeley DB-3.1.17 を利用します。とは言ってもおまけなのでコンパイル手順だけ.....

BIND は、セキュリティ・ホールの少ない最新版を利用してください。ここでは、bind-8.2.2-P7 を利用していますが最新版が出ている場合、新しいものを利用してください。 Berkeley DB-4 は、sendmail-8.11 では利用できないので古いものを使用しています。


ソースの入手先

Berkeley DB http://www.sleepycat.com/
BIND http://www.isc.org/products/BIND/
sendmail http://www.sendmail.org/

Berkeley DB のインストール

    # gzip -dc db-3.1.17.tar.gz | tar xf - 
    # cd db-3.1.17/build_unix
    # ../dist/configure
    # make
    # make install   デフォルトで /usr/local/BerkeleyDB.3.1 にモジュールがインストールされる

bind のインストール

    # mkdir bind-8.2.2-P7
    # cd bind-8.2.2-P7
    # gzip -dc ../bind-src.tar.gz | tar xf -
    # cd src
    # make DST=build_sol8 SRC=`pwd` links
    # cd build_sol8
    # make clean
    # make depend
    # make all
    # make install   デフォルトで /usr/local/bind にモジュールがインストールされる

sendmail のインストール

    # gzip -dc sendmail.8.11.2.tar.gz | tar xf -
    # cd sendmail.8.11.2/devtools/Site
    # vi site.config.m4
    システム依存のコンパイル環境を定義するためファイル site.config.m4 を作成(サンプル)
    define(`confCC', `gcc')
    define(`confMAPDEF', `-DNEWDB -DMAP_REGEX')
        define(`confNROFF', `nroff -h')
    APPENDDEF(`confINCDIRS', `-I/usr/local/bind/include -I/usr/local/BerkeleyDB.3.1/include')
    APPENDDEF(`confLIBDIRS', `-L/usr/local/bind/lib -L/usr/local/BerkeleyDB.3.1/lib')

    # cd ../..
    # ./Build
 
    インストール前にオリジナルを保存しておく
    # mv /usr/lib/sendmail /usr/lib/sendmail.org
    # mv /usr/sbin/makemap /usr/sbin/makemap.org
    # chmod 0000 /usr/lib/sendmail.org /usr/sbin/makemap.org
    # ./Build install