月別アーカイブ: 2010年8月

Avast! のメールシールド

先日、Avast! のメール検査が勝手にTLSを使う件について書いたが、その理解は正確ではないことがわかった。

Avast! 5 には「メールシールド」として、受信および送信メールの検査が行われる。Thunderbird のようなメールクライアントで SSL や STARTTLS を使うとメールの検査ができなくなるので、検査を行う場合はメールクライアント側では SSL や STARTTLS を使用しない設定にする。そのときは Avast! が SSL や STARTTLS のラッパーとして動作するのだ。

このラッパーの動作は Avast! 内のテーブルで定義され、通常は初回の接続時に自動で設定されるようだ。この自動設定は概ねうまくいく。

問題は、サーバの挙動が変化した時や、メールクライアントの設定を変更した時で、すでに存在する設定は自動的には再設定されない。なので、例えば、以前の送信設定でポート 25 を使っていたのをポート 587 に変更する場合など、メールクライアントの設定を変更しても、 Avast! の設定が以前のままで、サーバにはポート 25 で接続する、なんてことが起こりうる。

なので、Avast! でメールの検査を行っている場合、設定変更の際にはこのテーブルの内容の確認と設定を忘れないようにしたい。

このテーブルは Avast! の「リアルタイムシールド」-「メールシールド」-「詳細な設定」-「SSLアカウント」で確認および設定ができる。

メールサーバ設定のデバッグ

昔と違って、SMTP (“Simple” Mail Transfer Protocol) も複雑になったので、telnet などを使ってメールプロトコルを直接入力するのは大変である。設定のテストなどもメールクライアントなどを使うことになるので、必要なデバッグ情報を得るための設定をメモしておく。

Postfix でプロトコルのやりとりなどを記録するためには、main.cf に debug_peer_list を追加し、デバッグの対象としたいクライアントやサーバを指定する。指定にはホスト名やIPアドレスのパターンが使用できる。ログの冗長度は debug_peer_level で指定でき、デフォルトは 2 となっている。

debug_peer_list = 192.168.0.0/24
debug_peer_level = 2

Thunderbird でプロトコルのやりとりなどを記録するためには、環境変数 NSPR_LOG_MODULES と NSPR_LOG_FILE を指定して Thunderbird を実行する。たとえば、SMTP に関するログを記録するには、コマンドプロンプトから次のように実行すればよい。

C:\> set NSPR_LOG_MODULES=SMTP:5
C:\> set NSPR_LOG_FILE=d:\smtp.log
C:\> "c:\Program Files\Mozilla Thunderbird\thunderbird.exe"

NSPR_LOG_MODULES は、取得したいログの種類とレベルを指定する。ログの種類はSession logging for mail/news – MozillaZine Knowledge Base によれば、以下が使用できる。また、カンマ区切りで複数の種類を同時に指定できる。

POP3 	For getting mail
IMAP 	For getting mail
SMTP 	For sending mail
NNTP 	For usenet news
HTTP 	For RSS feeds
LDAP 	For address books

最近では、アンチウィルスソフトなどが通信に介入するケースも有るようなので、サーバのログtoとクライアントのログが一致しない場合には、パケットをモニタする必要もあるだろう。

Postfix の TLS support

Postfix の TLS (Transport Layer Security) サポートを有効にすると、通信経路の暗号化が可能になる。証明書をつかったクライアント認証を行うことも可能であるが、クライアント認証は SASL (Simple Authentication and Security Layer) によって行うこととしたため、ここでは考えない。

設定方法は、main.cf でサーバー証明書(ここでは mailservercert.pem)と秘密鍵(ここでは serverkey.pem)の場所を指定し、master.cf で submission ポートに対して起動する smtpd にオプション -o smtpd_tls_security_level=encrypt を指定すればよい。サーバ証明書で、中間証明書(またはオレオレCA証明書)が必要な場合はあらかじめサーバー証明書に結合しておく。秘密鍵の方は所有者を root にし、root だけが読み出せるようにしておく。ユーザ postfix が読み出せる必要はない。

smtpd_tls_cert_file = /etc/openssl/certs/mailservercert.pem
smtpd_tls_key_file = /etc/openssl/private/serverkey.pem
submission inet n       -       n       -       -       smtpd
-o smtpd_tls_security_level=encrypt
-o smtpd_sasl_auth_enable=yes
-o smtpd_client_restrictions=permit_sasl_authenticated,reject

SASL のクライアント認証の時のパスワードデータベース sasldb.db の時は、ユーザかグループの読み出し許可をつけておかないと読めなかったのに、秘密鍵はなぜ読めるんだろうと思って、smtpd を ktrace にかけてみた。結果、smtpd は最初 root 権限で実行され、その後 postfix 権限に落ちるが、秘密鍵の読み込みは root の時に処理され、sasldb.db の読み込みはユーザ postfix で処理されるということがわかった。Postfix の問題らしい。

ちなみに、smtpd を ktrace にかけるには、main.cf に debugger_command を設定し、master.cf の smtpd に -D オプションを付ける。

main.cf

debugger_command =
/usr/bin/ktrace -p $process_id -f /tmp/postfix_ktrace.out & sleep 5

master.cf

submission inet n       -       n       -       -       smtpd -D
-o smtpd_tls_security_level=encrypt
(略)

上記によって得られたデバッグ出力を見るのは、次のようにする。

$ sudo kdump /tmp/postfix_ktrace.out

メールクライアントの認証

外部のネットワークからのメールクライアントの接続を許可する場合、SMTP-AUTH による認証メカニズムの導入は必須であると言ってもよいだろう。昔は POP before SMTP なる技術が採用されたりもしたが、SMTP-AUTH が標準化され普及した今ではその意義もなくなっている。

メールクライアント (MUA: mail user agent) からの接続と、メールを配送するサーバ (MTA: mail transfer agent) からの接続を同一のホストで受ける場合、接続を受け付けるポートは別にしたほうが都合が良い。なぜなら、MUA からの接続と MTA からの接続を区別し、メールサーバの挙動を切り替えたい状況が多いからだ。

例えば、MUA からの接続に対しては SMTP-AUTH による認証を必須とする代わりに受け付けるメールの制限は少なくし、MTA からの接続に対しては認証を行わず受け付けるメールは自ドメイン宛のものに限定する、などといった類である。

同一ポートで、同様の切り替えを行うことは可能ではあるが、ポートを別にしたほうが設定や方針が分かりやすい。そのほうがミスを減らせるのではないか。

以下では、Postfix 2.7.1 を使用して、submission port (587) に、MUA からの接続を受け付ける SMTP サーバを用意し、SMTP-AUTH (SASL) による認証を必須とする設定を行う。

まず、main.cf に追加する smtpd に関する設定。smtpd_recipient_restrictions は中継を許可または拒否する設定であり、デフォルトでは “permit_mynetworks, reject_unauth_destination” となっている。ここでは、2番目に permit_sasl_authenticated を追加しており、SASL 認証を通して送られてきたメールの中継を許可している。ルールは先頭から順に該当したものが適用されるので、permit_mynetwork に該当するもの(接続元が自ネットワークのもの)は全て許可、SASL 認証を通過したものは全て許可、それ以外は中継を許可されたドメイン宛のメールだけが許可される、ということになる。

smtpd_recipient_restrictions =
permit_mynetworks,
permit_sasl_authenticated,
reject_unauth_destination

SASL 認証を行わない場合は、permit_sasl_authenticated に該当することはないので、結局のところデフォルトと同じ動作となる。

次に、master.cf の submission のところ(デフォルトでコメントアウトされている)を以下のようにする。先頭が空白の行は前の行から継続する行である。submission ポートに起動する smtpd は2~3行目に記述されているオプションが適用され、SASL 認証が有効、かつ、必須となっている。

submission inet n       -       n       -       -       smtpd
-o smtpd_sasl_auth_enable=yes
-o smtpd_client_restrictions=permit_sasl_authenticated,reject

これで、submission ポートに接続した MUA に対しては SASL 認証が必須となる。したがって、main.cf に設定した permit_sasl_authenticated が適用され、MUA からのメールは受信者アドレスの制限を受けない。

MUA に対する SASL 認証を行うためのパスワードの設定は Cyrus のツールを使う。

$ sudo saslpasswd2 -c -u `/usr/pkg/sbin/postconf -h myhostname`  (ユーザ名)
Password: (パスワードを入力)
Again (for verification): (もう一度パスワードを入力)

/usr/pkg/etc/sasldb.db が新規に作成、または更新される。smtpd は root として実行されないので sasldb.db の読み取り許可を確認して、smtpd が読み出せるようにしておく必要がある。
NetBSD では user=postfix, group=postfix で実行されるので、sasldb.db のグループを mail にしてグループ読み取り許可を付加し、グループ mail にユーザ postfix を追加しておくのが良いのではないかと思う。

/usr/pkg/lib/sasl2/smtpd.conf を設定するとかいう話があるが、CRAM-MD5 で認証する場合は不要である(デフォルトで O.K.)。同様に saslauthd も不要。

なお、Windows で Avast! を使っていると、Thunderbird からメールを送るときにエラーになる。TLS を使わない設定にしていても、Avast! が勝手に TLS を使おうとするようだ。Avast! の設定で、送信メールの検査を無効にすれば TLS を使っていなくても接続できる。送信メールの検査と、TLS を使わないのとを両立させることができるかどうかは不明。

Postfix の sender_dependent_default_transport_maps

Postfix の sender_dependent_default_transport_maps は、エンベロープの送信者アドレスによって、メールの配送先を選択する仕組みである。Postfix 2.7 以降で導入されている。

sender_dependent_default_transport_maps で指定したテーブルに送信者アドレスがマッチすると、マッチした行で指定された transport:netxthop が配送に使用される。

では、たとえば、送信者アドレスがテーブルにマッチするケースで受信者がローカルの場合はどうなるのだろうか。

これは、期待通りに動作する。つまり、受信者がローカルの場合はローカルに配送される。

postconf(5) によれば、sender_dependent_default_transport_maps は default_transport の設定を再定義する(override)。そして、default_transport は 受信者のアドレスが $mydestination, $inet_interfaces, $proxy_interfaces, $virtual_alias_domains, $virtual_mailbox_domains, $relay_domains にマッチしない場合に使用されるものであるから、受信者がローカルの場合は $mydestination にマッチし、default_transport は使用されない。つまり、sender_dependent_transport_maps も使用されない事になる。

プロバイダの SMTP サーバへの接続

今時のプロバイダでは、メールを送るのに SMTP-AUTH (SASL) による認証が必要となっている。

relayhost でプロバイダの SMTP サーバを指定して、外部宛のメールは全てプロバイダの SMTP サーバに送る、というような場合には、Postfix のドキュメントの日本語訳(Postfix SMTP クライアントで SASL 認証を有効にする)の記述に従えばよい。

独自ドメインを運用していて、プロバイダのメールも使用しているような場合、独自ドメインのアドレスでメールを送るときは直接配送で、プロバイダのアドレスでメールを送るときはプロバイダの SMTP サーバに送る、というような運用をしたい。

ようするに、エンベロープの送信者アドレス (envelope sender address = MAIL FROM のアドレス)をみて、転送先を切り替えたいというわけだ。

以前の Postfix でこれを実現するのは困難であったのだけれども、今はそうでもない。
sender_dependent_relayhost_maps (2.3以降で使える)や sender_dependent_default_transport_maps (2.7以降で使える)がそれだ。

ざっと見た感じでは、機能的には sender_dependent_relayhost_maps はsender_dependent_default_transport_maps に含まれているようにみえるが、もしかすると細かい挙動の違いとかあるのかもしれない。

sender_dependent_relayhost_maps を指定する場合、テーブルの基本的な文法は postmap(1) に記述されているとおりで、キーと値が空白で区切られる。この場合、キーにはエンベロープの送信者アドレスか @ 付きのドメインを記述し、値には配送先を記述する。配送先の書式は transport:nexthop で、transport_map と異なり、null エントリを指定することはできない。特に前者の、ドメインは @ が付いていないといけないあたりは注意が必要である。

main.cf に追加する設定。もちろん、smtp_sasl_password_maps や sender_dependent_default_transport_maps のファイル名は任意に付けて良い。

smtp_sasl_auth_enable = yes
smtp_sasl_password_maps = hash:$config_directory/sasl_passwd
smtp_sasl_type = cyrus
sender_dependent_default_transport_maps =
hash:$config_directory/sender_transport

/usr/pkg/etc/postfix/sasl_passwd の設定。編集後に当該ディレクトリで postmap
sasl_passwd を実行しておく。

[smtp.example.com]          account_1:password_1
[mail.example.ne.jp]:587    account_2:password_2

/usr/pkg/etc/postfix/sender_transport の設定。編集後に当該ディレクトリで postmap
sender_transport を実行しておく。

@example.com      smtp:[smtp.example.com]
@example.ne.jp    smtp:[mail.example.ne.jp]:587

この設定で、エンベロープの送信者アドレスが hoge@example.com であれば smtp.example.com に、fuga@example.ne.jp であれば mail.example.ne.jp のポート 587 に SMTP-AUTH を使って接続し、それ以外は直接配送となる。

SASL 付きの Postfix をインストールする

メールサーバとしてもっぱら Sendmail を長いこと使ってきていた。NetBSD 4.0 から 標準が Sendmail から Postfix に変わったが、SMTP-AUTH を使うためにはどのみち標準のメールサーバでは対応できす、pkgsrc から Cyrus-SASL を組み込んでコンパイルしたものを使わないといけないので、運用サーバが NetBSD 4.0 以降となっても Sendmail の方を使い続けてきた。

しかし、Sendmail も大昔のモノリシックな構成ではなくなった(あくまで使用者から見た場合の話で)ので、標準ではなくなった Sendmail を使い続ける意義も薄くなった。Sendmail を使っている理由のひとつには、僕が Postfix よりも Sendmail の方に慣れているということがあるのだけれども、じゃあ、お前は Sendmail のエキスパートなのかというと全くそんなことはあるわけもなく、それは昔 CF から cf に移行したときの苦労がもったいないとか、手元の初版と3版のコウモリ本をどうしようかとか、そんなつまらない理由なのかもしれない。もっとも、昔は Sendmail でサポートされた機能が Postfix にはまだ入っていなくて(認証とかフィルタとか)、とかの話もあったような気もするが、いずれにしてももう気にする必要もないのだろう。

SMTP-AUTH (SASL) を使えるようにするため、/etc/mk.conf に以下の行を追加して pkgsrc の postfix をインストールする。オプションの sasl は Cyrus-SASL を組み込むための、pcre は Perl 互換正規表現エンジンを組み込むための指定だ。pcre は指定しなくても標準の正規表現エンジンが使用できるが、本家のマニュアルでは pcre の方がいいようなことを書いてるのでついでに組み込んでおく。

/etc/mk.conf への以下の行を追加する。

PKG_OPTIONS.postfix= sasl pcre

pkgsrc から postfix をインストールする手順はいつもどおり。

$ cd (pkgsrc のルート)/mail/postfix
$ make update

NetBSD では標準の /etc/rc.d/postfix があるので、pkgsrc の RCD script はインストールされない。代わりに、インストール時に表示されるメッセージ(MESSAGE.NetBSD を参照)を参考に、以下の内容で /etc/rc.conf.d/postfix を作成すると、/etc/rc.d/postfix から pkg の方の postfix を操作できる。

postfix_command='/usr/pkg/sbin/postfix'
required_files='/usr/pkg/etc/postfix/main.cf'
postconf='/usr/pkg/sbin/postconf'

コマンドラインから実行する場合は、NetBSD 付属の方を実行しないようにパスに気をつける(えー)。

PKG_OPTIONS.postfix=sasl とした時、依存関係で security/cyrus-sasl がインストールされる。実際の SASL 認証は、プラグインが必要。何が必要かは相手の SMTP サーバによるが、僕が契約しているプロバイダでは CRAM-MD5 が使われている。なので security/cy2-crammd5 を追加でインストールする。インストールされた認証プラグインはデフォルトで全て有効になるそうだ(設定ファイルを記述すれば、使用するプラグインを個別に指定することが可能)。

Postfix の基本設定は、/usr/pkg/etc/postfix/main.conf を編集して行う。書式は、行頭の # がコメントで、行の途中からはコメントは記述できない。行の先頭が空白文字だと、継続行として扱われる。といった感じでちょっと文法に癖がある印象。

myorigin の設定。最終的にはドメイン宛のメールを受け付けるので myorigin=$mydomain にする予定だが、テスト運用期間中はデフォルトの myorigin=$myhostname にしておくので、変更しない。

mynetworks の設定。接続が信頼されたネットワークのものかどうかを識別する際に使われる。設定していないと、デフォルトの mynetworks_style=subnet が評価されるので、外部に接続するインターフェースを持ったマシンでは設定しておいたほうが良いと思う。

#myorigin = $mydomain
mynetworks = 192.168.0.0/24, 127.0.0.0/8

長くなったので、SASL とかは別の記事にまとめることにする。あと、Postfix を管理するにあたって感じたことを以下に。

Postfix のキューの構造は Sendmail とはずいぶん異なるようなので、障害時にキューに溜まったメールファイルを直接削除するとかは避けたほうが無難。キューを操作するコマンドは用意されているのでそれを使う。

  • キューのフラッシュ postfix flush または postqueue -f
  • キュー内の特定のメールの処理 postqueue -i <queue_id>
  • キューからの削除 postsuper -d ALL (全て)、postsuper -d <queue_id> (個別指定)

Postfix のログは、各コマンドが個別に吐く(もちろんファイルとしては一つにまとまるのだが)ので、メールの処理を追跡するという意味では、Sendmail に比べて読みにくいと思う。慣れればすむ話なのか、ログ出力をチューニングするとなんとかなるのかはわからない。

Postfix が付ける Received の書式が気に入らない(見せたくない情報を隠したいなど)となっても、書式をカスタマイズすることはできないらしい。代わりに header_checks でひっかけて、置換するんだとか。ヘッダを編集したいわけではないんだけどな。だいたいそれだと、まかり間違って既存の Received にマッチしたらそっちも置き換わってしまうんじゃ?

いろいろと、しっくりこないところはありますが、とにかく、しばらく Postfix と付き合っていこうかと思います。

Atom D510 の消費電力

前述の PC に NetBSD をインストールする際には、USB 接続の DVD-ROM ドライブを使用した。NetBSD インストール後のアイドル時の消費電力はワットチェッカーの読み値で 30W 程度。部屋に温度計がなかったので正確にはわからないが、室温は 40℃ くらいだったかと思う。その状態で2時間ほど放置しておいたら、ケースがやけに熱くなっていて、BIOS の温度表示で確認したら CPU 温度が 100℃ を超えてしまっていた。

明らかに冷却が足りていないので、ケースに収まりそうな薄型のファンを探してみると、Ainex CF-60SS が、厚さ10mmなので納まりそうである。実際に似たような状況で、このファンを使っていい結果を出している人もいるようなので、早速注文した。在庫有りのところを探し、ヨドバシ・ドット・コム で 1,440 円。たまたま別の買い物があったので、送料は無料になっている。

ファンが届くまでに、たまたま日本橋に立ち寄る用事があったので、温度センサも購入しておく。
共立電子 電脳専用体温計「白衣天使」ETM2000 787円。日本橋に行くんだったら冷却ファンも日本橋で買えばよいのだが気にしない。

冷却ファンはマザーボードのヒートシンクとケースの隙間に綺麗に納まった。個人差はあるだろうが、音は小さく気にならない。温度センサはヒートシンクの根元付近に貼り付けた。外付け DVD ドライブは取り外し、アイドル状態で放置した時の消費電力は 25W、温度は 45℃ くらい。BIOS の CPU 温度も 50℃ 以下だったので、問題なく冷却出来ているようである。ていうか、アイドル状態での DVD ドライブの消費電力が比較的大きい。USB 機器は電力消費が大きいのがあるので要注意ということか。