素敵なteapop

2002/07/05


teapop は、最初の配布が 1999/08/24 と、比較的最近作られた pop3 サーバです。
現時点でのバージョンは2002/06/11の0.3.5です。
公式な配布サイトは、
http://www.toontown.org/teapop/
となっています。
NetBSD, FreeBSD 等は pkg, ports に採り入れられており、すぐに使える状態になっていると思います。Linux では rpm 形式もあるようです。

最近作られただけあって、現在の流行にはよくマッチしている部分が多いです。特徴的な機能を挙げてみます。

認証の方法として利用できるものが、他のものに比べ多くなっています。
mbox、Maildir形式の両方に対応することで、MTAとの組み合わせ種類が広がります。
新しいものということで実績が心配ですが、いまのところ CERT-Advisary には上がっていません。

次の部分はちょっと残念だな、と思ったところです。

IPv6 に対応していないというのは、昨今のものとしては大変に遅れてる部分かもしれません。
認証IPファイル出力が hash, dbm に直接対応していれば、DRAC が必要なくなるかもしれません。どちらにしても、現時点では、かなり自由度の高い POP3 サーバではないかと思っています。
余談ですが、teapopがおしゃべりするpopメッセージは、とても丁寧です。 :-)

ここでは、Solaris 8 + postfix + DRAC + teapop という環境で、Pop Before SMTP 環境を構築する例を記述します。

レンタルサーバでのSMTPサービスなど、不特定多数から送信要求があるメールサーバは、何らかの認証を行った上でリレーを許可する必要があります。この認証に pop を利用するのが Pop Before SMTP です。
本質的にはSMTP AUTHを利用するべきかもしれませんが、既存のクライアントを変更する必要がないため、現時点では有用な解決策です。

Pop Before SMTPを実現するためには、例えば、ipop3d にパッチを当てて利用したり、poprelayd などの perl スクリプトを利用するものは多いですが、それぞれ、それなりに面倒です。
teapopは、Pop Before SMTP を単体でサポートしてしまおう、という実装になっています。

 


1. 環境

次のような環境を想定しています。

なお、Solaris 8 上での開発用環境は、Companion-CD についてくる gcc 等を利用することにします。これらは、/opt/sfw にインストールされます。


2. 各ソフトウエアの取得場所

ここでは、以下のソフトウエアは「自力で」インストールしますので、各サイトから取得する必要があります。オフィシャルサイトは、次の通りです。

DRAC

http://mail.cc.umanitoba.ca/drac/

postfix

http://www.postfix.org/

teapop

http://www.toontown.org/teapop/

DRACを利用するために、Berkeley-DB が必要となります。Solaris は標準でも利用できますが、Companion-CDにバージョンが上がったものが含まれていますので、そちらをインストールして使うことにします。

teapop の make には GNU-make が必要です。これも Companion-CD にありますのでインストールしておきます。


3. DRACのインストール

DRAC とは、Dynamic Relay Access Control の略で、SMTPサーバが動的にリレー可否を制御するデータベースを書き換えるための、クライアントサーバ型のプログラムです。drac クライアントとなるプログラムは、rpcを通して drac サーバと通信し、drac サーバがデータベースを書き換えます。

Pop Before SMTPは、pop認証が成功した接続クライアントのIPアドレスをSMTPサーバが読み込める形で提供し、SMTPサーバはそのアドレスは動的に許可対象とすることで実現されます。
この仕組みは、例えばpopサーバはIPアドレスをテキスト形式で書き出し、一定時間毎にperlスクリプトで更新する仕組みや、popサーバがその更新プログラムを認証時に起動するなどの方法もあります。

dracは、認証に成功したIPアドレスを通知する為のライブラリ(dracクライアント)通して、SMTPサーバが直接読み込める形式のファイルを出力する(dracサーバ)までを行います。

3.1. インストール

DRAC には configure スクリプトのような便利なものがありません。自力で Makefile を書き換えます。
DRAC の make には、Berklay-DB が必要です。Solaris の場合は OS にも付属しますし、 Companion-CD にも新しい版があります。ここでは Companion-CD にものを利用しましたので、それを利用するように記述します。
書き換えるべきなのは、利用するコンパイラと、Berkeley-DB のインクルードファイル、ライブラリの位置指定です。

CC = gcc
CFLAGS = $(DEFS) -g -I/opt/sfw/include
LDLIBS = -L/opt/sfw/lib -lnsl -ldb

書き換え後、

# make
# make install

でインストールします。
特になにもしなければ、/usr/local/sbinにrpc.dracd がインストールされます。

3.2. 設定

dracd のデフォルトでは、アクセスコントロールファイルは、/usr/local/etc/dracd.allowにあります。このファイルに、ローカルホストからのリクエストのみ許可するように記述しておきます。
netmask netaddr の順序なので、間違えないようにしてください。

 

# dracd.allow: clients trusted by rpc.dracd
#
255.255.255.255 127.0.0.1

システム起動時に、drac を自動的に起動させるために、次のようなスクリプトを/etc/init.d/dracd という名前で記述して、/etc/rc2.d/S98drac などの名前にリンクしておきましょう。

#!/bin/sh -
#
# dracd

PATH=/usr/local/sbin:/usr/bin:/usr/sbin; export PATH
DAEMON=rpc.dracd
DRACD_PID=`ps -e | grep 'rpc.drac$' | sed -e 's/^  *//' -e 's/ .*//'`

dracd_running() {
        ps -p $DRACD_PID >/dev/null 2>&1
}

case "$1" in
start)
        if dracd_running; then
                echo "$DAEMON is already running" >&2
        else
                echo "starting $DAEMON" >&2
                $DAEMON
        fi
;;
stop)
        if dracd_running; then
                echo "stopping $DAEMON" >&2
                kill $DRACD_PID
        else
                echo "$DAEMON is not running" >&2
        fi
;;
*)
        echo "Usage: /etc/init.d/dracd {start|stop}" >&2
;;
esac

#!/end

dracdが、データベースから認証したIPアドレスの削除を行うまでの時間は、デフォルトでは30分です。もしこの時間を調整する場合は、rpc.dracd起動時のオプションに -e minutes を指定します。minutes は、分単位の数値です。


4. postfix

postfix は、sendmail 互換プログラムを持つ MTA です。設定が簡単、かつ高性能なため、最近よく利用されています。NetBSD では、標準でインストールされています。

4.1. インストール

postfix で DRAC を利用する場合、作成時に少し作業が必要です。

DRAC はリレー許可データベースを、Berkeley-DB の btree 形式で吐き出します。これを読む為には、postfixも Berkeley-DB 対応で作成する必要があります。
README_FILES/DB_README に次のような記述があります。

% make tidy
% make makefiles CCARGS="-DHAS_DB -I/usr/local/BerkeleyDB.3.1/include" \
	AUXLIBS="-L/usr/local/BerkeleyDB.3.1/lib -ldb"
% make

このままでは、Companion-CD から入れた Berkeley-DB の位置が違うのと、postfix の起動時に LD_LIBRARY_PATH を記述していても、 db-3.1.so がない、というエラーになって動作できません。
なにもしなくても動作するよう、LD_RUN_PATH に該当する -R オプションと共に、次のように指定します。

% make tidy
% make makefiles CCARGS="-DHAS_DB -I/opt/sfw/include" \
	AUXLIBS="-L/opt/sfw/lib -ldb -R/opt/sfw/lib"
% make

インストール時の対話スクリプトは、特になにもしなければ、設定ファイル /etc/postfix、バイナリ /usr/sbinにインストールされます。

postfix は sendmail互換コマンドを持っているので、Solaris 標準の sendmail コマンドを置き換えようとします。置き換えたほうが後の取扱が楽になりますので、置き換えてしまったほうがいいです。
もし、必要なら保存しておいたほうがいいでしょう。

# mv /usr/lib/sendmail /usr/lib/sendmail.sun.orig

 

4.2. 設定

このメールサーバが、どの宛先を受け取るのかは、記述しなければなりません。ここに記述されているところ以外に送信しようとすると、不正リレーとみなされます。

mydestination = $myhostname, localhost.$mydomain, $mydomain, mail.$mydomain

postfix での Pop Before SMTP 設定は、/etc/postfix/main.cf に、次のような設定を追加する必要があります。
dracデータベースは特に指定しなければ btree形式となり、ファイルは /usr/local/etc/dracd.db として作られますので、check_client_access には次のような指定をします。

# POP Before SMTP Setting
smtpd_recipient_restrictions =
        permit_mynetworks,
        check_client_access btree:/usr/local/etc/dracd
        check_relay_domains

システム起動時に、postfix を自動的に起動させるために、次のようなスクリプトを/etc/init.d/postfixという名前で記述して、/etc/rc2.d/S98postfix などの名前にリンクしておきましょう。

#!/bin/sh -

PATH=/usr/sbin:/usr/bin

case $1 in
start)
        postfix start
        ;;

stop)
        postfix stop
        ;;

reload)
        postfix reload
        ;;

*)

        $FATAL "usage: postfix [ start | stop | reload ]"
        exit 1
        ;;

esac

 


5. teapop

5.1. インストール

teapop は、configure スクリプトにより make 環境をそろえることができます。
configure には、次のオプションが指定できます。
(通常触れなくていいところは抜いてあります)

--enable-piddir=DIR

スタンドアロンモード時の PID ファイルディレクトリを指定します

--enable-homespool=MAILBOX

Maildir 形式を扱うディレクトリ名を指定します

--enable-mailspool=DIR

mbox 形式のディレクトリ名を指定します

--enable-lock

ファイルロックをサポートします。デフォルトは flock です

--disable-apop

APOP を無効にします

--disable-vpop

バーチャルドメインを無効にします

--enable-extra-dividers=CHARS

メールアドレスの分離文字を指定します(デフォルト %)

--with-pgsql[=DIR]

PostgreSQL による認証をサポートします

--with-mysql[=DIR]

MySQL による認証をサポートします

--with-drac[=LIBDIR]

DRAC をサポートします

--with-dracinc=DIR

drac.h があるディレクトリを指定します

--with-whoson[=LIBDIR]

Whoson をサポートします

--with-whosoninc=DIR

whoson.h があるディレクトリを指定します

--enable-popauth-file[=FILE]

popauth ファイル出力をサポートします

--localstatedir=DIR

popauth ファイルができる位置を指定します

--with-java=DIR

Java による認証をサポートします

--with-javaclass=CLASS

Java AUTH クラスの位置を指定します

--with-ldap=openldap

OpenLDAP による認証をサポートします

--with-ldapinc=DIR

OpenLDAPのインクルードファイルがあるディレクトリを指定します

--with-ldaplib=DIR

OpenLDAPのライブラリがあるディレクトリを指定します


この例での目的は、DRACを利用して Pop Before SMTP を行うことです。
そこで、configureには、次のように指定します。

./configure  --enable-homespool=Maildir/ --with-drac=/usr/local/src/drac

このとき、--enable-homespool=Maildir/ オプションの最後のスラッシュに気をつけてください。pop_passwd.c の中で「最後の文字がスラッシュだったら Maildir形式」という判定をしています。
doc/INSTALLには、

./configure --enable-homespool=Mail

という例が記述されていますが、これはホームディレクトリにあるmbox形式の例を示しています。 Maildir形式を利用する場合は、スラッシュを忘れないでください。 また、DRACのパスを指定するときには、絶対パスで指定してください。相対パスだと、うまくいきません。

configure が終ったら、make します。GNU-makeが必要ですので注意してください。

# gmake
# gmake install

 

5.2. 設定

teapop は、inetd からでも、スタンドアロンでも起動できます。

inetd から起動させる場合は、inetd.conf に

pop3    stream  tcp     nowait  root    /usr/local/libexec/teapop teapop

のような記述が必要です。

スタンドアロンで起動する場合は、-s オプションをつけて起動します。
teapop を DRAC 対応で動作させるときには、rpc.dracd が動作しているホストの指定が必要です。この指定は -p IPアドレス です。

スタンドアロンで、ローカルのDRACサーバを利用する場合は次のようなコマンドになります。

# teapop -s -p 127.0.0.1

スタンドアロンで起動するときには、次のようなスタートアップスクリプトを記述して、/etc/init.d/teapopというような名前で置き、/etc/rc2.d/S99teapop という名前にリンクしておきましょう。

#!/bin/sh -
#
# teaop

PATH=/usr/sbin:/usr/bin
DAEMON=/usr/local/libexec/teapop
TEAPOP_PID=/var/run/teapop.pid

case "$1" in
start)
        $DAEMON -s -p 127.0.0.1
        echo "starting $DAEMON" >&2
;;
stop)
        kill `cat $TEAPOP_PID`
        rm -f $TEAPOP_PID
;;
*)
        echo "Usage: /etc/init.d/teapop {start|stop}" >&2
;;
esac

#!/end

 


6. 動作確認


動作の確認に関する主眼は次の点です。

  1. postfix が不正リレーを行わないこと
  2. teapop が 正しく認証できること
  3. teapop で認証されたクライアントの接続IPアドレスが、DRAC データベースに反映されること
  4. postfix が認証したIPアドレスからの接続をリレーできること

6.1. postifxの不正リレー防止確認

まず、postfix が正しく不正リレーを防止しているかを確認します。
例えば、設定しているドメイン以外のメールアカウントがあるのであれば、設定しているサーバを狙って、From:もTo:もこのサーバ以外になるようにしたメールを送ってみます。送信できなければ多分不正中継は防止されているでしょう。

しかし、もうすこし確実な方法を試みてみます。
実際に外部のネットワークからこのサーバに対してSMTP接続を行い、どのようなエラーとなるのかを目で見てみます。

このサーバが接続されているネットワーク外のどこかから、このサーバに対して、telnet を利用して接続します。例えば、このサーバが次のような環境であるとします。

ドメイン

hogehoge.jp

サーバ

mail.hogehoge.jp


このサーバに対しては、次のように接続できます。

% telnet mail.hogehoge.jp 25
220 mail.hogehoge.jp ESMTP Postfix

上のようなメッセージが表示されれば接続成功です。

手動でSMTPを喋ってみます。

HELO hogehoge.jp
250 mail.hogehoge.jp
mail from: foo@hoge1.jp
250 OK
rcpt to: bar@hoge2.jp
554 <bar@hoge2.jp>: Recipient address rejected: Relay access denied
rcpt to: user@hogehoge.jp
250 OK

bar@hoge2.jpに送った場合のように、rcpt to:で指定されるアドレスがサーバがスプールするドメイン以外の場合にrejectされれば、不正中継を防止しています。
user@hogehoge.jpの場合のように受け取るべきメールアドレスを指定した場合は、250 OKのレスポンスが返されます。

6.2. teapopの認証

では、同じサーバに対して、popを行ってみます。
お使いのMUAでpopしてもいいです。もちろんこのとき、アカウントは存在していなければなりませんので、先に作成しておくことを忘れないでください。

ここでも、手動でpopを喋ってみます。

telnet mail.hogehoge.jp
+OK Teapop [v0.3.5] - Teaspoon stirs around again <NNNNNNNNNN.HHHHHHHH@Llwellyn>
user user
+OK Welcome, do you hve any type of ID?
pass password
+OK I'm ready to serve you, Master

teapopが接続クライアントのことを「Master」と言ってくれれば、認証は完了しています。

6.3. DRACデータベースへの書き込み

ここまでできれば、DRACデータベースには、接続したIPアドレスの情報が記録されているはずです。
Barkeley-DB付属の db_dump コマンドで内容を確認してみます。

# db_dump -p /usr/local/etc/dracd.db
VERSION=2
format=print
type=btree
HEADER=END
210.174.nnn.mmm
1026039925
DATA=EN

表示されるIPアドレスの中に、pop接続を行ったホストのIPアドレスがあれば、成功です。

6.4. Pop Before SMTPリレー

これで、すべての機能は正常に動作しています。
再び、postfixのリレー防止確認と同様の手順で、接続してみます。

% telnet mail.hogehoge.jp 25
220 mail.hogehoge.jp ESMTP Postfix
HELO hogehoge.jp
250 mail.hogehoge.jp
mail from: foo@hoge1.jp
250 OK
rcpt to: bar@hoge2.jp
250 OK
rcpt to: user@hogehoge.jp
250 OK

今度は、bar@hoge2.jpも、正常な送り先として認識されています。


7. その他の情報


teapopの man page日本語訳したもの をつくりました。一部力及ばずで訳してません。