- Gmailのメール送信者向けのガイドラインや神奈川県出願システムのトラブルなどで話題になっていたから、送信ドメイン認証技術について最近調べた内容をまとめる。
- 別にGmailでは無くても良いんだけど、いちばん分かりやすいのでGmailに送ることを考える。
- 併せて、本記事ではPostfixにてSPF、DKIMを設定する部分までを記載する。本当ならDMARCまでやってしまいたいが、それはまたの機会にしたいと思う。
用語の簡単な説明
まずは簡単に用語の整理と説明。
- MUA
- MTA
- エンベロープTo、ヘッダTo
- エンベロープFrom
- Return-Pathとしてメールヘッダ内に記載されている送信者アドレス
- メールが相手のメールボックスに届けられなかったり、バウンスしたメールの送り先を指定する
- エンベロープFromとヘッダFromは一致しなくてよい。むしろバウンスメールを受信するとメールボックスがパンクするなどが考えられるので、別のバウンスメール受信用のアドレスを指定するのがベター
- ヘッダFrom
- MUA上で表示されているメールの送信元アドレス。普段、メールアドレスと言ったときに思い浮かべるのはこちらのアドレス
- Recievedフィールド
- メールがどういった中継サーバを経由して届いたかの履歴
- Postfixがメールを送信する場合、送信元サーバの$myhostnameが最初に記録される
- SPF
- DKIM
- エンベロープFromとヘッダFromが一致しないのはままありうるので、なりすましなどを防ぐにはSPFだけでは十分ではない。DKIMは、メールヘッダと本文に対して署名を行い、受信側でそれを検証することでなりすましやメールの改ざんを検知するための仕組み
- DKIMには、作成者署名(そのドメインを所有しているユーザの秘密鍵・公開鍵で署名と検証を行う)方式と第三者署名が存在する
- 第三者署名は、メールの作成者と署名者の関係性が分からないので、ほぼ役には立たない*1
- DMARC
- ヘッダFromを検証する仕組み
- さらに、SPFやDKIMの検証結果に応じて、そのメールをどう扱うか(破棄するか、受信するかなど)を予め指定出来る
ここでは、以下のような内容でメールを送るための設定例を記載する
myhostname = example.local # ローカルのホスト名を記入する
smtp_helo_name = mail.example.com # SMTPのEHLOやHELO コマンドで使用するホスト名を指定する(receivedフィールドの値に使用される)
mydomain = example.com # インターネットドメイン名
myorigin = $mydomain # 外部に出ていくときに使用するドメインを指定する(エンベロープFromで使用)
inet_interfarce = loopback-only # 受信するIPアドレスを指定する
mynetworks = localhost # メールを受信するネットワークアドレスを指定する
mydestination = $myhostname, localhost.$mydomain, localhost, $mydomain # 自ドメイン宛のメールを受信できるようにする
home_mailbox = Maildir/ # 自身のメールボックスを指定する
- SPFレコードの登録は、DNS側の設定なので、Postfixに設定が必要というわけでは無い。
- 使っているDNSに以下のようなTXTエントリを追加してあげれば良い
example.com. IN TXT "v=spf1 ip4:198.51.100.0/24 -all"
- 次はDKIMを設定していく
- 何はともあれDKIMを使うためには、opendkimパッケージが必要なのでインストールを行う
dnf config-manager --set-enabled crb
dnf install epel-release
dnf install opendkim
dnf install opendkim-tools
- opendkimに必要なライブラリがCRBリポジトリに存在するので、まずCRBリポジトリを有効化している
- 加えて、opendkimはEPELに存在するので使えるようにする
- opendkim-toolsは、署名に使うキーペアを生成するコマンドを含んだパッケージなのでインストールする
opendkimの設定
- opendkimの設定だが、以下のような流れになる
- 署名に使うキーペアを生成する
- opendkim.confに必要な起動設定を書く
- postfixのmain.cfにopendkimとの連携設定を書く
- DNSに作成したキーペアの公開鍵を登録する
- まずキーペアの作成は、今回は作成者署名を行うので、署名するドメインをexmaple.comとし、DKIMセレクタ名をdefaultとして作成する
mkdir /etc/opendkim/keys/example.com
opendkim-genkey -D /etc/opendkim/keys/example.com/ -d example.com -s default
chown opendkim:opendkim -R /etc/opendkim/example.com
Mode sv
#Socket local:/run/opendkim/opendkim.sock
Socket inet:8891@localhost
Domain example.com
Selector default
KeyFile /etc/opendkim/keys/example.com/default.private
InternalHosts refile:/etc/opendkim/TrustedHosts
- デフォルトでは、Modeが
v
になっており検証するだけなので、署名を行うためsv
に変更する
- 次にPostfixとの連携のためSocketディレクティブを書くが、ソケットを使う方法とIPを使う方法がある。上記では、IPを使う方法を書いている
- ソケットを使う場合は、
chown -R opendkim:mail /run/opendkim/
のようにディレクトリの所有グループをopendkimからmailに変更してあげる必要がある。そうしないとPostfixから読みか書きが出来ないため
- Domainには、署名するドメインを指定し、Selectorにはキーペア作成時に指定したセレクター名を指定、KeyFileには作成したキーペアのうち秘密鍵のパスを設定する
- 最後に、InternalHostsをアンコメントしてPostfixとの通信が出来るようにしてあげる
- いったんここまででopendkimパッケージの設定は終わりで、次はPostfixで連携設定を書く
milter_default_action = accept
smtpd_milters = inet:127.0.0.1:8891
smtpd_milters = local:/run/opendkim/opendkim.sock # ソケットを利用する場合
non_smtpd_milters = $smtpd_milters
- 上記の3行をmain.cfの末尾などに追記してあげる
- $smtpd_miltersは、opendkimとの通信方式に応じたどちらかの設定を書いてあげる
- ここまででopendkimとPostfixの設定は終わり。次にDNSにDKIMのキーペアの公開鍵を登録する
- 作成した公開鍵は下記のファイルに書かれているので、DNSにTXTレコードとして登録してあげる
cat /etc/opendkim/keys/example.com/default.txt
- digコマンドなどで登録されたことを確認できたら、opendkimとPostfixを再起動し、Gmailにテストメールを送って、メールヘッダを表示してみてSPF/DKIMのどちらもPASSしていれば完了
systemctl start opendkim
systemctl start postfix