[PREVIOUS CHAPTER] [NEXT CHAPTER]

9 Security

    9.1	Security 関係の基本思想

    基本的に

       1	デフォールトではすべてを認めない
       2	大丈夫と思われるものを通すようにする
       3	疑わしきものははじいて判断をＭＬの管理者へあおぐ

    という風に構成されています。

    9.2	Security Check Routine

    ファイアウォールでも同様ですが、概念的に２種類の考え方が出来ます。

    	1 明らかに危ないものを除いていく
    	2 安全なものを許可していってそれ以外は拒否する
    	1 deny all, permit secure conditions
    	2 permit all, deny known insecure conditions.

    fml は 1 のポリシーを採用しています。fml-support: 00950 でも述べていますが

    	1.x は外掘から埋める方式 (関数 InSecureP)
    	2.y は内掘から埋める方式 (関数 SecureP)

    といってます(^^)。1.x と 2.y の関係はそのまま 上の 1 と 2 の違いといっ
    て間違いありません。

    SecureP は以下のように『コマンドとしてうけいれる命令(メールの一行全体
    について実行)の形を限定』します。

        １ 	\w/\w の部分は見逃す。＃ ../ とか .[a.]/ とかはだ〜め
           	/ でOKのところは消去する
    	また、まとめ送り等の m=数字 等の特別なシンタックスは消去する。

        ２ 	/^[\#\s\w\-\.\,\@\:]+$/

        の形はゆるす。
        ＃注意： \w は [A-Za-z0-9_] なので、 "-" を加えた

        [Extension]
    	ユーザの拡張用に %SECURE_REGEXP というハッシュが用意されています。
    	このハッシュ(KEYは適当でよい)のいずれかの正規表現
    	にマッチしたら、ＯＫになるように動きます。
    	これは YOUR OWN RISK で定義して下さい。

    	逆に %INSECURE_REGEXP ハッシュはまずいパターンを記述できます。

        ３ 	これ以外を含んでいたらエラー

        ４ 	特殊なケース（admin コマンドの admin addr m=3) は
    	事前に例外処理をした後 &SecureP にまわす。

    例：	許される例

       summary
       mget 1-20,30,last:20 mp 1
       mget 10? mp 1			(default では許さない)
       mget 1[012]? mp 1			(default では許さない)
       chaddr fukachan@phys.titech.ac.jp fukachan@beth.phys.titech.ac.jp

    例：	許されない例
       mget `domainname`

    例外処理として:

       whois 日本語

    をどうしよう？という問題があります。今のところ”通さない”設定のままで
    すが、これはこれで何とかするべき問題なのですが、良い解決策はありません。

    例：	許されるパターンを拡張する例(%SECURE_REGEXPを使う)

       $SECURE_REGEXP{'whois'} = '\s*whois\s+\033\$[\@B][\041-\176]+\033\([BJ]\s*';

       ＃注意:
       ＃このパターンを調べるべき対象の文字列全体にマッチさせるので
       ＃最後のスペース等がありうるのなら、それらも考慮する必要がある

    [捕捉] 許されるコマンドのシンタックス
    シェルと関係しています。

    Quoted from 4.4BSD:/usr/share/man/cat1/sh.0
           Shell Patterns

           A pattern consists of normal characters, which match them-
           selves, and meta-characters.   The meta-characters are
           ``!'', ``*'', ``?'', and ``[''.  These  characters lose
           there special meanings if they are quoted.  When command
           or variable substitution is performed and the dollar sign
           or back quotes are not double quoted, the value of the
           variable or the output of the command is scanned for these
           characters and they are turned into meta-characters.

           An asterisk (``*'') matches any string of characters.   A
           question mark matches any single character. A left bracket
           (``['') introduces a character class.  The end of the
           character class is indicated by a ``]''; if the ``]'' is
           missing then the ``['' matches a ``['' rather than intro-
           ducing a character class.  A character class matches any
           of the characters between the square brackets.   A range
           of characters may be specified using a minus sign.  The
           character class may be complemented by making an exclama-
           tion point the first character of the character class.

           To include a ``]'' in a character class, make it the first
           character listed (after the ``!'', if any).  To include a
           minus sign, make it the first or last character listed

    NOTE: 1998/11/08 permit "admin add MAR+KUN@DOMAIN " syntax

      +'ed user <addr+ext@domain> (for sendmail users):
    	fix to permit this address syntax when automagic registration.
    	but not fix to permit command with this addr beautifully.
    	# so require more eloborate design

      +'d ユーザのアドレス体系を扱えるように修正

    9.3	DNS Spoofing

    デフォールトでは何もしていませんが $LOG_CONNECTION がONの時は

    	$LOG_CONNECTION = 1;

    コネクションを張ってきた相手先のIPアドレスを $PeerAddr に設定します。
    firewall 越しだったりすると無意味ですが…$PeerAddr という変数に相手の
    ホストのIPアドレスが保存されます。$PeerAddr を使って DNS Spoofing
    Check コードをHOOK掛ければよいでしょう。

    9.4	Address Spoofing

    これは無理っす。もっと下のlayerで何とかしてね。

    9.5	SYN Flooding

    これもカーネルレベルの話。根本的な対策は難しい。

    9.6	Email アドレスの表現とRFC822

    	From: なんか / なんか (なんか)

    とかいう怪しげなフィールドを作ると経路の途中でエラーになって、その先に
    配送されないことがあります。securiity 関係の話なので詳しいことは説明し
    ませんが…

    それは(設計思想として)「疑わしきものははじく」ということから来ています。
    sendmail のソースを読めばなぜ弾くのか理解できます。

    RFC822 はBNF表現でできる理論限界を表現している文書です。確かに使っても
    構わないのですが、表現のクラスをかなり制限したアドレスを使っていないと
    通信できない可能性はあります。

    では、どういうものならよいのか？というとすべてを網羅した表現はうまくで
    きませんが…

    9.7	smrsh.c

    smrsh.c は、
    	"|program ..."
    の program が何を実行するか？ではなく program の名前が /usr/adm/sm.bin
    の中にあるかどうか？を見ています。＃ access(2) で、

    よって、/usr/adm/sm.bin/fml.pl ですね:-)

    9.8	access(2)

    smrsh.c は access(2) を使っていますが…うぅ

    --- NetBSD 1.2REL /usr/share/man/cat2/access.0

    CAVEAT
         Access() is a potential security hole and should never be used.

    4th Berkeley Distribution     September 15, 1996                             2

    --- perl5.003/perl.c

    	/* On this access check to make sure the directories are readable,
    	 * there is actually a small window that the user could use to make
    	 * filename point to an accessible directory.  So there is a faint
    	 * chance that someone could execute a setuid script down in a
    	 * non-accessible directory.  I don't know what to do about that.
    	 * But I don't think it's too important.  The manual lies when
    	 * it says access() is useful in setuid programs.
    	 */

    9.9	Precedence Priority

    sendmail 8.8.5 operations manual tells:

                 5.7.  P -- Precedence Definitions

                         Values for the "Precedence:" field may be defined
                    using  the  P  control line.  The syntax of this field
                    is:

                        Pname==num

                    When the name is found in a "Precedence:"  field,  the
                    message  class  is  set  to  num.  Higher numbers mean
                    higher precedence.  Numbers less than  zero  have  the
                    special  property  that if an error occurs during pro-
                    cessing the body of the message will not be  returned;
                    this  is  expected  to be used for "bulk" mail such as
                    through mailing  lists.   The  default  precedence  is
                    zero.  For example, our list of precedences is:

                        Pfirst-class=0
                        Pspecial-delivery=100
                        Plist=-30
                        Pbulk=-60
                        Pjunk=-100

                    People  writing  mailing list exploders are encouraged
                    to use "Precedence: list".  Older versions of sendmail
                    (which discarded all error returns for negative prece-
                    dences)  didn't  recognize  this  name,  giving  it  a
                    default  precedence  of  zero.  This allows list main-
                    tainers to see error returns on both old and new  ver-
                    sions of sendmail.

    9.10	4.4BSD vacation

         No message will be sent unless login (or an alias supplied using the -a
         option) is part of either the ``To:'' or ``Cc:'' headers of the mail.  No
         messages from ``???-REQUEST'', ``Postmaster'', ``UUCP'', ``MAILER'', or
         ``MAILER-DAEMON'' will be replied to (where these strings are case insen-
         sitive) nor is a notification sent if a ``Precedence: bulk'' or
         ``Precedence: junk'' line is included in the mail headers.  The people
         who have sent you messages are maintained as a db(3) database in the file
         .vacation.db in your home directory.

    9.11	File and Directory Permission Default

    umask(2) default is customizable.

    	$FML_UMASK	for fml.pl
    	$MSEND_UMASK	for msend.pl
    	$UMASK	is used if neither $FML_UMASK nor $MSEND_UMASK is not defined.

    9.12	Directory Permissions

    複数の人が fmlserv と一緒に使う場合 fmlserv はメンバーリストを書き変え
    る等のために group permission が必要です。
    ＃ そのために root process を作れば、そうでなくてもできなくはないはず
    ＃ ですが、root process を増やすことはやりたくないので

    	$USE_FML_WITH_FMLSERV

    変数はそれを意味するための内部変数ですが、普通は fml.pl が $DIR の隣に
    fmlserv という directory があるなら自動的に設定します。うまくいかない
    ときは explicit に設定して下さい。それから $GID も fmlserv のために導
    入された変数です。

    9.13	sendmail 8.8 における check_* ルールセットについて

    詳しくは CF を読んでね。sendmail 8.8 では様々なアクセス制御を容易にカ
    スタマイズできるように以下のようなルールセットが用意されています。CFで
    物足りない場合（そうはないとおもうぞ）はこれらを使ってごりごり
    sendmail.cf を書きます。

    check_mail          発信者のチェック
    check_rcpt          受信者のチェック
    check_relay         SMTP接続のチェック
    check_compat        発信者および受信者のペアについてのチェック

    またSMTPコネクションの接続要求に対して tcp_wrapper のライブラリである
    libwrap.a を使うように sendmail を compile しておけば、
    /etc/hosts.allow などで制御できるようになります。NetBSD 1.3 などの最新
    のOSではこれが配布されるソースでのデフォールトです。
    ちなみに tcp_wrapper におけるデーモン名は sendmail です。

    Example:

    [/etc/hosts.allow]

    sendmail: mikoto.fml.org

    [/etc/hosts.deny]

    ALL: ALL

    check_mail と check_rcpt はSMTP処理ルーチン srvrsmtp() 内でそれぞれ
    MAIL FROM: と RCPT TO: の命令の引数に対して適用されます。つまりそれぞ
    れ SMTP で渡される MAIL FROM:のアドレス(発信者)と RCPT TO:のアドレス
    (配送先)のチェックに使われます

    check_relay はSMTPコネクションが張られた時に適用されます。check_relay
    は validate_connection() で呼ばれ接続が成立した SMTPコネクションが接続
    を許可されているホストからのものか？などについてチェックをします。
    validate_connection() では tcp_wrapper 形式の制御も可能です(前述)。

    check_compat は単純なチェックではなく送信者と受取人の組で判定をしなけ
    ればならないような複雑な判定に使います。
    check_compat は配送ルーチン deliver() で適用されメールの送り主と配送
    先のペアについてSMTP translation だけでなく配送するメールの全てについ
    て適用されます。

    9.14	SMTP and Authentication

    draft-myers-smtp-auth-11.txt (submitted to be Proposed Standard)
    RFC2222 (SASL)

    SASL: Simple Authentication and Security Layer

    draft-hoffman-smtp-ssl-06.txt (SMTP over secured layer)

    9.15	&system() function

    system は perl の内部関数ではなく独自に書いた system を使っています。
    何故かうまく動かない場合や、fork() がないNTなどでは perl 附属の
    system() を使わざるを得ない場合があります。デフォールトでは perl 附属
    の system() を使っていません。

    コマンドがうまく動かない場合に

    	$INSECURE_SYSTEM = 1;  (default 0)

    という変数設定をして動くことがあるかもしれません。

    なお NT では system() を使っています。

    いずれの場合でもシンタックスチェックが事前に行なわれ、その後 system を
    呼んでいます。

[PREVIOUS CHAPTER] [NEXT CHAPTER]