OpenDKIM

From ArchWiki
Jump to navigation Jump to search

DomainKeys Identified Mail (DKIM) はメールの電子署名・検証技術であり、一般的なメールプロバイダによってサポートされています (Yahoo, Google, Outlook.com など)。

概念

基本的に DKIM はサーバー上の全てのメッセージに電子署名を行って、メッセージが実際にサーバーから送信されたことを確認し、スパムやフィッシングメールでないことを保証します。

  • 送信者のメールサーバーは秘密鍵でメールに署名を行います。
  • メッセージが到着すると、受信者はドメインの DNS から公開鍵をリクエストして署名を検証します。

秘密鍵がドメインの公開鍵と一致していることでサーバーからメッセージが送信されたことが確認できます。

詳しくは RFC 6376 を見てください。

インストール

opendkim パッケージをインストールしてください。

設定

署名サービスのメイン設定ファイルは /etc/opendkim/opendkim.conf です。

  • サンプル設定ファイル /etc/opendkim/opendkim.conf.sample/etc/opendkim/opendkim.conf にコピーして、以下のオプションを変更してください:
/etc/opendkim/opendkim.conf
Domain                  example.com
KeyFile                 /path/to/keys/server1.private
Selector                myselector
Socket                  inet:8891@localhost
UserID                  opendkim
  • 秘密の署名鍵を生成するには、メールを送信するのに使うドメインを指定して、鍵を参照するのに使うセレクタを指定する必要があります。RFC によれば何でもかまいませんが、英数字の文字列が良いでしょう:
$ opendkim-genkey -r -s myselector -d example.com
  • ときどきメールは勝手に改変されることがあり (例えばタブが空白に置き換わるなど)、DKIM の署名が無効になってしまうことがあります。ヘッダーやボディの些細な変更によって署名が破壊されてしまわないように、フォーマットをどれくらい厳格にするか指定するポリシーである Canonicalization が存在します。全く改変が許されない simple と多少の変更は許可される relaxed が利用できます。詳しくは [1] を見てください。ヘッダとボディでそれぞれ別個に設定できます:
/etc/opendkim/opendkim.conf
...
Canonicalization        relaxed/simple
...

上記の場合はヘッダーの改変は許可されますがメッセージのボディは全く変更できません。OpenDKIM のデフォルト設定は simple/simple です。

  • 他にも設定オプションは存在します。ドキュメントを読んでください。

DNS レコード

セレクタと公開鍵を記述した DNS TXT レコードを追加してください。秘密鍵と同じ場所に作成される myselector.txt に適切なレコードが記載されています。

例:

myselector._domainkey   IN	 TXT	"v=DKIM1; k=rsa; s=email; p=...................."

他にも利用可能なスイッチは存在します (RFC4871 を参照)。例えば t=y はテストモードを有効にして、署名の状態に関係なく、メールを署名済みとして扱うように受信者に通達します。

DNS レコードが正しく更新されたことを確認するには:

$ host -t TXT myselector._domainkey.example.com

ウェブ上の DKIM キーチェッカー を使って DKIM の DNS レコードが設定されていることを確認することもできます。

Postfix の統合

以下のどちらかの行を main.cf に追加してください:

non_smtpd_milters=inet:127.0.0.1:8891
smtpd_milters=inet:127.0.0.1:8891

DKIM と DMARC を統合する場合は代わりに以下の行を使ってください (unix ソケットを使用):

 non_smtpd_milters = unix:/run/opendkim/opendkim.sock,
                     unix:/run/opendmarc/dmarc.sock
 smtpd_milters = unix:/run/opendkim/opendkim.sock,
                 unix:/run/opendmarc/dmarc.sock

もしくは master.cf の smtpd オプションを変更してください:

smtp      inet  n       -       n       -       -       smtpd
  -o smtpd_client_connection_count_limit=10
  -o smtpd_milters=inet:127.0.0.1:8891

submission inet n       -       n       -       -       smtpd
  -o smtpd_enforce_tls=no
  -o smtpd_sasl_auth_enable=yes
  -o smtpd_client_restrictions=permit_sasl_authenticated,reject
  -o smtpd_sasl_path=smtpd
  -o cyrus_sasl_config_path=/etc/sasl2
  -o smtpd_milters=inet:127.0.0.1:8891

Sendmail の統合

sendmail.mc ファイルを編集して、FEATURE から始まる行の後に、以下の行を追加してください:

/etc/mail/sendmail.mc
INPUT_MAIL_FILTER(`opendkim', `S=inet:8891@localhost')

次のコマンドで sendmail.cf ファイルを再生成してください:

# m4 /etc/mail/sendmail.mc > /etc/mail/sendmail.cf

その後 sendmail.service を再起動してください。詳しくはデーモンを参照。

マルチドメイン

同一サーバー上に複数の仮想ドメインを提供するメールサーバーサービスを動作させている場合、以下のように設定を編集する必要があります:

/etc/opendkim/opendkim.conf に以下のディレクティブを記述してください:

KeyTable                refile:/etc/opendkim/KeyTable
SigningTable            refile:/etc/opendkim/SigningTable
ExternalIgnoreList      refile:/etc/opendkim/TrustedHosts
InternalHosts           refile:/etc/opendkim/TrustedHosts
ノート: DKIM 鍵はドメインごとのフォルダに作成・移動する必要があります、例: /etc/opendkim/keys/domain1.com/。そうしないと dkim: FAILED, invalid (public key: not available) というエラーメッセージが表示されます。

以下の2つのファイルを作成して opendkim が適切なキーを認識できるようにしてください。全てのドメインで同一のキーを使うことも、ドメインごとにキーを生成することもできます。設定にあわせて変更するようにして、必要な分だけ行を追加してください:

/etc/opendkim/KeyTable
 
myselector._domainkey.example1.com example1.com:myselector:/etc/opendkim/myselector.private
myselector._domainkey.example2.com example2.com:myselector:/etc/opendkim/myselector.private
...
/etc/opendkim/SigningTable
*@example1.com myselector._domainkey.example1.com
*@example2.com myselector._domainkey.example2.com
...

/etc/opendkim/TrustedHosts ファイルは opendkim にキーを使用するユーザーを指定します。設定ファイルの ExternalIgnoreList ディレクティブで参照されます。Opendkim はメールを検証するときにリストに含まれているホストを無視します。そして、InternalHosts ディレクティブによっても参照されるため、同一リストのホストは内部のマシンだと認識され、opendkim はメールに署名を行います。例 (<server_ip> はあなたのサーバーの IP に置き換えてください):

/etc/opendkim/TrustedHosts
127.0.0.1
::1
localhost
<server_ip>
hostname.example1.com
example1.com
hostname.example2.com
example2.com
...

ファイルの所有者を opendkim に変更してください:

# chown -R opendkim:mail /etc/opendkim

各ドメインで DNS TXT レコードを追加してセレクタと公開鍵を指定してください。

その後 opendkim を再起動します。

セキュリティ

セキュリティの観点からすると OpenDKIM デーモンのデフォルト設定はあまりよろしくありません (ただし大きな問題ではありません):

  • OpenDKIM デーモンは root で動作させる必要が全くありません (上の設定では OpenDKIM は root 権限を捨てますが、systemd を使ってさらに早く root 権限を使わないようにできます)。
  • メールデーモンが OpenDKIM デーモンと同一のホスト上にある場合、ローカルホストで TCP ソケットを使用する必要はなく、伝統的なユーザー・グループのアクセス制御ができる Unix ソケットが使用できます。
  • OpenDKIM はデフォルトで /tmp フォルダを使用しますが、別のフォルダにすることでアクセス制限をかけることができます。
ノート: 以下の設定ファイルは単一ドメインでの設定です。

以下の設定ファイルは上記の問題をほとんど解決して systemd サービスユニットの不必要なオプションを削げ落としています (Postfix を使用していることが前提):

/etc/opendkim/opendkim.conf
BaseDirectory           /var/lib/opendkim
Domain                  example.com
KeyFile                 /etc/opendkim/myselector.private
Selector                myselector
Socket                  local:/run/opendkim/opendkim.sock
Syslog                  Yes
TemporaryDirectory      /run/opendkim
UMask                   002
/etc/systemd/system/opendkim.service
[Unit]
Description=OpenDKIM daemon
After=network.target remote-fs.target nss-lookup.target

[Service]
Type=forking
User=opendkim
Group=postfix
ExecStart=/usr/bin/opendkim -x /etc/opendkim/opendkim.conf
RuntimeDirectory=opendkim
RuntimeDirectoryMode=0750

[Install]
WantedBy=multi-user.target

ソケットディレクトリを作成して所有者を設定:

# mkdir /run/opendkim
# chown opendkim:mail /run/opendkim

/etc/postfix/main.cf を編集して Postfix が Unix ソケットを listen するようにしてください:

/etc/postfix/main.cf
smtpd_milters = unix:/run/opendkim/opendkim.sock
non_smtpd_milters = unix:/run/opendkim/opendkim.sock

トラブルシューティング

Error: "milter-reject: END-OF-MESSAGE from localhost"

/etc/postfix/main.cf において Postfix Milter プロトコルが誤って設定されている可能性が高いです:

# Postfix ≥ 2.6
milter_protocol = 6
# 2.3 ≤ Postfix ≤ 2.5
milter_protocol = 2

ノート

スパム対策を行ってサーバーの信頼性をあげたい場合、DNS レコードを追加してメールを送信するサーバーを認証する Sender Policy Framework を見てみてください。

参照