AmazoneSESを使ってメール送信する(SMTPリレー)

こんにちは。プラットフォームの小宮です。
ちょっと前にAmazoneSESを使ってSMTPリレーでメール送信の設定をしたのでその記録を公開させていただきます。

※SDKでなくSMTPリレーのほうを試します。(SDKつかうにはサーバにruby入っていてruby使う必要があるため。)

★SESの申し込みをする
SESのサービスダッシュボードに「RequestProductionAccess」というボタンがあるのでそれを押すと
お問い合わせ画面が出てくるので、必要な内容を入力する
(名前とサービスドメインとメールアドレスとメールの用途など)
Request Production Access to Simple Email Service(お問い合わせ)
入力送信すると、
リクエストありがとう、1日も早く使えるように審査するからマニュアル読んでお待ちください
と英文メッセージが出る。

申請の翌日SESのダッシュボードを確認したところ、以下の標記になっていた

[shell]Your Amazon SES Sending Limits
Sending Quota: send 10000 emails per 24 hour period
Quota Used: 0% as of 2013-03-08 10:53 UTC+9
Max Send Rate: 5 emails/second[/shell]

24時間に10000通まで送ることが可能
現在の使用率は0%
最大送信レートは秒間5通

送信元は以下と教えていただいた
→ 会員登録時「no_reply@hoge.jp」というメールを送信、
  問合せ時「support@hoge.jp」というメールを受信(転送)、

受信するのでMXレコードが要ることが発覚。別途設定する。
securitygroupも25番全開にしないといけない模様です。

とりあえず SESで送信元となるメールアドレスはVerified Sendersに登録する必要があるので以下を登録する

no_reply@hoge.jp
support@hoge.jp
no_reply@stg.hoge.jp
support@stg.hoge.jp

Verified Sendersに登録してみたところ以下のように
「メール受け取れたら確認された送信者リストに入るよ」という話なので
やっぱり受信できないとダメなようです。
[shell]You have successfully sent a verification email to no_reply@hoge.jp.
It may take up to an hour for the verification email to arrive in this user’s inbox.
When the user opens this email message and verifies the address, it will appear in your "Verified Senders" list.

Status:
pending verification [/shell]
となって、resendリンクが出ている状態となる。

★許可をいただいたのでpostfixのドメイン名を変更

stg環境:hoge.jp→stg.hoge.jp
本番環境:www.hoge.jp→hoge.jp
※stg環境と本番環境ともにhoge.jpとする要望だったが、
 ドメインがおなじで中継させると送信に成功しなかったため。
メールの達人の先輩の意見:
>・ドメイン同じにして考えられる事
>発信元はxxx@a.comで中継サーバに出す。
>中継元はa.comは自ドメインと認識してlocal配送して外に出さない
>
>となる可能性が高いと思いますが、、、

web側
[shell]vi /etc/postfix/main.cf
# diff /etc/postfix/main.cf{,.date +%Y%m%d}
76c76
< myhostname = hoge.jp

> myhostname = www.hoge.jp
318c318
< relayhost = [stg.hoge.jp]

> relayhost = [10.122.4.56]
# service postfix reload
postfix を再読み込み中: [ OK ]
[/shell]
stg側
hoge.jp→stg.hoge.jpに後ほど他の設定と一緒に変更する。

★SMTPアカウント追加する(VerifySendersメール受信のため)

[shell]mkdir -p /etc/skel/Maildir/{tmp,cur,new}
useradd -s /sbin/nologin no_reply
useradd -s /sbin/nologin support
tail -3 /etc/passwd
no_reply:x:1002:1002::/home/no_reply:/sbin/nologin
support:x:1003:1003::/home/support:/sbin/nologin

passwd no_reply
passwd support[/shell]

※先にskelにディレクトリを作り忘れたままアカウント作成した場合
[shell]mkdir -p /home/{no_reply,support}/Maildir/{tmp,cur,new}
chown -R no_reply. /home/no_reply/Maildir
chown -R support. /home/support/Maildir[/shell]

エイリアスファイル内に万が一予約されててrootにメールが行く設定になってる場合は以下のように修正。
[shell]vi /etc/aliases
#support: postmaster[/shell]

★MX登録
[shell]cd /var/named/var/named/zone
# cp -p hoge.jp.zone Backup/hoge.jp.zone.20130308
# diff hoge.jp.zone Backup/hoge.jp.zone.20130308
3c3
< 2013030801 ; serial

> 2013030701 ; serial
17,18d16
< hoge.jp. IN MX 10 hoge.jp.
< stg.hoge.jp. IN MX 20 stg.hoge.jp.
/usr/local/sbin/named-checkzone hoge.jp /var/named/var/named/zone/hoge.jp.zone
zone hoge.jp/IN: loaded serial 2013030801
OK
# ps -ef|grep named
named 7323 1 0 2011 ? 2-09:26:44 /usr/local/sbin/named -u named -t /var/named[/shell]
namedをリロードします

★SMTPCredensialを作る
Navigationの「SMTP Settings」を選択、
「CreateMySMTP Credentials」を押して
ユーザ名を必要なら修正しSMTP用IAMを作成する。
[shell]ses-smtp-user
SMTP Username:
AKIAJGYLX2Z3E*********
SMTP Password:
AivJPK/r95RFbjm+z1vApHSAacUnA90SqhU*********[/shell]
※これを後ほどsaslpasswordとして使う。

すると以下のようにAmazonSESのMTA情報が表示されている
[shell]Server Name: email-smtp.us-east-1.amazonaws.com
Port: 25, 465 or 587
Use Transport Layer Security (TLS): Yes
Authentication: Your SMTP credentials – see below.[/shell]

★SMTP連携してみる
必要なパッケージを入れる
[shell]sudo yum -y install mailx stunnel system-switch-mail
Installed:
stunnel.x86_64 0:4.29-2.el6[/shell]
※mailxは入ってたしsystem-switch-mailはパッケージがなく
 alternatives –config mtaで切り替える。(postfixしか入ってないので切替不要)

stunnelの設定をする(amazonses.comのメールMTAとSSLトンネルしてくれる)
[shell]vi /etc/stunnel/stunnel.conf
—–
[smtp-tls-wrapper]
accept = 2525
client = yes
connect = email-smtp.us-east-1.amazonaws.com:465
—–[/shell]
※先ほど表示されたAmazonSESのMTA情報を設定します。

起動する
[shell]stunnel /etc/stunnel/stunnel.conf[/shell]

すると以下のようにポートがあいた。
[shell]# netstat -lnpt
Active Internet connections (only servers)
Proto Recv-Q Send-Q Local Address Foreign Address State PID/Program name
tcp 0 0 0.0.0.0:3306 0.0.0.0:* LISTEN 8029/mysqld
tcp 0 0 0.0.0.0:80 0.0.0.0:* LISTEN 14206/httpd
tcp 0 0 0.0.0.0:4949 0.0.0.0:* LISTEN 15963/perl
tcp 0 0 0.0.0.0:22 0.0.0.0:* LISTEN 871/sshd
tcp 0 0 10.122.4.56:25 0.0.0.0:* LISTEN 20141/master
tcp 0 0 127.0.0.1:8891 0.0.0.0:* LISTEN 15222/dkim-filter
tcp 0 0 0.0.0.0:443 0.0.0.0:* LISTEN 14206/httpd
tcp 0 0 0.0.0.0:2525 0.0.0.0:* LISTEN 29423/stunnel ←これ[/shell]

コマンド起動だと危うい※ので起動スクリプトを用意して自動起動設定をする
[shell]curl -L http://www.gaztronics.net/rc/stunnel.txt > /etc/init.d/stunnel
chmod 755 /etc/init.d/stunnel
vi /etc/init.d/stunnel
—-
SEXE=/usr/sbin/stunnel

SEXE=/usr/bin/stunnel
—-
chkconfig –add stunnel
chkconfig stunnel on
chkconfig –list| grep 3:on

ps -ef
pkill stunnel
ps -ef
service stunnel start
netstat -lnpt;ps -ef[/shell]

※プロセスファイルが消されずに次回自動起動できなかったり色々問題が起こることがある

ステージングのMTA側でSESにリレーする設定をする(※本番環境はステージングにリレーしてます)
[shell]cp /etc/postfix/main.cf{,.date +%Y%m%d}
vi /etc/postfix/main.cf

relayhost = 127.0.0.1:2525
#smtp_sender_dependent_authentication = yes
smtp_sasl_auth_enable = yes
smtp_sasl_security_options = noanonymous
smtp_tls_security_level = may
smtp_sasl_password_maps = hash:/etc/postfix/sasl_passwd

diff /etc/postfix/main.cf{,.date +%Y%m%d}[/shell]

SES用のIAMのアクセスキーとシークレットキーをsaslパスワードとして設定する
[shell]vi /etc/postfix/sasl_passwd
cat /etc/postfix/sasl_passwd

127.0.0.1:2525 AKIAJGYLX2Z3EUK*****:AivJPK/r95RFbjm+z1vApHSAacUnA90SqhU+IB******
—[/shell]
さんこう:127.0.0.1:2525 YOUR_SMTP_USERNAME:YOUR_SMTP_PASSWORD

[shell]postmap hash:/etc/postfix/sasl_passwd
rm /etc/postfix/sasl_passwd
service postfix restart[/shell]

※SESに対してリレーしない場合のmilterをはずしておく。(ステージングでdkim-milterを設定してあったため)

★Verified Sendersの認証作業

※アカウントとそのメールディレクトリが存在し、
 hostsとdnsの名前解決がうまくいってて受け取りたいドメインのMXレコードが登録してあって、
 SecurityGroupで25番ポート(と465と587も必要に応じ)が全開なことを事前に確認してから
 Verified Sendersを登録すると以下のようにメールが届く。

[shell]# ll /home/no_reply/Maildir/new
合計 4
-rw——- 1 no_reply no_reply 1684 3月 11 11:13 2013 1362968004.Vca41I6309dM300065.hoge-stg01
# ll /home/support/Maildir/new
合計 4
-rw——- 1 support support 1679 3月 11 11:13 2013 1362968012.Vca41I6309eM30768.hoge-stg01[/shell]

中身をみて書いてあるURLを参照すると、、
[shell]# view /home/support/Maildir/new/1362968012.Vca41I6309eM30768.hoge-stg01

===================================
Dear Amazon SES customer:

We have received a request to authorize an email address for use with Amazon SES
. To confirm that you are authorized to use this email address, please go to th
e following URL:

https://email-verification.us-east-1.amazonaws.com/~略~

Your request will not be processed unless you confirm the address using this URL. This link expires 24 hours after your original verification request.

To learn more about sending email from Amazon SES, please refer to the Amazon SES Developer Guide.

Sincerely, Amazon Web Services
===================================
おめでとうございます!

Amazon Simple Email Service での Eメールアドレスの検証が完了しました。これで、このアドレスからのメール送信を開始できます。

Amazon SES をご利用いただくのが初めてであり、まだ Amazon SES へのプロダクションアクセス権を受け取っていない場合は、検証済みのアドレスへの Eメール送信だけができます。
検証済み Eメールアドレスのリストを見るには、AWS Management Console にアクセスするか、Amazon SES 開発者ガイドをご覧ください。

すでにプロダクションアクセスの承認を受けた場合は、どのアドレスにも Eメールを送信できます。

Amazon SES をご利用いただき、ありがとうございます。
===================================[/shell]
というメッセージが表示されるのでこれを登録した数だけ繰り返す。

すると、Verified Sendersに登録されたアカウントのStatusがverifiedになる。

★SESでDKIM(DomainKeyIdentifiedMail)をためす

ドメイン認証してみる
Verified SendersのEmailAddressesタブの隣にDomainsタブがあるのでそちらを選択し表示させる
VerifyNewDomain
でDomain:にhoge.jpを入力し、Generate DKIM Settingsにチェックを入れてVerifyThisDomainボタンを押す
すると
The domain hoge.jp has been added to the list of Verified Senders with a Status of “pending verification”. Further action is needed to complete verification of this domain. See details below.
レコードがいくつか出てくるので[copy record]のリンクを押してコピーする。(csvでダウンロードのリンクもある)
stg.hoge.jpもおなじことをする。CSVダウンロードしたものが以下。
[shell]Record name Record type Record Value
_amazonses.stg.hoge.jp TXT y8KcO9LXHuhPI4Cq5AyLiupqmLkL3heDHtPMvm1dIWQ=
vbprbshhpghfchslva**************._domainkey.stg.hoge.jp CNAME vbprbshhpghfchslva**************.dkim.amazonses.com
rxbb6kw5kowwwvwaob**************._domainkey.stg.hoge.jp CNAME rxbb6kw5kowwwvwaob**************.dkim.amazonses.com
5hh6n54jqgxlcmqv5s**************._domainkey.stg.hoge.jp CNAME 5hh6n54jqgxlcmqv5s**************.dkim.amazonses.com[/shell]

DNS登録をする

[shell]# cd /var/named/var/named/zone
# cp -p hoge.jp.zone Backup/hoge.jp.zone.20130311
# diff hoge.jp.zone Backup/hoge.jp.zone.20130311
3c3
< 2013031101 ; serial

> 2013030801 ; serial
19,27d18
< ; for amazon sns
< _amazonses IN TXT "16WLDm8JwrqC0k7/TFMhjHB246CeD2wV+6QLC4FxUFc="
< pbwpmydtc6ui65thcl**************._domainkey IN CNAME pbwpmydtc6ui65thcl**************.dkim.amazonses.com.
< 6zuapajg5fmtcvlcb3**************._domainkey IN CNAME 6zuapajg5fmtcvlcb3**************.dkim.amazonses.com.
< wiewjgibezmoyvtxyx**************._domainkey IN CNAME wiewjgibezmoyvtxyx**************.dkim.amazonses.com.
< _amazonses.stg IN TXT "y8KcO9LXHuhPI4Cq5AyLiupqmLkL3heDHtPMvm1dIWQ="
< vbprbshhpghfchslva**************._domainkey.stg IN CNAME vbprbshhpghfchslva**************.dkim.amazonses.com.
< rxbb6kw5kowwwvwaob**************._domainkey.stg IN CNAME rxbb6kw5kowwwvwaob**************.dkim.amazonses.com.
< 5hh6n54jqgxlcmqv5s**************._domainkey.stg IN CNAME 5hh6n54jqgxlcmqv5s**************.dkim.amazonses.com.

# /usr/local/sbin/named-checkzone hoge.jp /var/named/var/named/zone/hoge.jp.zone
zone hoge.jp/IN: loaded serial 2013031101
OK

# ps -ef|grep named|grep -v grep
named 7323 1 0 2011 ? 2-09:47:31 /usr/local/sbin/named -u named -t /var/named
[/shell]
ここで第3者確認を受ける

[shell]# kill -HUP 7323 && tail -f ../../log/named.log

dig +noall +answer _amazonses.hoge.jp txt
dig +noall +answer _amazonses.stg.hoge.jp txt
dig +noall +answer pbwpmydtc6ui65thcl**************._domainkey.hoge.jp cname
dig +noall +answer 6zuapajg5fmtcvlcb3**************._domainkey.hoge.jp cname
dig +noall +answer wiewjgibezmoyvtxyx**************._domainkey.hoge.jp cname
dig +noall +answer vbprbshhpghfchslva**************._domainkey.stg.hoge.jp cname
dig +noall +answer rxbb6kw5kowwwvwaob**************._domainkey.stg.hoge.jp cname
dig +noall +answer 5hh6n54jqgxlcmqv5s**************._domainkey.stg.hoge.jp cname
[/shell]
10分くらいで伝播されるはず。

Verified Sender: DomainのStatusがsuccessとなっていたのでDKIMのタブでenableのリンクを押す
あと、Verified Sender: EmailAddressesのタブで個別のEmailアカウントでもDKIMのタブでenableのリンクを押す必要がある。

※メール送信元認証とドメイン認証は両方やらないとだめなようです。

・メールを送ってみる

メールの送付経路:hoge-web01→hoge-stg01→amazonses.com→クライアント(試験はgmail等宛)

[shell]# cat testmail.sh
—————————–
#!/bin/bash
set -e
DATE=date '+%Y%m%d.%H%M'
HENKAN="/usr/bin/iconv -f UTF-8 -t ISO-2022-JP"
## mail
SUBJ="mailsend-test $1 "$DATE""
#mail_to=******@isao.co.jp’
#mail_to=******_y@ezweb.ne.jp’
mail_to=***_****_k@i.softbank.jp’
mail_from=’no_reply@hoge.jp’
mail_err=’support@hoge.jp’
mail_subj="$SUBJ"

$HENKAN <<EOF | mailx -t
To: $mail_to
CC: $mail_cc
BCC: $mail_bcc
From: $mail_from
Subject: $mail_subj

test "$1"

***
TEL:XX-XXXX-XXXX

EOF
exit 0
—————————–[/shell]
mail_toを変えつつgmailとiphoneとauガラケに届くことを確認。

# sudo -u no_reply ./testmail.sh 6
# sudo -u support ./testmail.sh 1

※stgと本番環境それぞれテストする。

gmailのメールヘッダを確認する。

★失敗の履歴
Mar 11 14:14:19 ip-10-122-4-56 postfix/smtpd[8876]: connect from unknown[54.249.xxx.xxx]
と出て届かない。外側のEIPをmynetworksに入れてあげる必要がある模様。

[shell]# sudo -u no_reply ./testmail.sh 2

Mar 11 14:31:14 ip-10-122-4-56 postfix/smtp[9573]: B754C24210: to=<no_reply@hoge.jp>, relay=127.0.0.1[127.0.0.1]:2525, delay=1.3, delays=0.01/0/1/0.21, dsn=5.0.0, status=bounced (host 127.0.0.1[127.0.0.1] said: 530 Authentication required (in reply to MAIL FROM command))[/shell]

どうやらSASLのパスワード認証に失敗している模様。

[shell]# diff main.cf{,.date +%Y%m%d}
321c321
< #smtp_sender_dependent_authentication = yes

> smtp_sender_dependent_authentication = yes
687,690c687,690
< #milter_default_action = accept
< #milter_protocol = 6
< #smtpd_milters = inet:127.0.0.1:8891
< #non_smtpd_milters = inet:127.0.0.1:8891

> milter_default_action = accept
> milter_protocol = 6
> smtpd_milters = inet:127.0.0.1:8891
> non_smtpd_milters = inet:127.0.0.1:8891
# service postfix reload
# service dkim-milter stop
Shutting down DomainKeys Identified Mail Milter: [ OK ][/shell]

SESに対してリレーしない場合のmilterをはずしておく必要があった模様。

これで届くには届きました。

amazonses.com 経由が表示されてしまうのでspfレコードを何回か修正しましたが、
Verified Sender: EmailAddressesのタブで個別のEmailアカウントでも
DKIMのタブでenableのリンクを押す必要があっただけで、
それを押してもう一度送付したところamazonses.com 経由が消えました。

送信元も、webとstgどちらから送ってもドメインがhoge.jpになっていました。

★現在のzone情報確認:
[shell]# cat /var/named/var/named/zone/hoge.jp.zone
$TTL 3600 ; 1 hour
@ IN SOA ns3.isao.net. Postmaster.ns3.isao.net. (
2013031104 ; serial
1800 ; refresh (30 mins)
900 ; retry (15 mins)
604800 ; expire (7 days)
600 ; minimum (10 mins)
)
IN NS ns3.isao.net.
IN NS ns4.isao.net.
IN A 54.249.235.xxx
stg IN A 54.249.238.xxx
www IN CNAME hoge.jp.
hoge.jp. IN TXT "v=spf1 +ip4:54.249.235.xxx/32 +ip4:54.249.238.xxx/32 include:amazonses.com ~all"
stg.hoge.jp. IN TXT "v=spf1 +ip4:54.249.238.xxx/32 54.249.235.xxx/32 include:amazonses.com ~all"
_policy._domainkey 7200 IN TXT "t=y\; o=~\;"
hoge_jp_selector._domainkey IN TXT "v=DKIM1\; g=*\; k=rsa\; t=y\; p=MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQ*****B" ; —– DKIM hoge_jp_selector for hoge.jp
hoge.jp. IN MX 10 hoge.jp.
stg.hoge.jp. IN MX 20 stg.hoge.jp.
; for amazon sns
_amazonses IN TXT "16WLDm8JwrqC0k7/TFMhjHB246CeD2wV+6QLC4FxUFc="
pbwpmydtc6ui65thcl**************._domainkey IN CNAME pbwpmydtc6ui65thcl**************.dkim.amazonses.com.
6zuapajg5fmtcvlcb3**************._domainkey IN CNAME 6zuapajg5fmtcvlcb3**************.dkim.amazonses.com.
wiewjgibezmoyvtxyx**************._domainkey IN CNAME wiewjgibezmoyvtxyx**************.dkim.amazonses.com.
_amazonses.stg IN TXT "y8KcO9LXHuhPI4Cq5AyLiupqmLkL3heDHtPMvm1dIWQ="
vbprbshhpghfchslva**************._domainkey.stg IN CNAME vbprbshhpghfchslva**************.dkim.amazonses.com.
rxbb6kw5kowwwvwaob**************._domainkey.stg IN CNAME rxbb6kw5kowwwvwaob**************.dkim.amazonses.com.
5hh6n54jqgxlcmqv5s**************._domainkey.stg IN CNAME 5hh6n54jqgxlcmqv5s**************.dkim.amazonses.com.[/shell]

★postfixのmain.cfのデフォルトとの差分

・hoge-stg01(ステージング環境、MTAサーバ)
[shell]# diff /etc/postfix/main.cf{,.org}
76c76
< myhostname = stg.hoge.jp

> #myhostname = virtual.domain.tld
83c83
< mydomain = hoge.jp

> #mydomain = domain.tld
114c114
< inet_interfaces = $myhostname

> #inet_interfaces = $myhostname
116c116
< #inet_interfaces = localhost

> inet_interfaces = localhost
119,120c119
< #inet_protocols = all
< inet_protocols = ipv4

> inet_protocols = all
268d266
< mynetworks = 54.249.238.xxx/32, 10.122.4.xxx/32, 10.121.18.xxx/32 54.249.235.xxx/32
320,325d317
< relayhost = 127.0.0.1:2525
< #smtp_sender_dependent_authentication = yes
< smtp_sasl_auth_enable = yes
< smtp_sasl_security_options = noanonymous
< smtp_tls_security_level = may
< smtp_sasl_password_maps = hash:/etc/postfix/sasl_passwd
427c419
< home_mailbox = Maildir/

> #home_mailbox = Maildir/
685,690d676
<
< # DKIM
< #milter_default_action = accept
< #milter_protocol = 6
< #smtpd_milters = inet:127.0.0.1:8891
< #non_smtpd_milters = inet:127.0.0.1:8891[/shell]

・hoge-web01(本番環境、SMTPクライアント)
[shell]# diff /etc/postfix/main.cf{,.org}
76c76
< myhostname = hoge.jp

> #myhostname = virtual.domain.tld
83c83
< mydomain = hoge.jp

> #mydomain = domain.tld
114c114
< inet_interfaces = $myhostname

> #inet_interfaces = $myhostname
116c116
< #inet_interfaces = localhost

> inet_interfaces = localhost
119,120c119
< #inet_protocols = all
< inet_protocols = ipv4

> inet_protocols = all
318c317
< relayhost = [stg.hoge.jp]

> #relayhost = [an.ip.add.ress]
420c419
< home_mailbox = Maildir/

> #home_mailbox = Maildir/
678d676
<[/shell]

★参考:
公式マニュアル
Amazon Simple Email Service Developer Guide

SDKを使ったSESでのメール送信
AWS SDK for Rubyを使った添付ファイル付きメール送信プログラム(サンプル)

SMTPインターフェースを利用したSESでのメール送信
Amazon SESをSMTPインターフェースとして使う時のまとめ
stunnelの起動スクリプト
Amazon SESを設定

SESで簡単DKIM

Amazon SESで送信したメールの「amazonses.com経由」をなくす方法

PostfixをSMTPクライアントとしてSASL認証
PostfixをSMTPクライアントとしてSASL認証
Postfix SASL How
Postfix でメールリレーの設定 (SMTP クライアント + SMTP Auth)
How to Use Amazon SES SMTP Server to Send Emails
530 Authentication required (in reply to MAIL FROM command)

おすすめ記事