はじめに
こんにちは!ミルディアでインフラエンジニア見習いをしている齊藤です!
最近、SMTPリレーの学習のため、Postfixを使用して社内サーバーからのメール送信をSES経由にする設定を行いました。
その際の作業内容を簡潔にまとめます。
なぜSESなのか
実践的な学習のため、実際の運用に近い環境で設定やトラブルシューティングを行いたく、SESを選択しました。
環境
- AmazonLinux2023(t2.large)
- Postfix v3.7.2
設定手順
SESの本番稼働
SESはAWSアカウントが初期状態でサンドボックスにあり、以下制限がかかった状態となっております。
- E メールの送信先は、検証済み E メールアドレスおよびドメイン、または Amazon SES メールボックスシミュレーターに制限されます。
- 最大で 24 時間あたり 200 メッセージを送信できます。
- 最大で 1 秒あたり 1 メッセージを送信できます。
- 送信承認については、ユーザーも代理送信者も、検証されていない E メールアドレスに E メールを送信することはできません。
- アカウントレベルのサプレッションでは、サプレッションリスト管理に関連する一括アクションと SES API コールが無効になります。
制限の内容をご確認いただいた上で、必要に応じて、SESを本番稼働させてください。
今回は制限付きの運用で十分なことから、本番稼働はさせておりません。
方法については AWS公式のデベロッパーガイド をご参照ください。
ブラウザでコンソール上から行う方法と、コマンドラインツールでAWS CLI を使用して行う方法の2つが説明されています。
(デベロッパーガイド 本稼働アクセスのリクエスト (Amazon SES サンドボックスからの移行))
SESの認証情報準備
SMTPクレデンシャルを発行しましょう。
SMTP設定を開きます。
SMTP認証情報の作成をクリックします。
IAMユーザーの作成画面が開かれるので、メールの送信権限があるか確認して、ユーザーの作成をクリックします。
ステートメントの内容
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": "ses:SendRawEmail",
"Resource": "*"
}
]
}
ユーザーの作成が完了すると、SMTPクレデンシャルの秘匿情報が表示されます。
次の Postfixの設定 で使用するので保存しておきましょう。
必要な情報は以下2つです。
- SMTP ユーザー名
- SMTP パスワード

Postfixの設定
postfixをインストールします。
$ sudo yum install postfix
バージョンを確認しておきましょう。
$ postconf | grep mail_version
mail_version = 3.7.2
Postfixを起動し、自動起動を有効化します。
$ sudo systemctl start postfix
$ sudo systemctl enable postfix
システムデフォルトのMTA(Mail Transfer Agent)がPostfixになっているか確認します。
なっていない場合は、ここで設定してください。
$ alternatives --config mta
There is 1 program that provides 'mta'.
Selection Command
-----------------------------------------------
*+ 1 /usr/sbin/sendmail.postfix
Postfixの設定を行います。
設定内容については、後述の「Tips ~main.cf 設定パラメータ詳細~」をご参照ください。
$ sudo vim /etc/postfix/main.cf
設定内容は以下のとおりです。
# メールサーバーの情報を記載(環境に合わせて適宜修正してください。)
myhostname = mail.example.com
mydomain = example.com
mydestination =
# SESを経由させる設定を記載
relayhost = [email-smtp.ap-northeast-1.amazonaws.com]:587
smtp_sasl_auth_enable = yes
smtp_sasl_security_options = noanonymous
smtp_sasl_password_maps = hash:/etc/postfix/sasl_passwd
smtp_use_tls = yes
smtp_tls_security_level = encrypt
smtp_tls_note_starttls_offer = yes
smtp_tls_CAfile = /etc/ssl/certs/ca-bundle.crt
設定が反映されているか確認してください。(以下記載は該当箇所のみ抜粋したもの)
$ postconf -n
mydestination =
mydomain = example.com
myhostname = mail.example.com
relayhost = [email-smtp.ap-northeast-1.amazonaws.com]:587
smtp_sasl_auth_enable = yes
smtp_sasl_password_maps = hash:/etc/postfix/sasl_passwd
smtp_sasl_security_options = noanonymous
smtp_tls_CAfile = /etc/ssl/certs/ca-bundle.crt
smtp_tls_note_starttls_offer = yes
smtp_tls_security_level = encrypt
smtp_use_tls = yes
作成したSMTPクレデンシャルを設定します。
$ sudo vim /etc/postfix/sasl_passwd
設定内容は以下のとおりです。
ご自身のSESリージョンと認証情報に合わせて記載を更新してください。
[email-smtp.ap-northeast-1.amazonaws.com]:587 ****(SMTPユーザーネーム):****(SMTPパスワード)
ハッシュ化します。
$ sudo postmap hash:/etc/postfix/sasl_passwd
ファイルの権限を更新します。
$ sudo chown root:root /etc/postfix/sasl_passwd /etc/postfix/sasl_passwd.db
$ sudo chmod 600 /etc/postfix/sasl_passwd /etc/postfix/sasl_passwd.db
再起動して、設定内容を反映させてください。
$ sudo systemctl restart postfix
※ 認証情報の取り扱いについて
本番環境ではサーバーに認証情報を直置きしてはいけません。
本番環境で認証情報をサーバーに直接保存すると、サーバーが侵害された際に認証情報が漏洩し、不正にSESを利用されるリスクがあります。
今回は検証環境での構築であり、簡単のため認証情報をサーバーに直置きしています。
本記事のように、サーバーがEC2上にある場合は AWS IAMロールや、AWS Secrets Manager を使用します。
そうでない場合も、安全な認証情報ストレージを使い、アクセス制御を行いましょう。
テスト
実際にメールを送信し、SES経由になっているか確認しましょう。
mailコマンドでテストメールを送信します。
$ mail -s "SES test mail" -r origin@example.com destination@example.com
test
.
EOT
届いたメールを確認します。
SES経由になっていることが確認できました。
Tips main.cf 設定パラメータ詳細
/etc/postfix/main.cfに設定したパラメータの詳細について記載します。
※適宜、お手元の環境の設定値として正しいか、公式ドキュメントの日本語訳と照らし合わせて設定してください。
(Postfix設定パラメータ)
myhostname
SMTP サーバーの FQDN を指定します。
デフォルト値: "postconf -d" の出力を参照します。
mydomain
myhostname のドメイン部分を指定します。
デフォルト値: "postconf -d" の出力を参照します。
mydestination
他のマシンに転送するのではなく、 メールをローカルで受信するドメイン名を指定します。
デフォルト値: mydomain, localhost
relayhost
next-hop配送先(中継サーバー)を指定します。
デフォルト値: empty
SMTP の場合、ドメイン名、ホスト名、hostname:port、[hostname]:port、 [hostaddress] または [hostaddress]:port を指定します。
smtp_sasl_auth_enable
Postfix SMTPクライアントの SASL 認証を有効化します。
デフォルト値: no
smtp_sasl_security_options
リレー先のTLS暗号化で使うセキュリティオプションを指定します。
デフォルト値: noplaintext, noanonymous
以下のオプションがあります。
- noplaintext
- 平文パスワードを使う方法を許可しない
- noactive
- active (非辞書) 攻撃を受けるような方法を許可しない。
- active 攻撃とは、攻撃者が認証プロセスに割り込み、パスワードを盗み取る手法のこと。
- nodictionary
- passive (辞書) 攻撃を受けるような方法を許可しない。
- 辞書攻撃とは、攻撃者が一般的なパスワードのリストを使って認証を試みる手法のこと。
- noanonymous
- 匿名認証を認めるような方法を許可しない。
- mutual_auth
- 相互認証を提供する方法のみを許可する。
smtp_sasl_password_maps
リレー先のTLS暗号化で使う認証情報が記載されたファイルの場所を指定します。
デフォルト値: empty
smtp_use_tls
リモートSMTPサーバがSTARTTLSサポートを案内したら TLSを使い、案内がなければ平文でメールを送ります。 (Postfix 2.2以降)
SES では STARTTLS がサポートされているので TLS を使うために有効化します。
デフォルト値: no
smtp_tls_security_level
Postfix SMTPクライアントでのSMTP TLSセキュリティレベル を設定します。
デフォルト値: empty
以下、設定値
- may
- 暗号化必須ではないが、可能であればする。
- encrypt
- 暗号化必須。規格に沿った証明書であればすべて許容(S/MIMEなど)。
- verify
- 暗号化必須。証明書のCAが信用できるかも合わせて検証。
- secure
- 暗号化必須。さらに、「証明書のSubjectAlternativeNameかCommonNameが接続先サーバ名と一致しているか」まで検証。
smtp_tls_note_starttls_offer
TLSが有効になっていない場合、STARTTLSを提供するリモートSMTPサーバのホスト名をログ出力させます。(Postfix 2.2以降)。
デフォルト値: no
以下のようなログが出るようになります。
postfix/smtp[pid]: Host offered STARTTLS: [name.of.host]
smtp_tls_CAfile
Postfix SMTPクライアント証明書を発行した認証局 (CA) の証明書を持つファイルの場所を指定します。(Postfix 2.2以降)
(Postfixが送信先のSMTPサーバーの正当性を確認するために必要です。)
デフォルト値: empty
さいごに
今回の作業を通して、SMTPリレーの仕組みやSESの利用方法について理解を深めることができました。特に、Postfixの設定で各パラメータの役割を理解するのに苦労しましたが、先輩のご助力や、公式ドキュメントを参照することで解決できました。
今後は、SESとCloudWatchと連携させて、メール送信の監視体制を構築してみたり、社内サーバへ導入したウイルスソフトからのアラートメールを振り分けられるようにしたり、知識を発展させていきたいと考えております。
最後までお読みいただき、ありがとうございました。この記事が、SMTPリレーやSESについて学習されている方の参考になれば幸いです。