Ruby で疑似メールサーバを作ってみた
昨日、静岡まで富士山を見に行ってきた suzuki です。雲が晴れるまで、40分くらい待って、写真を撮ってきました。
さて、今回は Ruby で擬似的なメールサーバを紹介してみます。
大量のメール配信の負荷テストと同時にエラーメールの処理テストを行いたい時があり、作ってみたプログラムです。このプログラムは次のようなイメージで使います。
まず、メールサーバからメールを送信し、一定の割合で疑似メールサーバがエラーを返します。すると、そのエラーメールをメールサーバからエラーメール処理サーバへ渡すようなイメージになります。
プログラムは、こちら。
■dummy-smtpd.rb
#!/bin/env ruby require 'socket' require 'syslog' # port number port = 25 # randmax 100 means => about 1 / 100 randmax = 100 gs = TCPServer.open(port) addr = gs.addr addr.shift syslog = Syslog.open('dummy-smtpd', Syslog::LOG_PID | Syslog::LOG_USER) syslog.log(Syslog::LOG_INFO, sprintf("server is on %s", addr.join(":"))) while true Thread.start(gs.accept) do |s| # greeting s.write("220 welcome to dummy smtp server\n") # DATA command flag dataflg = false while s.gets # request data original_request = $_.chomp request = original_request.upcase if dataflg == true # in DATA stream if /^\.$/ =~ request s.write("250 OK\n") dataflg = false end else # normal request case request when 'DATA' dataflg = true s.write("354 OK\n") when /^RCPT TO:/ if rand( randmax ) == 1 syslog.log(Syslog::LOG_INFO, original_request + ' :ERROR') s.write("550 ERROR\n") else syslog.log(Syslog::LOG_INFO, original_request + ' :OK') s.write("250 OK\n") end when 'QUIT' s.write("221 OK\n") s.close else # ok ok ok ! s.write("250 OK\n") end end end end end
使い方はこんな感じです。
■疑似メールサーバ
- 事前に本来の MTA(Postfix / qmail / sendmail など)を停止しておく
- root で dummy-smtpd.rb を起動する
# ruby dummy-smtpd.rb - 動作テスト(太字部分を入力する)
$ telnet localhost 25 Trying 127.0.0.1... Connected to localhost (127.0.0.1). Escape character is '^]'. 220 welcome to dummy smtp server EHLO localhost 250 OK MAIL FROM: <hoge@example.com> 250 OK RCPT TO: <hoge-1@example.com> 250 OK DATA 354 OK To: <hoge-1@example.com> From: <hoge@example.com> Subject: test test . 250 OK QUIT 221 OK
見た感じ、普通の SMTP サーバのようですが、ソースコードを見れば分かる通り、実際には何もしていません。
また、上記の処理中、RCPT TO: のところでランダムに「550 ERROR」が返るようにしています。そのアドレスは、syslog にも記録しています。
大量配信のテスト後、syslog に記録されたエラーアドレスと、実際にエラーメール処理サーバで処理したアドレスを比較するなどして、エラー処理に漏れが無いかどうか、などをチェックしました。
もちろん、疑似メールサーバなど使わずに、Postfix / qmail / Sendmail などの MTA を使っても良いのですが、大量送信時の負荷(特にディスク負荷)がバカになりません。送信側のピークより前に、受信側のピークが来てしまうのです。
このプログラムではメールキューをディスクへ保存していませんので、低スペックなサーバでも比較的負荷に耐えられるようになります。
あまり使う機会は無いかも知れませんが、何かの参考になれば幸いです。
ディスカッション
コメント一覧
まだ、コメントがありません