モダンな qmail 構築

昨今のメール事情に合わせ,今年度より DKIM, SPF を受信・送信側ともに導入し, SpamAssasssin による迷惑メールフィルタも取り入れた.


今年度は試行錯誤しながらの導入となったため,最適な手順ではない. 来年度以降は SPF, DKIM パッチあて後に SpamAssassin 導入とするのが 良いだろう.

1. SPF, DKIM 導入

https://www.saout.de/misc/spf/ ここから qmail-spf-rc5.patch を持ってくる.

# cd /usr/local/src
# wget https://www.saout.de/misc/spf/qmail-spf-rc5.patch

https://sourceforge.net/projects/indimail/files/netqmail-addons/qmail-dkim-1.0/ ここから dkim-netqmail-1.06.patch-1.48.gz を持ってくる.

# cd /usr/local/src
# wget https://sourceforge.net/projects/indimail/files/netqmail-addons/qmail-dkim-1.0/dkim-netqmail-1.06.patch-1.48.gz
# gunzip dkim-netqmail-1.06.patch-1.48.gz

いろいろなパッチを当てて netqmail をビルドしなおす. これが大変で,どこかで必ずコンフリクトが起こる. 今年度は *.rej を見て手動でパッチあてを行った. また,そのまま make は通らないため,Makefile など一部修正が必要. 来年度以降は WWW サーバに保存したパッチあて済みのもの (~epmail/y2024/dvlop/src/netqmail-spf-dkim-authhdr-patched.tar.gz として置いた) を使用されたい.

# systemctl stop qmail
# cd /usr/local/src
# tar zxvf netqmail-1.06.tar.gz
# cp -r netqmail-1.06 netqmail-spf-dkim-patched
# cd netqmail-spf-dkim-patched
# cp ../qmail-smtpd-auth-0.31/README.auth .
# cp ../qmail-smtpd-auth-0.31/base64.c .
# cp ../qmail-smtpd-auth-0.31/base64.h .
# cd ../qmail-smtpd-auth-0.31
# patch -d ../netqmail-spf-dkim-patched < auth.patch
# cd ../netqmail-spf-dkim-patched
# patch -p1 < ../qmail-103.patch
# patch -p1 < ../qmail-date-localtime.patch
# patch -p1 < ../qmail-smtpd-relay-reject
# patch -p1 < ../qmail-1.03-realrcptto-2006.12.10.patch
   ## 一部パッチあてが失敗する.*.rej を見ながら手動で書き換える.
# patch -p1 < ../qmail-spf-rc5.patch
   ## 一部パッチあてが失敗する.*.rej を見ながら手動で書き換える.
# patch -p1 < ../dkim-netqmail-1.06.patch-1.48
   ## 一部パッチあてが失敗する.すでに存在するファイルを生成する
   ## 警告には n と打鍵し,パッチの該当箇所を見ながら手動で書き換える.
   ## その他失敗箇所も *.rej を見ながら手動で書き換える.

Authentication-Results ヘッダを付加する. Andreas Gerstlauer 氏のコード を見て,手で dkim.h, dkimverify.cpp, qmail-dkim.c, qmail-queue.c, qmail-smtpd.c, spf.c, spfquery.c を編集. また,qmail-queue.c に #include "stralloc.h" を追加.

# vim Makefile
   ## そのまま make しても失敗した.Makefile を修正する.
   ## surblfilter: ターゲットの依存リストに strsalloc.o を追記.
   ## it: ターゲットの依存リストの +binm3 を binm3 に修正.
   ## qmail-queue: ターゲットの依存リストに env.o control.o 
   ## stralloc.a getln.o scan_ulong.o getln2.o byte_chr.o env.a 
   ## str_diffn.o str_cpy.o open_read.o alloc_re.o を追記.
   ## あと,どのファイルか忘れてしまったが,u_long を unsigned long に念のため修正.
   ## 何かのファイルの (おそらく) タイポを確認.
   ## (こちらはコンフリクトでパッチが失敗していたので修正不要)
# make man
# make
# make setup check
# cp spfquery /var/qmail/bin
   ## なぜかインストールされないので手動コピー
# chown root:qmail /var/qmail/bin/spfquery

繰り返すが,これは苦行なので来年度以降は上記の手順はすべて無視し, WWW サーバ上のパッチあて済み netqmail を取得し,make することを 推奨する.

まずは SPF の設定をしていく. 外部から 専攻ネットワーク宛のメールはすべて HINES ゲートウェイを 経由する.しかし,HINES メールゲートでは SRS (Sender Rewriting Scheme) は 導入されていないため,SPF 検証する MAIL FROM と 接続元 IP は必ず 不整合となる.

そこで,試験的導入として,直前に HINES ゲートを経由していない受信メールにのみ Received-SPF ヘッダを付加するように設定する. SRS が導入されたら,全メールに対してヘッダ付加するように設定を変更すること.

# vim /var/qmail/control/spfbehavior

以下のように書く. SPFBEHAVIOR は,0 なら何もしない.1 ならヘッダを付加. その他の値については SPF パッチのページか, man qmail-smtpd を参照.

1
# vim /etc/tcp.smtp

以下のように書き換える. HINES メールゲートからの SMTP 接続については SPF チェックは 行わない.

127.:allow,RELAYCLIENT=""
133.87.1.180:allow,SPFBEHAVIOR="0"
133.87.1.181:allow,SPFBEHAVIOR="0"
...
133.87.1.194:allow,SPFBEHAVIOR="0"
133.87.1.195:allow,SPFBEHAVIOR="0"
# /etc/init.d/qmail cdb

このままでは gate-daily 実行時に list-2-tcp で書き換えられてしまう. そこで,list-2-tcp も修正する (あとでやる) (やった 2025-08-22). list-2-tcp では,gate に登録された GIP を持つ全機器にリレーを許可する. RELAYCLIENT が指定された IP に対しては SPF チェックは行われないため, 実際に Received-SPF ヘッダが挿入されるのは,学内別サーバからの メールのみとなるだろう.

続いて DKIM の設定をしていく. https://notes.sagredo.eu/en/qmail-notes-185/configuring-dkim-for-qmail-92.html のガイドに従って進めていく.

当然ながら DKIM には署名・検証用の鍵ペアが必要であるので これを生成する.

# mkdir /var/qmail/control/domainkeys
# chown -R qmailr:qmail /var/qmail/control/domainkeys
# dknewkey -d ep.sci.hokudai.ac.jp -t rsa -b 2048 rsa-20250816

以下のように鍵が生成される.(秘密鍵の文字列は書き換えている)

Generating rsa DKIM private key keysize=2048, file /var/qmail/control/domainkeys/ep.sci.hokudai.ac.jp/rsa-20250816
Generating rsa DKIM public  key for rsa-20250816.domainkey.ep.sci.hokudai.ac.jp, file /var/qmail/control/domainkeys/ep.sci.hokudai.ac.jp/rsa-20250816.pub, keysize=2048
DKIM Private key for ep.sci.hokudai.ac.jp file /var/qmail/control/domainkeys/ep.sci.hokudai.ac.jp/rsa-20250816
-----BEGIN PRIVATE KEY-----
MIIlqckJADANBQMpkwG9w0BAQEFAASCBKgwggSkAzlWAoIBAQDovbkfEvinoKTG
...
/Mcxq84eN/DjLSWOlpnoEts
-----END PRIVATE KEY-----
-rw-r----- 1 root qmail 1704  8月 16 13:21 /var/qmail/control/domainkeys/ep.sci.hokudai.ac.jp/rsa-20250816
------------------------------------------------------
DKIM TXT record for ep.sci.hokudai.ac.jp with selector=rsa-20250816 file /var/qmail/control/domainkeys/ep.sci.hokudai.ac.jp/rsa-20250816.pub
rsa-20250816._domainkey.ep.sci.hokudai.ac.jp. IN TXT ("v=DKIM1; k=rsa; t=y; p=MII ... xEp" "0YF ... QAB")
-rw-r--r-- 1 root qmail 476  8月 16 13:21 /var/qmail/control/domainkeys/ep.sci.hokudai.ac.jp/rsa-20250816.pub
------------------------------------------------------

上の太字の行 (rsa-20250816._domainkey... から ...QAB") まで) を丸ごと DNS サーバの ep.zone に登録する. これをすることで,メールを受け取った相手が,ep で署名した DKIM を検証できるようになる. ただ,ここで一つ気を付けることは,この鍵はあくまで ep.sci.hokudai.ac.jp ドメイン用のもので, usuzumi.ep.sci.hokudai.ac.jp 名義で署名しても検証失敗になることである. メールをテストする際は,MAIL FROM を ep.sci. ドメインにして実施すること.

$ ssh hoge@yellow.ep.sci.hokudai.ac.jp
yellow:~$ sudo -s
yellow:~hoge# vim /var/cache/bind/ep.zone
   ## 適当な場所に rsa-20250816._domainkey... から ...QAB") まで を貼り付け
   ## DMARC レコードと SPF レコードの間あたりがいいだろう
   ## DKIM 鍵を作り直すたびにここに登録しなおすこと
   ## 編集後はシリアル番号を書式に従って増やすこと
   ## 典型的には yyyymmddNN (NN はその日何度目の編集かを書く)
   ## DKIM のテストがうまくいったら,t=y を消す
yellow:~hoge# rndc reload
yellow:~hoge# rndc reload ep.sci.hokudai.ac.jp
yellow:~hoge# dig @127.0.0.1 TXT rsa-20250816._domainkey.ep.sci.hokudai.ac.jp
   ## 登録テスト
yellow:~hoge# vim ~gate/ipdb/zone/zone.head
   ## gate-daily で上書きされないよう,ゾーンヘッダのひな型にも書いておく.
yellow:~hoge# exit
yellow:~$ exit

gate-toroku-system の zone.head にも反映させたほうがいいかもしれない (後でやる)

最近では,Ed25519-SHA256 の鍵が推奨されている. そこで,RSA-SHA256 のものと別にもう一つ鍵を作り, 二つの DKIM 署名を添付するようにする. いずれ Ed25519 が十分普及したら,Ed25519 の鍵のみを 使用すること.

# dknewkey -d ep.sci.hokudai.ac.jp -t ed25519 ed-20250816

RSA 鍵と同様に ep.zone や zone.head に登録すること.

qmail-remote で DKIM 署名するための rc スクリプトを書く. sagredo 氏のスクリプトをお借りし,ep 用に修正.

# vim /var/qmail/rc
#!/bin/sh

# Using splogger to send the log through syslog.
# Using qmail-local to deliver messages to ~/Mailbox by default.

QMAILDIR=/var/qmail

# Comment out DKIM_ON=1 to disable dkim sign at qmail-remote level
# You have to define your variables in control/filterargs (DKIM page for more info)
# echo "*:remote:/var/qmail/bin/qmail-dkim:DKIMQUEUE=/bin/cat,\
# DKIMSIGN=/var/qmail/control/domainkeys/%/default,DKIMSIGNOPTIONS=-z 2" > /var/qmail/control/filterargs
DKIM_ON=1

if [ -r $QMAILDIR/control/filterargs ] && [ -n "$DKIM_ON" ]; then
# DKIM sign at qmail-remote level
  exec env - PATH="$QMAILDIR/bin:$PATH" \
  QMAILREMOTE=$QMAILDIR/bin/spawn-filter \
  qmail-start ./Mailbox splogger qmail
else
# Use this if you are signing at qmail-smtpd level or you don't want to sign at all
  exec env - PATH="$QMAILDIR/bin:$PATH" \
  qmail-start ./Mailbox splogger qmail
fi

qmail-remote に渡す前に spawn-filter に渡し,DKIM 署名をしている. spawn-filter の設定ファイル filterargs に必要事項を記入. 内容については man qmail-dkim や man spawn-filter を参照のこと.

# vim /var/qmail/control/filterargs
*:remote:/var/qmail/bin/qmail-dkim:ERROR_FD=2,DKIMQUEUE=/bin/cat,DKIMSIGN=/var/qmail/control/domainkeys/%/rsa-20250816,DKIMSIGNOPTIONS=-z 2,DKIMSIGNEXTRA=/var/qmail/control/domainkeys/%/ed-20250816,DKIMSIGNOPTIONSEXTRA=-z 4

また,受信メールの DKIM 検証のため,/etc/init.d/qmail を書き換え

# vim /etc/init.d/qmail
        ...
        # For SMTP
        export QMAILQUEUE=/var/qmail/bin/qmail-dkim
        export DKIMVERIFY="p"   ## DKIM-Status ヘッダを追加するだけで reject しない
        # This is to allow msg without "subject" in the h= list
        # export UNSIGNED_SUBJECT=1
        # This is to avoid verification of outgoing messages
        export RELAYCLIENT_NODKIMVERIFY=1
        sh -c " /sbin/start-stop-daemon --start --quiet --user qmaild \
        ...

ようやく DKIM の設定が完了した. qmail を起動して送信テストしてみる.

# systemctl daemon-reload
# systemctl restart qmail

Thunderbird などで,usuzumi から Gmail, Gmail から usuzumi にメールを送ってみる. ただし,usuzumi から Gmail に送る際は MAIL FROM を @ep.sci.hokudai.ac.jp に しないと,DKIM 検証は失敗することに注意. Gmail 側で DKIM=PASS であること,usuzumi 側で DKIM-Status: good のヘッダがあることを 確認すること.

2. SpamAssassin の導入

迷惑メールフィルタとして SpamAssassin (以降 SA) を導入する. SA は DMARC や ベイジアンフィルタ,公開ブラックリストなど幅広い方法を使い, 柔軟にフィルタを設定できるのが特徴である.

Debian のパッケージをインストール.

# apt install spamassassin
# systemctl start spamd
# sa-update
# systemctl enable spamd
# systemctl is-enabled spamd  ## 自動起動が有効になっているか確認.enabled なら OK

local.cf を ep に合わせて編集. ちなみにデフォルトの設定は /usr/share/spamassassin 以下にあり, sa-update で定期的にアップデートできる.

# vim /etc/mail/spamassassin/local.cf
# This is the right place to customize your installation of SpamAssassin.
#
# See 'perldoc Mail::SpamAssassin::Conf' for details of what can be
# tweaked.
#
# Only a small subset of options are listed below
#
###########################################################################

#    A 'contact address' users should contact for more info. (replaces
#    _CONTACTADDRESS_ in the report template)
# report_contact youremailaddress@domain.tld

# 常に X-Spam-Report: を付加
add_header all Report _REPORT_

#   Add *****SPAM***** to the Subject header of spam e-mails
#
rewrite_header Subject *****SPAM*****


#   Save spam messages as a message/rfc822 MIME attachment instead of
#   modifying the original message (0: off, 2: use text/plain instead)
#
report_safe 0


#   Set which networks or hosts are considered 'trusted' by your mail
#   server (i.e. not spammers)
#
trusted_networks 133.50.0.0/16 133.87.0.0/16 192.50.101.190 192.168.0.0/24
internal_networks 133.50.0.0/16 133.87.0.0/16 192.50.101.190 192.168.0.0/24
#internal_networks 133.50.160.0/23 133.87.45.0/24 192.168.0.0/24

# Envelope-From として Return-Path を使う
always_trust_envelope_sender 1

#   Set file-locking method (flock is not safe over NFS, but is faster)
#
# lock_method flock


#   Set the threshold at which a message is considered spam (default: 5.0)
#
required_score 6.0


#   Use Bayesian classifier (default: 1)
#
use_bayes 1

#   Bayesian classifier auto-learning (default: 1)
#
bayes_auto_learn 1

bayes_path /var/spool/spamassassin/bayes
bayes_file_mode 0666

# 学習フィルタを重視する
score BAYES_00  0  0 -3.0   -3.8
score BAYES_05  0  0 -0.6   -1.0
score BAYES_20  0  0 -0.002 -0.002
score BAYES_40  0  0 -0.002 -0.002
score BAYES_50  0  0  4.0    1.6
score BAYES_60  0  0  5.0    3.0
score BAYES_80  0  0  5.4    4.0
score BAYES_95  0  0  6.4    6.0
score BAYES_99  0  0  7.6    7.0
score BAYES_999 0  0  0.4    0.4

# Validity への DNS クエリを無効化 (どのみちブロックされる)
dns_query_restriction deny bl.score.senderscore.com
dns_query_restriction deny sa-accredit.habeas.com
dns_query_restriction deny sa-trusted.bondedsender.org

# ep サーバで誤判定の多かった規定を無効化
meta RCVD_IN_PBL 0
score RDNS_NONE 0

#   Set headers which may provide inappropriate cues to the Bayesian
#   classifier
#
# bayes_ignore_header X-Bogosity
# bayes_ignore_header X-Spam-Flag
# bayes_ignore_header X-Spam-Status


#   Whether to decode non- UTF-8 and non-ASCII textual parts and recode
#   them to UTF-8 before the text is given over to rules processing.
#
normalize_charset 1

# 日本人からのメールを受け取る場合
meta FROM_EXCESS_BASE64 0

# 本文の文字エンコーディングが UTF-8 のメールを許容する場合
meta MIME_BASE64_TEXT 0

# スペースを多用する署名を許容する場合
meta TVD_SPACE_RATIO 0

# MIME エンコードしていない ISO-2022-JP の Subject を許容する場合
meta SUBJ_ILLEGAL_CHARS 0
# meta SUBJECT_NEEDS_ENCODING 0

# DNS として HINES のものを使う (yellow は再帰的に検索できない)
dns_server 133.87.1.11

#   Textual body scan limit    (default: 50000)
#
#   Amount of data per email text/* mimepart, that will be run through body
#   rules.  This enables safer and faster scanning of large messages,
#   perhaps having very large textual attachments.  There should be no need
#   to change this well tested default.
#
# body_part_scan_size 50000

#   Textual rawbody data scan limit    (default: 500000)
#
#   Amount of data per email text/* mimepart, that will be run through
#   rawbody rules.
#
# rawbody_part_scan_size 500000

#   Some shortcircuiting, if the plugin is enabled
#
ifplugin Mail::SpamAssassin::Plugin::Shortcircuit
#
#   default: strongly-welcomelisted mails are *really* welcomelisted now, if
#   the shortcircuiting plugin is active, causing early exit to save CPU
#   load.  Uncomment to turn this on
#
#   SpamAssassin tries hard not to launch DNS queries before priority -100.
#   If you want to shortcircuit without launching unneeded queries, make
#   sure such rule priority is below -100. These examples are already:
#
# shortcircuit USER_IN_WELCOMELIST       on
# shortcircuit USER_IN_DEF_WELCOMELIST   on
# shortcircuit USER_IN_ALL_SPAM_TO     on

#   the opposite; blocklisted mails can also save CPU
#
# shortcircuit USER_IN_BLOCKLIST       on
# shortcircuit USER_IN_BLOCKLIST_TO    on

#   if you have taken the time to correctly specify your "trusted_networks",
#   this is another good way to save CPU
#
# shortcircuit ALL_TRUSTED             on

#   and a well-trained bayes DB can save running rules, too
#
# shortcircuit BAYES_99                spam
# shortcircuit BAYES_00                ham

endif # Mail::SpamAssassin::Plugin::Shortcircuit

なお,これらの設定は状況に応じて変更すること. (この柔軟性が SA の良さの一つだと思う)

続いて,単語リストを作成する. 必要に応じて逐次追加すること.

# /etc/mail/spamassassin/70_user.cf
  body     BODY_JA_SPAMLIER   /配信停止/
  describe BODY_JA_SPAMLIER   You might be a spam sender.
  score    BODY_JA_SPAMLIER   1.0

こんな感じに迷惑メールによく使われる語句を追加する. 続いて,非迷惑メールの語句を別ファイルに書く.

# vim /etc/mail/spamassassin/75_safelist.cf

まだ何も書き込んでいない. 誤判定が出てしまった時に,スコア -8.0 で書く

追加で必要なモジュールをインストール.

# apt install libdigest-sha-perl libhtml-parser-perl libnet-dns-perl libnetaddr-ip-perl
# apt install libencode-detect-perl libnet-libidn-perl libemail-address-xs-perl libmail-dkim-perl \
        libmail-spf-perl libio-socket-ip-perl libmail-authenticationresults-perl libmail-dmarc-perl
# apt install antiword docx2txt unrtf odt2txt tesseract-ocr poppler-utils

https://notes.sagredo.eu/en/qmail-notes-185/installing-and-configuring-spamassassin-37.html を参考に,添付ファイルをテキスト変換する規定を作成.

# vim /etc/mail/spamassassin/70_extracttext.cf
ifplugin Mail::SpamAssassin::Plugin::ExtractText

extracttext_external pdftotext /usr/bin/pdftotext -nopgbrk -layout -enc UTF-8 {} -
extracttext_use pdftotext .pdf application/pdf

# http://docx2txt.sourceforge.net
extracttext_external docx2txt /usr/bin/docx2txt {} -
extracttext_use docx2txt .docx application/docx

extracttext_external antiword /usr/bin/antiword -t -w 0 -m UTF-8.txt {}
extracttext_use antiword .doc application/(?:vnd\.?)?ms-?word.*

extracttext_external unrtf /usr/bin/unrtf --nopict {}
extracttext_use unrtf .doc .rtf application/rtf text/rtf

extracttext_external odt2txt /usr/bin/odt2txt --encoding=UTF-8 {}
extracttext_use odt2txt .odt .ott application/.*?opendocument.*text
extracttext_use odt2txt .sdw .stw application/(?:x-)?soffice application/(?:x-)?starwriter

extracttext_external tesseract {OMP_THREAD_LIMIT=1} /usr/bin/tesseract -c page_separator= {} -
extracttext_use tesseract .jpg .png .bmp .tif .tiff image/(?:jpeg|png|x-ms-bmp|tiff)

add_header all ExtractText-Flags _EXTRACTTEXTFLAGS_

header PDF_NO_TEXT X-ExtractText-Flags =~ /\bNoText\b/
describe PDF_NO_TEXT PDF without text
score PDF_NO_TEXT 0.2

header DOC_NO_TEXT X-ExtractText-Flags =~ /\bNoText\b/
describe DOC_NO_TEXT Document without text
score DOC_NO_TEXT 0.2

header EXTRACTTEXT exists:X-ExtractText-Flags
describe EXTRACTTEXT Email processed by extracttext plugin
score EXTRACTTEXT 0.001

endif

各種プラグインを有効化する. *.pre の loadplugin Mail::SpamAssassin::Plugin::... の コメントアウトを外せばよい.

# cd /etc/mail/spamassassin
# vim init.pre
   ## RelayCountry, URIDNSBL, SPF のコメントアウトを外す
# vim v310.pre
   ## TextCat のコメントアウトを外す
# vim v342.pre
   ## Phishing のコメントアウトを外す
# vim v342.pre
   ## Phishing のコメントアウトを外す
# vim v400.pre
   ## ExtractText, DecodeShortURLs, DMARC のコメントアウトを外す
# vim v401.pre
   ## AuthRes のコメントアウトを外す

変更を反映させる. 設定変更後は必ず spamassassin --lint で不備がないか チェックすること.

# spamassassin --lint
# systemctl restart spamd

SA はベイジアンフィルタを導入している. フィルタの精度を上げるため,迷惑メールと非迷惑メールを 学習させる. 今回は自分あてのメールを用いて学習させた.

# cd ~mondohoge
# sftp hoge@grey.ep.sci.hokudai.ac.jp
sftp> get Junk Junk_learn
sftp> get Mailbox Mailbox_learn
sftp> exit
# sa-learn --spam --mbox Junk_learn >> sa-learn-spam.log
# rm Junk_learn
# sa-learn --ham --mbox Mailbox_learn >> sa-learn-ham.log
# rm Mailbox_learn

spamd を debian-spamd で起動する.

# vim /etc/default/spamd
  SAHOME="/etc/mail/spamassassin/"     # この行を追加
  OPTIONS="-u debian-spamd --create-prefs --max-children 5 --helper-home-dir"
    ## 上のように編集 (spamd を root 以外で動かす)
# chmod 755 /var/spool/spamassassin
# chown -R debian-spamd:debian-spamd /var/spool/spamassassin
# spamassassin --lint
# systemctl restart spamd

qmail-queue の前に spamc を噛ませる.

# systemctl stop qmail
# systemctl stop dovecot
# mv /var/qmail/bin/qmail-queue /var/qmail/bin/qmail-queue.org
# vim /usr/local/bin/qmail-queue
  #!/bin/sh
    exec /usr/bin/spamc | /var/qmail/bin/qmail-queue.org
# chmod 755 /var/qmail/bin/qmail-queue
# chown root:qmail /var/qmail/bin/qmail-queue
# mkdir /var/qmail/.spamassassin
# chown qmaild:qmail /var/qmail/.spamassassin
# chmod 755 /var/qmail/.spamassassin
# systemctl start dovecot
# systemctl start qmail

cron で sa-update を実行.

# cd /etc/cron.daily
# vim sa-update-daily
  #!/bin/bash
  umask 022

  timestamp() {
    echo "$(date "+%Y-%m-%dT%H:%M:%S.%6N%:z") $(hostname)"
  }

  logfile="/var/log/sa-update.log"

  /usr/bin/sa-update --checkonly 2>&1
  status=$?

  if [ $status -eq 0 ]; then
    echo "$(timestamp) SpamAssassin rules will be updated..." >> "$logfile"
    /usr/bin/sa-update >> "$logfile" 2>&1
    echo "$(timestamp) SpamAssassin will be restarted..." >> "$logfile"
    systemctl restart spamd >> "$logfile" 2>&1
    exit 0
  elif [ $status -eq 1 ]; then
    echo "$(timestamp) No fresh updates for SpamAssassin" >> "$logfile"
    exit 0
  else
    echo "$(timestamp) Something wrong happened... Check the log files" >> "$logfile"
    exit 1
  fi
  # sa-update の exit コードは man sa-update 参照
  # log に余計な出力をしないよう、更新のない場合もexit コードは 0 に指定
# chmod 755 sa-update-daily

追記.まずは全ユーザでなく,メール管理者のみ SA を適用させる. qmail-queue ラッパーを戻し,procmail で qmail-local から SA に渡す.

# systemctl stop qmail
# cd /var/qmail/bin
# mv qmail-queue qmail-queue.bak
# mv qmail-queue.org qmail-queue
# vim /etc/default/spamd
   ## OPTIONS から --create-prefs を削除
# systemctl restart spamd
# systemctl start qmail
# exit
$ cd ~
$ mkdir .procmail
$ vim .procmailrc
SHELL=/bin/bash
PATH=/bin:/usr/bin:/usr/local/bin
ADDRESS=mondohoge@usuzumi.ep.sci.hokudai.ac.jp
LOGFILE=$HOME/.procmail/`date +%Y%m`.log
LOCKFILE=$HOME/.procmail/.lockfile
MAILDIR=$HOME/Maildir
MBOX=$HOME/Mailbox
DEFAULT=$MBOX

# spamc に通す (フィルタ)
:0fw
| /usr/bin/spamc

# ========== ここから配送 ==========

# mbox 形式 (Mailbox)
:0c:
$HOME/Mailbox

# Maildir 形式
:0c
$HOME/Maildir/

# 外部アドレス転送
:0
! hogehoge@example.com
$ vim .qmail
   ## | preline /usr/bin/procmail を追記.
   ## 他の行はコメントアウト

これでローカル配送後に SA にメールを渡すようになる. .procmailrc の ADDRESS はサーバ入れ替え後に usuzumi を 消すこと.

3. 参考文献




最終更新日: 2025/08/22 山本 峻大 Copyright © 2025-2025 epcore