James君!〜単純に起動してみる

インストール

まあ、James君を起動してみる、なんてのはカンタンだ。下手すりゃ qmail とか Postfix を自前で立ち上げる、なんてことをするよりも単純じゃなかろうか(qmail だと最近の Linux だとコンパイルが素直に通らなかったりするしな..)。

とりあえず Apache から James を落せばいい。で、テキトーなディレクトリで解凍してやる。そうすると、次のようなディレクトリ構成になっているのが判ると思う。

james-2.2.0 -+- apps  --- james.sar
             +- bin   --- run.sh とか
             +- conf  --- kernel.xml と wrapper.conf (←Phoenix の設定ファイル)
             +- docs  --- ドキュメント類
             +- ext   --- 大したものは入ってない!
             +- lib   --- phoenix が起動するのに使うライブラリたち
             +- logs  --- phoenix のログ出力ディレクトリ

何かねえ、異常にシンプルな構成だ....と悪い予感のしたあなた、勘がいい。最初に言っておくけど、ここで各ディレクトリとして展開された内容は、「単に Phoenix が動作するためだけのディレクトリ構成である」ということなんである。言い替えると、「汎用サーバを実現する Phoenix」が起動するための環境をここで展開しただけなのである。具体的なメールサーバの機能を実現する部分は、実はまだ james.sar の中で固まっているのである!

つまり、今展開されたディレクトリ構成は、Phoenix ベースのサーバであれば、どれでも同じようなものになるのである。まあ、ここでファイルを見ても実際には何もできないので、とりあえず仕方がない。「設定がどうのこうの」言わずに、bin/run.sh をとにかく起動する(が、run.sh と phoenix.sh には実行パーミッションが立っていないので、こいつを立ててから起動せんとあかん)

$ cd james-2.2.0/bin
$ chmod 755 run.sh phoenix.sh
$ ./run.sh
Using PHOENIX_HOME:   /home/sug/public_html/soft/james/james-2.2.0
Using PHOENIX_TMPDIR: /home/sug/public_html/soft/james/james-2.2.0/temp
Using JAVA_HOME:      /usr/local/jdk1.5.0_04
Running Phoenix:

Phoenix 4.0.1

James 2.2.0
Remote Manager Service started plain:4555
org.apache.excalibur.containerkit.lifecycle.LifecycleException: Component 
named "pop3server" failed to pass through the Initialization stage. 
(Reason: java.net.BindException: Permission denied).
        at org.apache.excalibur.containerkit.lifecycle.LifecycleHelper.fail
                                                 (LifecycleHelper.java:289)
        (略)
Caused by: java.net.BindException: Permission denied
        at java.net.PlainSocketImpl.socketBind(Native Method)
        at java.net.PlainSocketImpl.bind(PlainSocketImpl.java:359)
        at java.net.ServerSocket.bind(ServerSocket.java:319)
      (略)

---------------------------------------------------------
The log file may contain further details of error.
Please check the configuration files and restart Phoenix.
If the problem persists, contact the Avalon project.  See
http://jakarta.apache.org/avalon for more information.
Shutting down Phoenix.
$ 

....のっけから例外スタックトレースなんて見せてすまん。まあ、こりゃ「BindException: Permission denied」で判るように、通常の POP3ポート(110番)を root 特権なしに開こうとした、というわけである。もし root になってやったとしても、多分テストするのにデフォルトのメーラとかを落してからやる、なんて配慮してないだろう。どうせ「BindException: Socket already in use」とか怒られるに決まってるから、とりあえず例外を投げるのを見せたわけである。

しかし、これでもイイ。さて、お立ち会い。apps/james ディレクトリを見てみると、解凍した時にはなかった james ディレクトリが出来ている。要するに apps/james/james.sar を解凍するために、一旦起動して見せたのである。このディレクトリの中身はこうなっている。

james-2.2.0/apps/james -+- SAR-INF -+- assembly.xml
                        |           +- config.xml
                        |           +- environment.xml
                        |           +- lib -+- mm.mysql.LICENCE
                        +- conf    -+- james-fetchmail.xml など
                        +- logs    --- すでに大量のログファイル
                        +- var     -+- mail   -+- address-error
                                    |          +- error
                                    |          +- inboxes
                                    |          +- outgoing
                                    |          +- relay-denied
                                    |          +- spam
                                    |          +- spool
                                    +- users

で、簡単に説明すると SAR-INF ディレクトリの3つの XML ファイルが、James の設定ファイル、ということになる。conf ディレクトリという紛らわしいものがあるが、こっちは config.xml の中で include すべきファイルがあるだけで重要ではない。また var ディレクトリ以下は実際にメールの送受信を行うと、ここにメールがスプールされる、という寸法だ。まあ、それでも少し設定ファイル自体を解説しておこう。

assembly.xml
これは James の「構成」を決めるための設定である。後でこのファイルの見方については説明するが、単なる Mailet 開発のレベルではこれをいじる必要はない。要するに Phoenix に James の構成を教えるためにこれがある。
config.xml
これがメールサーバとしての James の詳細動作を設定するための設定ファイルである。今からこれをいじって、とりあえず一般ユーザでも James を起動できるようにする。
environment.xml
これはロガーの出力設定である。要するに log4j.properites みたいなものだが、Phoenix が使うのは Avalon Logkit であり、Avalon Logkit の設定ファイルである。これも後回し

config.xml

で問題の config.xml である。こいつは、

  1. でかい
  2. 複雑
  3. 難解

と三拍子揃ったものだが、とりあえずコイツを制覇しないことには始まらない。

とはいえ、大体の仕様を決めておく。これは通常のメーラの設定が判っていれば「なるほど」な設定項目にすぎない。しかし、今のマシンで動いているメーラを落すのは面倒なので、すべて「一般ユーザで開ける」1024番以上のポートで起動することにしよう。具体的に言い替えると、

SMTP使用ポート
1025
POP3使用ポート
1110
NNTP使用ポート
1119
受け取るべきドメイン
mydomain.jp と localhost

のようにデフォルトのポート番号に1000を足したものを使うことにしておこう(なぜデフォルトのポート番号を使わないか...は後で協調動作をするからね)。

で config.xml の中身をおおざっぱに示すとこんな構成だ。

config -+- James     -+- postmaster        言わずと知れた postmaster メールアドレス
        |             +- servernames -* servername  受け取るドメイン名(複数可)
        |             +- usernames         ユーザ名に関する設定
        |             +- inboxRepository -- repository  保存するディレクトリ指定
        +- fetchpop     fetchmail の旧バージョン設定
        +- spoolmanager これはややこしい。一種のパイプラインで
        |                                        メールの具体的な処理を指定する 
        +- dnsserver  DNSサーバ指定
        +- remotemanager 管理ツールの指定(すぐ後で触れる)
        +- pop3server POP3 サーバ設定
        +- smtpserver SMTP サーバ設定
        +- nntpserver NNTP サーバ設定
        +- nntp-repository NewsGroupの指定など
        +- mailstore  メール保存方法の指定
        +- users-store  Jamesユーザたちの管理
        +- database-connections  データベース接続管理
        +- objectstorage
        +- connections  コネクションの設定
        +- sockets      ソケットの設定
        +- thread-manager スレッドマネージャの設定

うーん、何か階層構造がよくわからん...という感想を持ったのではなかろうか? 実はこの階層構造には深い理由があるのだが、その説明は後半だ。とりあえず、今することは明白だろう。pop3server とか smtpserver, nntpserver といったタグの中に port タグがあればOKだ。実際、

   <pop3server enabled="true">
      <!-- port 995 is the well-known/IANA registered port for POP3S  ie over SSL/TLS -->
      <!-- port 110 is the well-known/IANA registered port for Standard POP3 -->
      <port>1110</port>
   ..........
   <smtpserver enabled="true">
      <!-- port 25 is the well-known/IANA registered port for SMTP -->
      <port>1025</port>
   ..........
   <nntpserver enabled="true">
   <!-- THE NNTP PROTOCOL IS EXPERIMENTAL AND NOT AS WELL TESTED AS SMTP AND POP3 IN THIS RELEASE.
        The James project recommends that you check the James web site for updates to the NNTP
        service.  -->
      <!-- port 563 is the well-known/IANA registered port for NNTP over SSL/TLS -->
      <!-- port 119 is the well-known/IANA registered port for Standard NNTP -->
      <port>1119</port>

という風に修正してやる。で、後は、

myname@localhost
myname@mydomain.jp

という風なメールアドレスを宛先とするメールが届いた時に、「これは自分が受け取るべきもの!」と James が判断するために、James ブロックを修正する。

<config>
   <James>
      <postmaster>Postmaster@localhost</postmaster>
      <servernames autodetect="true" autodetectIP="true">
         <servername>localhost</servername>
         <servername>mydomain.jp</servername>
      </servernames>

とりあえず config.xml の設定はOKである。

しかーし、今はまだ「ドメイン名」を指定しただけだ。そのメールを受け取るべきユーザがまだまったく作られていない。勿論 James はローカルユーザから受取人を拾い出して...なんてことはまったくしない。James でメールを受け取りたいアカウントは、一つ一つ作るのである。

RemoteManager

でこれを作るのが先ほどの config.xml にあった「remotemanger」である。この設定がどうなっているか、というと、

   <remotemanager>
      <port>4555</port>
      <!--  特定のIPアドレスに固定するならコメントを外せ -->
      <!--
      <bind> </bind>
      -->
      <!--  SSLを使うんならコメントを外せ -->
      <!--
      <useTLS>true</useTLS>
      -->
      <handler>
         <!-- RemoteManager プロトコルで、サーバが自分自身で名乗る名前
              もし、autodetect が TRUE なら、サーバはホスト名を自分で探す。
	      もし、発見に失敗したら localhost を使う。もし、autodetect が
	      FALSE ならここで指定する値を使う。 -->
         <helloName autodetect="true">myMailServer</helloName>
         <administrator_accounts>
            <!-- デフォルトの login/password 名は変えようね -->
            <account login="root" password="root"/>
         </administrator_accounts>
         <connectiontimeout> 60000 </connectiontimeout>
      </handler>
   </remotemanager>

なので、要するに管理用のデーモンが4555番でアクセスを待ち受けている、ということである。そのアカウント名/パスワードのデフォルトは root/root なので、これは適当に変えるがよかろう。

じゃあ、これでユーザ特権でも James が起動できることになっているはずである。しかも、多分他のデーモンが使っているポートとはバッティングしないはずだ。で、もう一度起動してみよう。そうすると今度は、

$ bin/run.sh
Using PHOENIX_HOME:   /home/sug/public_html/soft/james/james-2.2.0
Using PHOENIX_TMPDIR: /home/sug/public_html/soft/james/james-2.2.0/temp
Using JAVA_HOME:      /usr/local/jdk1.5.0_04
Running Phoenix:

Phoenix 4.0.1

James 2.2.0
Remote Manager Service started plain:4555
POP3 Service started plain:1110
SMTP Service started plain:1025
NNTP Service started plain:1119
Fetch POP Disabled
FetchMail Disabled

というような具合でバナーが表示がされ、現在 James が起動している状態だ。ここで、telnet を使って RemoteManager とお話しよう。

$ telnet localhost 4555
Trying 127.0.0.1...
Connected to localhost.
Escape character is '^]'.
JAMES Remote Administration Tool 2.2.0
Please enter your login and password
Login id:
root  ←変えた方が良い
Password:
root  ←変えた方が良い
Welcome root. HELP for a list of commands

でまあ、「HELPを叩くと使えるコマンドのリストを表示するよ!」とご親切に教えていてくれるので、そうしよう。

Welcome root. HELP for a list of commands
HELP
Currently implemented commands:
help                                    このヘルプを表示する
listusers                               存在するアカウントを表示する
countusers                              存在するアカウントの数を表示する
adduser [username] [password]           新しいユーザを追加する
verify [username]                       指定するユーザが存在するかかどうか検証する
deluser [username]                      存在するユーザを削除する
setpassword [username] [password]       ユーザにパスワードを与える
setalias [user] [alias]                 'user' 宛メールを 'alias' に転送する
showalias [username]                    そのユーザの現在のエリアスを表示する
unsetalias [user]                       エリアスを消す
setforwarding [username] [emailaddress] 転送指定をする
showforwarding [username]               現在の転送指定を表示する
unsetforwarding [username]              転送指定を止める
user [repositoryname]                   別なユーザを変更するようにする
shutdown                                James をシャットダウンする
quit                                    切断する

まあ、こんなことができるわけだ。実際、James の起動スクリプトは bin/run.sh と bin/phoenix.sh と2つあり、run.sh の内部で「phoenix.sh run」のかたちで phoenix.sh を呼び出している。まあ、phoenix.sh を引数無しで起動すると、

$ bin/phoenix.sh
Usage: bin/phoenix.sh {start|stop|run|restart|check}

と表示するわけで、一般的なデーモンと同様に、start(デーモン動作)、run(端末で実行)の2通りの動き方がある。まあ、実戦投入する時には、/etc/rc.d/init.d/james とかいうシェルスクリプトを書いて、そこで

${JAMES_HOME}/bin/phoenix.sh start

という風にきっとすることだろう。しかし、そうすると、落す時にどうするか?という問題がある。開発中は「phoenix.sh run」の方がやりやすく、これは端末と結び付いたままなので、それこそ Ctrl+C で殺しても全然問題がないが、デーモン動作をさせた場合には、

$ bin/phoenix.sh stop

か、

$ telnet localhost 4555
telnet localhost 4555
Trying 127.0.0.1...
Connected to localhost.
Escape character is '^]'.
JAMES Remote Administration Tool 2.2.0
Please enter your login and password
Login id:
root
Password:
root
Welcome root. HELP for a list of commands
shutdown
Shutting down, bye bye
Connection closed by foreign host.

で落すことになるわけである。

失礼、ユーザを作るんだったな。ユーザの作り方なんぞ、書いてある通りだ。

$ telnet localhost 4555
telnet localhost 4555
Trying 127.0.0.1...
Connected to localhost.
Escape character is '^]'.
JAMES Remote Administration Tool 2.2.0
Please enter your login and password
Login id:
root
Password:
root
Welcome root. HELP for a list of commands
adduser sug hogehoge
User sug added
quit
Bye
Connection closed by foreign host.

で、sug@localhost, sug@mydomain.jp のどっちでもメールを受け取れるアカウントが作られたことになる(パスワードは「hogehoge」)。念のために、var/users を見てみると、

$ ls -l apps/james/var/users/
合計 4
-rw-r--r--    1 sug      users         338 12月  7日  15:58 737567.Repository.FileObjectStore

というようなファイルが新たに出来ている。これにアカウントとかパスワードが書かれているわけだ。

受信テスト

じゃ、アカウントが出来たのでテストだ。ハッカーならこういう時は、手でメールを出すよね。

$ telnet localhost 1025
Trying 127.0.0.1...
Connected to localhost.
Escape character is '^]'.
220 bizet SMTP Server (JAMES SMTP Server 2.2.0) ready Wed, 7 Dec 2005 16:04:19 +0900 (GMT+09:00)
HELO localhost
250 bizet Hello localhost (localhost [127.0.0.1])
MAIL FROM: <hoge@hoge.com>
250 Sender <hoge@hoge.com> OK
RCPT TO: <sug@localhost>
250 Recipient <sug@localhost> OK
DATA
354 Ok Send data ending with <CRLF>.<CRLF>
Subject: Hello! James!

Hello, James.
.
250 Message received
QUIT
221 bizet Service closing transmission channel
Connection closed by foreign host.

まあ、メッセージは特に文句がないようなので、届いているようだ。念のために確認すると、

$ ls apps/james/var/mail/inboxes
sug/
$ ls apps/james/var/mail/inboxes/sug
4D61696C313133333933393230353330392D31.Repository.FileObjectStore
4D61696C313133333933393230353330392D31.Repository.FileStreamStore

と2つのファイルが出来ている。これらがスプールファイルになっているわけだ。

じゃあ、今度は POP3 してみよう。

$ telnet localhost 1110
Trying 127.0.0.1...
Connected to localhost.
Escape character is '^]'.
+OK bizet POP3 server (JAMES POP3 Server 2.2.0) ready
USER sug
+OK
PASS hogehoge
+OK Welcome sug
LIST
+OK 1 511
1 511
.
RETR 1
+OK Message follows
Return-Path: <hoge@hoge.com>
Received: from localhost ([127.0.0.1])
          by bizet (JAMES SMTP Server 2.2.0) with SMTP ID 600
          for <sug@localhost>;
          Wed, 7 Dec 2005 16:05:57 +0900 (GMT+09:00)
Subject: Hello! James!
Date: Wed, 7 Dec 2005 16:05:57 +0900 (GMT+09:00)
From: hoge@hoge.com
Delivered-To: sug@localhost
Content-Transfer-Encoding: 7bit
Content-Type: text/plain; charset=us-ascii
Mime-Version: 1.0
Message-ID: <17103608.1133939205292.JavaMail.sug@bizet>

Hello, James.
.
QUIT
+OK Apache James POP3 Server signing off.
Connection closed by foreign host.

うん、目出度く届いており、それが POP3 で確認できた。あとは適当な POP3 クライアントを使って確認してもよかろう。これで一応、フツーの MTA としての設定ができたことになる。



copyright by K.Sugiura, 1996-2006