qmail にて SMTP 認証を行ってみる

SERVER


はじめに

この文書はサーバの設定完了にいたるまでの奮闘記みたいな感じになっています。設定が成功するまでに多くの無駄な作業をしているので気をつけてください。

もしこの文書を参考に SMTP 認証サーバを用意しようとする場合は、いちど慎重に最後まで目を通してから作業することをお勧めします。 最後にも念のためまとめを書いておきました。

 

qmail 1.03

qmail とは、http://www.jp.qmail.org/ にて公開されている、「安全確実で、信頼できて、高性能で、簡潔なメイル配送エージェント」 が売り文句になっているメールサーバです。

メールは各自のホームディレクトリへ Maildir 形式で保存されますので、アクセス権の問題や障害時の耐性の強化など、いろいろな効果が期待できるようです。

 

個人的にも、慣れるまではインストール作業に手間取るのですけど、それ以外は非常に使い勝手もよくてかなりいい感じのメールサーバです。機能の面でも基本的にはシンプルかつ十分に備わっているのですけど、今のところ標準では SMTP まわりの認証機能は搭載されていないようです。

そんな中、自分の環境にて SMTP の認証を施す必要がでてきたため、そのあたりについて調べてみることにしました。

 

SMTP 認証を行うにあたって

メールの配信に利用する SMTP プロトコルは、基本的にはパスワードを取り扱わないような仕組みになっています。SMTP が開発された当初は良かったのでしょうけど、インターネットが非常に発展・利用されるようになった今日ではその特徴をいわば不当に利用されてしまうようになりました。

自分にも他人にも害がないならまだ良いのですけど、SPAM メール等の大量送信に利用されると、サーバがそれにかかりっきりになってしまい、他のメールの配信が遅れたり、出来なくなってしまったりします。また、無差別に収集したメールアドレスへの広告送信などに利用された場合、受け取る側の人に迷惑がかかることが多いです。

このような不正利用が急激に増加したこともあり、SMTP 自体にも何らかの方法で制限を設ける方法が必要となってきました。

 

不正利用を防止する一番簡単な方法 は自ネットワーク内からのみ自由な送信を許可するという方法だと思うのですけど、これはプロバイダといったダイアルアップで直接接続してもらうような場合でないと現実的ではありません。他にもいくつか方法はあるようですけど、今回は SMTP サーバを利用する際にパスワードを必要とするという方法を用いるものとして話を進めていきます。

とはいえ自サーバのユーザ宛に届くメールも、自ユーザから他の誰かへ送るメールも同じ SMTP サーバが受け持つ場合が多く、どちらも同じ TCP 25 番ポートを利用するため、なかなか難しいところがあります。

たとえば自ユーザなら受信用 (POP) のアカウントを発行するついでに同じアカウントを利用して SMTP 認証も行うようにすればいいのですけど、同じ 25 番ポートの SMTP を利用して外部から送られてくるメールの受け取り処理も行っていると、特に対策を行わなければ、それにさえパスワードが必要になってしまいます。そのために一般にパスワードを公開してしまえば、認証がないのと同じです。ただそれでも認証がまったくないよりはましかもしれないですけど。

また、自ユーザからの送信用 (要認証) と、外部からの受け取り用とを別々のサーバに分けるとなると、2つの IP アドレスが必要になるほか、基本的には送信用の SMTP アカウントと、外部から受け取ったメールを受信するための POP アカウントを2つ管理する必要がでてきます。

SMTP ポート番号は変えることできるため、1台のサーバでも認証が必要な SMTP と、認証は要らないけれど自ユーザ宛のメールしか受け取らない受信専用の SMTP とを用意すれば比較的簡単に実装することは出来ます。そのような場合、外部から送られてくるメールは一般に 25 番ポートで受け取る必要があるため、事実上、変更できるのは自ユーザが送信するのに使う側の SMTP です。この場合、メールソフトによってはポート番号を変更できなかったり、または目立たないところにポート設定の項があったりするなど、パソコンに不慣れなユーザにとっては若干手間取る可能性もあります。

他、認証を必要とするとなると、サーバのみならず一般ユーザ側もそれに対応したメールソフトを使う必要がでてくるのですけど、一般的に広まっているメールソフトの多くが既にパスワードに対応できている状態なので、これは特に問題にはならないでしょう。

 

以上のようないろいろなことを考慮したうえで、今回は利用する自ユーザ側も比較的スムーズに対応できるように、次のような方針で話を進めていこうと思います。

  • 自ユーザ側から見て、送受信に使うアカウントの統一し SMTP ポート番号は標準のものを利用する。
  • SMTP サーバを、外部からのメール受け取り用と、自ユーザの送信用の2つを用意する。

 

qmail 用の SMTP 認証プログラム

qmail は標準では SMTP 認証を搭載していないようなので、これを実現するためにはそのための追加プログラム (パッチ等) を新たに組み込む必要があります。

インターネットを使って調べてみたところ、ざっと次の2つが見つかりました。

 

qmail-vida は純粋に SMTP 認証を追加するわけではなく、仮想ドメイン管理やユーザ管理、POP 認証などを一括して含めたパッケージのようです。

パスワードファイルを独自に持っていたり、仮想ドメイン等を運用するための機能が搭載されていたりと、なんだかとっつきにくそうな感じがします。パスワード認証については、設定を少し変えれば /etc/passwd を利用することが出来るようになるそうですが。

既に稼動中のサーバに SMTP 認証を追加したいだけには少々大きいプログラムな気がするので、今回はもうひとつの方を使ってみようかと思います。

 

そのもうひとつの qmail-smtpd-auth ですけど、こちらはいたってシンプルなようです。

パッチをあてて qmail をコンパイルすれば、qmail-smtp を SMTP 認証に対応したものにすることができます。ただ、SMTP 認証専用になってしまうらしいので、送信専用の SMTP サーバを作るなら問題ないのですけど、そうでない場合は少し工夫してやる必要があるようです。

なにはとも、あれこれを使えば既存の環境を大きく崩さずに済みそうです。

 

サーバ構成

次の条件の下、今回はサーバを2台使って SMTP 認証ありのメールサーバを用意してみることにします。

  • 利用者は外部ネットワークのユーザであるため、IP アドレスにより利用者を判断することは出来ません。
  • ユーザはメール送信の際に認証ありの SMTP サーバを標準ポート (25) で利用します。
  • 受信の際には当然ながら認証ありの POP サーバを標準ポート (110) で利用します。
  • ユーザに届くメールは、当然ながら認証なしの SMTP サーバ (標準ポート 25) が受け取ります。

POP 認証と SMTP 認証のアカウントを同一のものとしたいので、これらを1つのサーバへ用意します。

メールの取り扱いについては、誰かからユーザ宛に届くメールは認証なしで受け入れなくてはいけないのですが、ユーザが誰かに送るメールは認証ありで受け入れなくてはなりません。

これに関してはどちらも今回は外部ネットワークからの接続となるため IP アドレスによる判断ができません。また、仮に IP で判断できる環境だったとしても、どうやら qmail-smtpd-auth は条件 (環境変数など) によって振る舞いを変更することができないようなので、両方を同じ 25 番ポートで運用することができません。

 

サーバ [A]   サーバ [B]
SMTP (25) / 認証なし
自ユーザ宛のメールを受け取る
SMTP (10025) / 認証なし
サーバ [A] から自ユーザ宛のメールを受け取る
    SMTP (25) / 認証あり
自ユーザから送信されるメールを取り扱う
    POP (110) / 認証あり

以上から、外部からユーザ宛のメールを受け取るための認証なし SMTP サーバを別に用意して、そこからアカウントが登録されているサーバへ再度配信するという方法をとってみます。

サーバ構成は、上の表のような感じを想定してみました。

 

サーバ [A] を設定する 【失敗編】

設定方法の調査

今回での サーバ [A] とは、認証なしの SMTP を用意して外部から自ユーザ宛のメールを受け取る役割をもつサーバとなります。受け取ったメールはサーバ [B] へ転送し、そこでメールボックスへ蓄えられます。

この役割を担う上で必要となるのが、qmail でのリレー設定です。これを行うには、/var/qmail/control/ ディレクトリ内に smtproutes ファイルを用意して、次のような書式で設定を行います。

domain:relay:port

上記の各項目は次のように設定することが出来ます。

domain これで指定されたドメイン宛に送られてきたメールをリレーします。基本的には宛先の @ 以下がここに指定されたものと一致した場合にリレーを行いますが、 "." から始まる文字列が設定されていた場合は、そのドメインのサブドメインである場合にリレーの対象となります。
relay domain に該当するあて先であった場合、ここで指定したサーバへメールがリレーされます。relay が設定されていない場合は通常通りの送信 (MX) となるそうです。IP アドレスで指定する場合は [192.168.0.1] というような感じに指定するようです。
port リレー先のサーバが標準の 25 番ではないポートで SMTP を受け付けている場合、ここにポート番号を指定します。省略時は 25 番ポートへリレーします。

特に注意する恬としては、domain にて "." から始まるサブドメイン指定をした場合、そこに記載したドメイン自体は含まれないというところです。たとえば ".dummy.ez-net.jp" とした場合、"@dummy.ez-net.jp" 自体はリレーの対象とならないので注意が必要です。 また複数行指定することも出来、その場合は上から順番に条件が適用されるようです。

 

さて、上記の通り、設定自体は簡単そうです。

が、今回は基本的にはサーバ [B] がメールを受け取ったり拒否したりといった判断を行って、サーバ [A] の方では特に振るいにかけずに済むのが個人的な理想です。サーバ [B] にとっては、サーバ [A] から受け取ったメールは外部へ転送することなく自分のメールボックスへしまえばいいので。

とここまで考えたところで、それならサーバ [A] は 産業技術総合技術研究所 の佐藤豊さんの作成した DeleGate といった Proxy サーバを利用してしまえばすんなり行きそうな気がしてきました。とはいえメールの中継が目的であるので、メールサーバで受け取った方が何かと都合がいいような気がするので、その方向でもう少し調べてみることにします。

まず、ドメインを問わずすべてのメールをサーバ [B] に中継できるかという点ですけど、これは domain 指定をせずに relay だけ設定することで可能なようです。

そしてもうひとつ、どの宛先であっても受け入れを許可する (リレー先のサーバへ回す) 必要があります。これについては SMTP の待ちうけ設定にて、RELAYCLIENT 環境変数を設定してあげれば大丈夫そうです。

ここで無条件にメールを受け入れたとしても、サーバ [B] の方で適切に対応してあげれば、SPAM メールなどの不正利用は防ぐことが出来るはずです。

設定を行う

最初に qmail を普通にインストールします。インストールの方法については EZ-NET: qmail 1.03 のインストール などを参考にして見てください。また、今回は EZ-NET: qmail を daemontools で走らせる で触れたような daemontools や tcpserver を用いて運用する事とします。

これらを踏まえ、qmail が正常にインストールされたものとして、ここではその先の設定について触れてみようと思います。

 

まずはリレー専用のメールサーバということで、locals から自身の情報を削除しておきました。特にそうする必要は無いと思いますけど、ここにはメールボックスを用意しないので一応こうしておきました。

rcpthosts に関しても、すべて許可することになるので書き直さなくてもいいと思いましたけど、念のため自身の情報を削除しておきました。

そしてリレーサーバの指定です。/var/qmail/control/ ディレクトリ内に smtproutes ファイルを作成して、そこに次のような記載を行います。[B] の部分はサーバ [B] を示すドメイン名または IP アドレスとします。なお、転送先のポートは 10025 を指定する事とします。

:[B]:10025

これですべてのメールを、サーバ [B] の 10025 番ポートへ転送する設定が出来ました。今回は svscan を利用しているので、次のようにして qmail の再起動を行います。

svc -k /service/qmail

 

そして、SMTP にてすべてのメールを受け入れるよう設定します。SMTP 用の tcprules 設定ファイルを次のようにして cdb ファイルを再構築すれば完了です。

:allow,RELAYCLIENT=""

 

実験を行ってみる

まだサーバ [A] しか設定していませんけど、とりあえずここへメールを送ってみることにします。うまく機能しているなら、というかサーバ [B] が落ちている場合を想定しての実験です。

SMTP サーバとして "サーバ [A]" を設定してメールを送信してみたところ…、待てども待てどもエラーメールが帰ってきませんでした。これでは何らかの影響でサーバ [B] が落ちたりしたときにメールがやみに葬り去られてしまいます。

 

状況の把握

現在は、サーバ [A] の 25 番ポートは稼動していて、サーバ [B] の 10025 番ポートは稼動していない状況です。

まず smtprelay ファイルを消去して qmail を再起動し、メールを送信してみたところ、この場合は正常にメールが配信されました。けれど、smtprelay にてすべてのメールを停止中のサーバ [B] を中継するように設定すると、届かないのは当然としても、エラーメールさえ戻ってこなくなりました。

すべてのメールをリレーしようとしているのが悪いかとも思い、あて先ドメインを smtprrelay に指定し、送信元は smtprelay に当てはまらないようにしてみたのですけど、この場合も該当するアドレスの場合はどこかへ消えてしまいました。該当しないあて先のメールは正常に配信されました。

 

サーバ [B] 停止時にメールが消滅してしまうのではどうしようもないのですけど、そもそも smtprelay が、または qmail 自身がそもそも正常に機能しているのかを調べてみることにしました。自身へのメール受け取り専用の SMTP サーバを、サーバ [B] の 10025 ポートにて稼動させます。そしてサーバ [A] 経由で第三者宛のメールを送ってみることにします。

… すると、サーバ [B] からは第三者宛のメールは受け取らない旨を示す通知を得ているはずなのにもかかわらず、やはりサーバ [A] からエラーメールが戻ってくる様子はありませんでした。

ためしにサーバ [B] にてすべてのメールを配信するように調整を行って再び試してみたところ、その場合は正常にあて先へメールが届くことが確認できました。またこの状態であれば、存在しないメールサーバをあて先としてメールを送ると、ちゃんと送信元にエラーが帰ってくることもわかりました。

以上から、どうやらエラー通知メールさえも smtprelay を経由して配送されようとしている感じがします。その上、smtprelay 側のサーバが停止していたり、または送信先または返却先アドレスを拒否したりして配信できない場合は、それっきりという…。

 

このままではとても利用できたものではないですね。なにか smtprelay の設定の仕方が間違っている可能性が高いのでもう一度改めて調べてみることにしました。

…と、調べてみると気になる表記がありました。

qmailを使っても人為的に作られたメイルループからは守ってはくれない。 しかし、ネットワーク経由のメイルを受け取ることがなければ、 smtprouteを使うことで問題が起きることはない。

これは日本語版の qmail サイトの中の qmail-control(5) -qmail-1.03 からの引用なのですけど、今回はこのネットワーク経由でのメールを受け取ることで問題を起している気がします。ところで smtproute を使ってもネットワーク経由のメールを受け取らなければ問題が起こることはない、というのはどうなのでしょう。

今回の問題を整理すると、

  1. サーバ [A] がメールを受け取る。
  2. smtproute に基づいて、サーバ [B] へメールを転送しようとする。
  3. サーバ [B] から応答がない。
  4. サーバ [A] は不達メールを送信元へ返却しようとする。
  5. 送信元のアドレスをあて先として、不達メールを送信する手続きに入る。
  6. 2. へ戻る。(ループ)

と、こんな感じだと思うのですけど、自分がインターネットが一般的になった頃の人間だからか、メールといえば送信元も送信先も電子メールアドレスを使うもののような、というかそれ以外は今ひとつ想像できないのですけど。

そうなると、送信元には電子メールアドレスが表記されているわけで、smtproute に指定したサーバがダウンしているようなときには必ず、送信元へメールを配信しようとするはずです。つまりはネットワーク経由のメールは必須事項であり、条件付とはいえ smtproute で問題が起こることはない、などとはとてもとても声を大にしていえる状況ではないように思うのでした。

 

どこか自分の考え方が行き届いていないのでしょうか…。なにはともあれ、こうなると smtproute の設定を事細かに調整して、サーバ [B] が受け持つドメインを明記して転送させ、それ以外は MX レコードを参照するように設定する…。それでも、サーバ [B] が受け持つメールアドレス自身が送信元に指定されている場合は、サーバ [B] が停止していた場合にはエラー通知されることなく消滅してしまいます…。

これでは、使えない、のではないでしょうか。いろいろ調べてみると設定している事例は多いようなので、根本的に自分が間違っているのか、それとも他の方々がこのあたりを気にしていないのかはよくわからないのですけど。

 

サーバ [A] を設定しなおす

qmail を用いて今回の目的を果たすのは今の自分の技量では無理そうなので、転送の役目を担うサーバ [A] は、DeleGate を使って単純にサーバ [B] の 10025 ポートへ中継することにします。

DeleGate とは汎用プロキシサーバで、DeleGate Home Page (www.delegate.org) から入手することが出来ます。

 

qmail を停止させたら、次のような感じで DeleGate を起動できる環境を整えます。今回は qmail を動かすときに使っていた daemontools を利用して DeleGate を動かすことにします。

mkdir /var/delegate-smtpd

mkdir /var/delegate-smtpd/logfiles

cd /var/delegate-smtpd

とりあえず /var/delegate-smtpd と、その中に log というディレクトリを用意して、そこへ必要なスクリプトなどを準備することにします。

 

起動スクリプトを run という名前で用意します。中身は次の通りです。 なお、[A] はサーバ A の IP アドレスをさすものとします。IP アドレスは指定しなくても平気なので、ポート番号だけでよければ -P25 というように指定します。

#!/bin/sh

exec env -PATH="/usr/sbin" delegated -f -P[A]:25 += ./conf

また、上記で使用する conf ファイルを用意します。ここではサーバ [B] の IP アドレスとして [B] と表記しています。

SERVER="smtp://[B]:10025/

RELIABLE="*"

REACHABLE="*"

LOGFILE="./logfiles/[date+%Y%m%d]

これらが用意できたら、chmod +x run として、run スクリプトに実行権限を付け加えます。後は次のように /service ディレクトリ内へシンボリックリンクを張れば、自動的に DeleGate が起動するようになります。

ln -s /var/delegate-smtpd /service

 

サーバ [B] を調整する

受け入れ専用の 10025 ポートを用意する

上記の実験の中では既に動かしてしまった 10025 ポートの SMTP ですけど、改めてここで準備の経過を書いておくことにします。

 

 

基本的には簡単で、ただ 25 番で動かすところを 10025 で動くようにポート番号を変更すればいいのですが、今回は SMTP 認証を行うものも 25 番ポートで同時に動かさなくてはならないため、少し工夫が必要です。

というのも、今回利用しようとしている qmail-smtpd-auth というパッチは、当てることで qmail-smtpd を SMTP 認証専用にしてしまうらしいからです。そのため、今回はパッチを当てた qmail-smtpd と、普通の qmail-smtpd の2つが存在するようにしなくてはいけません。

 

 

それらを管理しやすくするために、ソース自体を複製して管理することにします。

/usr/local/src/ ディレクトリに qmail-natural-smtp/ というディレクトリを作成して、その中で qmail-1.03.tar.gz を 展開します。こちらは特にパッチを当てないので手を加える必要はないのですけど、念のために /usr/local/src/qmail-natural-smtp/Makefile を作成します。

内容は以下のような感じにしてみました。

SRC_PATH = ./qmail-1.03

TARGET_PATH = /var/qmail/bin

TARGET_BINNAME = qmail-smtpd-natural

SRC_BINNAME = qmail-smtpd

 

$(TARGET_BINNAME):    $(SRC_PATH)/qmail-smtpd.c

$(MAKE) -C $(SRC_PATH) qmail-smtpd

cp $(SRC_PATH)/$(SRC_BINNAME) $(TARGET_BINNAME)

cp $(TARGET_BINNAME) $(TARGET_PATH)/$(TARGET_BINNAME)

これで、/usr/local/src/qmail-natural-smtp/ ディレクトリへ移動して make コマンドを実行すれば、qmail-smtpd がコンパイルされて、/var/qmail/bin ディレクトリへ、"qmail-smtpd-natural" としてインストールされます。

 

そして、ルールの設定です。これは /etc/tcprules/ ディレクトリに smtp-receive.cdb を用意して利用することにします。内容は簡単で、/etc/tcprules/smtp-receive ファイルに次のような内容を記述します。

:allow

あとは、"tcprules smtp-receive.cdb smtp-receive.tmp < smtp-receive" という感じで、tcprules コマンドを利用して cdb ファイルを作成します。

 

これらの準備ができたら、起動スクリプト等で次のコマンドを実行し、10025 ポートにて受け入れ専用の SMTP サーバを起動させます。-u と -g で指定されている ID は、qmail-smtpd を動かすアカウントの UID と GID です。環境に合わせて調整してください。

/usr/local/bin/tcpserver -R -H -l0 -x /etc/tcprules/smtp-receive.cdb -v -u 1001 -g 1000 0 10025 /var/qmail/bin/qmail-smtpd-natural 2>&1 | /var/qmail/bin/splogger smtpd_natural 3 &

 

SMTP 認証を載せた 25 ポートを用意する (不完全)

SMTP 認証を実装するためには、qmail に qmail-smtp-auth パッチを充てる必要があります。

まずはパッチを充てるためのソースをおくディレクトリを用意することにします。これは、今回は /usr/local/src/qmail-patch-smtp/ とすることにします。

 

 

まずは qmail-smtpd-auth から、/usr/local/src/qmail-patch-smtp/ ディレクトリへ qmail-smtpd-auth-0.31.tar.gz をダウンロードして展開します。

続いて qmail-1.03.tar.gz を展開したら、次のようにして qmail-smtpd-auth パッチを充てます。

cd qmail-smtpd-auth-0.31/

 

cp README.auth base64.c base64.h ../qmail-1.03

patch -d ../qmail-1.03 < auth.patch

正常にパッチが当たったら、ひとつ前の /usr/local/src/qmail-patch-smtp/ ディレクトリへ戻って、次のような内容の Makefile を作成します。

SRC_PATH = ./qmail-1.03

TARGET_PATH = /var/qmail/bin

TARGET_BINNAME = qmail-smtpd-auth

SRC_BINNAME = qmail-smtpd

 

$(TARGET_BINNAME):    $(SRC_PATH)/qmail-smtpd.c

$(MAKE) -C $(SRC_PATH) qmail-smtpd

cp $(SRC_PATH)/$(SRC_BINNAME) $(TARGET_BINNAME)

cp $(TARGET_BINNAME) $(TARGET_PATH)/$(TARGET_BINNAME)

内容はほとんど /usr/local/src/qmail-natural-smtp/ で用意したものと一緒です。違う部分は TARGET_BINNAME の値だけです。

それと今回は、認証方式はクリアテキストだけをサポートさせる予定なので、念のため qmail-1.03/qmail-smtpd.c ファイルの中の "#define AUTHCRAM" の行をコメントアウトしておくことにしました。

準備が出来たら make コマンドを実行すれば、qmail-smtpd-auth としてインストール完了です。

 

 

そして、ルールの設定です。これも /etc/tcprules/ ディレクトリに smtp-auth.cdb を用意して利用することにします。/etc/tcprules/smtp-auth ファイルの内容は次のようにします。

:allow,RELAYCLIENT=""

あとは、"tcprules smtp-receive.cdb smtp-auth.tmp < smtp-auth" という感じで、tcprules コマンドを利用して cdb ファイルを作成します。

 

また、クリアテキスト認証用の checkpassword も必要です。qmail の場合、POP サーバをインストールする際にこれも使用すると思うので、ここでは既にインストールされているものとします。

 

これらの準備ができたら、起動スクリプト等で次のコマンドを実行し、25 ポートにて SMTP 認証サーバを起動させます。-u と -g で指定されている ID は、qmail-smtpd を動かすアカウントの UID と GID です。環境に合わせて調整してください。

/usr/local/bin/tcpserver -R -H -l0 -x /etc/tcprules/smtp-auth.cdb -v -u 1001 -g 1000 0 smtp /var/qmail/bin/qmail-smtpd-auth hostname /bin/checkpassword /bin/true 2>&1 | /var/qmail/bin/splogger smtpd_auth 3 &

 

これで設定完了かとおもったら…、なぜだか認証に失敗してしまいました。認証手続きを行おうとするもののパスワード不一致と判断されているような感じがします。

qmail-smtpd-auth に付属していた文書の使用方法を見てみたり、インターネットをいろいろあさってみたりしましたけど、SMTP の起動自体には間違いはなさそうでした。

 

そういえば、以前に認証が必要なプログラムを組む実験をしたことがあったのですけど、そのときに、一般アカウントで起動したプログラムでは認証関数がうまく動作しないことがありました。

今回も、qmail-smtpd-auth は qmaild アカウントで起動しているので、もしかすると checkpassword がうまく動けないのかもしれません。そこで、ためしに -u 1001 のところを、-u 0 として、root アカウントで qmail-smtpd-auth を起動するようにしてみます。

すると、正常に認証を通過することが出来ました。もちろん、間違ったパスワードを入力すればちゃんと拒絶されます。

 

ただちょっと、smtp-auth を root で動かしていいものなのかわからなかったので、ちょっとだけ手を加えることにします。

chmod u+s /bin/checkpassword

chmod +x /bin/checkpassword

こうすることで、どのアカウントであろうと checkpassword を起動することができ、起動したときには checkpassword 自身の権限で起動するようになります。このとき checkpassword 自身は root が所有している必要があります。

 

このように root 権限で実行されるように checkpassword を調整した場合、どれくらい危険があるのかはわかりませんけど、少なくとも tcpserver 自身を root で動かすよりは安全でしょう…。

 

SMTP 認証をしなくても送信できる…?

さて、実験していて気づいたことが…。

確かに SMTP 認証を必要と設定した上でメールを送信することが出来るのですけど、SMTP 認証不要の設定でも問題なくメールが送信できてしまうではないですか。

これではなんだか、何のための認証なのだか…。 と思いつつも付属の文書を念入りに調べてみると、なにやら認証に成功した時点で、そのセッションには RELAYCLIENT 環境変数が設定されるという記述を (いまごろ) 発見しました。

 

 

ということは、認証を通した段階で RELAYCLIENT が設定されて外部への配信が可能、認証が通っていなければ RELAYCLIENT が設定されていないため受け入れ専用となる、、、、ということですね。

なんと、何の問題もなく素直に qmail-smtp-auth を充てた qmail-smtpd を動かしておきさえすれば、今回の目的にあったメールサーバが簡単に動かせることが今頃わかったのでした。

 

念のため、本当に RELAYCLIENT 環境変数が付加された状態になるのか調べてみることにします。

qmail-smtpd-auth の起動に使用していた smtp-auth.cdb の内容を、:allow,RELAYCLIENT="" から、単純に :allow に変更します。これで、通常は rcpthosts に指定されたドメインへしかメールを出せなくなります。

この状態で、メールソフトの SMTP 認証をしない設定で第三者あてのメールを出してみたところ、しっかりと許可されていないアドレスとして送信が拒否されました。そして、SMTP 認証を必要とする設定で再送信を試みたところ、しっかりと送信することが出来ました。

 

これなら、サーバ[B] 一台だけで用事が済みそうです…。

 

 

サーバ [B] を設定する

管理を踏まえたり、認証と非認証との共存を考えて、Makefile を組んだりいろいろしてしまったのですけど、わざわざそんな手間をかける必要はなかったのですね…。

ということで、シンプルに設定しなおしてみることにします。

ということで、シンプルに設定しなおしてみることにします。

構成はこのように変更です。… 間違いを正して本来あるべき自然な姿に戻った感じですね。

サーバ [B]
SMTP (25) / 認証あり & 認証なし
認証あり: 自ユーザから送信されるメールを取り扱う
認証なし: 自ユーザ宛のメールを受け取る
POP (110) / 認証あり

 

今まで用意してきた qmail-patch-smtp/ ディレクトリは、qmail-1.03-with-auth/ に名前を変更します。qmail-natural-smtp の方は不要となりました。 そして、qmail-1.03-with-auth/ 内の Makefile はいらないので削除します。

そうしたら、qmail-1.03-with-auth/qmail-1.03/ ディレクトリ内で make setup check コマンドを実行して、改めてコンパイルとインストールを行っておきます。このとき、念のため qmail 関連のプロセスをとめておきましょう。

これで、qmail-smtpd 自体に SMTP 認証が実装された状態になります。

 

 

qmail を改めて起動して、smtp 起動スクリプトを次のように書き換えます。書き換えるといっても、qmail-smtpd-auth だったプログラム名を qmail-smtpd に書き直すだけですけど。

/usr/local/bin/tcpserver -R -H -l0 -x /etc/tcprules/smtp-auth.cdb -v -u 1001 -g 1000 0 smtp /var/qmail/bin/qmail-smtpd hostname /bin/checkpassword /bin/true 2>&1 | /var/qmail/bin/splogger smtpd_auth 3 &

CDB ファイル名のほうは、念のため、SMTP 認証を考慮していることに (管理者が) 気づけるように、smtp-auth.cdb のままにしておくことにします。

が、内容は少し変更となります。もとになる smtp-auth ファイルの中身を次のようにします。

:allow

これで、すべての接続を受け入れます。が、不正中継は qmail が rcpthosts ファイルと照らし合わせて遮断してくれます。

さらに qmail-smtpd-auth パッチが当たっていることによって、認証を通した場合は RELAYCLIENT 環境変数が設定されるため、rcpthosts に載っていない第三者へメールを送信することが可能です。

 

tcprules プログラムを使って smtp-auth.cdb を更新したら、上記スクリプトで SMTP プロセスを 25 番ポートで立ち上げれば完了です。

 

サーバ [A] は不要

いろいろと工夫して用意したサーバ [A] ですが、不要となりました。/service/delegate-smtpd シンボリックリンクを削除して、delegate プロセスを停止してやれば設定完了です。

設定終了(まとめ)

これで、サーバの設定は終了しました。

結局のところ、サーバ [B] だけで SMTP 認証による送信のやくわりと、自身へ届くメールを受け取る役割の2つを実現することが出来ました。

振り返ってみると、qmail-smtpd-auth パッチの仕様の "SMTP 認証を行った場合は、RELAYCLIENT 環境変数が設定される" という部分に気づくのが遅れたために、いろいろと遠回りをしてしまったのでした。

 

以上、作業をまとめると …

  • 既に稼動している qmail の設定ファイル、CDB ルールは手を加える必要なし
  • qmail-smtpd-auth パッチを充てて qmail-smtpd.c の #define AUTHCRAM をコメントアウト
  • 念のため qmail 関連を止めてから、make setup check
  • qmail-smtpd の起動の部分に3つの引数を追加して、qmail-smtpd hostname /bin/checkpassword /bin/true とする
  • checkpassword に、u+s と +x 権限を chmod コマンドにて与える

このような感じで、気軽に SMTP 認証による送信をサポートしたサーバにすることができそうですね。