安全で高速なメールサーバーqmail

以下のテキストは、執筆時当時の情報を元に書いたものであり、 現在の情勢にそぐわないことを含む場合があるので注意されたい。 また、テキストは最終提出原稿で校正を経る前のものなので、実際にUNIXUSER 本誌に記載されたものとは異なる。誤字脱字等そのままである。

致命的な誤り以外は加筆修正等は行なわないので情報の鮮度に気をつけつつ 利用して欲しい。

目次


【Part 4 qmail】

■
■qmail
■


DJBツールのうち最も早く有名になったのがqmailである。改めて何であるかの説
明は不要だろう。

●なぜqmailか

もしこれまでメイルサーバの管理をしていて、次のようなことを感じたことがあ
る場合はqmailを使う意味があるだろう。

	* セキュリティホールの心配は低い方がいい
	* CFがsendmailに追随されなくなって悲しい
	* せっかくCFを覚えたのにcfを覚え直すのは気が進まない
	* メイルアドレスを無限に作れたら楽しいだろうなあ
	* MLなどもコマンド一発で作れたら楽だろうなあ

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

●qmailの導入

これまで本誌でも何回かqmailの導入方法を解説してきた。ただしそれらは全て
DNSの設定例としてBINDの事例を紹介したものだったが、今回の特集はDJB特集と
いうことでdjbdnsでの設定例とともに導入方法を紹介することにしよう。

qmailによるメイルサーバ導入の流れは以下のようになる。

	1. メイルドメインのDNS登録
	2. qmailのインストール
	3. アクセス制限

今回はPart2とPart3においてtcpserverとdjbdnsの導入が完了しているの
で、全てのステップがスムーズに行くだろう。


・導入事例の前提

  今回導入するqmailによるメイルサーバは、以下のような条件であると仮定す
  る。

	ドメイン名		foo.ymzk.org
	メイルドメイン		foo.ymzk.org (DNSドメイン名と同一)
	メイルサーバ		venus.foo.ymzk.org (10.0.0.25)
	セカンダリメイルサーバ	saturn.foo.ymzk.org (10.0.0.26)
	ネームサーバ		ns.foo.ymzk.org (10.0.0.53)

・メイルドメインのDNS登録

  メイルサーバの構築にはMTAだけでなく、DNSのMXレコードの登録作業も重要で
  ある。とはいってもdjbdnsであればとても簡単にMXレコードが登録できる。今
  回の例では foo.ymzk.org ドメインのゾーンファイルを修正することになる。
  メイルサーバのプライマリとセカンダリについて以下の二つのレコードを追加
  しよう。

	@foo.ymzk.org:10.0.0.25:venus.foo.ymzk.org:0:86400
	@foo.ymzk.org:10.0.0.26:saturn.foo.ymzk.org:10:86400

  1行目は、@foo.ymzk.org メイルドメインのpreference(優先度)=0のサーバと
  して venus.foo.ymzk.org(10.0.0.25) を指定し、2行目は、preference=10の
  サーバとしてsaturn.foo.ymzk.org(10.0.0.26) を指定している。ゾーンファ
  イルの修正が終わったら、ゾーンファイルのあるディレクトリでmakeコマンド
  を叩く。

	# make

  tinydns-data コマンドが起動されて、最新情報に直ちに反映されるだろう。
  確認には host コマンドを利用する。tinydnsのサービスディレクトリにある
  env/IP ファイルに記述してある。今回の例では ns.foo.ymzk.org のIPアドレ
  スである 10.0.0.53 と同一のはずであるから、

	# host -t mx foo.ymzk.org 10.0.0.53
	  ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
	foo.ymzk.org mail is handled (pri=0) by venus.foo.ymzk.org
	foo.ymzk.org mail is handled (pri=10) by saturun.foo.ymzk.org

  のように返って来れば設定は完了である。


・qmailのインストール

  筆者が最初にqmailを導入したのは1997年のことであるが、その翌年にリリー
  スされたqmail-1.03をインストールして以来、まったくインストール方法が変
  わっていない。もう4年も前のソフトウェアでありながら、もう当たり前であ
  るかのようにバグフィクスもなく、それでいて機能的に不十分だと思う部分も
  皆無である。

  qmail-1.03は http://cr.yp.to/qmail.html にあるミラーサイト一覧、あるい
  は付録CD-ROMから入手できる。qmail-1.03のインストールについては、ソース
  アーカイブ中に含まれる "INSTALL" で始まるファイル群を見ながら進めるの
  が良いだろう。

	# gzip -dc qmail-1.03.tar.gz | tar xvpf -
	# cd qmail-1.03
	# less INSTALL*

  INSTALLファイルの記述に従うと、

	1. qmail動作に必要なUID/GIDの登録
	2. qmailのコンパイルとインストール
	3. sendmailの置き換え
	4. qmailの起動

  が大きな流れとなる。ただし、INSTALLファイルでは、送信デーモン
  qmail-sendの起動をシステムのスタートアップファイル経由で行ない、SMTP待
  ち受けデーモンqmail-smtpdの起動をinetd経由で行なうことを前提にしている
  が、今回はdaemontoolsを有効活用する方法で解説しよう。

  1. qmail動作に必要なUID/GIDの登録
  ==================================

  まずは INSTALL.ids にある通りUID/GIDを追加する。

  ---[Solaris, NetBSD, OpenBSD, 各種Linuxの場合]------------------
   # groupadd nofiles
   # useradd -g nofiles -d /var/qmail/alias alias
   # useradd -g nofiles -d /var/qmail qmaild
   # useradd -g nofiles -d /var/qmail qmaill
   # useradd -g nofiles -d /var/qmail qmailp
   # groupadd qmail
   # useradd -g qmail -d /var/qmail qmailq
   # useradd -g qmail -d /var/qmail qmailr
   # useradd -g qmail -d /var/qmail qmails
  ---[FreeBSDの場合]------------------
   # pw groupadd nofiles
   # pw useradd alias -g nofiles -d /var/qmail/alias -s /nonexistent
   # pw useradd qmaild -g nofiles -d /var/qmail -s /nonexistent
   # pw useradd qmaill -g nofiles -d /var/qmail -s /nonexistent
   # pw useradd qmailp -g nofiles -d /var/qmail -s /nonexistent
   # pw groupadd qmail
   # pw useradd qmailq -g qmail -d /var/qmail -s /nonexistent
   # pw useradd qmailr -g qmail -d /var/qmail -s /nonexistent
   # pw useradd qmails -g qmail -d /var/qmail -s /nonexistent

  もし、手許のシステムに useradd コマンドや pw コマンドなどがない場合は、
  /etc/group ファイルに

	qmail:*:2107:
	nofiles:*:2108:

  を追加し、vipwコマンドで passwd ファイルに

	alias:*:7790:2108::/var/qmail/alias:/bin/true
	qmaild:*:7791:2108::/var/qmail:/bin/true
	qmaill:*:7792:2108::/var/qmail:/bin/true
	qmailp:*:7793:2108::/var/qmail:/bin/true
	qmailq:*:7794:2107::/var/qmail:/bin/true
	qmailr:*:7795:2107::/var/qmail:/bin/true
	qmails:*:7796:2107::/var/qmail:/bin/true

  を追加しよう。なお、上記のGID 2107, 2108 は、groupファイルで未使用のも
  のであれば何でも良く、別の値に変更する場合はpasswd中の対応するGIDも変
  更すること。

  2. qmailのコンパイルとインストール
  ==================================
  UID/GIDの追加が終わったらqmailのコンパイルとインストールに移る。
  まずqmailをインストールするディレクトリを作成する。

	# mkdir /var/qmail

  続いてコンパイル、インストールを行う。

	# make setup check

  そしてそのホストに固有の設定ファイルを作成してもらう。

	# ./config

  ホストのDNS登録が完了していればconfigスクリプトにより必要最低限の設定
  ファイルが自動作成される。もしうまく行かない場合は、config-fast スクリ
  プトを利用するか若しくは、定義ファイルを全て手動で作成する必要があるが
  さほど難しくない。基本的な定義ファイルの書き方に関しては後述する。

  次に最低限のシステム全域のアドレスエイリアスを定義する。

	# (cd ~alias ; \
	>  touch .qmail-postmaster .qmail-mailer-daemon .qmail-root ; \
	>  chmod 644 ~alias/.qmail* \
	>  )

  この例では postmaster, MAILER-DAEMON, root というメイルアドレスを有効
  化している。これ以外にもRFC2142に書かれている代表的アドレスを受け取る
  ファイルとして .qmail-hostmaster, .qmail-abuse なども作成しておくのが
  望ましいだろう。


  3. sendmailの置き換え
  =====================
  システム標準の sendmail コマンドをqmailに適したものに置き換えよう。
  /var/qmail/bin/sendmail または、/var/qmail/bin/datemail がそれに当たる。
  後者はタイムスタンプをローカルタイム(日本の場合JST)で記録することのみ
  が異なる。システム標準sendmailコマンドはOSによって場所が違い、PC-UNIX
  では /usr/sbin, 商用Unixでは /usr/lib にあることが多い。

       (例: /usr/sbin/sendmail の場合)
	# cd /usr/sbin
	# mv sendmail sendmail.orig
	# chmod 000 sendmail.orig
	# ln -s /var/qmail/bin/datemail sendmail

  なお、mailer.conf(5) の存在するシステムであれば、mailer.conf ファイル
  を書き換える方が良いだろう。

  また、多くのホストではデフォルトで sendmail デーモンが起動するようになっ
  ていることが予想される。あらかじめ起動中のsendmailを止めておこう。

	# kill 「sendmailのPID」

  また、システムのスタートアップファイルでもsendmailが起動しないようにし
  ておく。

  4. qmailの起動
  ==============

  起動に必要なスクリプトを作成する。今回はdaemontoolsでqmail デーモンの
  起動を一括管理してもらうことにしよう。そのためにまずサービスディレクト
  リを作ろう。

	# mkdir -p /var/qmail/svc/qmail-send/log

  続いて、サービス起動スクリプト run を作成する。

	# cd /var/qmail/svc/qmail-send
	# touch run
	# chmod +x run
	# vi run
	(以下の内容にする)
---[ /var/qmail/svc/qmail-send/run ]---------------------------------
#!/bin/sh
echo 'Starting qmail...'
exec env - PATH="/var/qmail/bin:$PATH" qmail-start ./Mailbox
---------------------------------------------------------------------

  ためしに、このスクリプトで qmail デーモンが起動するか確認してみよう。

	# ./run
	status: local 0/10 remote 0/20

  status: 行が出力され、プログラムがフォアグラウンドで動き続けることが確
  認できたらいったんC-cで停止する。続いてログ採取用スクリプト log/run を
  作成しよう。以下の例では配送ログを /var/log/qmail-send/ ディレクトリに
  吐き出すように設定している。

	# touch log/run
	# chmod +x log/run
	# vi log/run
	(以下の内容にする)
---[ /var/qmail/svc/qmail-send/log/run ]-----------------------------
#!/bin/sh
exec env - \
PATH=/usr/local/daemontools/bin:/usr/local/bin:/bin:/sbin \
setuidgid qmaill multilog t s1000000 /var/log/qmail-send
---------------------------------------------------------------------

  log/run スクリプト中の s1000000 は一つのログファイルの最大サイズなので、
  パーティションの空き具合に応じて適宜増減すると良いだろう。また、最後の
  引数の /var/log/qmail-send がログファイルを書き出すディレクトリなので、
  あらかじめこのディレクトリをログ採取ユーザを所有者として作成しておく必
  要がある。

	# mkdir /var/log/qmail-send
	# chown qmaill /var/log/qmail-send

  以上の作業ででき上がったqmail用サービスディレクトリを /service にシン
  ボリックリンクすればqmailのデーモンが走り始める。

	# ln -s /var/qmail/svc/qmail-send /service

  としてsuperviseが起動するのを待とう。5秒程待って、svstatする。

	# svstat /service/qmail-send /service/qmail-send/log
	  ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
	/service/qmail-send: up (pid 16877) 17 seconds
	/service/qmail-send/log: up (pid 16878) 17 seconds

  これで、qmailデーモン(qmail-send)が起動する。qmail-sendにシグナルを送
  る場合は全て svc コマンドで手軽に送れるようになる。

  続いて、外部からのSMTPアクセスにそなえてSMTPデーモンを起動する。qmail
  の場合これは qmail-smtpd が行なう。これを起動するためのdaemontools用サー
  ビスディレクトリを作成しよう。

	# mkdir -p /var/qmail/svc/qmail-smtpd/log

  このディレクトリに qmail-smtpd 起動のための run スクリプトを作成する。

	# cd /var/qmail/svc/qmail-smtpd
	# touch run
	# chmod +x run
	# vi run
	(以下の内容にする)
---[ /var/qmail/svc/qmail-smtpd/run ]--------------------------------
#!/bin/sh
echo 'Starting qmail-smtpd...'
exec env - PATH="/var/qmail/bin:$PATH" \
envuidgid qmaild softlimit -d250000 \
tcpserver -vR -c40 -U 0 smtp qmail-smtpd 2>&1
---------------------------------------------------------------------

  SMTPアクセスのログを取りたい場合は、log/run スクリプトも作成する。

	# touch log/run
	# chmod +x log/run
	# vi log/run
	(以下の内容にする)
---[ /var/qmail/svc/qmail-smtpd/log/run ]----------------------------
#!/bin/sh
exec env - PATH="$PATH" \
setuidgid qmaill multilog t ./main
---------------------------------------------------------------------

  runスクリプトが完成したら、サービスディレクトリを /service にシンボリッ
  クリンクする。

	# ln -s /var/qmail/svc/qmail-smtpd /service

  5秒程待ってsvstatで起動状態を確認する。

	# svstat /service/qmail-smtpd /service/qmail-smtpd/log
	  ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
	/service/smtpd: up (pid 17443) 4 seconds
	/service/smtpd/log: up (pid 17444) 4 second

  問題なく起動できたら、telnetなどを利用して、SMTPサービスが利用できるか
  確認しよう。

	# telnet localhost 25
	  ~~~~~~~~~~~~~~~~~~~
	Trying 127.0.0.1...
	Connected to localhost.
	Escape character is '^]'.
	220 venus.foo.ymzk.org ESMTP

・qmailの動作定義ファイル

  実際にqmailを動かす前に設定ファイルの種類とそれらの意味を確認しておこ
  う。基本的に必要なファイルは、defaultdomain, locals, me, plusdomain,
  rcpthosts と、defaulthost ファイルだけである。どれも config スクリプト
  を起動することで自動作成される。

  * me

    メイルサーバ自身のホスト名を書いておく。以下で説明するdefaultdomain,
    defaulthost, locals, plusdomain ファイルが存在しないときのデフォルト
    値としても利用される。

  * locals ファイル (qmail-sendが参照)

    このメイルサーバで「ローカル配送」として処理すべきドメインを一行に一
    つずつ列挙する。受け取ったメイルの宛先のドメインパート(@記号より後ろ) 
    が、localsに書かれているものである場合、そのメイルは qmail-local に
    渡されてローカルで処理されることになる。qmailの動作中にこのファイル
    を更新したら qmail-send に HUP シグナルを送る必要がある。daemontools 
    経由でqmailを起動している場合はqmail-sendのサービスディレクトリを指
    定して、 svc -h /service/qmail-send などとすれば走行中のqmail-sendに
    HUPシグナルを送ることができる。

		
  * rcpthosts ファイル (qmail-smtpdが参照)

    ネットワーク経由で来たメイルのうち、このメイルサーバで受理するべきド
    メインを一行に一つずつ列挙する。rcpthostsファイルに書いてないドメイ
    ン宛のメイルは不正リレーとみなして受け取りを拒否する。例外として、
    qmail-smtpd の起動時に環境変数 RELAYCLIENT がセットされていた場合は
    rcpthostsファイルの内容は無視され、全てのドメイン宛のメイルを受理す
    るようになる。これを利用して部署内LANからのSMTP接続には自由にリレー
    配送させる。方法については後述する。

    ドメイン名をピリオド(.)で始めるとそのドメイン配下のアドレスは全て受
    理するものみなす。たとえば、@foo.ymzk.org 宛のメイルも @XXX.foo.ymzk.org
    (XXXは任意) 宛のメイルも全て受理したい場合は

	foo.ymzk.org
	.foo.ymzk.org

    と書く。ローカル配送すべきメイルは全て受理するわけであるから、すくな
    くとも locals ファイルに書いてあるものはすべて rcpthosts ファイルに
    も書くのが普通である。通常はこれに加えてセカンダリメイルサーバを受け
    持つドメインや、virtualdomain なども書き加えることになる。

  * defaultdomain ファイル (qmail-injectが参照)

    このホストで動くプロセスからメイルを送信するときに、宛先もしくは送信
    者のドメイン部にドット(.)が無いときに自動的に後ろに付加するドメイン
    名。たとえば、defaultdomain ファイルの内容が foo.ymzk.org の場合 
    foo@venus というメイルアドレスは自動的に foo@venus.foo.ymzk.org に置換
    される。

  * defaulthost ファイル (qmail-injectが参照)

    このホストからメイルを送信するときに、宛先もしくは送信者のドメイン部
    が省略されているときに自動的に後ろに付加するドメイン名。たとえば、
    defaulthost ファイルの内容が foo.ymzk.org の場合 foo というアドレス
    は自動的に foo@foo.ymzk.org に置換される。外部ドメインにメイルを出す
    ときにホスト名を隠蔽したい場合は defaulthost ファイルにドメイン名だ
    けを書いておく必要がある。

  * plusdomain ファイル (qmail-injectが参照)

    宛先のドメイン部が + で終っているときに追加するドメイン名。
    plusdomain に ac.jp と書いてある場合、foo@hoge+ というアドレスは 
    foo@hoge.ac.jp に置換される。あまり利用しないかもしれない。


  以後の説明では、各動作定義ファイルの内容がリスト6のようになって
  いる場合を仮定する。

	/--- リスト6 /var/qmail/control/* ファイルの内容 -------------------
	| [me]
	|    venus.foo.ymzk.org
	| [locals]
	|    localhost
	|    localhost.foo.ymzk.org
	|    foo.ymzk.org
	|    .foo.ymzk.org
	| [rcpthosts]
	|    foo.ymzk.org
	|    .foo.ymzk.org
	| [defaulthost]
	|    foo.ymzk.org
	| [defaultdomain]
	|    foo.ymzk.org
	| [plusdomain]
	|    ymzk.org
	\-------------------------------------------------------------------

・qmailの動作試験

  daemontools 管理下に置いたqmailは配送関係のログを
  /var/log/qmail-send/current に出力する。動作試験時にはこれを別端末に表
  示しておくと良いだろう(脚註: このようなtail -f をするシェルスクリプト
  を作っておくと管理効率が上がるだろう)。

	# tail -f /var/log/qmail-send/current | tai64nlocal
  
  qmailが正常に待機している場合はログファイルに以下のようなメッセージが
  あるはずである。
  
  	qmail: status: local 0/10 remote 0/20
  
  これが確認できたら配送試験に入る。まずはローカル配送から。
  
	# echo to: root@foo.ymzk.org | /var/qmail/bin/qmail-inject

  ログファイルに以下のようなメッセージが書き込まれたら配送が行なわれてい
  る。

  starting delivery 1: msg 39334 to local root@foo.ymzk.org

  デフォルトでは、このメイルは ~alias (/var/qmail/alias) ディレク
  トリにある Mailbox というmbox形式ファイルに書き込まれているはず
  である。


・リレーコントロール

  今回インストールしたqmail-smtpdでは、SMTPクライアントからの配送依頼に
  対し、自己ドメインのものしか受理しないようになっている。部署内にある
  SMTPクライアントには、いかなるドメインのものも配送できるようにしよう。
  既に、qmail-smtpd は tcpserver 経由で起動するようになっているので、
  tcpserver用のアクセスコントロールファイルを書くだけで良い。qmail-smtpd
  のサービスディレクトリに移動し、部署内ネットワークからのSMTP接続では、
  環境変数 RELAYCILENT をセットするようにしよう。部署内ネットワークが
  10.0.0.0/24 であるとした場合の作業例を示す。

	# cd /var/qmail/svc/qmail-smtpd
	# vi smtp
	(以下の内容にする)
---[ /var/qmail/svc/qmail-smtpd/smtp ]-------------------------------
127.0.0.1:allow,RELAYCLIENT=""
10.0.0.:allow,RELAYCLIENT=""
all:allow
---------------------------------------------------------------------

  また、このルールファイルをcdb形式に直すのが簡単になるように Makefile
  も作成しておくと良いだろう。

	# vi Makefile
	(以下の内容にする)
---[ /var/qmail/svc/qmail-smtpd/Makefile ]---------------------------
# Makefile for smtp.cdb
#
TCPRL	= /usr/local/bin/tcprule

all: smtp.cdb

smtp.cdb:       smtp
        cat smtp | ${TCPRL} $@ smtp.tmp
---------------------------------------------------------------------

  以後、ルールファイルsmtpを書き換えたら

	# make

  と叩き smtp.cdb ファイルを更新する。このファイルを tcpserver が読むよう
  に、起動スクリプト(run)を修正する。

	# vi run
	(以下の内容にする)
---[ /var/qmail/svc/qmail-smtpd/run ]--------------------------------
#!/bin/sh
echo 'Starting qmail-smtpd...'
exec env - PATH="/var/qmail/bin:$PATH" \
envuidgid qmaild softlimit -d250000 \
tcpserver -vR -c40 -U -x smtp.cdb 0 smtp qmail-smtpd 2>&1
                      ~~~~~~~~~~~追加
---------------------------------------------------------------------

  現在走行中の qmail-smtpd を終了させれば、新しい run スクリプトが再起動
  する。

	# svc -t /service/qmail-smtpd

●まとめ

qmailに関しては既に十分な文献があることから、今回はqmailそのもののインス
トールを丁寧に解説するのではなく、daemontools+tcpserverと組み合わせて運
用する場合のコツに注目するという観点で説明を進めた。既にqmailを導入して
いる場合でもdaemontoolsを組み合わせることで、更に管理に一貫性が持ててタ
イピング量が減らせることが実感して頂けただろうか。とくに、複数のOSで
qmailを動かしている場合には効果てきめんである。ぜひ新しい管理方法にチャ
レンジして頂きたい。


yuuji@example.org
Fingerprint16 = FF F9 FF CC E0 FE 5C F7 19 97 28 24 EC 5D 39 BA
HIROSE Yuuji - ASTROLOGY / BIKE / EPO / GUEST BOOK / YaTeX [Tweet]