SMTPGATE

X-Seqno: 5846
To: delegate@etl.go.jp
From: ysato@etl.go.jp (Yutaka Sato =?ISO-2022-JP?B?GyRAOjRGI0stGyhK?=)
Subject: [DeleGate] SMTPGATE
Date: Thu, 4 Sep 97 08:12:22 JST
Organization: Electrotechnical Laboratory, Tsukuba Science City
Lines: 285
Message-Id: <+q1oTJ.ysato@etl.go.jp>
References:  <5u0qce$rk@etlinn.etl.go.jp> 
	
Mime-Version: 1.0 (generated by vin2.0)
Content-Type: text/plain; charset=ISO-2022-JP

先週末から、突貫浩司、いや工事で、SMTP-NNTPゲートウェイを作っていました。
これは、

 ・/etc/aliases のような集中的なファイルを管理する必要がなく
 ・いちいち利用者のアカウントを作って ‾/.forward を置く必要もなく
 ・コンフィギュレーションを階層化して継承することができ
 ・Senderなどに基づいて通過可能なアドレスを制限することができ
 ・Subjectヘッダの加工や記事番号ヘッダの付加機能を内蔵し
 ・SMTPメールからNNTPニュースへのオンラインでの中継機能を持ち
 ・SMTP-SMTPの中継ではメーリングリストサーバのようにも機能する

SMTPゲートウェイ、というようなものです。まだかなりαな状態(特にMAILや
RCPTには無条件でうなづきながらDATA後にあーらごめんなさいという態度の
悪いSMTPサーバなの)ですが、SMTP-NNTP の中継機能としては実用に足ると思
い、公開します。

--

さて、メールからニュースへの中継サーバとしては様々のものがあります。わた
しのところでも、長年手作りの sh スクリプトにより mail から news への中継
を行ってきましたが、従来の方法での問題として、

 ・ニュースサーバ停止時にメールを保留し後に再送を試行することができない
 ・ニュースサーバ接続できても、確実に送達されたかの確認が不確実である

という点で難儀しておりました。
問題は SMTP と NNTP の間の接続が「オフライン」であることにあります。SMTP
サーバ(sendmail)は、メールを mail-to-news 等のフィルタプログラムに渡した
後、その先に NNTPがあることは知りませんから、NNTPプロトコルとの同期を
(きちんと)とることができません。SMTPサーバ間であれば当然機能する再送
機能も働きません(何か方法があるのかも知れませんが)。この問題は、

                    SMTP                         NNTP
  sendmail -------------------- DeleGate -------------------- inn
            RCPT,MAIL,DATA    mail-to-news  GROUP,STAT,POST
                                   |
                                aliases
                          access control list

というように、SMTPサーバとNNTPサーバの間を「オンライン」で接続し、変換・
中継を行えば、すっきり解決します。つまり、

 ・NNTPサーバに対する一時的な接続不能(サーバがダウンとか)/投稿不可
  (スプールがfullとか)に際しては、SMTPクライアント/サーバ間
  (sendmail-DeleGate間)の接続不可として扱うことで、後に再送が行われる。

 ・投稿不可な記事の場合、NNTPプロトコル上でののエラー情報を、送信者へ
  の return メールで知らせることができる(必須フィールドの欠損、形式の
  誤り、Messae-IDの重複、アクセス不許可等)。これは、DeleGateから
  sendmail(この場合SMTPクライアント)に対するSMTPのエラーコードとして
  伝えられる。

 ・VRFY/STMP や finger や Ident等を用いてオンラインで投稿者の認証ができ
  る「かもしれない」(実際には現状の枠組では、ごく一部にしか適用できな
  さそう)

ついでなので、フィルタ機能付きの SMTP-SMTP 中継も実現しました。また、この
枠組の中で SMTP-FTP (ftpmail) 等も一緒に実現できると思っています。

--------------------------------------------------------------------------
DeleGate の SMTPGATE 機能によるメール/ニュース中継と mailing-list 管理
--------------------------------------------------------------------------

#以下は、電総研内向けに書いた記事を一部手直したものですが、電総研固有の
#情報が残っています。


1.各ML管理者の作業
----------------------
ML@etl.go.jp を開設するには、etlpom において以下の設定を行う。

(1) /etc/aliases や .forward で以下のようにフォワードする。

  #############################################################
 /etc/aliasesでは、 ML: ML@smtpgate
  ‾ML/.forwardなら、 ML@smtpgate
  #############################################################

ここで、SMTPGATE-DeleGateのホスト名となる「smtpgate」は、実在するホストでも
良いし、sendmail.cf によるローカルホスト上の非標準SMTPポートへの読み変えでも
良い。また、はじめから ML@smtpgate.etl.go.jp という名前で ML を開設するなら、
この登録は不要。

(2) smtpgate上で 各 ML に対して必要に応じて以下のファイルを作る。

  /net/smtpgate/usr/lib/mail/smtpgate/users/ML/
   ./conf   -- ニュースやメールへの中継方法、投稿者等による制限等を記述
   ./count  -- 次の記事の記事番号 (無い場合には自動作成される)
   ./log    -- 動作ログ(自動作成される)

具体的に、例えば「delegate@etl.go.jp を aist.mail-lists.delegate に転送
する」には、以下のようなファイルを作成します。

  /net/smtpgate/usr/lib/mail/smtpgate/users/delegate/conf:
  #############################################################
  INHERIT:       MY-postnews
  Newsgroups:    aist.mail-lists.delegate
  Reply-To:      delegate@etl.go.jp
  Distribution:  fj
  #############################################################

ここで、例えば etl.go.jp と aist.go.jp からの投稿だけを受け付けるように
するには、以下のような指定を加えます。

  #############################################################
  Sender:        etl.go.jp, aist.go.jp
  From:          etl.go.jp, aist.go.jp
  #############################################################

ここで Sender とは、実際に(SMTPの入口で)メールを送信した人のアドレス
(SMTP の MAIL FROM: senderで与えられる)、From: はメッセージ中の From:
フィールドに書かれたアドレスです。後者はエディタで編集するなどして簡単
に詐称することができますが、前者のは些少ながら難しい(^_^)

同様に「vin@etl.go.jp に送られたメールを vin-members@etl.go.jp へ中継する」
には、以下のようにします。

  /net/smtpgate/usr/lib/mail/smtpgate/users/vin/conf:
  #############################################################
  INHERIT:       MY-sendmail
  To:            vin-members@etl.go.jp
  Sender:        ${expn:vin-members@etlpom}
  Header:        X-Seqno: ${seqno} ## sequence number
  OPTION:        isn               ## Increment-Sequence-Number
  #############################################################

ここで、${expn:name@host} は、host上のnameに関するaliasesを展開した結果を
表します。


2.SMTPGATE コンフィギュレーション記法
----------------------------------------

prefix/name: value という行形式を並べて書く。複数行にわたる場合には、継続行
の先頭に空白(スペースまたはタブ)を入れる。各行の中で "#" 以降はコメントと
して無視される。name: と value の間、および行末には任意個数の空白が有ってよ
い(無視される)。以下で (*) をつけたものを除いて、prefix は省略することが
できる。

  prefix   name          value
  -------- ------------- ----------------------------------------
  CONTROL/ INHERIT:      親クラス?名
  CONTROL/ SERVER-PROTO: 中継先サーバのプロトコル名
  CONTROL/ SERVER-HOST:  中継先サーバのホスト名
  CONTROL/ SERVER-PORT:  中継先サーバのポート番号
  CONTROL/ OPTION:       中継先"," で区切られたオプションフラグのリスト

  OUTPUT/  Newsgroups:   NNTPへの中継時に付加する Newsgroups:
  OUTPUT/  Distribution: NNTPへの中継時に付加する Ditribution:
  OUTPUT/  Reply-To:     NNTPへの中継時に付加する Reply-To:
  OUTPUT/  To:           SMTPへの中継時の送信先。${sender} 指定は返送を意味
  OUTPUT/  Subject:      送信メッセージのSujbect
  OUTPUT/  Header:       送信メッセージへの任意のフィールドの追加
  OUTPUT/  FILTER:       送信メッセージを加工するフィルタのパス名(CFIも可)

  ACCEPT/  Sender:       許可すべき送信者のリスト
  ACCEPT/  Recipient:    許可すべき受信者のリスト
  ACCEPT/  From:         許可すべきFrom:フィールドの値のリスト
 *ACCEPT/  To:           許可すべきTo:フィールドの値のリスト
  -------- ------------- ----------------------------------------

  INHERIT で指定できる組み込みクラス?名

    postnews   NNTPへの中継器
    sendmail   SMTPへの中継器
    ftpmail    FTPへの中継器 (未完)
    httpmail   HTTPへの中継器 (予定)

  ACCEPT でのアドレスマッチング

    ACCEPTで指定するフィールド値は、以下のように "," で区切られたアドレス(の
  部分列)の並びである。

        addr1,addr2,addr3,...

  "…でないもの" は、"!…" のように先頭に "!" を付けて表す。
  リストの最初が "!" で始まる場合、明示的に指定されたかったものは許可となり、
  そうでない場合には、明示されない限り禁止となる。

      例: Sender: d1, d2, !x.d1, u@x.d1
          送信者が d1 からなら許可
          送信者が d2 からなら許可, ただし x.d1 は禁止、ただし u@x.d1 は許可
          これら以外のものは禁止

      例: Sender: !d1, !d2
          基本的に許可、ただし  d1 と d2 からのものは禁止

  リストの要素としては、アドレスの部分列の他に、メイルリストのファイル名
  と、"${expn:name@host}" の形式が使用できる。メイルリストファイルは、
  aliasesファイルから :include:/path/of/list-file の形式で参照されるファイル
  の形式である。"${expn:name@host}" は、SMTPのEXPNコマンドを用いて、host上の
  nameに関する alias を展開した結果のリストである。いずれの場合も、現在検査
  しているアドレスが、リストにに含まれるなら許可となる。

  OUTPUT で指定できる特殊フィールド値

    ${sender}           送信者のアドレス (OUTPUT/To: での返送に用いる)
    ${recipient.name}   宛先アドレスから @domain を除いた部分
                        OUTPUT/To: で使って他のホストにごっそり転送したり、
                        OUTPUT/Newsgroups: で使ったりする。。。
    ${seqno}            中継したメール数のカウンター (要 OPTION: isn)
    ${error.status}     エラー時返送メールの OUTPUT/Subject: で使用する
    ${subject}          中継中のメールの(オリジナルの)Subject
    ${subject:hc}       先頭の "[...]" と 重複 "Re:" を除去した Subject

  OPTION で指定できるオプションフラグ名

    res  Reject-Empty-Subject      Subjectが無いか空の記事を不許可とする
    rni  Reject-No-message-Id      Message-Id の無い記事を不許可とする
    axo  Append-X-Original header  中継不可なフィールドをエスケープして中継
    rxo  Remove-X-Original header  元メッセージ中のX-Oヘッダを削除して中継
    gwt  GateWay-Trace             動作トレース情報をメッセージ末尾に付加
    isn  Increment-Sequence-Number 中継したメール数をカウントする


3.Unix上での SMTPGATE DeleGate の初期設定の例
-----------------------------------------------

(1) /etc/services に以下を追加。

    delegate-smtp 8025/tcp

(2) /etc/inetd.conf に以下を追加。

    delegate-smtp stream tcp wait daemon /usr/lib/mail/smtpgate/bin/smtpgate

  ここで "bin/smtpgate" は以下のようなスクリプトとする。

    delegated -P8025 ¥
                SERVER=smtp ¥
                VARDIR=/usr/lib/mail/smtpgate/delegate ¥
                SMTPGATE=/usr/lib/mail/smtpgate ¥
                PERMIT="smtp,nntp:*:localhost"

(3) /etc/sendmail.cf に以下の規則を追加。

    #### MAILER DEFINITIONS #### 通常の Msmtpのものを複製し 8025 を加える
    Msmtpgate, P=[IPC], F=mDFMuX, S=11, R=21, T=DNS/RFC822/SMTP,
               A=IPC $h 8025, E=¥r¥n, L=990

    ####  RULESET 0 ###  user@smtpgate 宛てなら localhost:8025 へ中継する
    R$*<@smtpgate$*>$*   $#smtpgate$@localhost$:$1

    これらは、foo@smtpgate 宛てのメールを、smtp://localhost:8025 に転送する
  ための規則です。

  #sendmail.cf をいじらずに -Plocalhost:25 として /etc/rc.local から起動
  #すれば、上記(1)(2)は不要ですが、delegated が何かの都合でこけてる時に、
  #localhost:25もご本尊 sendmail が掴んでエラーにしてしまいそうなので心配。
  #そもそも、ADDRANY でbind済されているポートに、アドレス指定付きのbindを
  #後から追加できないシステムもある(確かSolaris2.Xはそう)
  #
  #もちろん、SMTPGATE-DeleGateを本ちゃんの25番ポートに据えたメールサーバ
  #を作るなら、この項は不要です。


(4) /usr/lib/mail/smtpgate/admin/ に基本的な管理ファイルを作成する

    ./MY-postnews/conf: ニュースサーバへの中継方法

         INHERIT:     postnews     #### 組み込みのSMTP-to-NNTP変換器
         SERVER-HOST: nntpserver   #### NNTPサーバのホスト名

    ./MY-sendmail/conf: メールサーバへの中継方法

         INHERIT:     sendmail     #### 組み込みのSTMP-to-STMP中継器
         SERVER-HOST: mailserver   #### SMTPサーバのホスト名

    ./@default/conf:    該当アドレスが無い場合の処置方法

         INHERIT:     sendmail
         SERVER-HOST: mailserver
         To:          ${sender}    #### 送信者への返送
         Subject:     Returned mail: unknown user ${recipient.name}
         OPTION:      gwt          #### トレース情報の付加を指定

(5) /usr/lib/mail/smtpgate/users/ ディレクトリを作成し、ML開設を許可すべき
    利用者が自由に書き込めるオーナ・アクセス許可を設定する。

--------------------------------------------------------------------------

                    @ @  
佐┬─┐─┬─┌   //\^^   ( - )
藤├─  │ │ / 876m\  _<   >_ 
豊┴── ┴ ┴──────────────────────────────┘