coLinux日記

coLinuxはフリーソフトを種として、よろずのシステムとぞなれりける。

sendmail.cf のテスト方法まとめ

2007-05-26 18:00:15 | sendmail
長い間遊んできました sendmail (ここでは、8.14.1 ) ですが、今回で一応終わりにしたいと思います。

実際の sendmail.mc 作成で役立つのはこうもり本であることは間違いないですが、とても重いので、 sendmail のソースにある cf/README やインターネット上にあるその日本語訳cf/READMEなどを参考にすれば良いと思います。

次に作成された sendmail.cf のテスト方法をおさらいしてみます。

まず、sendmail をルールテスト・モードで起動します。

/usr/sbin/sendmail -bt -C./sendmail.cf

これで、プロンプト > が出力されて入力待ちになります。ここで、
> rule,rule,rule... アドレス

とルールセットとアドレスを指定すれば変換結果が得られるのが基本でしたね。

定義マクロの値とクラス・マクロの値の表示はそれぞれ、$ と $= が使えます。
> $j
> $=w

マクロの値を変えるには、.D と .C を使えばよいです。
> .Djnew.example.co.jp

=S に続いてルールセット番号またはシンボル名を指定すれば、ルールセットも表示できます。
> =S0
> =SParseLocal

=M は配信エージェントの表示ですが、すべての定義が表示されてしまいます。
> =M

/canon は、指定したホストの標準名を表示します。
> /canon www
getcanonname(www) returns fedora.example.co.jp
> 
標準名を得る様子は、デバッグ・スイッチ
> -d38.20 

を指定すればよいです。

さて、今までのルールセットのテストでは、呼び出すルールセットを順番に指定していましたがこれを /tryflags , /parse , /try を使ってテストしてみます。

/tryflags は、引数が、[ h | e ][ s | r ]で、ヘッダまたはエンベロープ、発信者または受信者を表します。
> /tryflags hs  (例: ヘッダの発信者アドレス)

/parse 受信者アドレス は、

3,0 で配信エージェント、受信者のホスト、受信者のアドレスの3組を求めてから、

その配信エージェントの R= 式の指示に従って、

受信者のアドレスを 2,エンベロープ用受信者ルールセット,final によって変換した結果を表示しています。
> /parse espiya@fedora.example.co.jp
.........
parse            returns: $# local $: espiya
2                  input: espiya
2                returns: espiya
EnvToL             input: espiya
EnvToL           returns: espiya
final              input: espiya
final            returns: espiya
mailer local, user espiya
>

/try 配信エージェント address は、
/tryflags の指示に従って、アドレスの種類を4つから選んでそれに応じて配信エージェントの R=式 または S=式 からルールセットを選び変換します。つまり、

/tryflags hs なら、 3,1,ヘッダ用発信者ルールセット,final
/tryflags hr なら、 3,2,ヘッダ用受信者ルールセット,final
/tryflags es なら、 3,1,エンベロープ用発信者ルールセット,final
/tryflags er なら、 3,2,エンベロープ用受信者ルールセット,final

のようなルールセットを使ってアドレスが変換されます。最後のケースは/parse の結果と一緒ですね。
> /try relay espiya@mail000.goo.ne.jp

これらは、配信エージェントで F=5 が指定されていた場合のルールセット5 の呼び出しまではテストしないので、それは自分で行う必要があります。

最後に、
> -d21.12

でルールの動作状況を詳しく見ることができます。

以上長い間 sendmail について見てきましたが、これでこうもり本なしでも簡単な sendmail.mc が作成できる気分になりました。

相変わらずcoLinux は安定していますが、Windows の update でリブートするときに、シャットダウンする必要があり残念です。また coLinux 用の Fedora Core 6 も出ましたので、そろそろ移行を考えています。
コメント
  • X
  • Facebookでシェアする
  • はてなブックマークに追加する
  • LINEでシェアする

sendmail.mc LOCAL_RELAYとMAIL_HUB

2007-05-24 00:16:02 | sendmail
引き続き sendmail 8.14.1 ネタですが、あともう少ししたら一応終わりにしたいと思います。

今回は、sendmail.mc で少し分かりにくい、LOCAL_RELAY と MAIL_HUB について調べてみました。

最初に、LOCAL_RELAY mcマクロですが、mc ファイルに指定するためには以下の行を追加します。

define(`LOCAL_RELAY',  `mail.example.co.jp')

これによって生成される sendmail.cf 内で、以下の定義マクロが追加されました。
DRmail.example.co.jp

また、Slocaladdr=5 内で、
R< > $+        $: < $R > $1        try relay

が追加されました。これは、Mlocal の F=式で F=5 が指定されている場合に呼び出されるルールセットです。従って、LOCAL_RELAY とは、local なホスト宛とみなされたメールをエイリアス展開後に別のホストに転送するための機能といえるようです。

普通のローカルユーザ宛のアドレスでは、Parse1 ルールセットで、
$# local $: ユーザ名

に変換されますので、例えば、
> 5 espiya
..................
localaddr    returns: $# relay $@ mail.example.co.jp 
                         $: espiya < @ mail.example.co.jp >
>

となって、LOCAL_RELAY へ再転送されます。(出力は適当に折り曲げてあります。)MXレコードで複数のホストが指定してあり、サブサーバが受けたメールを本サーバに一極集中的に集めるのには便利ですね。

次に MAIL_HUB mcマクロを見てみます。mcファイルでの指定は次のようになります。

define(`MAIL_HUB',  `mail.example.co.jp')dnl

生成される sendmail.cf ファイルは
DHmail.example.co.jp

の定義マクロ追加と、Slocaladdr=5 内で、
R< > $+      $: < $H > $1         try hub

が追加されています。$R が $H に変わっただけですね。つまりどちらかを使えば良いみたいです。

それはともかく、明らかに2つの mc マクロは、ローカルユーザ宛てのメールに対する書き換え用です。

しかも、同じ lhs を持っているので、2つ同時に指定しても最初に定義されているRコマンドの方にだけヒットしてしまうのではないでしょうか。というわけでこれらを使うにはどちらか一方だけ使う方が良いみたいです。
コメント
  • X
  • Facebookでシェアする
  • はてなブックマークに追加する
  • LINEでシェアする

sendmail.mc ルールセット1でマスカレード

2007-05-16 23:54:18 | sendmail
coLinux日記なのに、sendmail日記みたいになっていますが、前回に続いて、sendmail.mc を作ってみます。今まで書いていなかったのですが、mcファイルのコメントはどのようになっているのでしょうか。m4 のコメントそのままなら、行の先頭文字が # であればコメントのはずです。しかし、cf ではこれが成り立ちません。その理由は、cf/m4/cfhead.m4 の中で、
changecom(^A)    ^A は、0x01

と指定されているからです。これによってコメントデリミタは、# から ^A 文字に変わっています。従って、sendmail.mc のなかでコメントにして処理を無効にするには、先頭に dnl マクロを挿入するのが正しいといえます。

さて前回、SMART_HOST が分かったので、今回は、

「外に送るメールはすべて、自分の使っているプロバイダのメールサーバに転送を頼む。」

という普通のメーラのようなことをして見ます。

現在 spam メールの多くが直接 pc などから送られてくるので、普通のプロバイダでは直接外のメールサーバとの通信を許していません。( Outbound Port 25 Blocking :: OP25B ) したがって、coLinux から外部にメールを送る方法として通常のメーラのようなことをすることにしました。更にここの coLinux では 仮想ドメイン example.co.jp を使っているので、その場合正しいアドレス変換を行わないと、返信をうまく受け取れないばかりでなく、spam とみなされて拒否される可能性があるので慎重に行いたいです。

せっかく sendmail 8.14.1 を使っているので新しいオプションも使います。
ここでは、自分が使っているプロバイダのメールサーバと登録している自分のアドレスを

mail.example.com
myname@abc.example.com

とします。普段使っているメーラはメールサーバと、

HELO mail.example.com (または EHLO mail.example.com)
MAIL FROM <myname@abc.example.com>
RCPT TO <espiya@mail000.goo.ne.jp>

のように、smtp でやり取りしますから、HELO とエンベロープ発信者アドレスは書き換えたいです。

sendmail の場合、HELO は通常は、$j が使われますが、新しい mcマクロ confHELO_NAME を使うと書き換えられるみたいです。ヘッダやエンベロープの発信者アドレスの変換は、sendmail の用語でいう「マスカレード」ですが、普通は FEATURE(genericstable) などを使うと思います。それではつまらないので、ここでは思い切ってルールセット1 (Sender Rewriting) を使ってみます。

sendmail.mc は、
divert(0)dnl
VERSIONID(`TEST 2007 0002')
OSTYPE(linux)dnl
DOMAIN(generic)dnl
define(`SMART_HOST', `mail.example.com')dnl
define(`confHELO_NAME', `mail.example.com')dnl
MAILER(local)dnl
MAILER(smtp)dnl
LOCAL_CONFIG
FG/etc/mail/real-name
D{o_domain}abc.example.com
D{o_name}myname
LOCAL_RULE_1
R$=G                    $@ ${o_name} < @ ${o_domain} . >
R$=G < @ $j . >         $@ ${o_name} < @ ${o_domain} . >

ここで、/etc/mail/real-name は、
root
espiya

と複数ユーザも扱えるようにしてみました。つまり、発信者アドレス
espiya
や
root < @ fedora . example . co . jp . > 

などを、
myname < @ abc . example . com >

に変換して、mail.example.com にメールを転送するようにしたつもりです。ルールセット1 の Rコマンドはもちろんあらかじめテストして決めました。1文字の定義マクロを利用しようとしたのですが、大文字小文字も含めてほとんどが使われているらしいので断念しました。ルールセット1 を使うとすべて場合で発信者アドレスに影響するので制限がありますが、ルールセット1をどうしても使ってみたかったので気にしないことにします。

作成された sendmail.cf の変更は、前に紹介した定義マクロ S の指定以外では、
・ LOCAL_CONFIG 以下は定義マクロの最後の方に追加。
・ O HeloName=mail.example.com を指定。
・ ルールセット 1 が新たに作成され、Ssender=1 の中に、
  sendmail.mc で指定した2つの Rコマンドを追加。

のようになりました。LOCAL_RULE_1 が指定されると自動的にルールセット1 が定義されますね。テストしてみます。
$ ./sendmail -bt -C./sendmail.cf
.............
> 3,0 espiya@mail000.goo.ne.jp
............................
canonify  returns: espiya < @ mail000 . goo . ne . jp>
............................
parse     returns: $# relay $@ mail . example . com $: espiya < @ mail000 . goo . ne . jp >
>
> 3,1,EnvFromSMTP,final espiya@fedora.example.co.jp
............................
final     returns: myname @ abc . example . com
>
> 3,1,HdrFromSMTP,final espiya@fedora.example.co.jp
............................
final     returns: myname @ abc . example . com
>
> 2,MasqSMTP,final    espiya < @ mail000 . goo . ne . jp . >
............................
final     returns: espiya @ mail0000 . goo . ne . jp
> /quit
$

最終的なアドレスや送り先が希望通りになっていますね。このように、sendmailの設定は、自分の出したいメールの発信者および受信者アドレスが正しく変換され、正しい配信エージェントを使って、正しいホストに送られるかどうかを調べながら調整すれば良いようです。

実際に本当のサーバとアドレスにしてテストしてみたところうまくいきました。EHLO もうまく置き換わっていました。受信者アドレスの特殊な書き換えは、LOCAL_RULE_2 で行えばうまくいく場合もあると思います。やはり sendmail.cf を少し知っていると sendmail.mc の設定も何とかなります。

ここで、テストといっても書き換えがうまくいっているかどうかぐらいですので、実際運用なら更にテストが必要です。また、テストで /tryflags や /try がありますがそのうち使ってみたいです。まあ、blog ですからテストはいつも適当です。
コメント
  • X
  • Facebookでシェアする
  • はてなブックマークに追加する
  • LINEでシェアする

sendmail.mc の SMART_HOST

2007-05-03 23:28:15 | sendmail
長い間 sendmail.cf を見てきましたが、実際には cf を使って、sendmail.mc から作成するので、sendmail.cf を知る必要はないように思えます。しかし、cf は m4 のマクロですから sendmail の設定を簡単に作成するには便利ですが、設定のすべてが分かるわけではないです。やはり sendmail.cf を知ってないといけないのではという気持ちから、あえて sendmail.cf がどうなっているかを見てみたわけです。

確かに、sendmail.cf は難しいですが、ほとんど修正する必要がないためあまり深く考えなくても困らないように思えます。

今後は、sendmail.mc の設定を調べてみたいと思いますが、その場合も sendmail.cf はどのように変わるのかを見るように心がけたいと思います。

まず、SMART_HOST を見てみます。これは、

「外部に送るメールはすべてこのホストに送って、そのホストから送ってもらう。」

という機能ですね。これは defineマクロでの定義ですので、sendmail.mc は次のようにしました。

VERSIONID(`TEST 2007 0001')
OSTYPE(linux)dnl
DOMAIN(generic)dnl
define(`SMART_HOST', `mail.example.co.jp')dnl
MAILER(local)dnl
MAILER(smtp)dnl

送るホスト名は、mail.example.co.jp です。sendmail.cf の変更は、

DS



DSmail.example.co.jp

なるだけです。つまり、定義マクロ S が設定されるだけです。これが、Parse1 ルールセットで使われて、
espiya < @ mail000 . goo . ne . jp . > が、

R$* < @ $* > $*         $: $>MailerToTriple < $S > $1 < @ $2 > $3

によって、

< mail . example . co . jp > espiya < @ mail000 . goo . ne . jp . > 

を入力として MailerToTriple ルールセットが呼ばれて、
定義マクロ S が空値の場合は

R< > $*                 $@ $1 

でそのまま戻るところ、S が定義されているので、

R< $+ > $*              $#relay $@ $1 $: $2 

によって、

$# relay $@ mail . example . co . jp $: espiya < @ mail000 . goo . ne . jp . >

になるみたいです。

$@ の送り先のホスト名が置き換わっていますね。その直前で、
R< $=w > $*             $@ $2

があるので、SMART_HOST は自分自身を指定しても無意味になりますね。

ここで、relay を定義している Mコマンドを見ますと、
・ エンベロープ発信者ルールセットは、EnvFromSMTP
・ ヘッダ用発信者ルールセットは、    HdrFromSMTP
・ エンベロープ受信者ルールセットは、MasqSMTP
・ ヘッダ用受信者ルールセットは、    MasqSMTP

です。esmtp との違いは、EnvToSMTP が MasqSMTP になっているところです。ここで、MasqSMTP に渡される入力は、配信エージェントの 3組のアドレス( $: 以下)です。
SMasqSMTP
R$* < @ $* > $*       $@ $1 < @ $2 > $3
R$+                   $@ $1 < @ *LOCAL* >

SEnvToSMTP
R$+                   $: $>PseudoToReal  $1
R$+                   $: $>MasqSMTP  $1
R$* < @ *LOCAL* > $*  $: $1 < $ $j . > $2

SPseudoToReal
R$< @ $+ > $*         $@ < @ $1 > $2
R$+ < @ $+ .UUCP. >   $: < $2 ! > $1
R$+ < @ $* > $*       $@ $1 < @ $2 > $3
.............

ほとんど違いがないみたいです。
次回は、発信者アドレスの書き換えに挑戦するつもりです。
コメント
  • X
  • Facebookでシェアする
  • はてなブックマークに追加する
  • LINEでシェアする

sendmail.cf を覗く

2007-04-30 23:17:28 | sendmail
前回までで、sendmail.cf の遊び方が少し分かったので、実際のメール転送の設定をここで標準としている sendmail.cf で見てみます。

最初に sendmail がアドレスを書き換えるときのルールセットの順序を見てみます。
1) 受信者アドレス(送信先)を入力として、
   canonify=3 を通って、更に parse=0 に行って、
   配信エージェントを決める、Mコマンドを選択します。
2) 発信者アドレス(送信元)は、canonify=3 続いて 1 を通って、
   Mコマンドの S= で指定されたルールセットを通り、最後に final=4 を通って、
   メールメッセージのヘッダやエンベロープに現れます。
3) 受信者アドレス(送信先)は、canonify=3 続いて 2 を通って、
   Mコマンドの R= で指定されたルールセットを通り、最後に final=4 を通って、
   メールメッセージのヘッダやエンベロープに現れます。

要するに受信者アドレスから送信方法を決めて、発信者アドレスと受信者アドレスを書き換えて送信するのが sendmail の役割ですね。その際、アドレスはメールのヘッダ用とエンベロープ用があるので全部で4つ操作することになります。

特に 1) のテストは、どこにメールが送られるのかを決める重要な部分ですので、ほとんどのテストはここに集中するわけです。それで sendmail では、
$ /usr/sbin/sendmail -bt -C./sendmail.cf 
............
> 3,0 テストするアドレス
............


のようにテストすることが多いわけですね。ちなみにそのアドレスが自分宛であることを確認するには、
> 3,0 espiya@fedora.example.co.jp
...............

parse         returns: $# local $: espiya
>

のように 配信エージェントが$# local になれば良く、外部に送られる場合は、

parse         returns: $# esmtp $@ hoge.co.jp $: abc < @ hoge . co . jp >

のように 配信エージェントが$# esmtp で、$@ の示す受信者ホスト名が期待する送り先になっていれば良いわけです。

先ほどの sendmail.cf では、ルールセット 1 および 2 は、定義されていませんでした。また、Mコマンドで定義されている配信エージェント esmtp は、
・ エンベロープ発信者アドレス  EnvFromSMTP
・ ヘッダ用発信者アドレス   HdrFromSMTP
・ エンベロープ受信者アドレス  EnvToSMTP
・ ヘッダ用受信者アドレス   EnvToSMTP

のようになっています。以上まとめると、
・ 配信エージェント決定テストは、
    > 3,0  address
・ エンベロープ発信者アドレステストは、esmtp として、
    > 3,EnvFromSMTP,final  address
・ エンベロープ受信者アドレステストは、esmtp として、
    > 3,EnvToSMTP,final  address
・ ヘッダ用発信者アドレステストは、esmtp として、
    > 3,HdrFromSMTP,final  address
・ ヘッダ用受信者アドレステストは、esmtp として、
    > 3,EnvToSMTP,final  address

のようにテストすれば良いですね。例えば、ヘッダ用受信者アドレスは、

> 3,EnvToSMTP,final espiya@www.example.co.jp
canonify           input: espiya @ www . example . co . jp
Canonify2          input: espiya < @ www . example . co . jp >
Canonify2        returns: espiya < @ fedora . example . co . jp . >
canonify         returns: espiya < @ fedora . example . co . jp . >
EnvToSMTP          input: espiya < @ fedora . example . co . jp . >
PseudoToReal       input: espiya < @ fedora . example . co . jp . >
PseudoToReal     returns: espiya < @ fedora . example . co . jp . >
MasqSMTP           input: espiya < @ fedora . example . co . jp . >
MasqSMTP         returns: espiya < @ fedora . example . co . jp . >
EnvToSMTP        returns: espiya < @ fedora . example . co . jp . >
final              input: espiya < @ fedora . example . co . jp . >
final            returns: espiya @ fedora . example . co . jp
>

canonify ルールセットから呼び出された、Canonify2 ルールセットが、fedora.example.co.jpに書き換えていますね。

さて、ルールセット parse=0 を見てみます。
Sparse=0

R$*                     $: $>Parse0 $1          initial parsing
R<@>                    $#local $: <@>          special case error msgs
R$*                     $: $>ParseLocal $1      handle local hacks
R$*                     $: $>Parse1 $1          final parsing

ずいぶんすっきりしています。要するに、

・ ルールセット Parse0 の呼び出し
・ 特殊ケースを local に配信し終了
・ ルールセット ParseLocal を呼び出し
・ ルールセット Parse1 の呼び出し

を行って、それまでに配信エージェントが決定される仕組みですね。

もう一つ Canonify2 ルールセットで変換に関わる部分を抜き出してみました。
入力:espiya < @ www . example . co . jp >

R$* < @ $* $~P > $*      $: $&{daemon_flags} $| $1 < @ $2 $3 > $4

途中:$| espiya < @ www . example . co . jp >

R$* $| $* < @ $* > $*    $: $2 < @ $[ $3 $] > $4

出力:espiya < @ fedora . example . co . jp . >

なれないうちは、自分で作ったルールセットに Rコマンドを入れてテストするのが良いかと思います。最大の問題は、自分のケースでは必要ないように見える Rコマンドがいったい何に役立つのかほとんど分からないことです。

というわけで、sendmail.cf で既に書かれているルールセットの部分の修正は行わず、その結果が満足できない場合だけ、Rコマンドを継ぎ足していくのが無難ですね。
コメント
  • X
  • Facebookでシェアする
  • はてなブックマークに追加する
  • LINEでシェアする

sendmail.cf ルールセット呼び出しと arith

2007-04-26 22:31:24 | sendmail
sendmail.cf でルールセットからルールセットの呼び出しに挑戦してみます。

sendmail.mc で以下の行を追加します。

LOCAL_RULESETS
Slocal_test=9
# Test of R command
R$-+$-          $: $>PlusNum <$1><$2>
R$*             $@ RESULT : $1
SPlusNum
R<1><4>         $@ 5
R<2><4>         $@ 6
R<3><4>         $@ 7
R<4><4>         $@ 8
R<5><4>         $@ 9
R$*             $@ ERROR
#

早速テストしてみます。
$ ./sendmail -bt -C./sendmail.cf
.............
> 9 3+4
local_test         input: 3 + 4
PlusNum            input: < 3 > < 4 >
PlusNum          returns: 7
local_test       returns: RESULT : 7
> 9 4+4
local_test         input: 4 + 4
PlusNum            input: < 4 > < 4 >
PlusNum          returns: 8
local_test       returns: RESULT : 8
> 9 4+6
local_test         input: 4 + 6
PlusNum            input: < 4 > < 6 >
PlusNum          returns: ERROR
local_test       returns: RESULT : ERROR
> /quit
$

うまく変換されていますね。実際に計算が必要な場合は、Kコマンドでタイプ arith を使えばできます。

通常 sendmail.mc で作成されたものは、
Karith arith

が含まれています。これを使うには、sendmail.mc に以下の行を指定します。
Slocal_test=9
# Test of R command
R$+ $+ $+     $: $(arith $2 $@ $1 $@ $3 $: EXCEPTION $)
R$*             $@ RESULT : $1
#

sendmail.cf を作成し確かめてみます。
$ ./sendmail -bt -C ./sendmail.cf
..............
> 9 25+28
local_test         input: 25 + 28
local_test       returns: RESULT : 53
> 9 12*3
local_test         input: 12*3
local_test       returns: RESULT : 12*3
> 9 12 * 3
local_test         input: 12 * 3
local_test       returns: RESULT : 36
> 9 25 + 28
local_test         input: 25 + 28
local_test       returns: RESULT : 53
> 9 12 * 3
local_test         input: 12 * 3
local_test       returns: RESULT : 36
> 9 -12 / 3
local_test         input: -12 / 3
local_test       returns: RESULT : -4
> /quit
$

これは便利。マイナスも使えますね。それ以外に比較演算子みたいなのもあるので、IF文もどきのようなこともできるようです。

Kコマンドは、データベース・マップコマンドですから、/etc/passwd のようなテキスト型のものなど文字列の変換に色々利用できます。指定方法は、

Kname type switches file_or_map

で、定義された name は Rコマンドのrhs だけで使用できます。ちなみにクラス・マクロは Rコマンドの lhs だけでしか使用できず、定義マクロは lhs と rhs の両方で使用できます。

参照は、以下のように、$( と $) を使うそうです。

$(name key $: default $)
や
$(name key $@ text1 $@ text2 $: default $)

実際にテストする場合は、直接 sendmail.cf を修正すればよいのですが、今回はわざと sendmail.mc を使ってみました。だいぶテストも慣れてきましたので、メール転送関連の設定も調べてみたいと思います。
コメント
  • X
  • Facebookでシェアする
  • はてなブックマークに追加する
  • LINEでシェアする

sendmail.mc と sendmail.cf とRコマンドテスト

2007-04-24 20:08:42 | sendmail
前回 sendmail.cf を簡単にまとめてみて、だんだん気分が盛り上がってきましたので、R(ルール)コマンドをいろいろ試して見たくなりました。

そのための準備として、sendmail.mc と sendmail.cf の関係を少し見てみます。

./cf/README によると、sendmail.mc は次のような構成で作ると良いみたいです。
  VERSIONID
  OSTYPE
  DOMAIN
  FEATURE
  local macro definitions
  MAILER
  LOCAL_CONFIG
  LOCAL_RULE_*
  LOCAL_RULESETS

ここで、local macro definitions は、GNU m4 の define() マクロで指定するタイプの設定です。

生成される sendmail.cf は、ここでの標準の sendmail.cf で大体次のようになっていました。
  バージョン情報
  C , F , D コマンド
  O コマンド
  Q コマンド
  P コマンド
  T コマンド
  H コマンド
  [ REWRITING RULES のコメント ]
     Scanonify=3 のルールセット
      Sfinal=4 のルールセット
      Sparse=0 のルールセット
      Slocaladdr=5 のルールセット
      Scheck_ 系のルールセット
      その他関連ルールセット
  [ MAIL FILTER DEFINITIONS のコメント ]
    [ Local and Program Mailer specification のコメント ]
      SEnvFromL ルールセット
      SEnvToL ルールセット
      SHdrFromL ルールセット
      SHdrToL ルールセット
      その他関連ルールセット
      Mlocal と Mprog の設定
    [ SMTP Mailer specification のコメント  ]
      SEnvFromSMTP ルールセット
      SEnvToSMTP ルールセット
      SHdrFromSMTP ルールセット
      SHdrToSMTP ルールセット
      その他関連ルールセット
      Msmtp とか Mesmtp の設定      

要するに膨大なオプションとルールセットの塊です。大まかな構成はしっかりしていますね。

さて、Rコマンドをテストするために、新たにルールセットを作りました。ここでは、使っていない番号 9 を利用します。こういう場合は、sendmail.mc の中で、LOCAL_RULESETS を使います。

この設定は、REWRITING RULES コメント下のルールセット群の一番下に展開されます。

例えば、

R<$+>       $1

をテストする場合は、sendmail.mc の最後に

LOCAL_RULESETS
Slocal_test=9
# Test of R command
R<$+>          $1
#
R$*            $@ RESULT : $1

を追加します。Rコマンドの lhs と rhs の間はタブ文字です。
この Rコマンドは括弧で囲まれた複数のトークンから括弧をはずすためのつもりです。ここで、
rhs の先頭の $@  は、それ以降の内容を出力として、そのルールセットを
                     終了させます。
                     つまり、サブルーチンのリターンですね。
                     配信エージェントを指定する $# も同じ動作
                     になっていますね。
rhs の先頭の $:  は、それ以降の内容を次のルールコマンドの lhs に渡し
                     ます。
                     Rコマンドのループ抑制です。

早速テストしてみます。sendmail は、コンパイルしたものを使います。
$ ln -s ../../obj.Linux.2.6.11-co-0.6.4.i686/sendmail/sendmail sendmail
$
$ sb Build sendmail.cf
$ ./sendmail -bt -C./sendmail.cf
ADDRESS TEST MODE (ruleset 3 NOT automatically invoked)
Enter <ruleset> <address>
> 9 <abc>
local_test         input: < abc >
local_test       returns: RESULT : abc
> 9 <<<abc>>>
local_test         input: < < < abc > > >
local_test       returns: RESULT : abc
> /quit
$

うまくいきました。ここで、テストしたRコマンドがループとして動作し、複数の括弧( < > )がはずされたことがはっきり理解できます。この手のプログラム言語は、熟語のようなよく使う形式が現れますので、sendmail.cf のその他の Rコマンドを見ているうちになれてくるんじゃないかと思います。

coLinux なので、Rコマンドでルールセット呼び出し(サブルーチン呼び出し)なども気楽に試せます。ただし、外にメールを送る場合は正しく設定する必要があります。

ブログですから、次回もう少し遊んで見たいです。
コメント
  • X
  • Facebookでシェアする
  • はてなブックマークに追加する
  • LINEでシェアする

sendmail.cf の簡単なまとめ

2007-04-22 18:12:06 | sendmail
sendmail の設定ファイル sendmail.cf は難しいと様々なところでいわれています。普通は、sendmail.mc から sendmail.cf を作るので、直接 sendmail.cf は触らないのですが、本当の所はどうなんでしょうか。

確かに sendmail.cf の設定自身がプログラム言語(ループを1行で表すとか)のようになっており、過去のアドレス等に関するしがらみが多数含まれているため、全部読むのは大変です。それを助けるオライリーの sendmail の本は非常に重く持ち歩きはほとんど不可能ですから急に何とかと言われてもできないですね。

とりあえずこの重い本を使って、それを持ち歩かずにすむ程度のまとめをしておくのは何かの時に役立ちそうです。

sendmail.cf の文法の基本は、

1行が1コマンドで、コマンド名は行先頭の1文字

です。

# コマンドはコメント、空白およびタブコマンドは継続

ですね。よく使うコマンドは、
C : クラス・マクロ( 次の1文字がマクロ名、CX list 、CX $=Y の形式、$=X で参照)
F : クラス・マクロ( 次の1文字がマクロ名、FX /file 、FX -o /file 等の形式、$=F で参照)
D : 定義マクロ( DX test 、D(XXX) testの形式、$X, $(XXX) で参照)
O : オプション( 次の1文字が空白文字、続いて オプション名=値 の形式)
M : メール配信エージェント( Msymname, equate, equate,... の形式 Mlocal と Mesmtp が重要)
R : ルール( Rlhsタブ文字rhsタブ文字comment の形式、設定でもっとも大切なコマンド)
S : ルールセット( S空白文字可ident の形式、identは昔は数字だけだった)
H : ヘッダ( H?flags?name:field の形式 )

ぐらいだと思います。

早速、インストール時に作った、ここで標準としている sendmail.cf で各コマンドの例を見てみます。  

CO @ % !

クラス・マクロ O を @ , % , ! の3つのリストとして定義していますね。 $=O で参照できます。

FR-o /etc/mail/relay-domains

クラス・マクロ R を /etc/mail/relay-domains の内容をリストとして定義しています。同じく $=R で参照でき、-o が付いているのでファイルがなくても OK で、参照した値は空値です。

DnMAILER-DAEMON

定義マクロ n に MAILER-DAEMON とう値を定義しています。$n で参照できます。この sendmail.cf では、3つだけしか定義されていません。$m (ドメイン名) や $j (標準のホスト名)のように前もって定義されているものもあるようです。

O AliasFile=/etc/mail/aliases

オプション AliasFile を /etc/mail/aliases に指定しています。

Mesmtp,         P=[IPC], F=mDFMuXa, S=EnvFromSMTP/HdrFromSMTP, R=EnvToSMTP, 
		E=rn, L=990,
                T=DNS/RFC822/SMTP,
                A=TCP $h

配信エージェント esmtp の定義です。タブコマンドで継続行になっています。
各 equate は、式=引数 の形式で , で区切るようです。式の意味は、
P= : 配信エージェントのパスで、[IPC]はネットワークでメール転送です。
F= : 配信エージェントのフラグで、D,F,M がヘッダのフラグ、m が複数受信者可、
     u が受信者アドレスの大文字を保存、X が先頭メッセージの先頭がドットの
     ときにドットを1つ先頭に補うことを、a が拡張SMTP を表しているようで
     す。
S= : 発信者の書き換えルールセット
R= : 受信者の書き換えルールセット
E= : 行末文字
L= : 行最大の長さ
T= : DSN診断タイプ、ここでは、すべての SMTP と LMTP エージェントを表します。
A= : 配信エージェントの argv で、TCP はネットワーク配信を表し、
     $h はルール セット0 の $@ オペレータが返す接続相手先のホスト名で、
     この式は伝統的に最後に指定します。

です。

Sparse=0

ルールセット parse の開始を表し、番号 0 に対応付けされています。次のルールセットの開始までが1つのサブルーチンのようにみなされます。テストの時にも通常はこの番号を使います。

H?D?Date: $a

Date: ヘッダの追加宣言で、Mesmtp では、F=D が指定されていますので、配信時にこのヘッダが追加されます。

以上はそれほど難しくないですが、問題は、ルールコマンドです。

R$*        $: $>Parse1 $1       final parsing

lhs が $* , rhs が $: $>Parse1 $1 , comment がfinal parsing でそれらの間は「タブ文字」でなければなりません。ここをいい加減にすると動作がおかしくなります。OperatorChars=.:%@!^/[]+空白文字 を分割文字として、入力テキストをトークンに分割するのが sendmail の基本です。

上のコマンドは、$* で、0個以上のトークンと一致つまり lhs がなんでも rhs に変換の意味で、そのrhs は、$: 「一度だけ書き換え」で、$>Parse1 「Parse1 ルールセットを呼び出し」をその引数 $1 ( この場合は、入力をそのまま)として行った結果を次の行のルールコマンドに渡すという意味ですね。

要するにサブルーチン呼び出しです。

R$* < @* > $*      $#esmtp $@ $2 $: $1 < @ $2 > $3    user@host.domain

この行も重要です。入力が、espiya < @ other . example . co . jp > だとすると、lhs の3つの $* は、espiyaother . exampel . co . jp と 空値と一致して、rhs では、$1 , $2 , $3 として参照され、

$# esmtp $@ other . example . co . jp $: espiya < @ other . example . co . jp >

に変換されます。つまり lhs が入力と一致すれば、配信エージェント esmtp が選択されルールセットは完了します。rhs は、いわゆる配信エージェントの [3つ組]で、$# が配信エージェント $@ がホストを、$: がユーザを表します。

要するにここまでくればメールが送られるわけです。

やはり sendmail.cf は奥が深いです。
コメント
  • X
  • Facebookでシェアする
  • はてなブックマークに追加する
  • LINEでシェアする

sendmail 8.14.1 インストール

2007-04-17 22:30:11 | sendmail
4月に入って、sendmail 8.14.1 がでました。早速インストールします。

462bc9e00fdbef3a71b046b967c9a157 sendmail.8.14.1.tar.gz
$gpg --verify sendmail.8.14.1.tar.gz.sig 
gpg: 2007年04月04日 11時41分33秒 JSTにRSA鍵ID 7093B841で施された署名
gpg: “Sendmail Signing Key/2007 <sendmail@Sendmail.ORG>”からの正しい署名
gpg: 警告: この鍵は信用できる署名で証明されていません!
gpg:       この署名が所有者のものかどうかの検証手段がありません。
主鍵の指紋: D9 FD C5 6B EE 1E 7A A8  CE 27 D9 B9 55 8B 56 B6
$

$ tar xzf sendmail.8.14.1.tar.gz
$ cd sendmail-8.14.1
$ sh Build
..........
# sh Build install
..........
# cd cf/cf
# cp generic-linux.mc sendmail.mc
# sh Build sendmail.cf
Using M4=/usr/bin/m4
rm -f sendmail.cf
/usr/bin/m4 ../m4/cf.m4 sendmail.mc > sendmail.cf || ( rm -f sendmail.cf && exit 1 )
echo "### sendmail.mc ###" >>sendmail.cf
sed -e 's/^/# /' sendmail.mc >>sendmail.cf
chmod 444 sendmail.cf
# cp sendmail.cf sendmail.cf.original
# diff /etc/mail/sendmail.cf sendmail.cf
..........
130c130
< DZ8.14.0
---
> DZ8.14.1
439a440,442
> # issue temporary errors (4xy) instead of permanent error (5xy)?
> #O SoftBounce=False
>
# cp sendmail.cf /etc/mail/sendmail.cf

コメントになっていますが、少し修正がありますね。
後は、sendmail を再起動すれば終了です。

続いて、現在の sendmail の情報を表示してみます。
$ /usr/sbin/sendmail -bt -d0.1
Version 8.14.1
 Compiled with: DNSMAP LOG MATCHGECOS MILTER MIME7TO8 MIME8TO7
                NAMED_BIND NETINET NETUNIX PIPELINING SCANF XDEBUG

============ SYSTEM IDENTITY (after readcf) ============
      (short domain name) $w = fedora
  (canonical domain name) $j = fedora.example.co.jp
         (subdomain name) $m = example.co.jp
              (node name) $k = fedora
========================================================

ADDRESS TEST MODE (ruleset 3 NOT automatically invoked)
Enter <ruleset> <address>
> $=w
fedora.example.co.jp
fedora
www
[192.168.1.100]
localhost.localdomain
localhost
[localhost.localdomain]
[127.0.0.1]
example.co.jp
www.example.co.jp
> /quit
$

前回の設定も生きています。/etc/mail/local-host-names に従って、ちゃんと $=w の値は、IPアドレス、localhost、localhost.domain にファイル内容がマージされています。
コメント
  • X
  • Facebookでシェアする
  • はてなブックマークに追加する
  • LINEでシェアする

GNU m4

2007-04-09 20:18:40 | sendmail
sendmail の設定で、sendmail.mc から sendmail.cf を作成する場合に利用するのが
GNU m4 マクロプロセッサです。これには、マニュアルの日本語訳があります。
このシステムの GNU m4 は、Ver. 1.4.4 です。

m4 は、「1. 序論」にも書いてあるとおり、深入りすると健康をそこなうおそれがあるようですから、深入りせず sendmail で利用する機能に絞って、忘れないように調べてみます。

m4 は、入力をトークンに分割して処理するので、入力トークンの種類を見てみます。
・ 名前:
   _ または英文字で始まる、 _ または英数字の文字列。
  マクロ名かどうかはマクロ定義があるかどうかだけです。
・ クォートされた文字列:
   引用符 ` と ' (back quote,quote) のペアで囲まれた文字列で、一番外側のペアだけが有効です。
・ その他:
   上記2つ以外のすべての文字です。

さらに、コメントが次のように定義されています。

# と「改行文字」で区切られた部分で、その部分は何も処理されず、そのまま出力されます。

あとは、マクロの使い方を覚えるだけです。マクロは組み込みマクロとユーザ定義マクロがあります。m4 を使うには、このマクロ定義を行って、入力を変換して出力とすればよいわけです。ユーザ定義マクロの定義の方法ですが、
define(name[,  expansion])

のようにdefineマクロを使います。これで、name が expansion に展開されるよう
に定義されます。defineによるマクロ定義は出力されませんが、最後の改行文字は定義外ですのでそのまま出力されます。引数は、$1, $2 のように参照できます。

さて、マクロの呼び出しですが、
name                              引数なしの呼び出し
name(arg1, arg2, ... , argN)   N個の引数を伴った呼び出し
name()              空の文字列を1つだけ引数とする呼び出し

のようになり、name と ( の間は空けてはいけない決まりです。

・マクロ呼び出しで展開されて、再びマクロが現れたらもう一度そのマクロを呼び出します。
・マクロの引数がマクロなら、先にそのマクロを呼び出します。
・引数なしマクロを連続して展開し連結するなら、マクロ名の間は `' (空のクォートされた文字列)を挿入します。

また、空白文字に非常に敏感です。たとえば引数の前にある空白文字は無視されますが、引数の後ろの , までの空白文字は意味があります。また、引数の前なら改行文字があっても空白文字と同じに扱われるようです。つまり、マクロ定義中に改行可能です。

組み込みマクロの多くは、引数がないとマクロとみなされません。その場合は、そのまま出力されます。

名前の全部または一部をクォートすると、マクロとみなされなくなります。つまり展開されず、そのまま出力されます。

これで、m4 の説明はおしまいです。

さて、sendmail.mc の場合は、組み込みマクロ divert と dnl を知っておく必要があります。

dnl マクロは、最初の改行文字までにある文字をすべて捨てて出力しません。従って、
define(`x', `expansion')dnl

とすると、この行はまったく出力されず、先ほどの説明どおり後ろのdnl がなければ空行が出力されます。

divertマクロは、sendmail.mc の場合、sendmail.mc 自身のコメントを挿入するのに使います。
divert(-1)
複数行のコメント
.........
divert(0)dnl

とすれば、これらすべてが出力されません。

m4 の実行は単純で、入力ファイルが test.mc だとすると、以下のようになります。
$ m4 test.mc

標準出力に出力結果が出てきます。ためしにサンプルを作ってみます。
$ cat test.mc
divert(-1)
# TEST LINE No.1
# TEST LINE No.2
divert(0)dnl
test1 test2 dnl test3 test4 test5
test6 test7
define(`x',`expansion')dnl
define(`y',`dnl')
test8
x
test9
test10
y
test11
$ m4 test.mc
test1 test2 test6 test7

test8
expansion
test9
test10
test11
$

divert や dnl や macro 定義、参照が分かったでしょうか。

sendmail の cf/cf/Build は、
/usr/bin/m4 ../m4/cf.m4 sendmail.mc > sendmail.cf

です。OSTYPE とか、DOMAIN とかの mc ファイルの指定は、定義されたマクロであり、その定義は、cf/m4/cf.m4 から読み込まれる cf/m4/cfhead.m4 で行われています。

cf/m4/cfhead.m4 をチラッと見たところ、
OSTYPE は、cf/ostype 内の引数で指定された名前の .m4 ファイルを、
DOMAIN は、cf/domain 内の引数で指定された名前の .m4 ファイルを、
FEATURE は、cf/feature 内の引数で指定された名前の .m4 ファイルを、
MAILER は、cf/mailer 内の引数で指定された名前の .m4 ファイルを、
を展開するようです。

今後は、m4 を使って sendmail.mc から semdmail.cf を作成していろいろ調べたいと思います。
コメント
  • X
  • Facebookでシェアする
  • はてなブックマークに追加する
  • LINEでシェアする