ちょっと話題の記事

ELB + PostfixでElasticなMTA(メール受信)システムの構築 – ELB Proxy Protocol Supportの活用

2013.08.06

この記事は公開されてから1年以上経過しています。情報が古い可能性がありますので、ご注意ください。

AWSでメールシステムというと、メールを送信するためのAmazon SESという機能(関連記事 : Amazon SESでSPFとDKIMを用いて高信頼なメールを送る)がありますが、メールを受信する仕組みはMTA on EC2で構築することになります。 一般的なMTAの可用性確保および負荷分散はDNSラウンドロビンで行うことが多いですが、ロードバランサを用いたインテリジェントな負荷分散の構成もレシピとして欲しいところですよね。
そこで今回は、ELB + Postfix on EC2の構成をご紹介します。ポイントは、ELBに"Proxy Protocol Support"を追加する点です。

ELBの新機能として注目されているProxy Protocol Supportですが、アプリケーション側の対応が必要なため具体的な構成例がなかなか出てこない状況なので、ELB Proxy Protocol Supportの実用例として参考になるのではないかと思います。

概要と動作環境

従来のProxy Protocol SupportなしのELBでは、SMTPトラフィックの帰りのルーティングがEC2のデフォルトゲートウェイ経由になってしまい、コネクションを張ることができませんでした。Proxy Protocol Supportを追加することで、帰りのSMTPトラフィックが正しくELBに行くようになり、コネクションを張れるようになります。
PostfixのProxy Protocolサポートは、HAProxy向けにバージョン2.10で実装されました。Proxy Protocol自体は特に標準化された規格ではなさそうで、ELBとHAProxyのプロトコル仕様を突き合わせたところたまたま合致しており、動作している状況です *1。今後それぞれのプロトコル仕様が変更される可能性があることに注意してください。

elb-postfix00

動作確認環境

  • OS : Amazon Linux 2013.03 64bit
  • MTA : Postfix 2.10.1

ELBおよびEC2のセットアップ

今回は、植木さん作のCloudFormationテンプレート(ELB+EC2を一括作成するもの)を活用します。

上記記事にあるtcp-proxy-elb.templateをまるごとコピーし、CloudFromationでStackを作成します。Specify Parametersのポート番号を25にし、ELB/EC2共にSMTPをListenするようにします。

elb-postfix-01

しばらく待つと、Proxy Protocol Supportが有効になっているELB1台+EC2インスタンス1台が作成されます。
ELBの管理画面でDNS NamePort Configurationを確認しておきます。

elb-postfix02

Postfixのセットアップ

EC2にSSHでログインし、Postfixをインストールします。2013/08/02現在は、Amazon LinuxのyumコマンドでインストールできるPostfixのバージョンが古いため、今回はソースからインストールします。インストールオプションは必要に応じて調整してください。

$ sudo service sendmail stop
$ sudo chkconfig sendmail off
$ sudo yum groupinstall "Development Tools" -y
$ sudo yum install db4-devel
$ cd /usr/local/src
$ sudo wget http://mirror.postfix.jp/postfix-release/official/postfix-2.10.1.tar.gz
$ sudo tar zxf postfix-2.10.1.tar.gz
$ cd postfix-2.10.1
$ sudo make
$ sudo make install
(いろいろ聞かれますが、デフォルトのまま[Enter]キーを連打)
$ sudo groupadd -g 89 postfix
$ sudo groupadd -g 90 postdrop
$ sudo useradd  -u 89 postfix -s /sbin/nologin -d /var/spool/postfix -g postfix -G postdrop
$ sudo cp postfix /etc/init.d/
$ sudo chkconfig postfix on

PostfixでProxy Protocolサポートを有効にするために、/etc/postfix/main.cfファイルに以下を追加します。

smtpd_upstream_proxy_protocol = haproxy
$ sudo /etc/init.d/postfix start
postfix を起動中:                                          [  OK  ]
$

これで準備OKです。試しに、telnetコマンドでELBの25番ポートにアクセスしてみます。(注意 : 検証する場合には、telnetコマンドを実行するホストのローカルネットワークでOutbound Port 25 Blockingが有効になっていると接続できません)

$ telnet proxy-elb-ElasticL-XXXXXXXXXX.ap-northeast-1.elb.amazonaws.com 25
Trying 54.249.5.81...
Connected to proxy-elb-ElasticL-XXXXXXXXXX.ap-northeast-1.elb.amazonaws.com.
Escape character is '^]'.
220 ip-XX-XX-XX-XX.localdomain ESMTP Postfix
EHLO test.example.com
250-ip-XX-XX-XX-XX.localdomain
250-PIPELINING
250-SIZE 10240000
250-VRFY
250-ETRN
250-ENHANCEDSTATUSCODES
250-8BITMIME
250 DSN
QUIT
221 2.0.0 Bye
Connection closed by foreign host.

正常に接続できました!

おまけ : もくもく会のご紹介

今回のエントリーを書くにあたり、HAProxyおよびPostfixの調査・検証をAWSユーザーコミュニティであるAmazon Web Services 新宿鮫のAWSもくもく勉強会という会で行いました。
勉強会というと、プレゼンター主導の講義形式を連想する方が多いと思いますが、この会は参加者全員が時間内AWSについての作業を黙々と行う、ユニークな形態の勉強会です。
興味があれば、気軽に参加してみましょう!私も帰り道なこともあり、ときどき顔を出してます。

まとめ

"Proxy Protocol Support"を有効にすることでELB + Postfix on EC2のElasticなMTAを構成できることをご紹介しました。ELBを挟むことで、Auto Scalingとの連携など拡張性のあるアーキテクチャが可能になりました。

参考

脚注

  1. 恐らく、ELBがHAProxyを意識してProxy Protocolを実装したのではないかと推測しています。