セカンダリメールサーバの設定(認証サーバが落ちても動くようにプレインテキストにユーザ一覧を記入する構成)


Postfix Advent Calendar 2014の 20日目の記事です。

0.はじめに

2011年3月11日(金)未曽有の大地震「東北地方太平洋沖地震」が発生しました.その後,大規模な停電が発生.その後も2年程度は発電能力の不足による計画停電が政府および電力会社が通知されていました.

震央に近かった東北大学ではドメインが消失してしまった.東北大学の失敗は,tohoku.ac.jpの root DNSが学内にすべてあった事です.(現在ではSINETのセカンダリDNSサービスで多重化されているようです。)

DNSの消失が長時間にわたると,該当ドメインに送られてきたメールがロストしてしまいます.ロストを防止するには,DNSを遠隔地に分散設置し,メールサーバも遠隔地に分散設置する必要があります.メールサーバだけ多重化しても意味はありません.DNSを多重化してこそ意味があります.

DNSの多重化は本記事から外れるため詳細はぐぐって下さい.

何度もいいますが,メールサーバの耐障害性を上げる場合はDNSも分散設置して下さい.メールサーバだけ多重化しても意味はありません.

1.セカンダリメールサーバ
前おきが長くなりましたが,メールサーバは,プライマリ,セカンダリ,と優先順位をつけて複数設置できます.

セカンダリメールサーバの設定は色々ありますが,今回は設定が容易な構成にします.

*優先順位の異なるふたつのメールサーバを用意し,優先順位づけをします.優先順位が高いサーバをプライマリ,低いサーバをセカンダリとします.

*プライマリの方で,メール受信設定,popやimapなどの一般利用者向けのメールの送受信サービスを提供します.

*セカンダリではメール受信設定のみを行います.popやimapなどのサービスは提供しません.

*プライマリが障害で落ちている間は,セカンダリがメールの受信のみを行います.セカンダリは受信したメールをため込みます.プライマリが復旧したら,セカンダリがため込んだしたメールをプライマリに送りつけます.

プライマリが復旧しないと,セカンダリに溜ったメールが読めないため,少々不便ですが,設定が容易ですので,この設計にします.

2.DNSの設定
例えば メールドメイン「@example.jp」のプライマリとセカンダリを設置するには,こんな感じでDNSの正引きに記載します.

設定例はDNSサーバbind用の設定例です.

dns.zone
$TTL 86400
@   IN  SOA primary-dns.example.jp. postmaster.example.jp. (
            2014122001  ; Serial
            10800       ; Refresh
            3600        ; Retry
            1209600     ; Expire
            86400 )     ; Minimum
    IN  NS  primary-dns.example.jp.
    IN  NS  secondary-dns.example.com.
    IN  MX  10 primary-mail.example.jp.
    IN  MX  100 secondary-mail.example.com.
;
primary-mail    IN  A   198.51.100.1
primary-dns     IN      A       198.51.100.2
(省略)

「IN MX」の行に注視してください.

IN MX 10 primary-mail.example.jp
IN MX 100 secondary-mail.example.com

10と100はプライオリティです.数字が小さいほど優先順位があがります.そのため,10がプライマリメールサーバ, 100がセカンダリメールサーバになります.

プライマリを勤務先の会社やら大学のサーバ室にして,セカンダリをクラウドなどにすれば良いでしょう. クラウドを使う場合はメールサービスの提供可能なクラウドにして下さい.一部クラウドサービスはメールサービスに必要なsmtp(tcp:25)などのポートが開いてないようです.

3.プライマリ側の設定
3.1.postfixの設定
(おそらく必須では無いと思いますが)念のためmain.cfのmynetworksの設定に,セカンダリのIPアドレスを加筆して下さい.

/etc/postfix/main.cf
mynetworks = 198.51.100.0/24, 127.0.0.0/8,....,  セカンダリのIPアドレス

smtpd_recipient_restrictions = 
    .....
    permit_mynetworks,   # 普通入ってると思います.
    .....

なお,spamチェックなどを導入している場合は,セカンダリのIPアドレスをホワイトリストに登録しておくといいでしょう.

プライマリが稼働中でもわずかですがセカンダリ側にメールが届きます.そのため,セカンダリで受信したspamは素通りになってしまうのですが,それが問題の場合は,セカンダリ側にもspamチェック機能を導入して下さい.

3.2.有効な受信者メールアドレスの一覧表の作成

セカンダリメールサーバでメールドメイン「@example.jp」の有効な受信者メールアドレスの確認をする必要があります.無効なメールアドレスは受信拒否をする必要があります.無効なアドレスの受信拒否をしないと,存在しないユーザ宛のメールや,退職,卒業したユーザ宛のメールがいつまでも届きます.放置すると問題が出る場合があります。

例えばセカンダリで存在しないユーザのメールを受信したとしましょう.最初の設計の時に述べましたが,セカンダリが受信したメールはプライマリに転送します.プライマリに転送した後,ユーザが存在しないため,そこでエラーになり,送信者にエラーとして戻る事になります.その時ですが,エラーの送信者が「[email protected]」になります.メールの内容が一般的な文章だった場合は良いのですが,内容がspamだった場合ですがspamのメールは多くが発信者偽造をされています.無断で発信者にされたメールアドレスにエラーメールが戻ります.そして本ドメイン「[email protected]」はspam送信者の烙印をおされる事になるのです.そのため,有効なメールアドレスの確認をせずにセカンダリメールサーバでメールを受信するのは得策ではありません.

(有効なメールアドレスの確認方法は認証サーバに問い合わせたり毎回プライマリに問い合わせる方法がありますが、これは認証サーバやプライマリが落ちていた場合、使えないため、今回はプレインテキストにユーザ一の一覧表を記載する方法を用います。)

前置きが長くなりましたが,有効な受信者メールアドレスの表は、一般的なユーザ管理を行っているメールサーバの場合は/etc/aliasesとgetent passwdの内容を元に有効なメールアドレスの表がつくれます.

但し getent passwdの出力にはメールを受信するのにそぐわないようなアドレス (bin/sys/adm/nobodyなど)が含まれるためこれを除外する必要があります./etc/aliasesにも色々書いてありますが,不要そうなアドレスは除外して下さい.

注意点として/etc/aliasesのmailer-daemon, postmasterは除外しないで下さい.必ず受信して下さい.エラーメールしか届かないかもしれませんが,メールサーバを運用する場合はかならず読む義務があります.

なお~/.forwardの設定により拡張メールアドレスを設定できるようにしている場合はこちらの情報収集を行なう必要があります.こちらは少々大変かもしれませんね.

最終的にはgetent passwdの出力をもとにこんな形のプレインテキストファイルを作成して下さい.最後にxと書いてますが,なにか書いておけばいいだけです.

(ファイル:passwd-2ndmx)

/etc/aliasesはMLを運営していれば多数記載があるとおもいますが,MLを運営してなけば下記ぐらいだけと思います.

(ファイル:aliases-2ndmx)

MLを運用していたらこんな感じで多数記載する必要があります.

最後に、このファイルの作成作業は、ユーザの増減があった場合、/etc/aliasesの更新、ユーザの拡張メールアドレスを許可している場合は、ユーザが~/.forwardを更新した場合、毎回行う必要があります。

筆者が運用している環境では頻繁に更新が無いため、手作業で実施していますが、大規模なメールドメインでは自動化を検討した方がよいかもしれません。

4.セカンダリの設定

プライマリで作成したファイル aliases-2ndmx, passwd-2ndmxを/etc/postfix あたりに置いて下さい.そしてコマンドpostmapでDBにコンパイルして下さい.例ではhash形式を指定していますが,任意です.

postmap hash:aliases-2ndmx
postmap hash:passwd-2ndmx

Ref: Postfix Advent Calendar 2014の1日目の記事

main.cfに以下の記述を行って下さい.セカンダリの設定に限定した記述です.一般的なメールの設定の記述は省いています.

/etc/postfix/main.cf
# これは設定は必須ではありませんが,存在しないユーザにエラーを返す時のエラーコードです.
# プライマリでは「unknown_local_recipient_reject_code 」に相当します.
unknown_relay_recipient_reject_code = 550

# 今回対象のメールドメイン
relay_domains = example.jp

# プライマリで作成した有効な受信者メールアドレスの表です.
relay_recipient_maps = hash:/etc/postfix/passwd-2ndmx,
               hash:/etc/postfix/aliases-2ndmx

# プライマリのIPアドレスです.slowの定義は後述。
relay_transport = slow:[プライマリのIPアドレス]

上記のrelay_transportで利用しているslowの定義です。環境に応じて時間を調整してください。

/etc/postfix/master.cf
slow      unix  -       -       n       -       1       smtp
    -o fallback_relay=
    -o smtp_helo_timeout=5 -o smtp_connect_timeout=5

Ref: Postfix Advent Calendar 2014の5日目の記事
Postfix Advent Calendar 2014の17日目の記事

5.プライマリがもし落ちた時/復旧した後

プライマリが落ちている状態で、セカンダリが受信して,プライマリに送信待ちになっている溜っているメールは「mailq」コマンドで確認できます.

セカンダリは定期的にプライマリにメールを送りつけて,失敗した時はあきらめますが,プライマリが長時間止まるほど,再送間隔が長くなります.プライマリが復旧して,動作が正常だと確認された場合,強制的にセカンダリからプライマリに送信させたい場合は「postfix flush」として下さい.

6.プライマリが長期間落ちる事が見込まれる時

実際に調査は行っていないのですが,おそらく下記のパラメータのデフォルト値の5日を過ぎるとエラーとして送信者に戻されると思います.

maximal_queue_lifetime
bounce_queue_lifetime

Ref: Postfix 設定パラメータ

プライマリが5日以上とまってしまう事が確定の場合は,,

さてさて有効な手立てを知りません.とりあえずですが,セカンダリに溜っているメールは「postcat」で閲覧可能です.受信者の希望に沿って必要なメールを取り出すか,スクリプトを作成して全メールをplain textに変換して,受信者に個別に渡すか..