Menu

BLOG ベアメールブログ

OpenDKIM×Postfixを使ってDKIMを設定する

メールの信頼性と正当性を保証するには、DKIMの設定が不可欠です。2023年10月に発表されたGoogleの新たな「メール送信者のガイドライン」の影響もあり、SPF・DKIM・DMARCといった送信ドメイン認証への対応の重要性が高まっています。DKIMの導入はもはや避けて通れないものと言えるでしょう。
本記事では、メールサーバーにDKIMを実装する方法についてわかりやすく説明します。今回はOpenDKIMというパッケージを使用して、秘密鍵と公開鍵を作成し、DKIM署名を行うための設定を行い、テストを行うまでの手順を解説していきます。

DKIM認証とは

DKIM(Domain Keys Identified Mail)とは、メールの送信元が正当なものであることを証明する送信ドメイン認証技術の一つです。DKIMは、公開鍵と秘密鍵の仕組みを利用した電子署名に基づいており、送信サーバーがメールに電子署名を付与し、受信サーバーが公開鍵を用いてメールに添付された署名を検証することで成り立ちます。これにより、配送経路上でのヘッダやメール内容の改ざんを検知することができます。

近年では、メールサービスプロバイダが受信時のセキュリティチェックを強化していることもあり、DKIMを付与しないことでメールの到達率に影響が出るケースが増えています。
2024年2月から適用されているGoogleの新しい送信者ガイドラインでは、Gmail宛に1日5,000通以上配信する送信者は、SPFに加えDKIM認証にも合格することが必須の要件となっています。

その他のメールサービスプロバイダや、携帯キャリアなども同様の基準に追随することが予想できるため、今後DKIM対応が標準的な要件になることは間違いないでしょう。

DKIMに関しては、ベアメールブログで解説をしておりますので、宜しければご参照ください
https://baremail.jp/blog/?s=DKIM

DKIMの設定手順

それでは早速、DKIMの具体的な設定手順を解説していきます。

全体の大まかな流れとしては以下の通りです。

  1. OpenDKIMパッケージのインストール
  2. 秘密鍵と公開鍵のキーペアの作成
  3. OpenDKIMの設定
  4. Postfixの設定
  5. サービスの再起動

0.前提条件

今回は完全ローカル環境で構築、テストを実施し、その後外部宛にメールを送信します。
環境・構成は下記の通りです。

OS

# cat /etc/redhat-release
AlmaLinux release 8.9

使用するミドルウェア

  • Postfix :メールの送信(MTA)
  • OpenDKIM:電子署名の作成・付与

ドメイン及びアカウント

今回は環境構築後にローカルでの検証を行うため、以下のドメイン及びアカウントを準備しています。

  • テストアカウント①
    ドメイン:example.com
    ユーザー:testuser1
  • テストアカウント②
    ドメイン:sample.org
    ユーザー:demo1

構成を図にするとこんな感じになります。

OpenDKIMとPostfixの関係性を表した図

最終的に外部のメールサーバー(Gmailなど)にメールを送り、DKIMシグネチャが付与されていることを確認した上で、DKIM認証がPASSになることをゴールとします。  

DKIMを設定したメールサーバからGmailにメール送信し、認証が行われる仕組みの図式

1.OpenDKIMパッケージのインストール

それでは、メールを送信するサーバに必要なパッケージをインストールしていきます。

OpenDKIMをインストールするためにはEPELレポジトリが必要になるため、もしEPELレポジトリがまだ追加されていない場合は、先にレポジトリを追加する必要があります。

EPELレポジトリのインストール

[root@dkimtest ~]# dnf install -y epel-release

OpenDKIMのインストール

続けて、OpenDKIMをインストールします。

[root@dkimtest ~]# dnf install -y opendkim opendkim-tools

2.秘密鍵と公開鍵の作成

opendkim-genkeyコマンドを使い、秘密鍵と公開鍵を作成します。

今回はOpenDKIMの標準ディレクトリである/etc/opendkim/keys/に秘密鍵と公開鍵を作成します。

キーペアを作成すると秘密鍵と公開鍵の2ファイルが出力されます。

秘密鍵と公開鍵の作成

今回は検証のため、example.comとsample.orgの2つのドメインでキーペアを作成しています。

[root@dkimtest ~]# opendkim-genkey -b 2048 -D /etc/opendkim/keys/ -d example.com -s example.com.202312

[root@dkimtest ~]# opendkim-genkey -b 2048 -D /etc/opendkim/keys/ -d sample.org –s sample.org.202312

※オプション詳細

-b:鍵の長さ(ここでは2048bitを指定)
-D:出力するディレクトリ
-d:ドメイン
-s:セレクタ

セレクタは署名時にどの公開鍵を使用するのかを識別するために使用されます。
本記事ではドメイン名+年月でセレクタ名を指定していますが、任意の名前で作成することができます。

DKIMのキーペアは、セキュリティ対策のために新たに作成して更新する可能性があるため、将来の変更や管理をしやすくするため、意味のある命名規則を採用することをお勧めします。

作成した秘密鍵と公開鍵の確認

[root@dkimtest ~]# ll /etc/opendkim/keys/
合計 24
-rw------- 1 opendkim opendkim 1647 mm月  dd hh:mm example.com.202312.private
-rw------- 1 opendkim opendkim  521 mm月  dd hh:mm example.com.202312txt
-rw------- 1 opendkim opendkim 1647 mm月  dd hh:mm sample.org.202312.private
-rw------- 1 opendkim opendkim  530 mm月  dd hh:mm sample.org.202312.txt

それぞれ2ファイル作成されていることを確認できました。
「.private」が秘密鍵、「.txt」が公開鍵となります。

秘密鍵と公開鍵の所有者の変更

秘密鍵と公開鍵を作成したら、OpenDKIMがアクセス出来るように所有者をopendkimユーザーに変更します。

[root@dkimtest ~]# chown -R opendkim:opendkim /etc/opendkim/keys/

※「-R」を指定することでディレクトリ内全てのファイルの所有者/グループが変更されます。

3. OpenDKIMの設定

ではOpenDKIMの設定を行います。
設定が必要なファイルは以下の3つです。

  • /etc/opendkim.conf
  • /etc/opendkim/SigningTable
  • /etc/opendkim/KeyTable

OpenDKIMの設定ファイルを修正

/etc/opendkim.conf がOpenDKIMの設定ファイルです。
必要な設定を入れていきます。

[root@dkimtest ~]# vi /etc/opendkim.conf

#受信する場合は[sv]となります。[s] 送信時に署名 [v] 受信時に検証
Mode v

#デフォルト値なので変更無しであれば、コメントアウトのみでOKです。
KeyTable /etc/opendkim/KeyTable
SigningTable refile:/etc/opendkim/SigningTable

#後述するPostfixのsmtp_milters設定と合わせる必要があります
Socket  inet:8891@localhost

Postfixのデフォルトがポート設定だったためポートで待ち受けをしています。

環境によってはソケット通信を使用しているケースもあるかと思いますので、その場合はソケットで待ち受け設定をする必要があります。その場合は、/etc/opendkim.confに「”Socket local:/var/run/opendkim/opendkim.sock” 」と設定して下さい。

SigningTableのレコード設定

SigningTableはメールアドレスと秘密鍵を関連付けるために行います。
/etc/opendkim/SigningTable を編集します。

基本的なフォーマットは下記のとおりです。

*@[ドメイン名] [セレクタ]._domainkey.[ドメイン名]

以上のフォーマットを踏まえて、SigningTableのレコードを末尾に入力します。

[root@dkimtest ~]# vi /etc/opendkim/SigningTable
*@example.com example.com.202312._domainkey.example.com
*@sample.org sample.org.202312._domainkey.sample.org

KeyTableのレコード設定

KeyTableはDKIMレコードと秘密鍵の関連付けるためのレコードです。
/etc/opendkim/KeyTable を編集します。

フォーマットは以下の通りです。

[セレクタ名]._domainkey.[ドメイン名] [ドメイン名]:[セレクタ名]:[秘密鍵へのパス]

以上をフォーマット踏まえて、KeyTableの末尾にレコードを入力します。

[root@dkimtest ~]# vi /etc/opendkim/KeyTable

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

sample.org.202312._domainkey.sample.org sample.org:sample.org.202312:/etc/opendkim/keys/sample.org.202312.private

OpenDKIM側の設定は以上となります。

4.Postfixの設定

メールにDKIM署名を付与するためには、OpenDKIMとメールを送信するMTA(Mail Transfer Agent)を紐づける必要があります。

今回はPostfixを使用しているため、PostfixにOpenDKIMを連携させる設定を行います。
Postfixの設定ファイルであるmain.cfの末尾に以下の設定を追加します。

[root@dkimtest ~]# vi /etc/postfix/main.cf
※末尾に追加

smtpd_milters = inet:127.0.0.1:8891
non_smtpd_milters = $smtpd_milters
milter_default_action = accept

opendkim.confの設定に合わせて「smtpd_milters = inet:127.0.0.1:8891」としています。
ソケット通信が必要な場合は、「Socket local:/run/opendkim/opendkim.sock」とすることで、ソケットで通信されます。

main.cfとopendkim.confで通信方式の設定を合わせる必要がありますので、変更した際には注意してください。

Postfixのバーチャルドメイン設定

今回は1台のサーバ内で2つのドメインを扱うため、PostfixのVirtual Domain機能を使用します。
シングル構成でテストをする場合や、すでに配信環境を持っている場合、本手順は必要ありません。

Virtual Domainの設定はPostfixのmain.cfとvirtual_user_tableに設定を追加します。

[root@dkimtest ~]# vi /etc/postfix/main.cf
※末尾に追加

virtual_alias_domains = example.com sample.org
virtual_alias_maps = hash:/etc/postfix/virtual_user_table

[root@dkimtest ~]# vi /etc/postfix/virtual_user_table

#テストに使うメールアドレスとアカウントを記載
testuser1@example.com testuser1
demo1@sample.org demo1

5.サービスの再起動

OpenDKIMとPostfixの設定が終わったら、サービスの再起動を行います。

[root@dkimtest ~]# systemctl restart postfix

[root@dkimtest ~]# systemctl restart opendkim

メールの送信テスト

それではテストメールを送信して、DKIMが付与されているか確認します。

普段はメーラーと呼ばれるソフトウェアやWEBメールを使い、メールを送受信している方が大多数だと思いますが、今回はせっかくなのでtelnetを使って直接25番ポート(SMTP)に接続し、メールを送信したいと思います。

環境によってはtelnetがインストールされていないことも考えられますので、インストールされていない場合は以下のコマンドでインストールして下さい。

# dnf install –y telnet

テストパターン① ローカル検証その1

「testuser1@example.com」から「demo1@sample.org」へメールを送ります。

[root@dkimtest  ~]# telnet localhost 25       ←telnetで25番ポートにアクセス
Trying 127.0.0.1...
Connected to localhost.
Escape character is '^]'.
220 dkimtest .localdomain ESMTP Postfix
helo localhost       ←SMTPを使うことを宣言
250 dkimtest .localdomain
MAIL FROM:testuser1@example.com       ←EnvelopeFROMの指定
250 2.1.0 Ok
RCPT TO:demo1@sample.org       ←送信先の指定
250 2.1.5 Ok
DATA          ←メールデータの送信を開始
354 End data with <CR><LF>.<CR><LF>

From:testuser1@example.com       ←HeaderFROMの指定(無くてもOK)
subject:DKIM-TEST-PATTERN_1       ←メールのタイトルを指定
              ←ヘッダーと本文の間を1行空ける
DKIM-TEST_01       ←メール本文(Body部分)
.            ←入力の完了(ドット)
250 2.0.0 Ok: queued as 3FF4585232BB
quit       ←メールデータの送信を終了
221 2.0.0 Bye

Connection closed by foreign host.

無事に送信できたようですので、送信したメールを確認します。

メールは受信したユーザのホームディレクトリ内にあるMaildirに格納されています。

[root@dkimtest  ~]# ll /home/demo1/Maildir/new/
-rw------- 1 demo1 demo1 1051 yy月 dd hh:mm 1703724404.Vfd00I8522f79M830290. dkimtest

送信したメールがありました。メールを確認すると下記にようになるかと思います。

[root@dkimtest  ~]# cd /home/demo1/Maildir/new/
[root@dkimtest  ~]# cat 1701935827.Vfd00I8522f8dM716954. dkimtest 
Return-Path: <testuser1@example.com>
X-Original-To: demo1@sample.org
Delivered-To: demo1@dkimtest localdomain
Received: from localhost (localhost [127.0.0.1])
by dkimtest.localdomain (Postfix) with SMTP id 3FF4585232BB
for <demo1@sample.org>; w, dd mm yyyy hh:mm:ss +0900 (JST)
DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=example.com;
s=example.com.202312; t=1703724404;
bh=ZzfDLqEZ5cs9niaCsvmywzqmeYdfYpV38WKlTzSLZ70=;
h=From:subject:Date:From
b=USkxSyMJmVhXIPPrzCryfhxSACqnfBZifhSkurzQfnrrfZt6y6XOrYm9jjyVnzKLL2sArNh+kezeW+77set5Ry6rCYh+c5Q9Zy9lfNLi0WezLOGytFSYX7C0HWqx3Pb5T4kYzTMQAYNzlfBRY6TNsuDvq5Iq7nfM+oWHgKfOrfy4jzhNWiwNQ5hZ5AJJVrPOXmv+1O2MHExRxjkN/887LbP48rUaFfr2pKufUZWeyZpw2A9SXa4ZsdkijCAUcl3uR4m95sgIozYfjJcm5nlJUNSA7bNOISfpi5Ozd6SIkmfevpnM+3qDShZcauaoLmNvDzUBWpfELv/u1Dtiag==

From:testuser1@example.com
subject:DKIM-TEST-PATTERN_1
Message-Id: <20xxxxxxxxxxxx.xFFxxxxxxxBB@dkimtest.localdomain>
Date: w, dd mm yyyy hh:mm:ss +0900 (JST)
DKIM-TEST_01

赤字の箇所がDKIMシグネチャになります。

d=example.com
s=example.com.202312

example.comドメインから送られたメールに、example.com.202312セレクタが使われていることが分かります。
無事にDKIMを付与することができました。

テストパターン② ローカル検証その2

次は「demo1@sample.org」から「testuser1@example.com」からへメールを送ります。
コマンドはFromとToを入れ替えるのみでほぼ同じです。

[root@dkimtest  ~]# telnet localhost 25       ←telnetで25番ポートにアクセス
Trying 127.0.0.1...
Connected to localhost.
Escape character is '^]'.
220 dkimtest .localdomain ESMTP Postfix
helo localhost       ←SMTPを使うことを宣言
250 dkimtest .localdomain
MAIL FROM:demo1@sample.org      ←EnvelopeFROMの指定
250 2.1.0 Ok
RCPT TO:testuser1@example.com       ←送信先の指定
250 2.1.5 Ok
DATA          ←メールデータの送信を開始
354 End data with <CR><LF>.<CR><LF>

From:From: demo1@sample.org      ←HeaderFROMの指定(無くてもOK)
subject:DKIM-TEST-PATTERN_2       ←メールのタイトルを指定
              ←ヘッダーと本文の間を1行空ける
DKIM-TEST_02       ←メール本文(Body部分)
.            ←入力の完了(ドット)
250 2.0.0 Ok: queued as 3FF4585232BB
quit       ←メールデータの送信を終了
221 2.0.0 Bye

Connection closed by foreign host.

では、メールを見てみましょう。

[root@dkimtest ~]# cd /home/testuser1/Maildir/new/
[root@dkimtest ~]# cat 1704879958.Vfd00Ic18aeb5M157793. dkimtest
Return-Path: demo1@sample.org
X-Original-To: testuser1@example.com
Delivered-To: testuser1@dkimtest.localdomain
Received: from localhost (localhost [127.0.0.1])
by dkimtest.localdomain (Postfix) with SMTP id 6545C85232BB
for testuser1@example.com; w, dd mm yyyy hh:mm:ss +0900 (JST)
DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=sample.org;
s=sample.org.202312; t=1704879958;
bh=es7kI95i7luCajN8HY9mC08mjeY4zjoMEXK9vnrMfzk=;
h=From:subject:Date:From;
b=YeKfoaLmhdBq5ffg+SZnLf6UYiM8XVWYhjq0TtyuzizFOhipGmPS+3Mvgbfu3vu3qPGUy/F9lSACLZc4MMWAK4uLx52HSWc74kyg+eUNroN2/4ScUDGyR7YeUl9dsF3G4Ex7dn6wAycmpqsNX+KwadKT6QCTGDf5NP8JtCjfpMiIs0v5HwqdwPQlwP0jqSI0MVkKLeoaY1WIIi8XP4jxx6HKEf0VEdi/iL2LoxKcUy2u9ihXEPRpkSvX8I8QxtvGEuAZfE7VN9Apl3S0+B1m8+Ezc7kaFnxlSB/Xq8nqChECekYKWiYJiC5OKc5gw8r1eDAiOcAHpNpmYc1UOQ==

From: demo1@sample.org
subject:DKIM-TEST-PATTERN_2
Message-Id:20xxxxxxxxxxx.xxxxCxxxxxBB@dkimtest.localdomain
Date: w, dd mm yyyy hh:mm:ss +0900 (JST)
DKIM-TEST_02

こちらにもDKIMシグネチャを付与することができました。

テストパターン③ 外部サーバー(Gmail)へ送信

ローカル環境内では互いにシグネチャを付与できることを確認出来ましたので、次は外部のメールサーバーに向けてメールを送ってみたいと思います。

インターネット経由でメールを送信するには、ドメインを取得し、メールサーバーをDNSに登録する必要がありますが、ここでは送信可能な環境が既に整っていることを前提として進め、「baresupport.jp」を送信元のドメインとします。

DKIMは秘密鍵を使用してDKIMシグネチャをメールに付与します。メールに付与されたDKIMシグネチャが正しいかどうかを検証するためには、ペアとなる公開鍵をDNSに登録する必要があります。

公開鍵は、秘密鍵を作成したディレクトリと同じ場所にあります。今回baresupport.jp.202312という名前でセレクタを作成したため、「baresupport.jp.202312.txt」が公開鍵になります。

公開鍵の中身はこのようになっています。

[root@dkimtest  ~]# cat /etc/opendkim/keys/
baresupport.jp.202312.txt
baresupport-blog.co.jp.202312._domainkey   IN      TXT     ( "v=DKIM1; k=rsa; "p=8IIBHjXNBgkqh-kiG9w0BXQEFXXOCXQsX8IIBBgKB/gCy6DZGzrK1jl+EWXobp+wPFxDusvdP7BYRWIn1AR8osXyUqud0hGL81YRJJtsdusJelR/LXWAXhsLF8r8vBVuVv3jjrFZrXjptIdKzjfstxEIICAvXxHAAvkPVKWfxkX3qf+/bivInjrSZXtR43bv3UShQeEsu48EQDewqDAj7AXyEtGLi8rwViXiwiLN8VdBjPl6gCWu8x8+d3x"

"jHE4A/zeJWPpcErYU8pByTrfQICSF4D698DTh7iCXSok3Z8w1b1S4XiQS8jw8RuNLZKYXD3Yh1xAPHk4vXto6sGIuXgbQf7l8/eHyXcF8w6kCxnxdxS9kSNY/0wWuVbbDBXg8BXXE=" )  ; ----- DKIM key baresupport.jp.202312 for baresupport.jp

この情報を、送信元ドメインのDNSにDKIMレコードとして登録する必要があります。

レコードは以下の通りです。

Name: baresupport.jp.202312._domainkey
RecodeType: TXT
Content: v=DKIM1; “ k=rsa; p=8IIBHjXNBgkqh-kiG9w0BXQEFXX-CXQsX8IIBBgKB/gCy6DZGzrK1jl+EWXobp+wPFxDusvdP7BYRWIn1AR8osXyUqud0hGL81YRJJtsdusJelR/LXWAXhsLF8r8vBVuVv3jjrFZrXjptIdKzjfstxEIICAvXxHAAvkPVKWfxkX3qf+/bivInjrSZXtR43bv3UShQeEsu48EQDewqDAj7AXyEtGLi8rwViXiwiLN8VdBjPl6gCWu8x8+d3x""jHE4A/zeJWPpcErYU8pByTrfQICSF4D698DTh7iCXSok3Z8w1b1S4XiQS8jw8RuNLZKYXD3Yh1xAPHk4vXto6sGIuXgbQf7l8/eHyXcF8w6kCxnxdxS9kSNY/0wWuVbbDBXg8BXXE=”

今回、鍵長を2048bitで作成をしています。お使いのDNSの仕様によっては登録できるレコードの長さに制限があり、1024bitまでしか登録出来ない可能性がありますので、環境に合わせてDKIM鍵を作成して下さい。

設定できたらメールを送ってみます。

送信元は「test-mail@baresupport.jp」、受信側は「recive-test@gmail.com」としてメールを送ります。

[root@dkimtest  ~]# telnet localhost 25
Trying 127.0.0.1...
Connected to localhost.
Escape character is '^]'.
220 dkimtest .localdomain ESMTP Postfix
helo localhost      
250 dkimtest .localdomain
MAIL FROM: test-mail@baresupport.jp
250 2.1.0 Ok
RCPT TO: recive-test@gmail.com
250 2.1.5 Ok
DATA   
354 End data with <CR><LF>.<CR><LF>
From: test-mail@baresupport.jp
subject:DKIM-TEST-PATTERN_3 
DKIM-TEST_03 
.
250 2.0.0 Ok: queued as 3FF4585232BB
quit

221 2.0.0 Bye
Connection closed by foreign host.

無事にメールが送れたら、送信したメールをGmailで確認します。
メールヘッダを確認するとDKIMがPASSとなっていることを確認できます。

まとめ

今回はDKIMのキーペアの作成からDKIM署名の設定、そして実際にテストメールを送信し、DKIM認証がPASSとなるまでを解説しました。
ここ最近ではDKIMを設定しないことで重要なメールが届かないケースが増えており、今後DKIM対応は基本的な要求事項とみなされることが想定されます。主要なメールサービスでも対応を求められていますので、DKIMの導入にあたりこの記事を参考にしていただければ幸いです。