2024/06/20(木)FreeBSD 13.3R で dovecot 2.3.21 はそのまま構築できない
2024/06/21 16:36
FreeBSD 13.3 では、clang が Ver 17 になった影響か、dovecot 2.3.21 ではこんな感じで、コンパイルエラーになる:
test-mail-index-transaction-update.c:633:14: warning: comparison of function 'timezone' equal to a null pointer is always false [-Wtautological-pointer-compare] 633 | test_assert(timezone == 0); | ^~~~~~~~ ~ ../../src/lib-test/test-common.h:20:8: note: expanded from macro 'test_assert' 20 | if (!(code)) test_assert_failed(#code, __FILE__, __LINE__); \ | ^~~~ test-mail-index-transaction-update.c:633:14: note: prefix with the address-of operator to silence this warning 633 | test_assert(timezone == 0); | ^ | & ../../src/lib-test/test-common.h:20:8: note: expanded from macro 'test_assert' 20 | if (!(code)) test_assert_failed(#code, __FILE__, __LINE__); \ | ^ test-mail-index-transaction-update.c:648:42: warning: arithmetic on a pointer to the function type 'char *(int, int)' is a GNU extension [-Wgnu-pointer-arith] 648 | hdr.day_stamp = tests[i].old_day_stamp + timezone; | ^ ~~~~~~~~ test-mail-index-transaction-update.c:648:17: error: incompatible pointer to integer conversion assigning to 'uint32_t' (aka 'unsigned int') from 'char *(*)(int, int)' [-Wint-conversion] 648 | hdr.day_stamp = tests[i].old_day_stamp + timezone; | ^ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ test-mail-index-transaction-update.c:650:49: warning: arithmetic on a pointer to the function type 'char *(int, int)' is a GNU extension [-Wgnu-pointer-arith] 650 | mail_index_update_day_headers(t, tests[i].now + timezone); | ^ ~~~~~~~~ test-mail-index-transaction-update.c:650:36: error: incompatible pointer to integer conversion passing 'char *(*)(int, int)' to parameter of type 'time_t' (aka 'long') [-Wint-conversion] 650 | mail_index_update_day_headers(t, tests[i].now + timezone); | ^~~~~~~~~~~~~~~~~~~~~~~ ./mail-index-transaction-private.h:127:77: note: passing argument to parameter 'day_stamp' here 127 | void mail_index_update_day_headers(struct mail_index_transaction *t, time_t day_stamp); | ^ test-mail-index-transaction-update.c:654:63: warning: arithmetic on a pointer to the function type 'char *(int, int)' is a GNU extension [-Wgnu-pointer-arith] 654 | test_assert_idx(new_hdr.day_stamp == tests[i].new_day_stamp + timezone, i); | ^ ~~~~~~~~ ../../src/lib-test/test-common.h:26:9: note: expanded from macro 'test_assert_idx' 26 | if (!(code)) test_assert_failed_idx(#code, __FILE__, __LINE__, i); \ | ^~~~ test-mail-index-transaction-update.c:654:37: warning: comparison between pointer and integer ('uint32_t' (aka 'unsigned int') and 'char *(*)(int, int)') [-Wpointer-integer-compare] 654 | test_assert_idx(new_hdr.day_stamp == tests[i].new_day_stamp + timezone, i); | ~~~~~~~~~~~~~~~~~ ^ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ../../src/lib-test/test-common.h:26:9: note: expanded from macro 'test_assert_idx' 26 | if (!(code)) test_assert_failed_idx(#code, __FILE__, __LINE__, i); \ | ^~~~ 5 warnings and 2 errors generated. gmake[3]: *** [Makefile:916: test-mail-index-transaction-update.o] エラー 1 gmake[3]: ディレクトリ '/usr/local/src/dovecot-2.3.21/src/lib-index' から出ます gmake[2]: *** [Makefile:573: all-recursive] エラー 1 gmake[2]: ディレクトリ '/usr/local/src/dovecot-2.3.21/src' から出ます gmake[1]: *** [Makefile:704: all-recursive] エラー 1 gmake[1]: ディレクトリ '/usr/local/src/dovecot-2.3.21' から出ます gmake: *** [Makefile:548: all] エラー 2軒並み、timezone 絡みのようで、この件に関するパッチが3つ公開されています:
その1 https://github.com/dovecot/core/commit/e983ead775671186b3c8567d59973d2e52b678c7
その2 https://github.com/dovecot/core/commit/1a7b1f66fe4b86cb642dbcfe5a0192c1b77d0e17
その3 https://github.com/dovecot/core/commit/867a37fa7b74f798a931fb582214b5377f57610e
〔その1 src/lib/ioloop-notify-kqueue.c を修正〕
@@ -11,6 +11,7 @@ | |||
11 | 11 | ||
12 | 12 | #include "ioloop-private.h" | |
13 | 13 | #include "llist.h" | |
14 | + | #include "time-util.h" | |
14 | 15 | #include <unistd.h> | |
15 | 16 | #include <fcntl.h> | |
16 | 17 | #include <sys/types.h> |
〔その2 src/lib-index/test-mail-index-transaction-update.c を修正〕
@@ -6,6 +6,7 @@ | ||||
6 | 6 | #include "test-common.h" | ||
7 | 7 | #include "mail-index-private.h" | ||
8 | 8 | #include "mail-index-transaction-private.h" | ||
9 | + | #include "utc-offset.h" | ||
9 | 10 | |||
10 | 11 | #include <time.h> | ||
11 | 12 | |||
@@ -630,7 +631,9 @@ | ||||
630 | 631 | |||
631 | 632 | /* daylight savings times were confusing these tests, so we'll now | ||
632 | 633 | just assume that TZ=UTC */ | ||
633 | - | test_assert(timezone == 0); | ||
634 | + | time_t now = time(NULL); | ||
635 | + | struct tm *local_time = localtime(&now); | ||
636 | + | test_assert(utc_offset(local_time, now) == 0); | ||
634 | 637 | |||
635 | 638 | hdr.messages_count = 10; | ||
636 | 639 | t = mail_index_transaction_new(); |
〔その3 src/lib-index/test-mail-index-transaction-update.c を修正〕
@@ -648,13 +648,13 @@ | ||||
648 | 648 | i_zero(&hdr); | ||
649 | 649 | for (j = 0; j < N_ELEMENTS(hdr.day_first_uid); j++) | ||
650 | 650 | hdr.day_first_uid[j] = 8-j; | ||
651 | - | hdr.day_stamp = tests[i].old_day_stamp + timezone; | ||
651 | + | hdr.day_stamp = tests[i].old_day_stamp; | ||
652 | 652 | memcpy(t->post_hdr_change, &hdr, sizeof(hdr)); | ||
653 | - | mail_index_update_day_headers(t, tests[i].now + timezone); | ||
653 | + | mail_index_update_day_headers(t, tests[i].now); | ||
654 | 654 | |||
655 | 655 | struct mail_index_header new_hdr; | ||
656 | 656 | memcpy(&new_hdr, t->post_hdr_change, sizeof(new_hdr)); | ||
657 | - | test_assert_idx(new_hdr.day_stamp == tests[i].new_day_stamp + timezone, i); | ||
657 | + | test_assert_idx(new_hdr.day_stamp == tests[i].new_day_stamp, i); | ||
658 | 658 | test_assert_idx(memcmp(new_hdr.day_first_uid, | ||
659 | 659 | tests[i].new_day_first_uid, | ||
660 | 660 | sizeof(uint32_t) * 8) == 0, i); |
これらのパッチを手動で当て、いつもの手順でコンパイルすることで、いくつか Warning が出るものの、通常通りの使用可能となるようです。
バージョンアップで、この不具合が解消されることを期待したいところ。
2023/11/12(日)Python 一部モジュール・ライブラリが更新できない
2023/11/13 1:03
通常、OSバージョンアップの場合、前バージョンまでの動作互換性は保証しているので、必ずしも必要ではないはずなのですが、それでも不可解な挙動が生じる場合があり、それを未然に防ぐために「全てのアプリケーション再構築」という作業を行うことにしているのです。
多くのマトモな方々には信じられないかもしれないですが、この事業を始めたばかりの頃、
『たった1回のアプリケーション障害で、しかもたった1日で一方的なサーバホスティング解消』をされたことがあり、これは純粋にアプリケーションの不具合で、OSアップデートが問題ということでもなく、運用側でどうすることも出来ない不可抗力な原因の事象でした。
当然、「一方的」だったので、説明責任のかけらも果たすことが出来ませんでした。
まぁ、そんなに信用できないなら「最初から易々と近づくな」と言いたいし、何より舐められまくってますね。
そんな態度の「上から目線なクライアント」は、相手にしないことは言うまでもないです。
きっと、他所でも毛嫌いされていることだろうと思われます。
20年以上やっていますが、この類の不具合は、この件含めて2回。
2回目は説明責任果たせたので、理解してもらえました。過去20年に限れば安定稼働しています。
前置きが長くなり過ぎたのですが、ここから本題。
FreeBSD12 → FreeBSD13 にOSアップデートして、アプリケーション再構築をすると、一部の Python アプリケーションが再構築出来ずに、以下のようなエラーを吐いてしまう。
File "/usr/local/lib/python3.9/importlib/__init__.py", line 127, in import_module return _bootstrap._gcd_import(name[level:], package, level) File "<frozen importlib._bootstrap>", line 1030, in _gcd_import File "<frozen importlib._bootstrap>", line 1007, in _find_and_load File "<frozen importlib._bootstrap>", line 972, in _find_and_load_unlocked File "<frozen importlib._bootstrap>", line 228, in _call_with_frames_removed File "<frozen importlib._bootstrap>", line 1030, in _gcd_import File "<frozen importlib._bootstrap>", line 1007, in _find_and_load File "<frozen importlib._bootstrap>", line 986, in _find_and_load_unlocked File "<frozen importlib._bootstrap>", line 680, in _load_unlocked File "<frozen importlib._bootstrap_external>", line 850, in exec_module File "<frozen importlib._bootstrap>", line 228, in _call_with_frames_removed File "/usr/local/lib/python3.9/site-packages/setuptools/__init__.py", line 18, in from setuptools.dist import Distribution File "/usr/local/lib/python3.9/site-packages/setuptools/dist.py", line 34, in from ._importlib import metadata File "/usr/local/lib/python3.9/site-packages/setuptools/_importlib.py", line 39, in disable_importlib_metadata_finder(metadata) File "/usr/local/lib/python3.9/site-packages/setuptools/_importlib.py", line 28, in disable_importlib_metadata_finder to_remove = [ File "/usr/local/lib/python3.9/site-packages/setuptools/_importlib.py", line 31, inこの現象は、時々起きるらしく、外国のメンテナンス作業者の解決策として、どうやらif isinstance(ob, importlib_metadata.MetadataPathFinder) AttributeError: module 'importlib_metadata' has no attribute 'MetadataPathFinder' ERROR Backend subprocess exited when trying to invoke get_requires_for_build_wheel *** Error code 1
# cd /usr/local/lib # rm -rf python3.*としてから、
# portupgrade -rf python.3.9.18(インストールされている Python バージョンに合わせる)
とすると、解消する模様。やや強引かつ豪快な解決手段だが、これが確実なのだとか。
これをやったら、確かに問題は解消しました。
2023/11/03(金)FreeBSD14 と FreeBSD12
2023/11/03 7:07
質問やコメントにも目を通しているものの、殆ど反応出来ずな状態です。
さて、いつの間にか FreeBSD 12は、リリースから5年が経過しようとしています。2018/12/11 に 12.0 がリリースされました。
メンテナンスサポート期間は5年と定められたため、5年後の月末を以ってサポート終了です。
〔FreeBSD 公式サイト日本語版より https://www.freebsd.org/ja/security/#sup〕
FreeBSD 12.4 を稼動させるサーバ機器が7台あるのですが、そのうちの5台を急遽 13.2 (2023/04/11 リリース)へアップデート中。
さて、FreeBSD 14 ですが、これもいつの間にか近日リリースなのです。
〔FreeBSD 公式サイトより https://www.freebsd.org/releases/14.0R/schedule/〕
どういう新機能等があるのか、概要の意訳をして確認してみました:
・root アカウントのデフォルトシェルは、sh(1) になる。 → 何で?
・デフォルトのMTAは、sendmail(8) から dma(8) に変更される。 → 既に Postfix 使いなので、関係ないか?
・Locale が CLDR41.0 , Unicode 14.0 に対応 → ちょっと対応遅いと思う。
・Base64 ライブラリが標準装備になった
・portsnap は削除した。代わりに git を使え。 → えぇぇ!?(でも gitup が使えそうだ)
・pw(8),bsdinstall(8) は、ユーザホームディレクトリを /usr/home 配下ではなく、/home 配下に作成するようにした。→ まともにするための改修ですね。
・libfido2 ライブラリが 1.13.0 になった。→ あれ、既に(大手企業で流行りの)パスキーに対応しているらしい。
・OpenSSL ライブラリが、1.1.1 から 3.0.12 になった。→ 流石にこれはアップデート必須です。
・mergemaster(8) は非推奨になった。代わりに etcupdate(8) を使え。→ えぇぇ!?
・デバイスドライバ amr(4)、iir(4)、mn(4)、mly(4)、nlmrsa(4) 、twa(4) は削除した。→ 時代の流れだね。
・Wi-Fi6 に対応した。 → やっとか。
・FreeBSD15 以後は 32bitプラットフォームをサポートしない。但し、互換機能で32bit アプリケーションの動作は可能とする。 → これも時代の流れですね。。2029年には32bitCPU でFreeBSD は動作しなくなるのかな。
他、多くの項目ありますが、当方が興味なかったり、説明が難しかったりしたので、結構端折っています。
〔2023/12/16 追記〕
FreeBSD14 は、2023/11/20 付けでリリースされました。
FreeBSD13同様、5年間のサポート(2028/11/30 まで)を実施するようです。
また、本家から日本語のページが無くなってしまいました。非営利ベースで担当出来る人が居なくなった模様。
2023/04/06(木)Let's encrypt のサーバ証明書をpostfix で使う場合の注意
2023/04/06 16:15
発端は、「こんなメッセージが出るんだが・・・」という一報。
証明書の更新は正常にできているので、謎の現象です。さらに「証明書の表示(V)...」で表示される内容を送ってもらうと・・・
こんな感じになるらしい。確かにここでは「期限切れ」になっています。
証明書の誤認識であることには間違いないので、クライアント側の設定で何か問題を引き起こしているのではないかと思うのですが、いろいろと不可解なので、一報を頂いた会社へ許可を得て出向いて、原因究明と解消を試みました。
証明書チェーンはあっているが、変にキャッシュしているのかと思い、色々と余計な「オレオレ証明書(最近まで使わせていました)」を削除したが、進展せず。
よく聞くと、最初の送信時だけ出て、電子メール送受信ソフトウェアを終了させない限りは「出ない」とのこと。
また、受信時は一切出ないとのこと。ということは postfix の問題か?
ということで、結局、試行錯誤と考察でひらめいたのが、postfix のhash DB です。
試しに
# postmap -F hash:tls_sni.map(tls_sni.map には、証明書の一覧などが所定フォーマットで記述してある)
# postfix reload
とやったあと、試してみると、当初のメッセージは一切でなくなりました。
ここには、証明書の有効期限までもデータとして保存される作りらしい。
ということで、
2022/12/25 付けの記事 メールサーバの中規模改修と基礎知識(3)~ Dovecot+Pigeonhole,cert-bot
の最終部分に記述した内容は
#!/bin/sh /usr/local/etc/rc.d/apache2 stop /sbin/pfctl -d /usr/local/bin/certbot renew -m user@example.com /sbin/pfctl -e /usr/local/sbin/postmap -F hash:/usr/local/etc/postfix/tls_sni.map /usr/local/sbin/postfix reload /usr/local/sbin/dovecot reload /usr/local/etc/rc.d/apache2 startのようにし、postfix が扱う証明書情報も更新しないと駄目です。
これでこの件は解決。
2023/01/09(月)dovecot に謎のエラー
2023/01/08 18:21
Jan 8 17:31:43 mx2 dovecot[57447]: auth: Error: auth client 0 disconnected with 2 pending requests: EOF Jan 8 17:31:44 mx2 dovecot[57447]: auth: Error: auth client 0 disconnected with 1 pending requests: EOF Jan 8 17:31:47 mx2 dovecot[57447]: auth: Error: auth client 0 disconnected with 2 pending requests: EOF Jan 8 17:31:47 mx2 syslogd: last message repeated 1 times Jan 8 17:41:42 mx2 dovecot[57447]: auth: Error: auth client 0 disconnected with 1 pending requests: EOF Jan 8 17:41:42 mx2 dovecot[57447]: auth: Error: auth client 0 disconnected with 2 pending requests: EOF Jan 8 17:41:42 mx2 dovecot[57447]: auth: Error: auth client 0 disconnected with 1 pending requests: EOF Jan 8 17:41:42 mx2 syslogd: last message repeated 3 times Jan 8 17:51:42 mx2 syslogd: last message repeated 1 times Jan 8 17:51:44 mx2 syslogd: last message repeated 6 timesどうやら、外国のWebサイトにて Apple Mail クライアントの行儀の悪さが原因だという記事を見かけました。
しかしながら、接続元情報が一切出てこない上に、関連付けが出来る他の情報も無いため、断定しきれないですね。
「電子メールの送受信が出来ないという不満が出て来なければ、気にする必要無い」と結論付けていて、それはその通りとも言えますが、原因がハッキリしないエラーメッセージはあまり気分のよいものではないです。
Mac 環境での電子メール設定は、時折問い合わせを受けるものの、問題特定できない内容ばかりで都度悩むのですが、一方で、問い合わせ側の試行錯誤でいつの間にか解決してしまうので、成功事例みたいなものが共有できないんです。
かといって、手本を示すのと、検証の為だけにMac を買うということには絶対にならないので、悩ましいところですね。
2023/01/08(日)whois に障害??
2023/01/08 17:45
mx2-root[97]# whois basekernel.co.jp whois: connect(): Operation timed out mx2-root[98]# whois basekernel.co.jp whois: connect(): Operation timed outメンテナンス情報とか見当たらないし、こういう事態は初めて、、
〔2023/01/08 17:51 追記〕
キャッシュDNS再起動したら復旧。。orz 何だったのだろう??
2023/01/06(金)fml4 → fml8 へのアップデート
2023/01/06 5:00
本家のチュートリアルを見る限り、そんな印象は受けなかったので、本家のチュートリアルを参考に実施しています。
先ずは fml8 を新規インストールします。(2022/12/31(土) fml8 の新規インストール 参照)
fml4 既存MLの fml8 移行の場合は、改めて fml8 で新規ML作成の必要は基本的に無しです。勝手に fml4 環境を上書きされることも無く、fml4 が既存でも問題はありません。
※ https://www.fml.org/software/fml8/ にて、チュートリアル → レシピ一覧 fml4 のMLを fml8 形式のMLへ変換する のリンクを辿っても閲覧出来ない。
チュートリアルページの下の方に
『II. fml のセットアップ~MLの作成』の項目があって、その下の fml4 のMLを fml8 形式のMLへ変換する
https://www.fml.org/software/fml8/Documentation/ja/tutorial/mergeml.fml4to8.html のほうを参照ください。
とはいえ、本家のチュートリアルどおりでは成功しませんので、下記手順を参考にどうぞ:
※ fml4 → fml8 移行に関しては、root ユーザで実施するのが無難です。
# makefml newdomain example.com /var/mail/example.com/~ml ( makefml newdomain バーチャルドメイン名 バーチャルドメインML 格納ディレクトリ )既存の fml4 で運用している、バーチャルドメインにおけるML一式を格納しているディレクトリを指定します。
既存環境に上書きされることはなく、fml8 環境設定ディレクトリに対応付けが設定されるのみです。
尚、これは該当バーチャルドメイン上に複数のMLがあっても、最初の一度だけ実施でよいです。
23/01/06 00:43:01 makefml[1766] warn: /var/mail/example.com/~ml already exist. reuse it.といったメッセージが出ますが、このメッセージは無視して大丈夫です。
次に、
# makefml mergeml ml-name@example.com /var/mail/example.com/~ml/ml-name # cd /var/mail/example.com/~ml/ml-name # chown fmladmin * # chown -R fmladmin varmakefml mergeml にて、既存の fml4 で運用している、バーチャルドメインにおけるメーリングリスト個別ディレクトリを指定します。
makefml mergemlで、fml8 に適応したコンバートが行われます。
ファイル・ディレクトリ所有者が、一部 root になってしまうので、全て fmladmin (fml8 の実行権限ユーザ) に変えます。
postfix の場合、 /etc/mail/aliases /usr/local/etc/postfix/virtualtbl などにML関係の設定をしている場合は、必ず、それらを削除することを忘れないでください。
《※ postfix の設定を変更》 # vi /usr/local/etc/postfix/main.cf 《下記の例のように、alias を追加》 alias_maps = hash:/etc/mail/aliases hash:/var/mail/example.com/~ml/etc/mail/aliases virtual_alias_maps = hash:/usr/local/etc/postfix/virtualtbl/forwardlist hash:/var/mail/example.com/~ml/etc/postfix/virtual
# vi /etc/mail/aliases 《下記を追加》 fmladmin: root 《追加後、下記を実行》 # newaliases上記、makefml mergeml の実行で、雛形ファイルが自動生成されますので、それを流用します。
ただし、そのままでは使えないため、一部変更します:
# cd /var/mail/example.com/~ml/etc/postfix # vi virtual ----- 以下、変更 ----- # example.com is one of $mydestination # CAUTION: DO NOT REMOVE THE FOLLOWING LINE. # example.com example.com ← コメントアウトまたは削除 ### <VIRTUAL test-ml@example.com ML> ### # 以下の5行に、@realmx.example.jp (postfix main.cf で指定の myhostname で示す実ホスト名)を追加 test-ml@example.com test-ml=example.com@realmx.example.jp test-ml-ctl@example.com test-ml-ctl=example.com@realmx.example.jp test-ml-request@example.com test-ml-request=example.com@realmx.example.jp test-ml-admin@example.com test-ml-admin=example.com@realmx.example.jp test-ml-error@example.com test-ml-error=example.com@realmx.example.jp ### </VIRTUAL test-ml@example.com ML> ### ----- 変更はここまで ----- ※ MLごとの個別変更で、題名に通し番号を追加する(makefml mergeml を使用しても、環境によっては引き継がれない設定がある。弊社環境ではこれが発生した) # cd /var/mail/example.com/~ml/text-ml # vi config.cf ----- 以下を、変更または追加(位置的には =cut 行の前) ----- article_header_rewrite_rules += rewrite_article_subject_tag article_subject_tag = [$ml_name:%05d] ----- 変更はここまで ----- ※ この設定で[test-ml:12345] みたいなのがメールタイトルの先頭に自動追加されるようになります。 # postmap hash:virtual # postfix reloadこれで、元通り fml8 での運用が出来るようになりました。
このアップデートは、ML利用者側から見れば、特に利点はありません。
fml4 が運営側にとって、維持困難になってきているので、主な目的はその解消といったところですね。
2023/01/04(水)セカンダリメールサーバの再構築
2023/01/04 6:22
プライマリメールサーバの負荷が高く、応答が遅い時などもセカンダリメールサーバが活用される場面があります。
最近はセカンダリメールサーバを用意していない組織もあるようですが、弊社ではセカンダリメールサーバを備えています。
セカンダリメールサーバは、実は色々な構成があり、プライマリメールサーバのように、電子メールの発信のみを出来るようにしているものもあります。
弊社では、セカンダリメールサーバから電子メールの発信を出来るようにしていませんが、今回はプライマリメールサーバの負荷軽減目的で、明らかなコンピュータウィルスや、確実な spam メールを捨てる仕組みを設けました。
※ この図は、Postfix やメールサーバの構成をそのまま示した図ではありません。
受信メッセージの流れを中心とすると、上記のように感じかなと考えています。
milter-manager で受信メッセージのコンピュータウィルス検査と spam チェックを行います。
実はこれ、Postfix のオンラインマニュアル等を読んでもどうもよく判らないんです。たぶん、こんな感じかなという想像図。。
「outbound」というのは、プライマリメールサーバなどへ送信する場面を想定しています。
上記セカンダリメールサーバ固有の設定
先ず、spamassassin を milter インタフェースで動作させるために、spamass-milter を導入します。一応、http://savannah.nongnu.org/projects/spamass-milt/ が公式サイトのようで、ダウンロードも出来ますが、永らく更新されておりません。
Ver 0.4.0 をダウンロードしてインストールしましたが、Ver 4.0.0 の spamassassin との組み合わせでも使えるようです。
# tar xvzf spamass-milter-0.4.0.tar.gz # cd spamass-milter-0.4.0 # setenv CPPFLAGS '-I/usr/local/include -I/usr/include' # setenv LDFLAGS '-L/usr/local/lib -L/usr/lib' # ./configure --localstatedir=/var # gmake # gmake installとすると、インストール完了です。
milter 形式だと、サーバ単位での spam 判定になってしまうため、少し緩め閾値で spamassassin の挙動を設定しておきます。
サーバ単位での spamassassin の設定は、/etc/mail/spamassassin/local.cf で設定します:
※ /etc/mail/spamassassin/local.cf の内容(変更部分のみ抜粋): rewrite_header Subject report_safe 0 required_score 17.0経験上、閾値 17.0 では、殆どの spam は通過してしまいます。15.0 未満が妥当ですが、運用しながら、様子見で少しずつ下げていくようにします。
以下、FreeBSD 固有の環境になりますが、下記のスクリプトを /usr/local/etc/rc.d 配下に spamass-milter と言う名前で作成しておきます:
#!/bin/sh # PROVIDE: spamass-milter # REQUIRE: LOGIN # BEFORE: mail # KEYWORD: shutdown # # Add the following lines to /etc/rc.conf to enable spamass-milter: # #spamass_milter_enable="YES" # # See spamass-milter(8) for flags. # . /etc/rc.subr name=spamass_milter rcvar=spamass_milter_enable command=/usr/local/sbin/spamass-milter required_dirs=/usr/local/share/spamassassin start_postcmd=start_postcmd stop_postcmd=stop_postcmd start_postcmd() { sleep 1 /usr/sbin/chown ${spamass_milter_socket_owner}:${spamass_milter_socket_group} ${spamass_milter_socket} /bin/chmod ${spamass_milter_socket_mode} ${spamass_milter_socket} } stop_postcmd() { rm -f ${spamass_milter_socket} } load_rc_config $name : ${spamass_milter_enable="NO"} : ${spamass_milter_socket="/var/run/spamd/spamass.sock"} : ${spamass_milter_flags="-f -p ${spamass_milter_socket} ${spamass_milter_localflags}"} : ${spamass_milter_socket_owner="spamd"} : ${spamass_milter_socket_group="mailuser"} : ${spamass_milter_socket_mode="660"} run_rc_command "$1"※注:このスクリプトは Postfix のみの対応です。sendmail が MTA だと、不具合起こすと思います。
上記スプリプトに実行権を与え、更に /etc/rc.conf へ
spamass_milter_enable="YES"の1行を追加しておきます。
ClamAV と、milter-managerも、インストールしておきます。過去記事を参考にしてください。
milter-manager をインストール後、
# /usr/local/sbin/milter-manager -u milter-manager --show-configとやってみて、
define_milter("clamav-milter") do |milter| # /usr/local/lib/milter-manager/binding/lib/milter/manager/detector.rb:44 milter.connection_spec = "unix:/var/run/clamav/clmilter.sock" # default milter.description = nil # /usr/local/lib/milter-manager/binding/lib/milter/manager/detector.rb:37 milter.enabled = true # default milter.fallback_status = "accept" ・ ・ ・ define_milter("spamass-milter") do |milter| # /usr/local/lib/milter-manager/binding/lib/milter/manager/detector.rb:44 milter.connection_spec = "unix:/var/run/spamd/spamass.sock" # default milter.description = nil # /usr/local/lib/milter-manager/binding/lib/milter/manager/detector.rb:37 milter.enabled = true # default milter.fallback_status = "accept"といった表示がされるのを必ず確認しておきます。
最後に、Postfix 側の設定で、milter と関連するもののみ抜粋すると、
milter_protocol = 6 milter_default_action = accept milter_mail_macros = {auth_author} {auth_type} {auth_authen} smtpd_milters = unix:/var/run/milter-manager/milter-manager.sock non_smtpd_milters = unix:/var/run/milter-manager/milter-manager.sock transport_maps = hash:/usr/local/etc/postfix/virtualtbl/transport.map header_checks = pcre:/usr/local/etc/postfix/header_checks
※ /usr/local/etc/postfix/virtualtbl/transport.map の内容: example.jp smtp:[primary1.example.net] example.net smtp:[primary2.example.net] ※ /usr/local/etc/postfix/header_checks の内容: /^From:\s*<>/m DISCARD /^X\-Spam\-Flag:\s+YES/m DISCARD /^X\-Virus\-Status:\s+Yes/m DISCARD /^X\-Spam\-Level:/m IGNORE /^X\-Spam\-Checker\-Version:/m IGNORE /^X\-Spam\-Status:\s+No/m IGNORE /^X\-Virus\-Scanned:/m IGNORE /^X\-Virus\-Status:\s+Clean/m IGNOREのような感じ。
# postmap hash:/usr/local/etc/postfix/virtualtbl/transport.mapを忘れずに実施しておきます。
上記の、/usr/local/etc/postfix/header_checks の簡単な説明ですが、
「DISCARD」で終わる行は、電子メールヘッダ部分にて、左辺のパターンが出現したら「配信しました」と送信元に返答しつつ「メッセージを捨てる」という処理を行い、
「IGNORE」で終わる行は、電子メールヘッダ部分にて、左辺のパターンが出現したら「そのヘッダ行は削除して最終配信先へ送る」という処理を行います。
このファイルに記述された内容は、上から下へ順番に処理しますが、「DISCARD」で記述した行は、「そこで打ち切る」という挙動になるらしいです。
この構成で稼働させているが・・・
どうやら、header_checks の設定が上手く反映できていないみたいなのです。IGNORE で「ヘッダ行削除」の挙動がどうも上手く行っていない模様。
X-Virus.... は上手く行っているが、 X-Spam.... が上手く行かない。。
取り敢えず実害はないのですが、セカンダリメールサーバ経由で受信したメッセージは、
X-Spam... は、受信者から見ると2回出てくることになり、不自然なのでどうにかしたいのです。
バグなのか、設定の問題なのか、、、 困っているところです。
2022/12/31(土)fml8 の新規インストール
2023/01/01 0:48
fml4 は、今となっては運用に難があり、fml8 (作者の趣味・志向で 4 → 8 というビットシフト的バージョンアップを企てている)が、後継ですが、長らくリリース候補版(7.99.1) です。
fml8 インストールの準備
fml8 は、Perl で組まれているため、運用には必然的に下記が必要です:perl5-5.36.0_2 (Ports カテゴリ:lang) ※注:FreeBSD Ports におけるパッケージ表記です。Perl 5.26 以上が要求されます。
インストールに先立ち、fml8 の運用セキュリティに従うために、実行ユーザ fmladmin を用意します:
vipw でやる場合は、下記の1行を追加します:
fmladmin::2007:3000::0:0:FML Administrator:/home/staff/fmladmin:/bin/cshまた、/etc/group の該当行を下記のように変更しておきます:
mailuser:*:3000:opendkim,milter-manager,postfix,fmladmin続いて、下記手順でインストールを、必ず root ユーザで実行します:
# passwd fmladmin # mkdir /home/staff/fmladmin # chown fmladmin:mailuser /home/staff/fmladmin # cp fml-7.99.1.tar.gz /usr/local/src # cd /usr/local/src # tar xvzf fml-7.99.1.tar.gz # cd fml-7.99.1 # ./configure --with-fml-owner=fmladmin --with-fml-group=mailuser # make install
fml8 の新規セットアップ
# vi /usr/local/etc/fml/site_default_config.cfとして、最低限下記2行を変更または追加します:
use_article_mime_component_filter = no use_article_filter = noこれを設定しないと、ISO-2022-JP 文字コード以外で記述された電子メールを拒絶してしまいます。
昨今では、UTF-8 や UTF-7 でメッセージ交換するのが普通になっているため、今となっては時代遅れになってしまった余計な機能になっています。
○ 収容バーチャルドメインにおけるMLの運用準備
% su # makefml newdomain example.com /var/mail/example.com/~ml (バーチャルドメイン運用初回のみ) 〔参考 ※バーチャルドメイン削除の場合〕 # makefml rmdomain exmple.com (バーチャルドメイン上から MLドライバ削除)○ メーリングリストの新規作成
# su fmladmin % makefml newml test-ml@example.com (ML 新規作成) 〔参考 ※メーリングリスト削除の場合〕 % makefml rmml test-ml@example.com (ML の削除) % exit
《※ postfix の設定を変更》 # vi /usr/local/etc/postfix/main.cf 《下記の例のように、alias を追加》 alias_maps = hash:/etc/mail/aliases hash:/var/mail/example.com/~ml/etc/mail/aliases virtual_alias_maps = hash:/usr/local/etc/postfix/virtualtbl/forwardlist hash:/var/mail/example.com/~ml/etc/postfix/virtual
# vi /etc/mail/aliases 《下記を追加》 fmladmin: root 《追加後、下記を実行》 # newaliases上記、makefml newml の実行で、雛形ファイルが自動生成されますので、それを流用します。
ただし、そのままでは使えないため、一部変更します:
# cd /var/mail/example.com/~ml/etc/postfix # vi virtual ----- 以下、変更 ----- # example.com is one of $mydestination # CAUTION: DO NOT REMOVE THE FOLLOWING LINE. # example.com example.com ← コメントアウトまたは削除 ### <VIRTUAL test-ml@example.com ML> ### # 以下の5行に、@realmx.example.jp (postfix main.cf で指定の myhostname で示す実ホスト名)を追加 test-ml@example.com test-ml=example.com@realmx.example.jp test-ml-ctl@example.com test-ml-ctl=example.com@realmx.example.jp test-ml-request@example.com test-ml-request=example.com@realmx.example.jp test-ml-admin@example.com test-ml-admin=example.com@realmx.example.jp test-ml-error@example.com test-ml-error=example.com@realmx.example.jp ### </VIRTUAL test-ml@example.com ML> ### ----- 変更はここまで ----- ※ MLごとの個別変更で、題名に通し番号を追加する(デフォルトでは通し番号はつかない) # cd /var/mail/example.com/~ml/text-ml # vi config.cf ----- 以下を、変更または追加(位置的には =cut 行の前) ----- article_header_rewrite_rules += rewrite_article_subject_tag article_subject_tag = [$ml_name:%05d] ----- 変更はここまで ----- ※ この設定で[test-ml:12345] みたいなのがメールタイトルの先頭に自動追加されるようになります。 # postmap hash:virtual # postfix reload○ 投稿メンバ兼配送メンバの追加
makefml add test-ml@example.com test@example.net○ 投稿メンバ兼配送メンバの削除
makefml bye test-ml@example.com test@example.net
2022/12/30(金)メールサーバの中規模改修と基礎知識(8)~ メールサーバ稼動
2022/12/31 22:49
の構成を稼働させる記事です。ほぼ、FreeBSD固有の手順です。ただ、参考になる部分はあるかもしれません。
(Linux系は、この辺りの仕組みは全く別物なので、読み替えることが出来るスキルが必要になる)
早速、順番に示していきます。作業は root ユーザで全てを実施します。
Postfix と dovecot の起動
先ず、下記のスクリプトファイルを、/usr/local/etc/rc.d ディレクトリ配下に postfix_dovecot というファイル名で作成します。実行権を与えるのを忘れないようにしてください:
#!/bin/sh # # PROVIDE: postfix-dovecot # REQUIRE: DAEMON NETWORKING openldap # KEYWORD: shutdown . /etc/rc.subr name="postfix_dovecot" rcvar="postfix_dovecot_enable" start_cmd="mailserver_start" stop_cmd="mailserver_stop" restart_cmd="mailserver_reload" # start postfix,dovecot, and E-Mail account control server smtpserv=/usr/local/sbin/postfix dovecot=/usr/local/sbin/dovecot mailserver_start() { echo ' ' if [ -x $dovecot ]; then /usr/local/sbin/dovecot -c /usr/local/etc/dovecot/dovecot.conf echo ' dovecot 2.3.19.1 ' fi if [ -x $smtpserv ]; then /usr/local/sbin/postfix start > /dev/null 2>&1 echo ' Postfix 3.7.3 ' fi } mailserver_reload() { /usr/local/sbin/postfix reload /usr/local/sbin/dovecot reload echo ' reloaded postfix and dovecot config ' } mailserver_stop() { /usr/local/sbin/postfix stop /usr/local/sbin/dovecot stop echo ' stoped Mail server ' } load_rc_config $name run_rc_command "$1"次に /etc/rc.conf に下記の2行を追加します
# vi /etc/rc.conf
sendmail_enable="NONE" postfix_dovecot_enable="YES"その後で、
# cd /usr/local/etc/rc.d # ./postfix_dovecot startとして、エラーが表示されないことを確認したら、
で、下記のタスクが動作しているのが確認出来れば、成功です:
# ps -aux | grep postfix
root 32817 ... 13692 - Ss 03:13 0:00.00 /usr/local/libexec/postfix/master -w postfix 32818 ... 13704 - S 03:13 0:00.01 pickup -l -t fifo -u postfix 32819 ... 13796 - S 03:13 0:00.01 qmgr -l -t fifo -u postfix 32820 ... 13840 - S 03:13 0:00.01 tlsmgr -l -t unix -u postfix 32821 ... 13648 - S 03:13 0:00.01 postlogd -l -n postlog -t unix-dgram -u※ 記事表示スペースの関係上、実際の表示項目を一部省略しています。
# ps -aux | grep dovecot
root 64526 ... 5684 - Is 02:11 0:00.27 /usr/local/sbin/dovecot -c /usr/local/etc/dovecot/dovecot.conf dovecot 64528 ... 5368 - I 02:11 0:00.07 dovecot/anvil root 64529 ... 5444 - I 02:11 0:00.04 dovecot/log root 64530 ... 7808 - I 02:11 0:00.45 dovecot/config dovecot 64995 ... 5680 - I 02:11 0:00.08 dovecot/stats※ 記事表示スペースの関係上、実際の表示項目を一部省略しています。
ClamAV の起動
先述の記事で、既に起動スクリプト作成までは出来ているはずなので、/etc/rc.conf に下記の5行を追加します:
# vi /etc/rc.conf
clamav_clamd_enable="YES" clamav_freshclam_enable="YES" clamav_milter_enable="YES" clamav_milter_socket_mode="660" clamav_milter_socket_group="mailuser"その後で、先ず、
# cd /usr/local/etc/rc.d # ./clamav_clamd startとして、エラーが表示されないことを確認したら、
# ps -aux | grep clamavとして、下記のように /usr/local/sbin/clamd が存在することを確認します。
clamav 56967 0.0 7.7 1371840 1291000 - Is 03:03 2:42.64 /usr/local/sbin/clamd続いて、同じように、
# ./clamav_freshclam start # ps -aux | grep clamavとして、下記のように /usr/local/bin/freshclam が存在することを確認、
clamav 57001 0.0 0.2 48820 30412 - Is 03:20 0:08.24 /usr/local/bin/freshclam --daemon -p /var/run/clamav/freshclam.pid最後に、
# ./clamav-milter start # ps -aux | grep clamavとして、下記のように /usr/local/sbin/clamav-milter が存在することを確認します:
clamav 57009 0.0 0.2 92520 29912 - Ss 03:22 0:03.82 /usr/local/sbin/clamav-milter -c /usr/local/etc/clamav-milter.conf何らかの問題が発生した場合、/var/log/clamd.log, /var/log/clamav-milter.log,/var/log/freshclam.log,/var/log/maillog などに解決のヒントが記述されているので、解決を試みることになります。
OpenDKIM の起動
先述の記事で、既に起動スクリプト作成までは出来ているはずなので、/etc/rc.conf に下記の3行を追加します:
# vi /etc/rc.conf
milteropendkim_enable="YES" milteropendkim_cfgfile="/usr/local/etc/opendkim/opendkim.conf" milteropendkim_socket="local:/var/run/milteropendkim/dkim-milter"その後で、先ず、
# cd /usr/local/etc/rc.d # ./milter-opendkim startとして、エラーが表示されないことを確認したら、
# ps -aux | grep opendkimとして、下記のように /usr/local/sbin/opendkim が存在することを確認します:
opendkim 33260 ... 12776 - Ss 03:31 0:01.16 /usr/local/sbin/opendkim -l -p local:/var/run/milteropendkim/dkim-milter -u opendkim:mailuser -P /var/run/milteropendkim※ 記事表示スペースの関係上、実際の表示項目を一部省略しています。
milter-manager の起動
先述の記事で、既に起動スクリプト作成までは出来ているはずなので、/etc/rc.conf に下記の1行を追加します:
# vi /etc/rc.conf
milter_manager_enable="YES"これで、起動準備完了なのですが、初めての場合・milter アプリケーションを追加した場合、「miiter-manager が milter アプリケーションを自動検出できるかどうか」を必ず事前確認することを強くお勧めします。
自動検出できるか否かのチェックは、
# /usr/local/sbin/milter-manager -u milter-manager --show-configで実行でき、この時に表示される内容で、
define_milter("clamav-milter") do |milter| # /usr/local/lib/milter-manager/binding/lib/milter/manager/detector.rb:44 milter.connection_spec = "unix:/var/run/clamav/clmilter.sock" # default milter.description = nil # /usr/local/lib/milter-manager/binding/lib/milter/manager/detector.rb:37 milter.enabled = true # default milter.fallback_status = "accept" ・ ・ 《中略》 ・ ・ define_milter("milter-opendkim") do |milter| # /usr/local/lib/milter-manager/binding/lib/milter/manager/detector.rb:44 milter.connection_spec = "local:/var/run/milteropendkim/dkim-milter" # default milter.description = nil # /usr/local/lib/milter-manager/binding/lib/milter/manager/detector.rb:37 milter.enabled = true # default milter.fallback_status = "accept"といった内容が含まれていることと、
特に milter.enabled = true になっている点、
milter.connection_spec が示す ソケットインタフェースのファイルパスが正しく指示していることを確認します。
上記例のようになっていれば問題ありません。
その後で、先ず、
# cd /usr/local/etc/rc.d # ./milter-manager startとして、エラーが表示されないことを確認したら、
# ps -aux | grep milter-managerとして、下記のように /usr/local/sbin/clamd が存在することを確認します。
milter-manager 31520 ... 28472 - S 03:57 0:41.49 /usr/local/sbin/milter-manager --pid-file /var/run/milter-manager/milter-manager.pid --user-name milter-manager --group root 31518 ... 28072 0- S 03:57 0:05.64 /usr/local/sbin/milter-manager --pid-file /var/run/milter-manager/milter-manager.pid --user-name milter-manager --group※ 記事表示スペースの関係上、実際の表示項目を一部省略しています。
○ FreeBSD 版 milter-manager における自動検出の仕組み
単純にソースコードからインストールしただけだと、「自動検出」が可能な状態にはなりません。
ですが、milter-manager 日本語版 の説明を隅々まで眺めると、『milter アプリケーションを Ports/Packages でインストールしたことを前提としている』と書かれています。
ということは、/usr/local/etc/rc.d ディレクトリ配下に、決まった形式の起動・終了スクリプトを用意すれば、自動検出が可能になるのでは?
ということで、試しに設置することにします。
スクリプトの雛形は 各 Ports の files ディレクトリ配下にあり、これを実運用環境に合わせて変更します。
この時、 /etc/rc.conf の変更も必要です。/etc/rc.conf の中に最低限 clamav_clamd_enable="YES" のような一文が無いと、手動で起動・停止スクリプトを実行する際にエラーを吐いて起動しないのです。
ClamAV はこれで自動検出できるようになったのですが、OpenDKIM は自動検出しません。
散々悩んだ挙句、/usr/local/etc/rc.d ディレクトリ配下に設置する、スクリプトファイル名の問題でした。
当初、opendkim_milter というファイル名で作成したのですが、これを opendkim-milier に変えたら自動検出できるようになりました。このあたりの仕組みがブラックボックスなので、悩むところです。
おそらく、各起動スクリプトの3行目 にある PROVIDE 行と実際のファイル名を一致させないと駄目なのかもしれません。
トラブル解決の際の参考になれば幸いです。
SpamAssassion の起動
先述の記事で、既に起動スクリプト作成までは出来ているはずなので、/etc/rc.conf に下記の1行を追加します:
# vi /etc/rc.conf
spamd_enable="YES"その後で、先ず、
# cd /usr/local/etc/rc.d # ./sa-spamd startとして、エラーが表示されないことを確認したら、
# ps -aux | grep spamdとして、下記のように spamd が存在することを確認します。
root 49139 0.0 0.7 162040 124744 - Ss 04:53 1:13.97 spamd (perl) spamd 49141 0.0 0.8 162040 127988 - I 04:53 0:03.52 spamd child (perl) spamd 49142 0.0 0.7 162040 124816 - I 04:53 0:00.51 spamd child (perl)
送受信のテスト
テストの前に、テストで使用する受信者のメールボックスディレクトリ直下に .dovecot.sieve のファイル名で、下記のような sieve スクリプトを用意します。
require ["fileinto","vnd.dovecot.filter"] ; filter "spamass.sh" "user@example.com" ; # rule:[SpamAssassin] if header :is "X-Spam-Status" "Yes" { fileinto "spamdrop" ; stop ; } # rule:[Clamav] if header :is "X-Virus-Status" "Yes" { fileinto "spamdrop" ; stop ; }更に、/usr/local/etc/dovecot/sieve-filter ディレクトリ配下に spamass,sh というファイル名で、下記スクリプトを用意します:
#!/bin/sh randomid=`/usr/bin/od -An -tu4 -N4 /dev/random | /usr/bin/tr -d ' '` tmpfname1="/tmp/_${randomid}_1" tmpfname2="/tmp/_${randomid}_2" while read line do /bin/cat >> $tmpfname1 done usernam=`echo -n $1 | /usr/bin/cut -d @ -f 1` userdom=`echo -n $1 | /usr/bin/cut -d @ -f 2` if [ -d /var/mail/${userdom}/${usernam}/spamassassin/spamd ]; then /usr/local/bin/spamc -u $1 < $tmpfname1 > $tmpfname2 /bin/cat $tmpfname2 /bin/rm $tmpfname1 /bin/rm $tmpfname2 else /bin/cat $tmpfname1 /bin/rm $tmpfname1 fi exit 0このスクリプトは、実行権限を付与するのを忘れないでください。
これで、電子メール配信毎に、配信最終段階で、自動的に spamass.sh を実行し、その中で spamassassin による電子メール spam チェックを行い、spamassassin がメールヘッダ部に追加した spam チェック結果により spamdrop ディレクトリ配下にメッセージを隔離する処理を自動振り分けの形で行う挙動になります。
この時、隔離先に指定している spamdrop は、テストで使用する受信者のメールボックスディレクトリ直下に .spamdrop のディレクトリ名で用意しなければなりません。この点がどこにも明記されておらず、ディレクトリを用意しているのに「spamdrop が無い」と、sieve スクリプトでエラーを吐かれるという現象に何時間も悩みました。。
spamassassin の挙動設定や、フィルタのデータは、各受信者のメールボックスディレクトリ直下の spamassassin/spamd ディレクトリ配下の user_prefs などを参照します。
この状態でテスト受信者宛てに電子メールを送信してみて、受信電子メールのメールヘッダに以下のようなヘッダが含まれていれば、成功です:
X-Spam-Checker-Version: SpamAssassin 4.0.0 (2022-12-14) on mx0.example.com X-Spam-Level: X-Spam-Status: No, score=-2.5 required=4.0 tests=BAYES_00,KHOP_HELO_FCRDNS, NICE_REPLY_A,SPF_HELO_NONE,SUBJ_ALL_CAPS autolearn=ham autolearn_force=no version=4.0.0また、テスト受信者から、返信か新規に電子メールを送信してみて、下記のようなDKIMヘッダが付いていれば、成功です:
DKIM-Signature: v=1; a=rsa-sha256; c=simple/simple; d=example.com; s=mx0; t=1672471637; bh=3mQXSVMo2kr2sHu262xQGwzCfRBaMvLhHS2T4KSLTSw=; h=Date:Subject:To:References:From:In-Reply-To; b=AjxunnUSbCBDAP3yGcB9lCa1Gjys9PYqZ0cup0a0D2QibriW1KpJPxeUKc84e+/aQ Q3FkBGJ42pe0tReKbA/G40SI3+TI07q5Ktdn2M+Zz3WK1vyeQfnyZ8gZEvj2tLiin2 9Jc6H5qKeEvIx5AQrvIEAyukmXCuXVjGIbujHF2WZbfOmsqeI5eBvDPYK5QAcdrkM+ Ewgc8asLgEIxhOzpMruDEyvJJ8UYJnEPf/hqT5ULWcivOkzvgKL95EEzI42xo3QBd6 DgpQ8kjx9KpsNRJv7IYDrmD9aFoP5mvjzTx51f9+K1uKENXimM7d7MB1kaktiNVKtO XB7v6ywP9dQCw==