【Ubuntu】SPFとDKIMに対応した送信専用のメールサーバーを作る【postfix】

ネコニウム研究所

PCを利用したモノづくりに関連する情報や超個人的なナレッジを掲載するブログ

【Ubuntu】SPFとDKIMに対応した送信専用のメールサーバーを作る【postfix】

2024-7-24 |

Ubuntuでpostfixを使ってSPFとDKIMに対応した送信専用のメールサーバーを作りたい!

概要

今回の記事では、Ubuntuでpostfixを使ってSPFとDKIMに対応した送信専用のメールサーバーを作る手順を掲載する。

GMailやYahooメールなどのメールアドレスにメール送信するのにSPFとDKIMのどちらか、メールを一斉送信する場合には両方に対応する必要がある。対応しないとブロックされたり、迷惑メールに分類されたりする。

仕様書

環境

  • Ubuntu 20.04.4 LTS
  • postfix 3.4.13
  • async_zip: 0.1.0

手順書

インストール編、DNS設定編、テスト編の3部構成です。

この記事ではドメイン名はexample.com、メールはサブドメインmail.example.comを使うとする。

インストール編

postfixやopendkim、その他にテストに使うソフトウェアをインストールする。

apt install postfix opendkim opendkim-tools mailutils

postfixのインストール時に初期設定を聞かれるのでNo configuration(設定なし)を選択する。

postfixのバージョンを確認するには下記のコマンドを実行する。

postconf | grep mail_version

postfixの設定ファイルを/etc/postfix/main.cfを編集する。

myhostname = mail.example.com
mydomain = example.com
myorigin = $mydomain
inet_interfaces = all
inet_protocols = all
mydestination = localhost
mynetworks = 127.0.0.0/8
relayhost =
smtpd_banner = $myhostname ESMTP
home_mailbox = Maildir/

smtpd_sasl_auth_enable = yes
smtpd_sasl_security_options = noanonymous
smtpd_sasl_local_domain = $myhostname
smtpd_recipient_restrictions = permit_sasl_authenticated, permit_mynetworks, reject_unauth_destination
broken_sasl_auth_clients = yes
smtpd_tls_auth_only = yes
smtpd_tls_security_level = may
smtpd_tls_cert_file=/etc/ssl/certs/ssl-cert-snakeoil.pem
smtpd_tls_key_file=/etc/ssl/private/ssl-cert-snakeoil.key
smtp_tls_security_level = may
smtp_tls_CAfile = /etc/ssl/certs/ca-certificates.crt
smtp_tls_loglevel = 1
smtp_tls_session_cache_database = btree:${data_directory}/smtp_scache
smtpd_tls_session_cache_database = btree:${data_directory}/smtpd_scache

暗号化に使う認証ファイルはUbuntuに最初から入ってるのを使う。certbotなとで取得したのを使ってもいい。

sendmailなどのパスを調べる。

postconf -d

調べたパスなどを/etc/postfix/main.cfに入力する。私の環境では下記のような感じだった。

sendmail_path = /usr/sbin/sendmail
newaliases_path = /usr/bin/newaliases
mailq_path = /usr/bin/mailq
setgid_group = postdrop
html_directory =/usr/share/doc/postfix/html
manpage_directory = /usr/share/man
sample_directory = /etc/postfix
readme_directory = /usr/share/doc/postfix

/etc/mailnameにメールドメインを入力する。

example.com

メールアドレスになるアカウントを作る。mailman@example.com@より前の部分。

sudo adduser mailman

ここからはopendkim関連の作業。

opendkimの設定ファイルetc/opendkim.confを編集する。

Syslog yes
UMask 007
KeyTable /etc/opendkim/KeyTable
SigningTable refile:/etc/opendkim/SigningTable
Mode s
Socket inet:8892@localhost
PidFile /run/opendkim/opendkim.pid
OversignHeaders From
TrustAnchorFile /usr/share/dns/root.key
UserID opendkim:opendkim

Socketの値inet:8892@localhostは再度main.cfで使うので覚えておく。

鍵を生成して、opendkimが使えるよう権限を設定する。

sudo mkdir /etc/opendkim/keys/example.com
sudo opendkim-genkey -v -b 1024 -D /etc/opendkim/keys/example.com/ -d example.com -s default
sudo chown opendkim:opendkim /etc/opendkim/keys/example.com/default.private

鍵のサイズをオプションで1024にしてるのは、私の検証環境のkagoyaのDNS設定の制限の関係。セキュリティ的にはデフォルトの2048にした方がよい。

/etc/opendkim/KeyTableを作る。

default._domainkey.example.com example.com:default:/etc/opendkim/keys/example.com/default.private

/etc/opendkim/SigningTableを作る。

*@example.com default._domainkey.example.com

/etc/opendkim/TrustedHostsを作る。

127.0.0.1
localhost
example.com
mail.example.com

main.cfの最後に下記を追加する。

milter_default_action = accept
smtpd_milters = inet:localhost:8892
non_smtpd_milters = $smtpd_milters

smtpd_miltersの値はetc/opendkim.confSocketの値inet:8892@localhostを入力する。

postfixがopendkim関連のファイルにアクセスできるようにする。

usermod -a -G opendkim postfix

postfixの設定を確認する。

postfix check

postfixとopendkimを再起動する。

systemctl restart postfix
systemctl restart opendkim

エラーが発生しなければひとまずOKだ。

DNS設定編

メール関連のDNSの設定をする。kagoya VPSでの設定の例。

ホスト名 TYPE 優先度
mail A <ip4>
mail AAAA <ip6>
<空> MX mail.example.com 10
<空> TXT v=spf1 a mx ip4:<ip4> ip6:<ip6> ~all
default._domainkey TXT <key>

v=spf1 a mx ip4: ip6: ~allを設定するTXTレコードはSPFの設定になる。

<ip4>はメールサーバーのip4のIPアドレス、<ip6>はメールサーバーのip6のIPアドレスに置き換える。

ホスト名がdefault._domainkeyTXTレコードはDKIMの設定になる。

<key>/etc/opendkim/keys/example.com/default.txtにある()の中の文字列に置き換える。

これはkagoya特有の問題かもなのだけどp=の後の文字列の中に"が含まれてるとDNSの設定を保存できないので、万一"が含まれてた場合は再度鍵を生成して"が含まれないのが生成されるまで鍵ガチャをする。囲み文字の"はOK。というかkagoyaの場合は登録できる文字列の関係で囲み文字の"は不要なので消してしまってよい。v=DKIM1; h=sha256; k=rsa; p=*****************のような感じになる。

ip4のみの解説の記事が結構あるんだけども、現在はip6と療法設定した方がよい。ip6のみに対応したサーバーが増えてきてる印象。

DNSの設定が反映されるまで15分くらい待つ。

DNSの設定が反映されて名前解決できるか確認する。

# SPFの確認
dig @8.8.8.8 example.com txt
# DKIMの確認
dig @8.8.8.8 default._domainkey.example.com txt

それぞれ設定した文字列が表示されればOKだ!

テスト編

実際にGMailのアドレスにメールが届くのかsendmailでメール送信してみる。

echo -e "From: mailman@example.com\nTo: example@gmail.com\nSubject: SPF and DKIM Test\n\nThis is a test email from mailman@example.com." | sendmail -t

迷惑メールフォルダーに分類され図にメールが届けばOKだ!

ちゃんとSPFとDKIMが有効になってるか確認する。
GMailの場合は届いたメールを開いて、ウィンドウ右上の「...」をクリックして表示されるメニューの中の「メッセージのソースを表示」をクリックする。

下図のようにSPFとDKIMの行の値がPASSとなってればOKだ!

メールが受信できてない場合はvar/log/mail.logを確認してみる。

エラーの一例でsigning table references unknown keyとなってる場合は、/etc/opendkim/KeyTable/etc/opendkim/SigningTableの設定が間違ってる可能性が高い。私の場合はSigningTableがVSCode上でMarkdown判定になってたせいで不要な記号が挿入されてしまっててこのエラーが発生した。

まとめ(感想文)

想像の100倍大変だった!

過去に何度かpostfixを使ってメールサーバーを作るテストをしたことがあったんだけども、成功したのは初めてで嬉しい!

ただセキュリティ的には自分でメールサーバーは運用せず、Google Workspaceなどで運用した方が安全な気がする。独自のメールサーバーだと柔軟に運用できるんだけどもやはりセキュリティが気になる今日この頃。

参考文献・引用

下記の記事を参考にさせていただきました。ありがとうございました。