個別機能のmilterを一掃してRspamdを活用

これまでmilterにまみれていたpostfixだが、Rspamdを1.9.0に更新したついでにRspamdにある機能はRspamdに移すことにした。

この記事のファイルのPathはFreeBSDのシステムやpkg/portsパッケージに倣っている。

ウイルス検知 ClamAV

これまでclamav-milterを使用していたが、RspamdでもClamAVと連携できるのでそちらを使うことにした。

/usr/local/etc/rspamd/local.d/antivirus.conf
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
#enabled = false;     #無効ならこれだった。この行はもう要らない。

clamav {
    action = "reject";
    message = '${SCANNER}: virus found: "${VIRUS}"';
    log_clean = true;
    scan_mime_parts = true;      #旧verのattachments_onlyの代わり
    max_size = 256000;
    servers = "/var/run/clamav/clamd.sock";
}

DKIM

DKIM署名を作る
# mkdir /var/db/rspamd/dkim
# rspamadm dkim_keygen -d example.com -s rsa201903 -b 2048 -k /var/db/rspamd/dkim/example.com.rsa201903.key > /var/db/rspamd/dkim/example.com.rsa201903.pub
RSAで電子署名を作成する場合。こちらは必須。
# mkdir /var/db/rspamd/dkim
# rspamadm dkim_keygen -d example.com -s eddsa201903 -b 2048 -t ed25519 -k /var/db/rspamd/dkim/example.com.eddsa201903.key > /var/db/rspamd/dkim/example.com.eddsa201903.pub
Ed25519で電子署名を作成する場合。こちらは任意。Ed25519だと公開鍵が短くそれでいて強度が高めなので理想的だが他所が非対応ということが多くてEd25519のみというのは非現実的。RSAのみかRSA + Ed25519にする。フォールバックを有効にすることでRSA + Ed25519の両方を登録できる。

上の例の201903の部分はセレクタで任意の文字列を指定する。この例では毎月変更する運用を予定していて2019年3月用という意味のつもり。 これで、/var/db/rspamd/dkimにexample.com.201903.pubとexample.com.201903.keyの2つのファイルが作成される。 Rspamdに登録するのはexample.com.201903.keyの方。
example.com.201903.pubの内容をDNSのexample.com用ゾーンファイルに書く。DNSがBINDならそのままコピペでOK.もちろん、気に入る書き方に変更するのも可。RSAで1024bit以上を指定すると公開鍵が255文字を超えるので避けたいところだが1024bitでは弱い。そこで-t ed25519を指定してRSAではなくEd25519にしている。こちらはとても短い公開鍵なのでDNSのTXTレコードの長さも余裕。


/usr/local/etc/rspamd/local.d/dkim_signing.conf (新規)
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
allow_envfrom_empty = true;
allow_hdrfrom_mismatch = true;
allow_hdrfrom_mismatch_sign_networks = true;
allow_username_mismatch = true;
use_domain = "header";
use_esld = true;
sign_local = true;
use_redis = false;

domain {
    example.com {
        selector = "rsa201903";
        path = "/var/db/rspamd/dkim/example.com.rsa201903.key";
    }
}
ドメインが複数あってセレクタの文字列が単純な複数ドメインで共通するものでないならこんな感じ。(ドメイン1つしか書いてないけど)
Ed25519の署名と両方使うなら上の例の9行目以降を以下のようなのと差し替え。
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
try_fallback = true;

domain {
    example.com {
        selectors [
            {
                path: "/var/db/rspamd/dkim/example.com.rsa201903.key";
                selector: "rsa201903";
            },
            {
                path: "/var/db/rspamd/dkim/example.com.eddsa201903.key";
                selector: "eddsa201903";
            }
        ]
    }
}
これもドメイン1つしか書いてないけど複数書けるというのはわかる筈。

DKIMのためのDNSの設定

先に作成した電子署名の公開鍵のファイル /var/db/rspamd/dkim/example.com.rsa201903.pub (と /var/db/rspamd/dkim/example.com.eddsa201903.pubの中身を全てDNSのゾーンファイルにコピペする。一応BIND用になっているので違う種類のDNSサーバなら修正が要るかも。括弧を使った複数行設定なので大抵は問題ない筈だけど、古いシステムと通信した場合に問題が発生することも。(なので公開鍵の文字列が短いEd25519が良いんだけどまだ普及していないのでEd25519だけにするのは無理)
RSAで1024bitまでにするとDNSのTXTレコード255文字問題は回避できるかもだけど強度が低いし。
シリアルを増やすのを忘れずに、ゾーンファイルを保存して rndc reload または何かしてDNSの設定をリロードするか再起動するか。

DMARC

DMARCはDNSで宣言するのでDNSへの設定追加が必要。Rspamdの方は受信したときの指定とレポート送信を設定する。

/usr/local/etc/rspamd/local.d/dmarc.conf
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
reporting = true;
actions = {
    quarantine = "add_header";
    reject = "reject";
}

send_reports = true;
report_settings {
    org_name = "EXAMPLE.COM";
    domain = "example.com";
    email = "postmaster@example.com";
}

関連記事:
いまさらだけど遅すぎというほどでもないDMARC 導入編
いまさらだけど遅すぎというほどでもないDMARC レポート編1

メールヘッダの情報表示追加

Rspamdは受信したメールにメールのスパム判定について記載してくれるが、その設定。
特に「送信ドメイン認証」関係は初期値では非表示(または判りにくい)なので「導入したけど機能しているのかしら?」にならないよう表示設定する。逆に、迷惑メールの判定根拠を含めてこの手の結果は利用者には見せないという方針なら非表示にするのもアリ。

/etc/rspamd/local.d/milter_headers.conf
1
2
3
4
extended_spam_headers = true;
skip_local = true;
authenticated_headers = ["authentication-results"];
use = ["authentication-results", "x-spam-status"];

こんな感じ。1,2行目はこの記事的にはどうでも良い。しかも2行目は初期値なので書く必要すらない。4行目のx-spam-statusもこの記事的には不要だが、書き方の例として。

Postfixの設定変更

/usr/local/etc/postfix/main.cf (Milter部分 変更前)
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
#Milter
milter_default_action = accept
milter_mail_macros =  i {mail_addr} {client_addr} {client_name} {auth_authen}
milter_protocol = 6

smtpd_milters =
    unix:/var/run/opendkim/dkim.sock      #DKIM
    unix:/var/run/opendmarc/dmarc.sock    #DMARC
    unix:/var/run/clamav/clmilter.sock    #ClamAV
    unix:/var/run/rspamd/rspamd.sock      #Rspamd

non_smtpd_milters =
    unix:/var/run/opendkim/dkim.sock
    unix:/var/run/opendmarc/dmarc.sock
    unix:/var/run/clamav/clmilter.sock
    unix:/var/run/rspamd/rspamd.sock

/usr/local/etc/postfix/main.cf (Milter部分 変更後)
1
2
3
4
5
6
#Milter
milter_default_action = accept
milter_mail_macros = i {mail_addr} {client_addr} {client_name} {auth_authen}
milter_protocol = 6
smtpd_milters = unix:/var/run/rspamd/rspamd.sock
non_smtpd_milters = unix:/var/run/rspamd/rspamd.sock

基本的にはmain.cfの変更だが、master.cfに関連する設定を書いている場合はそれも忘れずに削除する。個人的なことだが、今回ClamAVでもDKIMでもDMARCでもない以前に使っていたmilterの関連設定が残っていたためにDKIM署名が機能しなくて非常に苦労した。(smtpd_milters= というのが残っていた)

サービスの停止・再起動・再読込

# service clamav-milter stop   #ClamAV-milterは停める
# service dkimproxy_out stop   #DKIM署名用milterは停める
# service milter-opendkim stop #DKIM受信判定用Milterは停める
# service opendmarc stop       #DMARCのmilterは停める
# service postfix reload       #Postfix設定再読込 またはrestartで
# service rspamd restart       #Rspamd再起動

届いたメールのヘッダを確認する

Authentication-Results: mx.example.com;
dkim=pass header.d=example.net header.s=abc12345 header.b=vwxyz;
dmarc=pass (policy=none) header.from=example.net;
spf=pass (mx.example.com: domain of hoge@example.net designates 192.168.0.250 as permitted sender) smtp.mailfrom=hoge@example.net

X-Spamd-Result: default: False [-5.21 / 10.00];
JUST_EICAR(0.00)[Eicar-Test-Signature];

送信ドメイン認証の結果がAuthentication-Resultsの項目に纏められて表示されるのでわかり易い。
今回ウイルスとしてEicar(ウイルスの代替として使われることが決まっている文字列)を利用したが、Rspamdはアタマが良いのか悪いのか、Eicarを認識するも無害として扱われてしまった。迷惑メールとしてもゼロ点扱い。Eicarはウイルス検知の挙動を確認するためのものだからこれは逆に良くないんじゃないかしら?


Rspamdのログを確認した。
2019-03-25 16:08:44 #9198(normal) ; lua; common.lua:90: clamav: virus found: "Eicar-Test-Signature - score: 1"

こちらはvirus foundになっているので(ClamAVがそう判断してるんだけど)、これでOK。

これまではPostfixに個別の機能のmilterを継ぎ足し継ぎ足しして何がなんだかわかりにくい状態になっていたが、全てRspamdに纏めたのでPostfix側はスッキリ。まぁ、SPFなど一部は既にRspamdに移ってたので言うほど個別機能が多かった訳ではないけど、設定して数年もすると設定した本人も忘れちゃうのよね。再び何がどうなっているのか理解するまでが大変。
継ぎ足し継ぎ足しは秘伝のタレだけで良い。

問題はRspamdが理解できる範囲を超えて肥大しすぎてて・・ワカラナイ

関連記事: