DKIM (DomainKeys Identified Mail) は、電子メールの送信者がメールの内容を改ざんされないよう保護し、受信側がそのメールが正当なものであることを検証するための仕組みです。DKIMは以下の手順で動作します。
メールの署名: 送信メールサーバーは、メールのヘッダーや本文にデジタル署名を施します。この署名は、秘密鍵を使用して生成されます。
DKIM-Signature: v=1; a=rsa-sha256; d=example.com; s=selector;
c=relaxed/relaxed; q=dns/txt; h=from:subject:date:message-id;
bh=<hashed body>; b=<encrypted hash>
公開鍵の公開: メールの送信ドメインに対応する公開鍵は、DNSテキストレコード(TXTレコード)として公開されます。これにより、受信側は送信側が公開した公開鍵を取得できるようになります。
selector._domainkey.example.com IN TXT "v=DKIM1; k=rsa; p=<public key>"
メールの検証: 受信メールサーバーは、DNSから公開鍵を取得し、メールのDKIM署名を検証します。署名が正しく検証された場合、メールは改ざんされていないと判断されます。
DKIMは、電子メールのセキュリティを強化するために使用される技術です。送信者がメール内容を保護し、受信側がそのメールが正当であることを確認できるようにします。この技術は、メールの送信者を確認し、スパムやフィッシング攻撃から身を守る上で役立ちます。
前提条件
Postfixの構築が完了していることを前提とします。
AlmaLinux9.2環境で検証しています。
OpenDKIM の導入
OpenDKIM は、送信メールサーバーにDKIM署名機能を追加するために使用されるオープンソースソフトウェアです。主な機能として以下があります。
- メールのDKIM署名
- DKIM署名の検証
OpenDKIMは、標準のMTA(Mail Transfer Agent)プロトコル(たとえばPostfixやSendmailなど)と連携し、メールの送信時に自動的にDKIM署名を行います。また、受信側ではOpenDKIMを使ってメールのDKIM署名を検証できます。
セットアップの手順
必要なソフトウェアのインストール
almalinux-crb.repo を有効にしておけば、yumで普通にインストールできるかと思います。
dnf config-manager --set-enabled crb
dnf repolist --all | grep crb
crb AlmaLinux 9 - CRB enabled
crb-debuginfo AlmaLinux 9 - CRB - Debug disabled
crb-source AlmaLinux 9 - CRB - Source disabled
sudo yum install epel-release
sudo yum install opendkim opendkim-tools
libmilter.so の依存関係のエラーがでたら sendmail-milter をインストールします。
リポジトリに無い場合は、RPMパッケージをダウンロードしてきて手動でインストールします。
wget https://repo.almalinux.org/almalinux/9/CRB/x86_64/os/Packages/sendmail-milter-8.16.1-10.el9.x86_64.rpm
rpm -ql sendmail-milter-8.16.1-10.el9.x86_64.rpm | grep libmilter.so
/usr/lib64/libmilter.so.1.0
/usr/lib64/libmilter.so.1.0.1
sudo rpm -Uvh sendmail-milter-8.16.1-10.el9.x86_64.rpm
rpm -qa | grep sendmail-milter
sendmail-milter-8.16.1-10.el9.x86_64
設定ファイルの編集
OpenDKIMの設定ファイル(/etc/opendkim.conf
など)を編集し、必要な設定を行います。
sudo vi /etc/opendkim.conf
設定ファイルを以下のように変更してください。
デフォルト値のものは省略しています。
Domain your_domain
#Canonicalization relaxed/relaxed
Canonicalization relaxed/simple
ExternalIgnoreList refile:/etc/opendkim/TrustedHosts
InternalHosts refile:/etc/opendkim/TrustedHosts
KeyTable refile:/etc/opendkim/KeyTable
SigningTable refile:/etc/opendkim/SigningTable
#Mode v
Mode sv
PidFile /var/run/opendkim/opendkim.pid
Socket inet:8891@localhost
#OversignHeaders From
SignHeaders Date,From,To,Subject,Message-ID
# 転送メール目的
On-BadSignature accept
RemoveOldSignatures no
#PreserveExistingSignature no
設定オプションについて
分かりにくいオプションのみ説明します。
Canonicalization オプション
OpenDKIM が DKIM 署名を作成および検証する際に使用する正規化アルゴリズムを指定します。正規化とは、メールのヘッダーや本文を特定の形式に変換することで、署名プロセス中に一貫したデータ表現を保証します。Canonicalization
オプションでは、ヘッダー(Header)と本文(Body)の正規化アルゴリズムをそれぞれ設定できます。主に次の2種類の正規化アルゴリズムが利用できます。Canonicalization relaxed/simple
の場合は、ヘッダーにrelaxed
本文にsimple
を摘要します。
simple
simple
正規化アルゴリズムでは、元のメールデータに対して最小限の変更しか加えません。ヘッダーの場合、行末の空白や改行が削除され、連続する複数のヘッダーフィールドが1つにまとめられます。本文の場合、空白行が削除されます。
Line 1.
Line 2.
Line 3.
正規化後
Line 1.
Line 2.
Line 3.
relaxed
relaxed
正規化アルゴリズムでは、メールデータの空白文字がより多く処理されます。ヘッダーの場合、すべての空白文字が連続する1つのスペースに置き換えられ、行末の空白や改行が削除されます。本文の場合、連続する空白文字が1つのスペースに置き換えられ、空白行が削除されます。
From:Joe <joe@example.com>
Subject: Important email!
正規化後
from:joe <joe@example.com>
subject:Important email!
Canonicalization
の設定をrelaxed/simple
にすると、次のようなメリットがあります。
- ヘッダーの柔軟性:ヘッダーの正規化では、
relaxed
を使用するため、ヘッダーフィールド内のわずかな違いや空白の違いを無視します。これにより、メールクライアント間でヘッダーが変更されることに対処できます。 - メール本文の厳格さ:一方、
simple
アルゴリズムはメール本文の正規化に使われます。これにより、メール本文が厳密な仕様に従っており、変更されていないことが確認できます。
このオプションは、ヘッダーの柔軟性とメール本文の厳格さが求められる場合に適しています。ただし、relaxed/simple
設定を使用すると、メール本文が異なるメールクライアントやサービス間で変更される可能性があり、署名が無効になるリスクが高まります。そのため、この設定は特定のニーズや要件に応じて選択する必要があります。
ExternalIgnoreList オプション
どの外部ソースからのメールを署名プロセスから除外するかを指定します。このリストに含まれる送信者ドメインのメールには、署名が追加されず、検証も実行されません。
ExternalIgnoreList /etc/opendkim/TrustedHosts
上記の例では、/etc/opendkim/TrustedHosts
ファイルにリストされたホストが、無視される外部ソースとして認識されます。
InternalHosts オプション
独自ドメインからの送信を許可する内部ホストのリストを指定します。このリストに含まれるホストからのメールは署名されます。
InternalHosts /etc/opendkim/TrustedHosts
上記の例では、/etc/opendkim/TrustedHosts
ファイルにリストされたホストが、署名される内部ホストとして認識されます。
KeyTable オプション
DomainKeys Identified Mail (DKIM)の署名キーをドメインとセレクタにマッピングするために使用されます。このオプションは、 DKIM署名プロセス中にどのキーが選択されるかを決定するのに役立ちます。
/etc/opendkim/keytable
ファイルの内容の例
default._domainkey.example.com example.com:default:/etc/opendkim/keys/example.com/default.private
このエントリは以下の情報を提供します。
default._domainkey.example.com
: 使用する セレクタ(default
)と ドメイン名(example.com
)example.com
: ドメイン名default
: セレクタ名/etc/opendkim/keys/example.com/default.private
: 署名キーのプライベートキーへのパス
SigningTable
どのドメインおよびアドレスがどのキーテーブルエントリを使用して署名されるかを指定します。これにより、送信者のアドレスに基づいて適切な DKIM 署名を選択することができます。
例: /etc/opendkim.conf
の中で SigningTable オプションを設定する方法
SigningTable refile:/etc/opendkim/SigningTable
この設定は、/etc/opendkim/SigningTable
という名前のファイルを参照して署名テーブルをロードするように指示します。refile:
は正規表現ベースのファイルを意味します。
/etc/opendkim/SigningTable
ファイルの内容の例:
*@example.com default._domainkey.example.com
このエントリは以下の情報を提供します。
*@example.com
: example.com ドメインからのすべてのメールアドレスdefault._domainkey.example.com
: 使用するセレクタ(default
)とドメイン名(example.com
)
SigningTable
の設定により、送信者アドレスが example.com
ドメインの場合、上記でリンクした KeyTable
エントリのキーを使用してメールが署名されます。
VirtualDomain で複数ドメインを引用したり、転送メールで不特定のドメインを扱う場合は、全ての鍵セットを用意するのが難しい場合は、以下のようにワイルドカードで署名してしまう方法もあります。
* default._domainkey.example.com
Mode オプション
OpenDKIM の動作モードを設定します。主に2つのモードがあります。
v – Verify(検証)
このモードでは、OpenDKIM は受信したメールに対して DKIM 署名の検証を行います。メールが正当な署名を持っているかどうかを確認し、結果をメールヘッダーに追加することで、他のメールサービスやクライアントがスパム判定の参考情報として利用できます。
s – Sign(署名)
署名モードでは、送信されるメールに対して DKIM 署名を付与します。これにより、受信側で DKIM 検証が可能になり、メールの信頼性が向上します。
sv – Sign and Verify(署名と検証)
sv
モードでは、OpenDKIM は受信メールの検証および送信メールの署名の両方を行います。このモードを使用することで、受信メールの DKIM 検証と、送信メールに DKIM 署名を付与する機能を同時に実行できます。
Socket オプション
OpenDKIM daemon が接続を受け入れるために使用するソケットの場所を指定します。AlmaLinux9.2 を使用している場合、inet(ネットワーク)ソケットまたは Unix(ローカル)ソケットのいずれかを設定できます。
inet ソケットの設定
通常、Postfix MTA(Mail Transfer Agent)と共に OpenDKIM を使用する場合、inet ソケットを使用して通信します。/etc/opendkim.conf
ファイルでこの設定を行うには、以下のような行を追加します。
Socket inet:8891@localhost
この設定では、ポート番号 8891
で localhost
上の inet ソケットを使用して OpenDKIM が接続を受け入れるように指示しています。さらに、Postfix の主設定ファイル /etc/postfix/main.cf
にも、opendkim との通信方法を追加する必要があります。
smtpd_milters = inet:localhost:8891
non_smtpd_milters = inet:localhost:8891
OpenDKIM で推奨される Socket
のポート番号はありませんが、一般的に使われるポート番号は 8891
です。これは他の一般的なサービスと競合しない範囲であり、ほとんどのセットアップで問題なく動作します。
ただし、使用しているシステムやネットワークの状況に応じて、異なるポート番号を選択することも可能です。その場合は、1024
から 65535
の範囲内で、既存のサービスと競合しないポート番号を選択してください。
Unix ソケットの設定
Unix ソケットを使用する場合は、/etc/opendkim.conf
ファイルで次のように設定できます。
Socket local:/var/run/opendkim/opendkim.sock
この設定では、/var/run/opendkim/opendkim.sock
というパスで Unix ソケットを使用して OpenDKIM が接続を受け入れるように指示しています。Postfix の主設定ファイル /etc/postfix/main.cf
でも opendkim との通信方法を追加する必要があります。
smtpd_milters = unix:/var/run/opendkim/opendkim.sock
non_smtpd_milters = unix:/var/run/opendkim/opendkim.sock
変更を適用した後、OpenDKIM と Postfix サービスを再起動して設定を有効にします。
SignHeaders
SignHeaders Date,From,To,Subject,Message-ID
この設定では、Date
、From
、To
、Subject
、および Message-ID
の5つのヘッダーが署名対象となります。
注意: ヘッダーリストをカスタマイズする際は、RFC 6376 によって推奨されているヘッダーや、通常メール配送に必要なヘッダーを含めるように注意してください。一部の重要なヘッダーを省略することで、受信者側でDKIM検証が失敗したり、メールが正しく表示されなくなる恐れがあります。
DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=example.net; s=default; t=1686714708; bh=C03Eedg6ydYEfmB7DmRDcLHGocW2c83LpfE8bdVNBXQ=; h=Date:From:To:Subject:Message-ID; b=hwapHyoIt/9PnC0o+1lkszGP4YG+Ewgqxv9FVKMpgeNI1pKbYobSAuqv3rYAViZrf
5nj3LRrZRyJw6nMuOvp1qTnYm+dD2fRpeImLRZ0KzYCW66AE9ft/RwWI/xvMSxIGFH
RqFGEU9+PF/JY4zmvEed8MNdLFV84iamqyWXxKbN08SzT+nlHKk/XiPE7mLe5gWSqJ
6D6fgu8V0O7J7p/pXu+8RGK7leVjHbrL3CHWrqlxGsIgmCpq6LOzXYjCNj+PselmJ9
tkC0ZidEMeYGFLiCaND7WwnWMxxPD79XrmSoIYJO4Z7BCIavJGcTWoBEMh9nUiv8/E
i3nTIFsSZvg4w==
受信メールのDKIM-Signatureヘッダー内の h=Date:From:To:Subject:Message-ID を確認することで、どのヘッダーが署名対象化確認できます。
On-BadSignature オプション
転送メールに DKIM 署名を追加する際、送信元ドメインが不定の場合でも署名プロセスが正常に動作するようにします。
元のメールに既に DKIM 署名がある場合、その署名が失敗してしまう問題を解消するために、 /etc/opendkim.conf
設定ファイルで On-BadSignature
を accept
に設定します。
これにより、元のメールの DKIM 署名が無効または壊れている場合でも、新しい署名をメールに追加できます。
RemoveOldSignatures オプション
既存の DKIM 署名がメールから削除されないようにするために、RemoveOldSignatures
を no
に設定します。
強制的に再署名する場合は yes
に設定します。
On-BadSignature と RemoveOldSignatures の設定により、送信元ドメインが不定でも、転送時に新しい DKIM 署名が正しく追加されるはずです。
DKIM署名は/etc/opendkim/TrustedHostsで許可されたIPからのメールにしか署名を行いません。
強制的に転送メールに DKIM再署名を行うには、0.0.0.0/0 のように全て許可するようにする必要があります。
強制再署名するには、更に /etc/opendkim/SigningTable で ワイルドカードで特定の証明書にマッチさせる必要があります。
Postfix と OpenDKIM の連携
Postfix の設定ファイル /etc/postfix/main.cf
を編集して、OpenDKIM と連携させます。
sudo vi /etc/postfix/main.cf
設定ファイルの末尾に以下の行を追加します。
milter_default_action = accept
milter_protocol = 6
smtpd_milters = inet:localhost:8891
non_smtpd_milters = inet:localhost:8891
OpenDKIM のディレクトリとファイルの作成
必要なディレクトリとファイルを作成し、アクセス権限を設定します。
※パッケージをインストールした時点で作成されているかと思います。
sudo mkdir /etc/opendkim
sudo chown opendkim:opendkim /etc/opendkim
sudo mkdir /etc/opendkim/keys
sudo chown opendkim:opendkim /etc/opendkim/keys
sudo touch /etc/opendkim/SigningTable
sudo touch /etc/opendkim/KeyTable
sudo touch /etc/opendkim/TrustedHosts
sudo chown opendkim:opendkim /etc/opendkim/{KeyTable,SigningTable,TrustedHosts}
信頼できるホスト(TrustedHosts)の設定
/etc/opendkim/TrustedHosts
ファイルを編集し、信頼できるホスト(ローカルホストおよびドメインサブネット)を追加します。
sudo vi /etc/opendkim/TrustedHosts
以下の内容をファイルに追加します。
127.0.0.1
localhost
::1
*.<your_domain>
<your_domain>
を実際のドメイン名に置き換えます。
Gmail等にメールを転送するような場合、不特定多数の送信元IPに対して強制DKIM再署名を行うため 0.0.0.0/0 のように全てのIPを許可する必要があります。
転送で拒否されるのを回避する手段は、DKIM以外にもSPFのSRS等もあります。
DKIM 鍵ペアの生成
ドメインごとに DKIM 鍵ペアを生成します。<selector>
は任意の文字列ですが、一般的に default
や mail
などを使います。
まず、キーディレクトリを作成します。
sudo -u opendkim mkdir -p /etc/opendkim/keys/<your_domain>
次に、鍵ペアを生成します。
sudo -u opendkim opendkim-genkey -b 2048 -d <your_domain> -D /etc/opendkim/keys/<your_domain> -s <selector> -v
このようなファイルが作成されます。
-rw------- 1 opendkim opendkim 1708 6月 12 19:04 default.private
-rw------- 1 opendkim opendkim 500 6月 12 19:04 default.txt
KeyTable と SigningTable の設定
ドメインとその署名鍵に関する情報を保持しています。KeyTableファイルは、各ドメインごとにどのセレクタと秘密鍵ファイルを使用するかを指定します。<selector>
は任意の文字列ですが、一般的に default
や mail
などを使います。
<selector>._domainkey.<your_domain> <your_domain>:<selector>:/etc/opendkim/keys/<your_domain>/<selector>.private
<selector>._domainkey.example.com
は、公開鍵レコードが保存されるDNSのテキスト(TXT)レコードです。<your_domain>
は、署名対象となるドメインです。<selector>
は、鍵ペアを識別するための名前です。/etc/opendkim/keys/<your_domain>/<selector>.private
は、秘密鍵ファイルへのパスです。
/etc/opendkim/keytable
ファイルを編集
sudo vi /etc/opendkim/KeyTable
以下の行を追加し、<selector>
と <your_domain>
を実際の値に置き換えて、以下の行を追加します。
<selector>._domainkey.<your_domain> <your_domain>:<selector>:/etc/opendkim/keys/<your_domain>/<selector>.private
/etc/opendkim/SigningTable
ファイルの編集
sudo vi /etc/opendkim/SigningTable
以下の行を追加し、<selector> , <your_domain>
を実際の値に置き換えます。
*@<your_domain> <selector>._domainkey.<your_domain>
DNSに公開鍵を追加する
生成された公開鍵を DNS TXT レコードに追加する必要があります。/etc/opendkim/keys/<your_domain>/<selector>.txt
ファイルに記載されている内容を確認します。
sudo cat /etc/opendkim/keys/<your_domain>/<selector>.txt
出力されたレコードをドメインの DNS 設定に追加します。TXT レコード名は <selector>._domainkey
で、値はファイルの内容を使用します(括弧や改行なし)。
例:
default._domainkey IN TXT "v=DKIM1; k=rsa;""p=MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA0GCczxhT+nmdkQcmyhnCF3aZzGBK4N9+Nmuqm5L3nllXSUwwZdHmPThsqiBujLKoiMSZzc""zdh4zvvgJxlm+Z/mqjr8AZ67RTaserdvUkaJDMlJFdJGJkhooAm+DrKPbCDHVf9exg/+JpmuLwLUOyKXRp2F74xL0XTl6glgBT""GuhPEwufLY/CMC+NVhQ0PguYAuOJJz8didQkWa15jpYWQjfUq5xrU7D9JLL3ElBQ+sQ9r+c1RxTqrmoXjjnkZFPvQKhR4qzzNf""7EAd/kZC73H36fQUS5wu1dDm1dt945J/0FiGf0EDbFzPD5U/VwgUFpzh8nwNkGQmJz9rClRUKgCQIDAQAB"
これで、default._domainkey
に正しく長いDKIMレコードが登録されます。
OpenDKIM と Postfix の再起動
設定が完了したら、OpenDKIM と Postfix サービスを再起動して変更を適用します。
sudo systemctl restart opendkim
sudo systemctl restart postfix
以上で、Postfix 環境で DKIM を導入するための手順が完了しました。
OpenDKIMは、電子メールの送信側でのDKIM署名および受信側での検証を実現するオープンソースソフトウェアです。このツールを使って、メールサーバーにDKIM機能を追加し、メールのセキュリティを向上させることができます。