導入編 | ||
FreeBSDルーター編 | ||
ローカルDNSサーバー | ||
フレッツADSLで固定IP | ||
ドメイン取得とDNS運用 | ||
>>> | メールサーバー / remove-prependパッチ | |
おまけ |
27 Aug 2011 | 新規作成。 |
netqmail-1.05用のパッチです。 netqmail-1.06でも平気だと思います。 作っておいて言うのもなんですが、「なくてもいいかなー」ってちょっと思ってたりして。
BEFORE using the following patch, READ preamble of the patch.
~user/.qmail
で転送を指示した場合に、~user/.qmail-owner
があると、表書き差出人がuser-owner@example.jp
の形に書き換えられます。
このアドレスは~user/.qmail-owner
の配送指示に従いますが、このファイルがあるからこのアドレスが生成されたので、必ず配送が可能です。
一方、user@virtual.domain
がcontrol/virtualdomains
に合致するとprepend-
プレフィックスが付けられて配送されます。
これはユーザーprepend
に配送され、~prepend/.qmail-user
の配送指示に従います。
もし、~prepend/.qmail-user
で転送が指示されていて、~prepend/.qmail-user-owner
が存在すると、表書き差出人はprepend-user-owner@virtual.domain
に書き換えられますが、このアドレスにメールを差し出すとcontrol/virtualdomains
によりさらにプレフィックスが付けられてしまい、prepend-prepend-user-owner@virtual.domain
宛に配送されることになります。
このアドレスは~prepend/.qmail-prepend-user-owner
の配送指示に従いますが、普通このようなファイルはありませんから、このメールは正しく配送されません。
また、prepend-
というのは一種の内部情報で、外に漏れて欲しくない場合もあるでしょう。
表書き差出人を書き換えているのはqmail-localです。
qmail-localが書き換えるときにcontrol/virtualdomains
を参照して、合致するアドレスの場合はprepend-部分を削除すればより望ましい動作になるでしょう。
ここでは、特定のドメインに対してのみ適用したい場合や、不具合があった場合に備え、control/removeprepend
というファイルを用いています。
Delivered-To:
ヘッダフィールドにも同じようなアドレスが書かれます。
control/removeprependdt
というファイルがあると、同様にDelivered-To:
ヘッダフィールドに対してもprepend-プレフィックスを削除するようになります。
control/removeprepend
・control/removeprependdt
の形式はcontrol/virtualdomains
と同じです。
したがって、全仮想ユーザー・仮想ドメインに対して適用したい場合、control/virtualdomains
へのシンボリックリンクで済ませることができます。
ひとつ制限があります。 仮想ドメインに対してはうまく動きます。 しかし、仮想ユーザーに対してはうまく動かないかもしれません。 例えば、
actual-user@virtual.domain:real user@virtual.domain:real-actual
という記述があると、どちらの仮想ユーザーもreal-actual-user@virtual.domain
宛に配送となります。
こうなってしまうとどちらのルールに合致してプレフィックスが付けられたのか区別がつきません。
プログラム上は配送されたアドレスに対し、
control/removeprepend
に対して順番に比較しているため、この場合は常にactual-user@virtual.domain:real
が採用され、たとえuser@virtual.domain
で受信した場合でも、転送時の表書き差出人はactual-user-owner@virtual.domain
になってしまいます。
アドレス全体は仮想ユーザーの例外に対してのみチェックされます。 アドレス全体がヒットして例外の指定ではない、つまり、prependがあるということは、もしこのルールにヒットしたら「prepend-アドレス全体」というアドレスになるはずです。 しかし、チェックしているのは「prepend-」がない「アドレス全体」ですから、一致することはありません。 したがって、アドレス全体を仮想ユーザー指定に対してチェックするのは意味がありません。
仮想ドメインについては、ドメイン部は書き換えられないので、配送時にヒットしたルールは、qmail-localでも確実にヒットするはずです。
配送時にヒットしていなければqmail-localでもヒットしないはず。
したがって、仮想ドメインでは正確にprepend-を取り除いてくれるはずです。
virtualdomainsにはsub.example.jp
と.example.jp
が指定してあるのに、removeprependには.example.jp
しか指定してなかったりするとダメですが。
あと、removeprependとは関係ありませんが、仮想ユーザーvirtual-user@virtual.domainに対して、virtual-user-onwer@virtual.domainのようなアドレスでメールを受けるには、このためのルール(仮想ユーザー・qmail-users機構など)が必要ですので、念のため。
.qmailから起動するコマンドに渡される環境変数LOCAL・RECIPIENTはprepend部が付いたものが設定されます。 これはそのままの動作にしてあります。 一方、NEWSENDER・DTLINEはremoveprepend・removeprependdtにヒットするとprepend部を取り除いたものが設定されます。
このパッチを当てなくても、~prepend/.qmail-user
でqmail-injectの-fオプションで表書き差出人アドレスを差し替えれば解決します。
複数の宛先に転送したい場合は、qmail-injectで表書き差出人アドレスを書き換えた上で配送用のローカルなアドレスにメールを投げ、そのアドレスに転送先のアドレスを並べればOKです。
要するにメーリングリストと同じ要領です。
動作の確認はてきとーにやってあります。 今回、Cygwin上でビルドして確認してみました。 以前はerr変数関係を修正しないとビルドが通らなかった覚えがありますが、net-qmail-1.05ならばほぼ普通にビルドできるようです。 ただし、ビルドコマンド生成シェルスクリプトとCygwinのテキストモードマウントの相性がよろしくないため、バイナリモードでマウントしたディレクトリでビルドした方がいいです。
一部のコマンド・・・auto_uids.oをリンクしているコマンド・・・は説明どおりにユーザーIDを作らないとビルドできません。
qmail-localはやらなくてもビルドできるので今回はやっていませんが、Cygwinの/etc/passwdを編集してユーザーを作ればビルドできるのではないかと思います。
また、場合によってはファイルディスクリプタの数が足りないと言われるかもしれませんが、指示に従ってconf-spawnの数値を書き換えてやればOKです。
とりあえず今回はmake qmail-local
一発で済んでしまいました。
コンパイラのコマンドラインはconf-cc
で設定できます。
gcc -O2
だとふたつ警告が出ます。
ビルトイン関数と宣言がぶつかるという警告と、mainの戻り値がintじゃないという警告です。
試しに-W
も付けたらいっぱい警告が出てきたのでさっくり外しました(ぉぃ)。
-fno-builtin -Wno-main
を付けると警告は消えると思います、qmail-localをビルドしている範囲では。
qmail-localは.qmailを読んで、mailbox・Maildirへの配送、コマンド実行、転送を行います。 配送は直接ファイルを操作します。 転送はqmail-queueを呼び出そうとします。 このふたつは動作テストにはちょっと都合が悪いです。 しかし、コマンド実行は好きなコマンドを実行して終了するため、動作確認にもってこいです。
次に実行に必要なものを用意しなければなりません。 元々のqmail-localは制御ファイルを使いませんから、制御ファイルは用意する必要ありません。 メールを配送する場合はメールボックスが必要ですが、メールを配送しないのならこれも要りません。 ホームディレクトリはCygwinのものがそのまま使えます。 .qmailはコマンド実行を指定するのを適当に書いておきます。
あとは入力メッセージが必要です。 これは標準入力へ入力しますが、シーク可能なストリームでなければなりません。 これは適当なメールメッセージをファイルとして作っておいて、リダイレクトすればOKです。 catしてパイプでつないだのではダメです。
次。 コマンドラインを調べましょう。
qmail-local [ -nN ] user homedir local dash ext domain sender defaultdelivery
・・・引数、多いです。
-n
を指定すると実際の実行をしません。
しかし、今回はコマンドを実行させたいので、これは指定しません(-N
が通常の動作で、デフォルトで指定されている状態です)。
userはメールが配送されるユーザー名、homdirはホームディレクトリなので、bashから実行するなら~userでOK、localはメールアドレスの@より前、dashとextは.qmailを決めるので、後で考えることにして、domainはメールアドレスの@より後ろ、senderは表書き差出人アドレスで、defaultdeliveryはmailbox形式なら./mailbox、Maildir形式なら./Maildir/ ですが、今回は配送はさせない予定なので、まあどっちでもいいです。
で、dashとextですが、qmail-localは.qmailとして、homedir/.qmaildashext
を探します。
これはuserがどうだろうが、localがどうだろうがこの名前です(実際にはdot-qmailのマニュアルに書いてある通り変換を受けます)。
で、dashが空の場合は.qmailファイルが見つからなかった場合に、空の.qmailファイルがあるのと同じ扱いになり、defaultdeliveryの指示に従うことになりますが、今回は.qmailが見つかってくれないと困るので、dashにハイフン、extに残りを指定すればいいです。
qmail-usersのワイルドカード型割り付けで指定したpreはどこにいったかというと、これはqmail-sendがextにくっつけてqmail-localに渡しています。 なので、extはpreをくっつけた状態で指定します。
したがって、message.txt という内容のメールが joe@example.com から bob@example.jp へ送られ、virtualdomainsのbob@example.jp:user
に引っかかってuser-bob@example.jpとなり、user宛に配送されて~user/.qmail-bob の配送指示に従う場合、
qmail-local user ~user user-bob - bob example.jp joe@example.com ./Maildir/ < message.txt
.qmail中で指定したコマンドは、sh -c
の引数として渡され、メールメッセージは標準入力で渡されます。
この例で.qmailに|/bin/cat
とでも書いておけば、message.txtの内容が表示されるでしょう。
|/bin/echo "$NEWSENDER"
と書いておけば、環境変数NEWSENDERの内容が表示されるでしょう。
あとは好きなだけコマンドラインをいぢるなり、.qmailをいぢるなりしてください。
Copyright (C) 2011 You SUZUKI
$Id: remove-prepend.htm,v 1.4 2017/05/17 07:51:05 you Exp $
ひっそりとえいごも書いてみた