DKIM (DomainKeys Identified Mail) の導入 + 転送メール強制DKIM再署名の実験

あわせて読みたい
「Google社・米国Yahoo社が2024年2月よりメール受信の厳格化」に対応するためのまとめ 【SPF、DKIM、DMA... 迷惑メールや不正行為の対応するための手段として、SPF、DKIM、DMARC等の技術が使われてきました。今までは、比較的容易に対応可能なSPFだけ対応していれば問題なく利用...

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環境で検証しています。

あわせて読みたい
Postfix, PostfixAdmin, Dovecot の導入 (MariaDB連携, SMTP-Auth, Sieve) https://int-design.jp/content/spf-dkim-dmarc-arc-gmail/ Postfixは、オープンソースの高速かつセキュアなSMTPサーバーです。主にメールの送信機能(MTA:Mail Transf...

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

この設定では、DateFromToSubject、および 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機能を追加し、メールのセキュリティを向上させることができます。

よかったらシェアしてね!
  • URLをコピーしました!
  • URLをコピーしました!
目次