なんちゃってアイ○ンポート

最近転職して、今は粛々とサーバー周りの管理をしておりますが、最近メルマガ配信がよくISPに多段ブロッキングされてしまいます。

で、今回配信用のサーバーとして、1台構築したんですが、前職で使っていたアイ○ンポートというメールアプライアンス製品に真似たことをPostfix&iptablesでやってみようじゃないかってことで以下忘備録。

OSはCentOS5.1
使用したソフトは、
 iptables-1.4.0 http://www.netfilter.org/projects/iptables/downloads.html#iptables-1.4.0
 Postfix-2.5.2 http://www.postfix.org/start.html

もともとCentOSに入ってたiptables-1.3.5はyum removeで消しちゃった。
あと、sendmailも同様にyum removeで削除。

インストール方法は割愛。
さくっと入ります。

iptablesの設定ファイルを/etc/sysconfig/iptablesに用意…の前に、あらかじめ複数個のグローバルIPアドレスをサーバーに持たせておきましょう。

# ifconfig eth0:0 ***.***.***.10
# ifconfig eth0:1 ***.***.***.11

のような感じで。
/etc/sysconfig/network-scripts/ifcfg-eth0:0とか作るのも可。
ずっと設定するなら上記ファイル編集したほうが良いかと。

で、iptablesの設定ファイルにhttp://hanzubon.jp/node/247 を参考(設定を拝借いたしました)にSNAT設定します。

iptables -t nat -A POSTROUTING -p tcp --dport 25 -m statistic --mode nth --every 3 -j SNAT --to-source ***.***.***.10
iptables -t nat -A POSTROUTING -p tcp --dport 25 -m statistic --mode nth --every 3 -j SNAT --to-source ***.***.***.11

25ポートに対して通信しにいくとき、接続元のIPを***.***.***.10〜11に書き換えます。

次にPostfix

以前に書いたPostfixの設定が基本で、あとはheader_checksを使って無駄なReceivedヘッダを削除します。

# vi /etc/postfix/header_checks
/^Received:.*192\.168\..*/ IGNORE
/^Received:.*127\.0\.0\.1.*/ IGNORE

# vi /etc/postfix/main.cf
header_checks = regexp:/etc/postfix/header_checks

みたいな感じで。
あとは、追加したAliasIPのホスト名をDNSに正引き、逆引き共に設定します。

これで(ほんっとうになんちゃってな)疑似アイ○ンポートができあがります。

まだまだ改善の余地アリなので、それについてはおいおいということで。

リモートのtail -f の実現

#!/usr/bin/perl -w

use strict;
use Net::SSH::Perl;
use Parallel::ForkManager;

my @list = qw/
    192.168.0.173
    192.168.0.174
    192.168.0.175
/;

my $pm = Parallel::ForkManager->new( scalar(@list) );

foreach my $name ( @list ) {

    my $pid = $pm->start and next;
    my $ssh = Net::SSH::Perl->new($name , (protocol=>"2") );
    $ssh->login("testuser","testuser");
    $ssh->register_handler("stdout", sub {
        my($channel, $buffer) = @_;
        print "====> ".$name." <==========================================\n";
        print $buffer->bytes;
    });
    $ssh->cmd("tail -f /usr/local/apache/logs/access_log");
    $pm->finish;
}
$pm->wait_all_children();

動作内容:
@listで定義したリモート先サーバーにログインしてtail -f /usr/local/apache/logs/access_logを実行

Postfixの設定もろもろ

思い込み多々あり。

http://www.postfix-jp.info/trans-2.3/jhtml/postconf.5.html

<再送まわり>

 
 minimal_backoff_time
 maximal_backoff_time
 maximal_queue_lifetime
 bounce_queue_lifetime
 queue_run_delay

ここらへんの設定がいる模様。

たとえば、

 
 minimal_backoff_time = 60s
 maximal_backoff_time = 600s
 maximal_queue_lifetime = 1800s
 bounce_queue_lifetime = 1800s
 queue_run_delay = 60s
 ※「s」は秒

した場合、


最初再送に失敗したら、defferedキューに入って、queue_run_delayごとにdefferedキューがキューをスキャン。
スキャンしたときにキューにあるメールの時間がminimal_backoff_timeをこえてたら再送。


再送失敗してしまったら、今度はdefferedキュースキャンしたとき、minimal_backoff_timeの倍の時間後に再送開始。
再送失敗してしまったら、今度はdefferedキュースキャンしたとき、minimal_backoff_timeの倍の倍の時間後に再送開始。
再送失敗してしm(ry


って感じでmaximal_backoff_timeをこえるまで繰り返し。
こえた後はmaximal_backoff_timeの間隔で再送。


最終的にmaximal_queue_lifetimeをこえたら再送終了、bounce_queue_lifetimeの時間をこえたらBounce扱いで送信者にエラーメールで返る、っという感じ。


実際にテストした結果はこのような感じ。

 May 29 18:47:16 testserver postfix/qmgr[4833]:
      9D7FE1D0051:from=<root@test.hogehoge>,
      size=293, nrcpt=1 (queue active)
 May 29 18:47:16 testserver postfix/smtp[4847]:
      9D7FE1D0051:to=<test@hogehoge.jp>, 
      relay=none, delay=107, delays=107/0.01/0/0, 
      dsn=4.4.3, status=deferred 
      (Host or domain name not found. 
       Name service error for name=hogehoge.jp 
         type=MX: Host not found, try again)
 May 29 18:49:16 testserver postfix/qmgr[4833]: 
      9D7FE1D0051:from=<root@test.hogehoge>, 
      size=293, nrcpt=1 (queue active)
 May 29 18:49:16 testserver postfix/smtp[4854]: 
      9D7FE1D0051:to=<test@hogehoge.jp>, 
      relay=none, delay=227, delays=227/0.01/0/0,
      dsn=4.4.3, status=deferred 
      (Host or domain name not found.
       Name service error for name=hogehoge.jp 
        type=MX: Host not found, try again)
 May 29 18:53:16 testserver postfix/qmgr[4833]: 
      9D7FE1D0051:from=<root@test.hogehoge>, 
      size=293, nrcpt=1 (queue active)
 May 29 18:53:16 testserver postfix/smtp[4865]: 
      9D7FE1D0051:to=<test@hogehoge.jp>, 
      relay=none, delay=467,delays=467/0.01/0/0,
      dsn=4.4.3, status=deferred 
      (Host or domain name not found.
       Name service error for name=hogehoge.jp 
        type=MX: Host not found, try again)
 May 29 19:01:16 testserver postfix/qmgr[4833]: 
      9D7FE1D0051:from=<root@test.hogehoge>, 
      size=293, nrcpt=1 (queue active)
 May 29 19:01:16 testserver postfix/smtp[4885]: 
      9D7FE1D0051:to=<test@hogehoge.jp>, 
      relay=none, delay=947, delays=947/0.01/0/0, 
      dsn=4.4.3, status=deferred 
      (Host or domain name not found. 
       Name service error for name=hogehoge.jp 
        type=MX: Host not found, try again)
 May 29 19:11:16 testserver postfix/qmgr[4833]: 
      9D7FE1D0051:from=<root@test.hogehoge>, 
      size=293, nrcpt=1 (queue active)
 May 29 19:11:16 testserver postfix/smtp[4907]: 
      9D7FE1D0051:to=<test@hogehoge.jp>, 
      relay=none, delay=1547, delays=1547/0.01/0/0, 
      dsn=4.4.3, status=deferred 
      (Host or domain name not found. 
       Name service error for name=hogehoge.jp 
        type=MX: Host not found, try again)
 May 29 19:21:16 testserver postfix/qmgr[4833]:
      9D7FE1D0051:from=<root@test.hogehoge>, 
      size=293, nrcpt=1 (queue active)
 May 29 19:21:17 testserver postfix/smtp[4928]:
      9D7FE1D0051:to=<test@hogehoge.jp>, 
      relay=none, delay=2147, delays=2147/0.01/0/0, 
      dsn=4.4.3, status=deferred 
      (Host or domain name not found. 
       Name service error for name=hogehoge.jp 
        type=MX: Host not found, try again)
 May 29 19:21:17 testserver postfix/qmgr[4833]: 
      9D7FE1D0051: from=<root@test.hogehoge>, 
      status=expired, returned to sender
 May 29 19:21:17 testserver postfix/qmgr[4833]: 
      9D7FE1D0051: removed

18:47:16⇒配信開始 minimal_backoff_time(60s)すでに2倍から開始
↓ +2
18:49:16⇒再送1回目
↓ +4
18:53:16⇒再送2回目
↓ +8
19:01:16⇒再送3回目 maximal_backoff_time(600s)をこえたので、これ以降600sずつ
↓ +10
19:11:16⇒再送4回目
↓ +10
19:21:17⇒再送5回目 maximal_queue_lifetime(1800s)をこえたので
          Bounce扱いでキューから削除


<配送まわり>

 smtp_destination_concurrency_limit
  配送先ごとの並列送信数

 smtp_destination_recipient_limit
  1セッション内に配送するメールの数

特定のあて先ドメインごとに上記設定を反映も可能。
たとえば、docomo.ne.jp宛てのメールだけ並列送信なしで1セッション1通のみ送信とかしたい場合。

master.cfに

 docomo-smtp unix - - n - 1 smtp
    -o smtp_destination_concurrency_limit=1
    -o smtp_destination_recipient_limit=1

とか追加。
で、transportファイルなどを用意

  docomo.ne.jp docomo-smtp:

# postmap transport

っと実行したら、transport.dbが更新(新規作成)される。

main.cf内に、

  transport_maps = hash:/etc/postfix/transport

を記述

で、リロード

 /etc/rc.d/init.d/postfix reload

とか。

ちなみに、docomo.ne.jpあてのメールを別サーバーにリレーさせたいのなら、

 docomo.ne.jp docomo-smtp:

を、

docomo.ne.jp docomo-smtp:[192.168.0.100]
IPやホストを書く場合、[]で囲ってあげにゃだめ。

とかとか。