postfixチューニング


F&Fでは地震情報の配信を行っている。
これは即時性が求められるため、出来るだけ遅延無くメールを配信したい。
サーバのディスクがクラッシュした際にFreebsd7をインストールし、自宅サーバ運用を行うためにbind9を入れた。
普通に考えればローカルにDNSを持っている訳なのでメールの配信速度は上がっても良いはずだ。
しかし実際にそうはいかなかった。
mailqコマンドで見ると配信できなかったメールがqueueに大量に溜まるのである。
メール配信時に配信の状態をチェックするためqueu
の状態をモニタしているのだが、それで異常に気づいた。
maillogをチェックしてみるとsocket too many open file descriptors のメッセージが出ている。
しかしその後名前引きは正常に完了してメールは配信される。
何故DNSが引けないのか?ログにはdsn=4.4.3, status=deferred (Host or domain name not found. Name service error for name=smcon.co.jp type=MX Host not found, try again) のメッセージが大量に残っている。
そこでまずkernel関係のパラメタを調整する。
/etc/sysctl.comf
/boot/loader.conf
しかし様子は変わらない。
そこでsocketを確認してみる。
メール配送がピークに達したと思われるときに、sockstat | grep named | wc -
とすると、どうやらこれが1024以上に増えないようだ。
socketが不足するためにpostfixとnamedがお話しできなくなる感じだ。
そこでsocket数を増やすのだが、これには再コンパイルを要する。
まずはヘッダファイルでFD_SETSIZEを大きくする。
/usr/include/sys/select.h /usr/src/sys/sys/select.
この中の、#define FD_SETSIZE 16384U ←デフォルトは1024
を、変更してbind,postfix,kernel(一応)を再コンパイルした。
この状態でbindを起動すると、named.confのfiles数がFD_SETSIZEより小さいと言われる。
そこで、named.confのoptionesに書かれているfilesを、files 65535
とする。
またpostfixのmain.cfにも以下の記述をしている。
smtpd_recipient_limit = 100000
smtpd_client_connection_rate_limit = 10000
anvil_rate_time_unit = 1
default_process_limit = 500
queue_run_delay = 60
minimal_backoff_time = 100 この中のdefault_process_limitはpostfixの同時起動数で、指定しない場合は200程度の筈だ。
ただこれをやたら大きくすればいいと言うものでもなくCPUパワーやメモリ搭載量に応じた最適値でなければいけない。
特にメモリの少ないシステムでこれを過大に設定するとswapが起きてどうにもならなくなる。
以上の変更によって従来ISPのDNSを引いていたときよりも速くメールが配信できるようになった。


spamは相変わらずである。
ホームページにメールアドレスなど書こうものなら、すぐにspamがやってくる。
同時にそのドメインがメールを受信できる状態であると判断されるため、辞書方式と思われるような手当たり次第的にメールアドレスを抜き出そうとする試みも見られる。
そこで出来る限りの対策を行うことにするが、正常なメールを拒否してしまわないような注意も必要だ。
いや、拒否するのだから異常なメールなのだが異常な送り方をされながらも内容は正常なメールもある。
SPFレコードなどはそれにあたり、転送や独自ドメインを持ちながらもDDNS運用+メール送信はISPのSMTPサーバという組み合わせではどうにもならない。
ただ、世の中的にはspamerは同様な送り方をしてくる訳なのでいずれ排除されることになるのだろう。
このあたり、自宅サーバ運用者の一人として何とも難しいことだと思う。
main.cfの設定は以下のようになっている。
smtpd_recipient_restrictions =
     permit_mynetworks,
     reject_non_fqdn_recipient
     reject_non_fqdn_sender
     permit_sasl_authenticated
     reject_unauth_destination
     reject_unknown_sender_domain
# check_policy_service unix private/policy ←SPFによる拒否は現在保留中smtpd_recipient_limit = 100000
smtpd_client_connection_rate_limit = 10000
anvil_rate_time_unit = 1
default_process_limit = 500
queue_run_delay = 60
minimal_backoff_time = 100 smtpd_sasl_auth_enable = yes
smtpd_sasl_local_domain = $myhostname
smtpd_sasl_security_options = noanonymous
broken_sasl_auth_clients = ye
smtpd_client_restrictions =
     permit_mynetworks,
     reject_unknown_client
     reject_rbl_client sbl-xbl.spamhaus.org,
     reject_rbl_client all.rbl.jp,
     reject_rbl_client bl.spamcop.net,
     permi
smtpd_helo_required = yes
smtpd_helo_restrictions =
     permit_mynetworks,
     reject_invalid_hostname,
     check_helo_access hash /usr/local/etc/postfix/reject_helo,
     permi
smtpd_sender_restrictions =
     reject_unknown_sender_domain,
     reject_non_fqdn_sender hash /usr/local/etc/postfix/reject_sende
disable_vrfy_command=yes
smtpd_reject_unlisted_sender = ye
mailbox_size_limit = 0 RBLによるブラックリスト掲載IPからの接続拒否も問題がないわけではない。
本人が気づかずにISPのIPブロックごとブラックリストに載っている場合は厄介だからだ。
RBL JPのリストは2日で自動消去されると言うことなのでメール再配送の設定がそれより長ければ助かる可能性がある。
しかしこのブラックリストによるspam排除効果は無視できないのでF&Fでは設定している。
なおホワイトリストによって日本のIPアドレスからの送信ならば受信する設定も出来る。
日本のプロバイダはほぼ全てが逆引き設定しているのでドメイン判定でも可能だとは思うがjpドメイン以外を使うところもあるので注意したい。
ドメインから割り当て国を引くにはここが便利だ。
明らかにspam発送が多いISPはブラックリストに入れて拒否する。
cnc-nocなど中国系や、こちらにリスとされている所などがそれにあたる。
spam拒否関係のページを見ていると、たびたびインターリンクの名が見られる。
実はF&Fでも数年以上前にここの経営者と一悶着演じたことがある。
インターリンクは自らspam発送を行っており(特定商取引法改正以前)送信拒否を申し入れた。
しかし先方は「通常の商行為であり送信拒否には応じられない」と突っぱねられた。
同社はメールアドレス売りも行っていたのでその被害は相当なものになった。
オマケに、同社へ問い合わせに使用したメールにまでもspamが来るようになってしまった訳で、yournetやnttpcよりも酷いと言わざるを得ない。
しかし同社はISPであるのでドメイン拒否を行うと影響が大きくなるのはnttpcやyournetとも似ている。
インターリンクは固定IPアドレスサービスも行っているので自宅サーバ運用を考えている方は検討に値するかも知れないのだが、自宅サーバでメール送受信も行おうとするとspam評価の点で辛い事になりそうだ。
HELOのチェックも行っている。
spamの中にはここでfnf.jpを名乗るもの、IPアドレスを通知してくるものもあるので効果がある。
HELOにしてもそうなのだが、メール送信者(From )にF&Fドメインを名乗る輩もいる。
ごくローカルなメールサーバの場合は運用ドメイン間のメールのみ中継するものもあるからだろうが、これもdisable_vrfy_command=ye
で拒否する。
これは実在するID以外のIDを名乗っての接続を禁止する記述だ。
逆引きできないドメインも拒否するが、SMTPサーバが逆引きできない事はあり得ないのでこれは良いだろう。
中国などでは逆引き設定を行わないのが普通?みたいで、中国がこの方針を貫く限りspam防止には役立つ。
クライアントIPの逆引きも、これが出来ない接続は拒否するが、中国出張の時などは空港のホットスポットもホテルもみんな逆引き不可能IPだったりするので注意が必要だ。
ちなみに中国に割り当てられているIPアドレスを全てブロックしている所もある。
これは日本人spamerが中国やタイランドにspam発信基地を作り、様々なドメインを使いながらspamを送りまくった事に起因する対策だ。
(info spamなど) spam拒否効果を見るにはspamが来ないといけない。
そこでホームページなどに架空のアドレスを掲載してspamerを呼ぶ。
ドメインがバレてしまうデメリットもあるし、辞書方式で手当たり次第のアタックを受ける可能性もあるがデバッグにspamは必要だ。
なお同一IPから連続アタックを受けた場合はこちらに書いているような方法でIPアドレスを遮断してしまうのが良いだろう。


【追記】常時接続送信者を多少でも助けるためにこちらに書かれている方法を実装した。
CIDERテーブルを作成して、IPアドレス発行国が日本の場合は多少制限を緩くするシカケだ。
他にspfのチェックも行うことにした。
今まではspfレコードのないものを全てリジェクトしていて、それはおそらく/usr/local/sbin/postfix-policyd-spfがいけないのではないかと思っていた。
そこでCPANなどで必要モジュールをインストールした上で、/usr/local/sbin/postfix-policyd-spf-perlを組み込んでみたが結果は変わらなかった。
現時点でspfによるリジェクトをするのは正しいとは思えない。
結局master.cfをいじくり回していて、
spfcheck unix - n n - - spawn ←この記述だとspfエラーはリジェクト
policy  unix - n n - - spawn ←この記述だとspfエラーを拡張ヘッダに付け加えて受信
 user=nobody argv=/usr/local/sbin/postfix-policyd-spf-perl と言うことが解った。
ちなみにmain.cfの当該部分はcheck_policy_service unix private/polic
となっている。
これら色々な仕掛けを設定すると何が何だか解らなくなってくる。
更に様々なリストを参照するようにするとパフォーマンスも落ちてくる。
そこでreject_senderファイル(hash)にホワイトリストも混ぜてしまった。
main.c
smtpd_recipient_limit = 100000
smtpd_client_connection_rate_limit = 10000
anvil_rate_time_unit = 1
default_process_limit = 500
queue_run_delay = 60
minimal_backoff_time = 100 smtpd_sasl_auth_enable = yes
smtpd_sasl_local_domain = $myhostname
smtpd_sasl_security_options = noanonymous
broken_sasl_auth_clients = ye
smtpd_restriction_classes =
    check_dynamic_client
    check_client_jp
    check_client_n
check_dynamic_client =
    check_client_access
    cidr /etc/postfix/check_client_country
    check_client_n
check_client_jp =
    check_policy_service
    inet 10027
    sleep 15
    permi
check_client_na =
    check_policy_service
    inet 10028
    sleep 1250 #Connect CLIENT IP address
smtpd_client_restrictions =
    permit_mynetworks,
    reject_unknown_client
    reject_rbl_client sbl-xbl.spamhaus.org,
    reject_rbl_client all.rbl.jp,
    reject_rbl_client bl.spamcop.net,
    permi
#MAIL RCPT TO section
smtpd_recipient_restrictions =
    permit_mynetworks,
    check_sender_access hash /usr/local/etc/postfix/reject_sender
    check_client_access regexp /etc/postfix/check_dynamic_client
    reject_non_fqdn_recipient
    reject_non_fqdn_sender
    permit_sasl_authenticated
    reject_unauth_destination
    reject_unlisted_recipient
    reject_unknown_sender_domain
    check_policy_service unix private/polic
smtpd_helo_required = yes
smtpd_helo_restrictions =
    permit_mynetworks,
    reject_invalid_hostname,
    check_helo_access regexp /usr/local/etc/postfix/reject_helo,
    permi
# MAIL FROM section (Not Fom )
smtpd_sender_restrictions =
    check_sender_access hash /usr/local/etc/postfix/reject_sender
    reject_unknown_sender_domain,
    reject_non_fqdn_sende
disable_vrfy_command=yes
smtpd_reject_unlisted_sender = ye
mailbox_size_limit = 0 reject_senderには拒否アドレス(ドメイン)と共にホワイトリストも同居させたため、記述位置を一番上にする。
(そうしないと先に他の条件でリジェクトされる)reject_senderにはhashを使うので正規表現記述は出来ない。
一方でreject_heloは正規表現しないとどうにもならないのでregexpを使う。
smtpd_recipient_restrictionsの中でルールの記述があればsmtpd_sender_restrictionsでの設定は不要だとも思える。