Linux/opendkim のインストール

opendkimを使ったDKIMの設定(2016-12-01、更新:2017-03-21)


(※ここにある情報は古いです。CentOS Stream8での手順 を別途メモしています)


DKIMを使うために、opendkimを導入します。
opendkim の導入と、それに対応する設定をDNS に実施することで
送受信するメールの信頼性を上げるのが目的です。



注意:OpenSSL 1.1.0 について

opendkim-2.10.3 時点では、OpenSSL 1.1.0 には未対応でした。
対応を待った方が良いと思います。

と、思ったんですが、2018/08 現在は2.10.3 のままなので
openssl1.1.0以降を使ってしまっている場合は、少し別の手も考えたほうが良さそうです。
(configure時に --with-openssl で指定する、だけでは足りない場合の対応例

既存の opendkim の確認

まず、入っているかどうかの確認から。
既存のバージョンで満足するならば、yum install 等でよろしいかと。

 # opendkim -V
 # yum info opendkim

新たにソースからビルドしたい場合は、パッケージの方は一旦削りましょう

取得とインストール

まず、例によってソースコードの取得から。
Google:linux opendkim で検索して、ソースのダウンロード先を見つけます。
www.opendkim.org (からリンクしているsourceforge)で落とせるようです。

# cd 任意のディレクトリ
# wget https://sourceforge.net/projects/opendkim/files/latest/download?source=files
(もしファイル名がdownload?source=filesになっちゃったら、opendkim.tar.gzにリネームしましょう)
# md5sum opendkim-2.10.3.tar.gz
(ここで sourceforge.net にあるMD5ファイルと比べること)
# tar zxvf opendkim-2.10.3.tar.gz 

展開先で make します。
・・・が、先に言うと、今回は./configure で以下のように失敗しました。

configure: error: no strlcpy/strlcat found
configure: error: milter not found

よって、今回はyumで以下を追加しました*1

# yum install libbsd-devel
# yum install sendmail-milter
# yum install sendmail-devel

これで必要なものが揃って、ようやく makeです。
configure のオプションはお好みで。domain は変えてください。

# ./configure --sysconfdir=/etc/opendkim --prefix=/usr/local --localstatedir=/var --with-domain=null-i.net
# make
# make install

※なお、前述の通り、OpenDKIM/OpenSSLのバージョン組み合わせによっては失敗します。

そして、ユーザーも conf も何もないので、全部自力で用意します。

# useradd -d /dev/null -s /sbin/nologin opendkim
# mkdir -p /etc/opendkim/keys
# chown -R opendkim:opendkim /etc/opendkim
# mkdir /var/run/opendkim
# chown opendkim:opendkim /var/run/opendkim
# cp ./opendkim/opendkim.conf.sample /etc/opendkim/opendkim.conf
# chown opendkim:opendkim /etc/opendkim/opendkim.conf

さらに、(CentOS 7 の場合)
/var/run を reboot時に消されないようにします。*2
localstatedirをデフォルトのまま /usr/local/var/run にすれば必要ない作業なのかもしれませんが・・

# vi /etc/tmpfiles.d/opendkim.conf
d /var/run/opendkim 0775 opendkim opendkim -

(消されないように、なら d では無くて x が正解かもしれませんが)

設定

署名用の秘密鍵、DNS記載用の公開鍵の作成

# mkdir /etc/opendkim/keys/null-i.net
# cd  /etc/opendkim/keys/null-i.net
# opendkim-genkey -d null-i.net -s select2016 -b 1024
# chown -R opendkim:opendkim ../null-i.net
# ls
  select2016.private  select2016.txt  (秘密鍵と、DNSに書くTXTが生成される)

opendkim-genkey でドメイン名(-d)とセレクタ名(-s)と鍵の長さ(-b)を指定すると、
秘密鍵 private と、DNSに設定する内容 txt が作成されます。
鍵の長さ(-b)は長い方がいいのですが、DNS上の制約や負荷の問題もあるので、各環境に合わせましょう。
ただし、鍵の長さが短すぎるとエラーになります。

短すぎるときのpostfixのログ例:
SSL error:04075070:rsa routines:RSA_sign:digest too big for rsa key

(短いのに「too big」と言われるのが一見すると紛らわしいところ。英語力の問題?)

あとは、
テキストファイル(前述の例では select2016.txt)を参考に、
自分の管理するDNSサーバに DKIM 情報を設定しましょう。

DNSサーバの追加設定

前述のopendkim-genkey で作ったテキストファイルに合わせて設定します。

  select2016._domainkey.ドメイン名.  IN TXT "v=DKIM1; k=rsa; p=公開鍵"
  _adsp._domainkey.ドメイン名.   IN   TXT   "dkim=unknown"

DNSサーバから、設定どおりの情報が拾えればOKです。
_adsp は unknown より厳しく設定できますので、そちらは自分の運用方針に合わせましょう。
設定後もDNSキャッシュが残っていれば、
設定が反映されるまでの間に若干のタイムラグがあるかもしれません。
反映状態の確認例は以下

 # dig _adsp._domainkey.null-i.net  txt
 # dig select2016._domainkey.null-i.net  txt

鍵関連の設定

色々と要るので、手始めに空のファイルを作ります。
/etc/opendkim の場所やドメイン名等、各環境に読み替えてください。

# cd /etc/opendkim
# touch KeyTable SigningTable TrustedHosts
# chown opendkim:opendkim !:*

(一応。「!:*」は、前のコマンドの全ての引数(KeyTable SigningTable TrustedHosts)という意味です)

まず、KeyTable に署名用の秘密鍵を設定

# vi KeyTable
select2016._domainkey.null-i.net null-i.net:select2016:/etc/opendkim/keys/null-i.net/select2016.private

つぎに SigningTableに署名を使うドメイン名を設定

# vi SigningTable
*@null-i.net  select2016._domainkey.null-i.net

さらに TrustedHosts に信頼済みホストを設定。

# vi TrustedHosts
127.0.0.1

これで、config が書けるようになりました。

configの設定例

これらを踏まえ、opendkim.conf を更新します。
更新箇所の例は以下。

AutoRestart             yes
Canonicalization        relaxed/simple
Domain                  null-i.net
ExternalIgnoreList      refile:/etc/opendkim/TrustedHosts
InternalHosts           refile:/etc/opendkim/TrustedHosts
# KeyFile               /var/db/dkim/example.private # コメントアウト
KeyTable                refile:/etc/opendkim/KeyTable
LogWhy          yes
MinimumKeyBits  1024
Mode                    sv
PidFile         /var/run/opendkim/opendkim.pid
ReportAddress           "DKIM Error Postmaster" <root@localhost>
Selector                select2016
SigningTable            refile:/etc/opendkim/SigningTable
Socket                  inet:8891@localhost
TemporaryDirectory      /var/tmp
UMask                   022
UserID          opendkim:opendkim

Canonicalization の厳しさは、お好みで。
LogWhy は 動作確認のために、yes にしています。
MinimumKeyBits は、前述の「鍵の長さ(-b)」の話題に絡みます。
Mode はs(署名者)とv(検証者)を指定してますが、後日再検討の予定。

あとは、起動スクリプトを持ってきて起動します、
が、例として2つ。

その1。init.d 方式。

# cp -i [makeしたPATH]/contrib/init/redhat/opendkim /etc/init.d/
# chmod 755 /etc/init.d/opendkim
# vi /etc/init.d/opendkim
(chkconfig 行 を編集して、開始終了の両方に登録されるようにする。
 例えば 「chkconfig: 2345 ~」とか)
# chkconfig --add opendkim

その2。systemd 方式(CentOS 7)。

# cp -i [makeしたPATH]/contrib/systemd/opendkim.service /usr/lib/systemd/system/
# vi /usr/lib/systemd/system/opendkim.service
(適宜修正。${exec_prefix} とかは正しいPATHに直すこと。
 必要ならカスタマイズ用の /etc/systemd/system/opendkim.service も複製しておく)
# vi /etc/sysconfig/opendkim
 (OPTIONS="-x /etc/opendkim/opendkim.conf" を記載)
# systemctl list-unit-files   # opendkim が増えていることを確認
# systemctl enable opendkim

環境に合わせて、選んでください。

そして、起動します。

# service opendkim start
Starting OpenDKIM Milter: /usr/local/sbin/opendkim:
 error while loading shared libraries:
 libopendkim.so.10: cannot open shared object file: No such file or directory
 (本当は一行ですが、長いので改行してます)

おおぅ・・・ [worried]
気を取り直して。(動的リンカを更新してから)

# ldconfig
(makeで入れたライブラリを反映する)
# service opendkim start
Starting OpenDKIM Milter:                                  [  OK  ]

Postfix の設定

main.cf に以下を追加

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

これは環境に依存しますが、私の場合はpostfix もソースからのビルドなので、
postfix の sendmail と先ほどの sendmail-devel が被ってしまいました。

/var/log/maillog より
warning: /usr/lib/sendmail and /usr/sbin/sendmail differ
warning: Replace one by a symbolic link to the other

どうやら sendmail-devel 足したときに、/usr/lib/sendmailが新たにできてしまった模様です。
(これは リンクのリンクで・・・/usr/sbin/sendmail.sendmail ?)
/usr/sbin/sendmail の方が postfix の sendmail。
どっちか replace しろって言っているので、とりあえず postfix 側を生かすように
リンク削除後に「ln -s /usr/sbin/sendmail /usr/lib/sendmail」になおして、しばらく様子見です。

そして、設定を再読み込み。

# service postfix reload
Reloading postfix:                                         [  OK  ]

結果

DKIMメールの受信先で、メールのヘッダを見てみましょう。
Outlookだとメールのプロパティとかで確認できます。
その中に

Authentication-Results: (中略)dkim=pass (ok);

のような記述があればOK。それ以外で
「dkim=neutral (no sig); 」署名無し、とか
「dkim=permerror (bad sig);」署名エラー、とかになった場合は、
残念ながら、うまくいっていないという事です。*3
postfixのログから何か分かるかもしれません。

これで DKIM 対応はひとまず OK です!


*1 特にmilterに苦戦して、結局 postfixのサイト を参考にしつつ sendmail-devel を入れました。sendmail-devel を yum install したら依存関係で milter も入るようですね。
*2 前述の configureで --localstatedir=/var にしなれけば、要らない作業かもしれません。そこはお好みで。
*3 ・・・具体的な記述例が上がるという事は、私も何度かやらかしたという事です