DMARC界隈の動きにあわせてPostfixをAuthenticated Received Chain(ARC)とEd25519 SHA-256のDKIMに対応させてみます。
FreeBSD上のPostfix + OpenDMARC + OpenDKIM を Postfix + OpenDMARC + dkimpy-milter + OpenARCに変えていきます。いずれOpenDKIMの状況が整った暁にはPostfix + OpenDMARC + OpenDKIM + OpenARCに戻すことにします。
まずはOpenARCでARCを追加します。まだportsが無いのでgit cloneでいきます。元気な方はぜひportsの作成を。まだDKIM対応させていない場合は先にDKIM対応させて、RSA鍵ペアを作ってDNSに公開鍵を突っ込むところまで済ませておきます。次にでてくるdkimpy-milterの現状の制限で、適用する各ドメインにそれぞれ同じ鍵で同じ名前のセレクタが必要です。
1 2 3 4 5 |
# git clone 'https://github.com/trusteddomainproject/OpenARC.git' # cd OpenARC # autoreconf -fvi # ./configure # make install |
/usr/local/etc/openarc.confは次のような感じで、鍵はOpenDKIMで使用中のRSA鍵とセレクタを流用。特定条件下での脆弱性が見つかっても大丈夫なように良い子はARC専用に鍵ペアを作った方が無難かもです。ここでのDomain指定は公開鍵のためのドメインで、ヘッダにARCのフィールドを追加するかいなかの指定ではないです。SigningTableの実装を待ちます。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 |
AutoRestart yes AutoRestartRate 1/3m PidFile /var/run/openarc.pid Syslog yes Socket inet:8891@127.0.0.1 UserID mailnull AuthservID test.example.com Mode sv Canonicalization relaxed/relaxed Domain abacustech.jp KeyFile /usr/local/etc/mail/private/a3.private Selector a3 # end of file |
portsになった場合には気にしないで良くなりますが、ここでは起動はbsnmpdにお任せすることにして/etc/snmpd.configを編集。
1 2 3 4 5 |
prNames.9 = "openarc" prMin.9 = 1 prMax.9 = 10 prErrFix.9 = 1 prErrFixCmd.9 = "/bin/pkill -F /var/run/openarc.pid; /usr/local/sbin/openarc" |
Postfixのmaster.cfの中のすでにOpenDKIMなどのmilterがあるところに軒並みOpenARCのmilterを追加。
1 |
-o smtpd_milters=.....,inet:127.0.0.1:8891 |
起動してエラーが無いことを確認。
1 2 |
# service bsnmpd restart # service postfix restart |
Gmailにテストメールを送り、
1 2 3 |
ARC-Seal: i=1; a=rsa-sha256; d=abacustech.jp; s=a3; t=1574077290; cv=none; b=Azj9r8YI7hLe4Gt+EqNmEfkH05B61hSEvSdLOSPqYWhzqAZLeMEpywC0kABOs52OUbkKjOVlnkZ+fuislMsZ4uSUOI/U3OXknfcswuim79W7tbHOnxIZ2JAOZouU2UMjXdaTltAI4goD4avf04yF8YYiOwo8pZmWZekMRVDo0n4= ARC-Message-Signature: i=1; a=rsa-sha256; ... |
のように、ヘッダの中のi=1のARC-SealとARC-Message-Signatureフィールドがopenarc.confで指定したドメインとセレクタでついていることを確認し(改行無しで78文字超えた署名がつくのであまりお行儀はよろしくない(as of 2019-11-18)です)、
1 |
Authentication-Results: mx.google.com; |
で始まるフィールドの値に、
1 |
arc=pass (i=1); |
があることで付加した最初(i=1)の署名の対象が正しいとされたことが確認できます。
続いてOpenDKIMがed25519-sha256に正式に対応するまでの代替にdkimpy-milterを使ってみます。こちらはほぼReplacing OpenDKIM with dkimpy-milterに書かれている通りです。pip版は動かない、KeyTableEd25519も動かない、というのもその通りでした(as of 2019-11-18)。unix domain socketを使う設定になっていますがその場合Postfixの設定ではsock:ではなくてunix:かと思われます。こちらもportsが無いのでgit cloneで行きます。
1 2 3 4 |
# portmaster mail/py-dkimpy mail/py-milter mail/py-authres security/py-pynacl dns/py-dnspython # git clone 'https://git.launchpad.net/dkimpy-milter' # cd dkimpy-milter # python3.6 setup.py install --single-version-externally-managed --record=log.txt |
Ed25519の鍵ペアを作ります。
1 2 3 4 |
# cd /usr/local/etc/mail/private # dknewkey --ktype ed25519 a5 # chown root:mailnull a5.key a5.dns # chmod ug=r,o= a5.key a5.dns |
KeyTableが使えないのでRSA SHA-256およびEd25519 SHA-256のDKIM署名を付けるすべてのドメインの セレクタ._domainkey.ドメイン の TXT RR を設定します。上のEd25519の例では出来上がったa5.dnsの内容がそれです。
1 2 |
... a5._domainkey IN TXT "v=DKIM1;k=ed25519;p=Ojkrl32ZrJkUgj4A14...c0J5SnsDc=" |
/usr/local/etc/dkimpy-milter.confを編集します。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 |
# UserID mailnull PidFile /var/run/dkimpy-milter.pid Socket inet:8892@127.0.0.1 UMask 077 Syslog yes SyslogSuccess yes Mode sv MacroList daemon_name|ORIGINATING MacroListVerify daemon_name|VERIFYING Canonicalization relaxed/relaxed Domain abacustech.co.jp abacustech.jp akkan.be SubDomains yes KeyFile /usr/local/etc/mail/private/a3.private Selector a3 KeyFileEd25519 /usr/local/etc/mail/private/a5.key SelectorEd25519 a5 # end of file |
プロセス名がpythonなので今度はbsnmpdではなくて/etc/rc.localでの起動にしてみます。
1 2 3 |
... /bin/rm -f /var/run/dkimpy-milter.pid /usr/local/bin/dkimpy-milter & |
Postfixのmaster.cfの中のOpenDKIMのmilterをdkimpy-milterに変更。
1 |
-o smtpd_milters=.....,inet:127.0.0.1:8892,..... |
受信(主に25/tcp smtp)の場合はdkimpy-milter.confで指定したマクロ
1 |
-o milter_macro_daemon_name=VERIFYING |
も指定し、他の送信系では
1 |
-o milter_macro_daemon_name=ORIGINATING |
を指定します。pickupの場合は専用のcleanupを指定してそのcleanupでmilterを設定する必要があるかもしれません。
1 2 3 4 5 6 |
cleanup-pickup unix n - n - 0 cleanup ... -o non_smtpd_milters=...,inet:127.0.0.1:8892,... -o milter_macro_daemon_name=ORIGINATING pickup unix n - n 60 1 pickup -o cleanup_service_name=cleanup-pickup |
先のブログの通りDKIMValidator.comに表示されるアドレスにテストメールを送り、結果を見るボタンを押すことでed25519-sha256署名の検証や、SPF、ついでにデフォルト設定のSpamAssassinのスコアも表示してくれます。ありがたや。
Gmailではa=rsa-sha256の方はdkim=passとなるものの、a=ed25519-sha256はまだ検証してくれずにdkim=neutral (no key)、となります(as of 2019-11-18)。
1 2 3 4 5 6 7 8 9 10 11 12 13 |
ARC-Authentication-Results: i=2; mx.google.com; dkim=neutral (no key) header.i=@abacustech.jp header.s=a5; dkim=pass header.i=@abacustech.jp header.s=a3 header.b="Rz/kaXOF"; arc=pass (i=1); spf=pass (google.com: domain of orch@abacustech.jp designates 2001:db8::25 as permitted sender) smtp.mailfrom=orch@abacustech.jp; dmarc=pass (p=REJECT sp=REJECT dis=NONE) header.from=abacustech.jp Received-SPF: pass (google.com: domain of orch@abacustech.jp designates 2001:db8::25 as permitted sender) client-ip=2001:db8::25; Authentication-Results: mx.google.com; dkim=neutral (no key) header.i=@abacustech.jp header.s=a5; dkim=pass header.i=@abacustech.jp header.s=a3 header.b="Rz/kaXOF"; arc=pass (i=1); spf=pass (google.com: domain of orch@abacustech.jp designates 2001:db8::25 as permitted sender) smtp.mailfrom=orch@abacustech.jp; dmarc=pass (p=REJECT sp=REJECT dis=NONE) header.from=abacustech.jp |
OutlookではARC-Authentication-Resultsでは結果dmarc=passとなるので良いもののdkim=failとdkim=passが入り乱れ、Authentication-Resultsにはdkim=passだけが入っていました(as of 2019-11-18)。
1 2 3 4 5 6 7 8 |
ARC-Authentication-Results: i=2; mx.microsoft.com 1; spf=pass (sender ip is 203.0.113.123) smtp.rcpttodomain=live.com smtp.mailfrom=abacustech.jp; dmarc=pass (p=reject sp=reject pct=100) action=none header.from=abacustech.jp; dkim=fail (signature syntax error) header.d=none; dkim=pass (signature was verified) header.d=abacustech.jp; arc=pass (0 oda=0 ltdi=0 93) Authentication-Results: spf=pass (sender IP is 203.0.113.123) smtp.mailfrom=abacustech.jp; live.com; dkim=pass (signature was verified) header.d=abacustech.jp;live.com; dmarc=pass action=none header.from=abacustech.jp; |