Postfixメール送信制限 その2

項番 機能
1 主要3キャリアへの独自?ルールにより送信(セッション数、同時メール送信数の制限)
2 配信時刻制限(docomo.co.jp宛のメールは深夜帯を避けるなど)
3 エラーメール処理(バウンスメールをカウントして、設定した回数を越えたら配信しない)
4 絵文字メール送信
5 単位時間あたりのメール送信制限(例 1時間に6万通を上限にする等)
6 複数アドレスによるメール送信(キャリア宛のメール送信の高速化)

今日は、2について記述する。2はどこで活躍するか?なのですが、業務の現場では携帯メールを深夜帯に飛ばしたくないみたいな要望があるらしいのです(受信者側のマナーモードで対応しろといった理屈は、通用しないらしい)ということで、調べてみるとdefer_transport(master.cfで指定したサービス名を記述すると、メール配信を保留状態にする(メールキューにに滞留する))といった状態にすることが出来ます。これと、cron等と組み合わせて配信時刻制限をすることが出来ます。例として、softbank,au,docomoのサービスを登録して、配信時刻制限をするといったことを設定してみます。

1. master.cfにサービスを登録します
smtp_destination_concurrency_limitとsmtp_destination_recipient_limitは、上記表の1に関連しますので、次の機会でお話します

## 配信制限用
smtp-docomo unix - - n - - smtp
-o smtp_destination_concurrency_limit=1
-o smtp_destination_recipient_limit=1
smtp-softbank unix - - n - - smtp
-o smtp_destination_concurrency_limit=1
-o smtp_destination_recipient_limit=1
smtp-ezweb unix - - n - - smtp
-o smtp_destination_concurrency_limit=1
-o smtp_destination_recipient_limit=1

2. transportマップにそれぞれのドメインを定義します
デフォルトローカル向きですので、必ずmailgatewayの設定は実施しましょう。

## 配信時刻制限をしたいドメイン ##
docomo.ne.jp smtp-docomo:[mailgateway]
ezweb.ne.jp smtp-ezweb:[mailgateway]
softbank.ne.jp smtp-softbank:[mailgateway]

3. main.cfにdefer_transportを設定します
defer_transports = smtp-docomo smtp-ezweb smtp-softbank
4. 設定反映

#postmap /etc/postfix/transport
#postfix reload

これで、defer_transortsに各サービスタイプが記述されているときはメール配信はされないので、夜間は 3のような記述をし、規程した営業時刻は"postconf -e defer_transports="を実行、メールキューの吐きだしをすれば配信時刻の制限は可能となります。

ベンチマーク時には、smtpd_client_event_limit_exceptionsを

同一クライアントからのメール送信を制限しようと、smtpd_client_message_rate_limitとanvil_rate_time_unitを設定し、メールのベンチマークツールpostalを利用して、
動作確認を行っていたが、いっこうに制限がかからない、、、、main.cfに追加した設定は以下のとおり。

# 単位時間あたりの送信数制限
smtpd_client_message_rate_limit = 5
# 単位時間の設定
anvil_rate_time_unit = 60s

上記設定をすれば、同一クライアントからは1分間に5通しか送信できなくなるはず。。。
で、原因はpostfixを起動している端末でベンチマークを実行していたというよくある話であった。
接続カウントや接続速度、SMTP要求速度の制限から除外されるクライアンを設定する、smtpd_client_event_limit_exceptionsの
デフォルトは、$mynetworksである。これを以下のようにブランクにしてあげれば、動作確認を行うことが出来る。

# 単位時間あたりの送信数制限
smtpd_client_message_rate_limit = 5
# 単位時間の設定
anvil_rate_time_unit = 60s
# 接続カウントや接続速度、SMTP要求速度の制限から除外されるクライアント
smtpd_client_event_limit_exceptions =

postalで、この制限を破ると以下のような出力となる

$postal -M 1 -m 1 -t 1 -r 20 localhost userlist
time,messages,data(K),errors,connections,SSL connections
Server error:450 4.7.1 Error: too much mail from 127.0.0.1
.
Server error:450 4.7.1 Error: too much mail from 127.0.0.1
.

maillogは、以下のような出力となる

Sep 6 14:29:28 oos-h-671 postfix/smtpd[20641]: > localhost[127.0.0.1]: 450 4.7.1 Error: too much mail from 127.0.0.1
Sep 6 14:29:28 oos-h-671 postfix/smtpd[20641]: warning: Message delivery request rate limit exceeded: 7 from localhost[127.0.0.1] for service smtp

Postfixでメール送信制限 その1

最近関わった仕事で携帯メールの送信で飯を食べている会社が結構あるということを知り、Postfixでそれらを実現出来ないかということを目標に少々調査してみました。
で、私が知っている携帯メールアドレスへ送信の製品(名前は出しませんが)が保持していた機能は、以下のようなものでした。

項番 機能
1 主要3キャリアへの独自?ルールにより送信(セッション数、同時メール送信数の制限)
2 配信時刻制限(docomo.co.jp宛のメールは深夜帯を避けるなど)
3 エラーメール処理(バウンスメールをカウントして、設定した回数を越えたら配信しない)
4 絵文字メール送信
5 単位時間あたりのメール送信制限(例 1時間に6万通を上限にする等)
6 複数アドレスによるメール送信(キャリア宛のメール送信の高速化)

4はPostfixというより、どのようにMTAにメールを渡すかと言う問題なのでスルー。
6は、あんまり調査していないので次の機会。
5は、コンテンツフィルタを仕込んで単位時間あたりのメール数をカウント?みたいなことを考えて、
4倍性能が落ちるという噂のサンプルシェルを試したが、確かに遅い、、、で他の方法を調べていると
こんな記事が。。トミーが言うなら間違いないだろうということで、ここの落としどころは、
同MLに紹介されている

1. smtp の同時起動数(maxproc)の調整 master.cf
2. 並列配送の最大数 smtp_destination_concurrency_limitの調整 master.cf

と思われます。
3は、宛先ユーザ情報のDBを持って、エラーカウントを保持。定期的にログを巡回してbouncedならエラーカウントをアップすれば良いと思う。
使えそうなツールがpostfix-perl-scriptsパッケージのpflogsumm。検索すると色々出てくるけど、今回の目的(bouncedしたメールアドレスの抽出)にのみ利用するのであれば、少々修正が必要です。下記の様に、%bouncedmailaddrにメールアドレスを放り込むといった方法で良いと思う。

# diff -c pflogsumm /usr/sbin/pflogsumm 
*** pflogsumm	2010-09-02 17:37:25.918924484 +0900
--- /usr/sbin/pflogsumm	2010-02-26 21:31:39.000000000 +0900
***************
*** 413,419 ****
      $dateStr,
      %panics, %fatals, %warnings, %masterMsgs,
      %msgSizes,
!     %deferred, %bounced, %bouncedmailaddr,
      %noMsgSize, %msgDetail,
      $msgsRcvd, $msgsDlvrd, $sizeRcvd, $sizeDlvrd,
      $msgMonStr, $msgMon, $msgDay, $msgTimeStr, $msgHr, $msgMin, $msgSec,
--- 413,419 ----
      $dateStr,
      %panics, %fatals, %warnings, %masterMsgs,
      %msgSizes,
!     %deferred, %bounced,
      %noMsgSize, %msgDetail,
      $msgsRcvd, $msgsDlvrd, $sizeRcvd, $sizeDlvrd,
      $msgMonStr, $msgMon, $msgDay, $msgTimeStr, $msgHr, $msgMin, $msgSec,
***************
*** 790,796 ****
  			$bounceReas =~ s/^\d{3} //o;
  		    }
  		    ++$bounced{$relay}{$bounceReas};
- 		    ++$bouncedmailaddr{$addr}
  		}
                  ++$bncPerHr[$msgHr];
  		++${$msgsPerDay{$revMsgDateStr}}[3];
--- 790,795 ----
***************
*** 922,929 ****
      print_nested_hash(\%fatals, "Fatal Errors", $opts{'q'});
      print_nested_hash(\%panics, "Panics", $opts{'q'});
      print_hash_by_cnt_vals(\%masterMsgs,"Master daemon messages", 0, $opts{'q'});
- # Adding "%bouncedmailaddr"
-     print_nested_hash(\%bouncedmailaddr, "message bounced mailaddr for dealing with bounced mail", $opts{'q'});
  }
  
  if($opts{'mailq'}) {
--- 921,926 ----

これで抽出したアドレスをカウントアップすれば良い。
1,2は、次回に書きます

25分のオンライン英会話 レアジョブ

レアジョブという、先生がフィリピン大学の学生 or 卒業生のオンライン英会話の授業を毎日とっています。一日25分で毎日、月5000円と日本人の金銭感覚では激安。ただ、フィリピン人先生の賃金を考えれば、そこそこなお値段設定です。フィリピンの学校に居たころは、朝9:00から授業が始まって、一日7,8時間くらいは勉強していたので、25分で何をするかというのが私の英語力向上にストレートに影響してきます。最近は、英文記事を読んで授業を進めたりしますが、オンラインだと

1. 私が英文を読む
2. 分からない単語を先生が説明する
3. 先生から、記事に関する質問がなされる

といった具合で進むので、長い文章だと25分かかっても満足いく説明がされないまま授業が終了するといったこともしばしば。
また、先生の予約は戦争みたいなもので、2日続けて同じ先生を予約するのも至難な技。
最近辿りついてきた結論としては、記事を読むのではなく、ニュースの見出しを2人でディスカッションするというのが、オンライン英会話では効果的な授業になりうるといったことです。その時、それぞれの国の反応は?といった主旨を混ぜるのがポイントです。
例えば、

マニラで発生したバスジャック事件

に関してディスカッションすると、現地人は、中国の政府、国に対する批判に関してかなり不満を持っていることが分かります。
「なんで、一人が行なった事件で、国全体が悪いといった反応になるのか?」
といった意見を彼らは持っています。このような、大々的に報道されているニュースに対して、その国の人達の我々が持つ感情とことなる感覚を知ることが出来るとディスカッションしていてグッと楽しくなります。だいたい25分もあれば、お互い言いたいことは言えるので、締まりもあって中身のある授業になるのではないでしょうか。 ただ、通常の会話が出来る程度の英語力は必要かと思います。

マニュアルを読め俺

出来るでしょうと高をくくっていた、mod_rewriteとmod_proxy_balancerを使ったセッション維持。つまり、ProxyPassを利用しないstickysessionの指定。なんだか、すごい遠回りをしてapacheの英語マニュアルに辿り着きました。客先には、「まあ、いけるでしょ。これで」と想定した設定ファイル記述方法を偉そうにドキュメントとして渡していたのだが、、、、結論としてはProxySetを利用しなさいということです。これで、バックエンドサーバののrewriteモジュールは無効でも良さげ。今日は一日、青ざめながら仕事をしていました。

This directive is used as an alternate method of setting any of the parameters available to Proxy balancers and workers normally done via the ProxyPass directive. If used within a container directive, the url argument is not required. As a side effect the respective balancer or worker gets created. This can be useful when doing reverse proxying via a RewriteRule instead of a ProxyPass directive.

abのlengthエラー

忘れっぽいので書いておく。mod_proxy_balancerのメンバ数増加による影響をちらっと調べる為にベンチマークとってみようと思った。で、2台のノートPCのトップページをBalancerMemberに設定して、abで計測すると以下のエラーが出ます。

Complete requests: 100
Failed requests: 50
(Connect: 0, Receive: 0, Length: 50, Exceptions: 0)

何かな〜と思っていたら、2台のトップページのサイズが異なりますよということでした。ちゅうことで、同じhtmlファイル置いて終了。

Logブックがやっと

キューバのログブックがやっと届くようです。。。某国で同じ学校だった人が帰国するので、持ってきてもらえます。やっとこれで、ログを書き込めるではないか。もっともっと深海に行くために、経験を積むのであります。