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="/var/tmp/_${randomid}_1" tmpfname2="/var/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==
2022/12/29(木)メールサーバの中規模改修と基礎知識(7)~ postfix
2022/12/29 7:43

postfix は、sendmail の代替を目指す、電子メール送受信プログラムです。
記事公開日時点では、3.7.3 が最新バージョンです。
Postfix のインストール
機能説明等は不要と思いますので、早速インストール手順を示してみます。インストール作業は、全て root ユーザで行います。
Postfix をインストールする場合、FreeBSD13 では、下記のモジュールが事前に必要です。(但し、2022/12/24 現在)
これらの多くは、Ports や Package でインストールしても、管理上特段問題にはなりません。
・perl5-5.36.0 (Ports から カテゴリ:lang) ・ca_root_nss-3.86 (Ports から カテゴリ:security) ・autoconf-2.71 (Ports から カテゴリ:devel) ・libltdl-2.4.7 (Ports から カテゴリ:devel) ・libtool-2.4.7 (Ports から カテゴリ:devel) ・pcre2-10.40 (Ports から カテゴリ:devel) ・OpenLDAP 2.6.3 以上 (これはソースコードからの構築を強く推奨) ・dovecot 2.3.19.1 以上 (本記事シリーズでソースコードから構築) ・gmake-4.3_2 (Ports から カテゴリ:devel) ・icu-72.1,1 (Ports から カテゴリ:devel)上記をインストール出来ていたら、先ず、運用時における Postfix 自体が意図しているセキュリティポリシーに合わせるため、ここで専用のユーザを予めvipw や useradd コマンドで作っておきます。
vipw の場合は、編集画面で、下記の行を追加しておきます:
postfix::2000:2000::0:0:postfix:nonexistent:/usr/sbin/nologinvipw でユーザ追加した場合は、/etc/group ファイルに下記の行を追加しておきます:
postdrop:*:65001:更に、/etc/group ファイル内の該当行を下記のように変更しておきます:
mailuser:*:3000:opendkim,milter-manager,postfixユーザID、グループIDは、上記例にこだわる必要はありませんが、当然のことながら、ユーザID・グループIDが他と重複しないように注意です。
更に vipw でユーザ追加した場合は、つまらないセキュリティホールを作らないために、下記コマンドも一応実行しておきます:
# passwd postfix今度は以下の手順に沿ってインストール作業を行います。Postfix のインストールは configure を使わない独特で且つ汎用的に対応できる形態になっています。
# cp postfix-3.7.3.tar.gz /usr/local/src # cd /usr/local/src # tar xvzf postfix-3.7.3.tar.gz # cd postfix-3.7.3 # setenv CPPFLAGS '-I/usr/local/include -I/usr/include' (configure が上手くライブラリを探せないため) # setenv LDFLAGS '-L/usr/local/lib -L/usr/lib' (configure が上手くライブラリを探せないため) # unsetenv LD_LIBRARY_PATH' (3.7.x からは、LD_LIBRARY_PATH が設定されているとコンパイルを受け付けない) ※画面上では、説明のために改行していますが、 make の部分は、改行せずに、半角スペースで区切って、一気に入力。 # make -f Makefile.init makefiles (OS等を自動識別してコンパイル) 'CCARGS=-DHAS_LDAP -DUSE_TLS -DUSE_SASL_AUTH (LDAP,SSL,SASL認証をサポートする指示) -DDEF_SASL_SERVER=\"dovecot\" (dovecot SASL を使用する指示 ※2.3.x 以降で必須) -DDEF_COMMAND_DIR=\"/usr/local/sbin\" (postfix 各種実行プログラムの格納ディレクトリ) -DDEF_CONFIG_DIR=\"/usr/local/etc/postfix\" (postfix 各種設定ファイル格納ディレクトリ) -DDEF_DAEMON_DIR=\"/usr/local/libexec/postfix\" (postfix 各種デーモンプログラムの格納ディレクトリ) -I/usr/local/include -I/usr/include/openssl' (openssl のヘッダファイル) 'AUXLIBS=-L/usr/lib -lssl -lcrypto (SSL ライブラリのある場所) -L/usr/local/lib -lldap -llber -licudata -licui18n -licuio -licutest -licutu -licuuc' (LDAP・icu ライブラリのある場所)postfix の場合、いわゆる「メール送信」だけを行う Null Client な構成だと、上記 make コマンドに与えるパラメータが異なってくるのですが、今回は、普通のメールサーバの構築を行うため、提示のオプションになります。
続いて、
# makeで、エラーが出ないで終了したことを確認したら、
# make installで、インストールを実施します。CUIインタフェースですが、対話形式のインストーラとなっています。
[ ] 内で示す文字列は、デフォルト値または、識別している値です。
変更しない場合は、そのままリターンキー押下、変更する場合に設定値を入力してリターンキー押下で次の項目に進みます。
※下記のように設問に対応する。(設問順序は、必ずしもこの順番にはなりません) Please specify the prefix for installed file names. This is useful if you are building ready-to-install packages for distribution to other machines. install_root: [/] Please specify a directory for scratch files while installing Postfix. You must have write permission in this directory. tempdir: [/usr/local/src/postfix-3.7.3] /tmp Please specify the destination directory for installed Postfix configuration files. config_directory: [/usr/local/etc/postfix] Please specify the destination directory for installed Postfix administrative commands. This directory should be in the command search path of adminstrative users. command_directory: [/usr/local/sbin] Please specify the destination directory for installed Postfix daemon programs. This directory should not be in the command search path of any users. daemon_directory: [/usr/local/libexec/postfix] Please specify the final destination directory for Postfix-writable data files such as caches or random numbers. This directory should not be shared with non-Postfix software. data_directory: [/var/lib/postfix] /var/tmp/postfix Please specify the destination directory for the Postfix HTML files. Specify "no" if you do not want to install these files. html_directory: [no] Please specify the owner of the Postfix queue. Specify an account with numerical user ID and group ID values that are not used by any other accounts on the system. mail_owner: [postfix] Please specify the full destination pathname for the installed Postfix mailq command. This is the Sendmail-compatible mail queue listing command. mailq_path: [/usr/bin/mailq] /usr/local/libexec/postfix/mailq Please specify the destination directory for the Postfix on-line manual pages. You can no longer specify "no" here. manpage_directory: [/usr/local/man] Please specify the full destination pathname for the installed Postfix newaliases command. This is the Sendmail-compatible command to build alias databases for the Postfix local delivery agent. newaliases_path: [/usr/bin/newaliases] /usr/local/libexec/postfix/newaliases Please specify the destination directory for Postfix queues. queue_directory: [/var/spool/postfix] Please specify the destination directory for the Postfix README files. Specify "no" if you do not want to install these files. readme_directory: [no] /usr/local/etc/postfix/docs Please specify the full destination pathname for the installed Postfix sendmail command. This is the Sendmail-compatible mail posting interface. sendmail_path: [/usr/sbin/sendmail] /usr/local/libexec/postfix/sendmail Please specify the group for mail submission and for queue management commands. Specify a group name with a numerical group ID that is not shared with other accounts, not even with the Postfix mail_owner account. You can no longer specify "no" here. setgid_group: [postdrop] Please specify the final destination directory for Postfix shared-library files. shlib_directory: [no] Please specify the final destination directory for non-executable files that are shared among multiple Postfix instances, such as postfix-files, dynamicmaps.cf, as well as the multi-instance template files main.cf.proto and master.cf.proto. meta_directory: [/usr/local//etc/postfix]もし間違えたら、修正手段は容易されていないので、Ctrl+C で中断し再度
# make installを行います。
次に、FreeBSD に特化した設定内容として、 /etc/mail/mailer.conf の設定変更を行います。
このファイルの内容を下記のように変更します:
# $FreeBSD: src/etc/mail/mailer.conf,v 1.3 2002/04/05 04:25:12 gshapiro Exp $ # # Execute the "real" sendmail program, named /usr/libexec/sendmail/sendmail # sendmail /usr/local/libexec/postfix/sendmail send-mail /usr/local/libexec/postfix/sendmail mailq /usr/local/libexec/postfix/sendmail newaliases /usr/local/libexec/postfix/sendmail hoststat /usr/local/libexec/postfix/sendmail # purgestat /usr/local/libexec/senamail/sendmail
Postfix の設定
○ サーバ証明書の取得とセットアップLet's Encrypt の certbot を使用する前提でここに手順を記述しています。
※ 操作するサーバ上で Webサーバが稼動している場合は、必ず一旦停止させること。 # certbot certonly --standalone --agree-tos -m user@example.com -d smtp.example.com # certbot certonly --standalone --agree-tos -m user@example.com -d smtp.example.net # cd /usr/local/etc/postfix # vi tls_sni.maptls_sni.map は、上記例をもとにすると、下記内容のように記述します:
※複数行の表示になっているが、
1ドメイン=1行で [対象ドメイン名] [秘密鍵ファイル名] [CA・公開鍵結合ファイル名] の順に、
半角スペースで区切って入力してください。
smtp.example.com /usr/local/etc/letsencrypt/live/smtp.example.com/privkey.pem /usr/local/etc/letsencrypt/live/smtp.example.com/fullchain.pem smtp.example.net /usr/local/etc/letsencrypt/live/smtp.example.net/privkey.pem /usr/local/etc/letsencrypt/live/smtp.example.net/fullchain.pemtls_sni.map の編集を行ったら、
# postmap -F hash:/usr/local/etc/postfix/tls_sni.mapで、 Postfix で処理できるデータベース形式に変換しておきます(tls_sni.map.db が新たに生成されます)。
○ main.cf の設定変更
次に、/usr/local/etc/postfix/main.cf を下記の要領で編集します:
# cd /usr/local/etc/postfix # cp main.cf main.cf.org # vi main.cf※ 最低限の変更部分のみ抜粋:
compatibility_level = 3.6 #挙動の設定 inet_protocols = all #IPv4,IPv6 両方使用 inet_interfaces = all unknown_address_reject_code = 550 tls_server_sni_maps = hash:/usr/local/etc/postfix/tls_sni.map #TLS対象ホスト名 smtpd_tls_CApath = /etc/ssl/carts #接続相手先のCAルート証明書情報 smtpd_tls_chain_files = /usr/local/etc/letsencrypt/live/pmx1.admin-plus.net/privkey.pem, /usr/local/etc/letsencrypt/live/pmx1.admin-plus.net/fullchain.pem #デフォルト適用の証明書情報 smtpd_tls_received_header = yes smtpd_tls_session_cache_database = hash:/var/tmp/postfix/smtpd_scache #キャッシュデータベース smtpd_tls_loglevel = 1 #ログレベルの設定(必要に応じ 1 ~ 3 ) smtpd_tls_security_level = may #TLSサポートレベルの設定 smtpd_sasl_auth_enable = yes #SASL による SMTP-AUTHサポート smtpd_sasl_type = dovecot #SASL認証機構の指定 smtpd_sasl_path = private/auth #SASL認証ソケットの指定 smtpd_sender_restrictions = reject_unknown_sender_domain smtpd_relay_restrictions = permit_mynetworks, permit_sasl_authenticated, defer_unauth_destination smtpd_recipient_restrictions = permit_mynetworks, permit_sasl_authenticated, reject_unauth_destination smtp_tls_CApath = /etc/ssl/carts #接続クライアントのCAルート証明書情報 smtp_tls_session_cache_database = hash:/var/tmp/postfix/smtp_scache #キャッシュデータベース smtp_tls_security_level = may #TLSサポートレベルの設定 smtp_tls_loglevel = 1 #ログレベルの設定(必要に応じ 1 ~ 3 ) milter_protocol = 6 #milterプロトコルパージョンを6にする milter_default_action = accept #milter接続失敗時のアクション milter_mail_macros = {auth_author} {auth_type} {auth_authen} #milter呼び出し時のパラメータ設定 smtpd_milters = unix:/var/run/milter-manager/milter-manager.sock #SMTPD 時の milter 呼び出しアクション non_smtpd_milters = unix:/var/run/milter-manager/milter-manager.sock #SMTPD 以外の milter 呼び出しアクション virtual_mailbox_maps = ldap:/usr/local/etc/postfix/ldap-mailbox.cf #バーチャルユーザ情報 virtual_transport = dovecot #バーチャルユーザ配送 LDA指定 dovecot_destination_recipient_limit = 1 #同時配送数(複数メールの同時処理無し設定)○ master.cf の設定変更
次に、/usr/local/etc/postfix/master.cf を下記の要領で編集します:
# cp master.cf master.cf.org # vi master.cf※ 最低限の変更部分のみ抜粋:
smtp inet n - n - - smtpd smtps inet n - n - - smtpd -o smtpd_tls_wrappermode=yes -o smtpd_sasl_auth_enable=yes -o smtpd_sasl_type=dovecot -o smtpd_sasl_path=private/auth -o smtpd_sender_restrictions=reject_unknown_sender_domain -o smtpd_relay_restrictions=permit_mynetworks,permit_sasl_authenticated,reject_unauth_destination -o smtpd_recipient_restrictions=permit_mynetworks,permit_sasl_authenticated,reject_unauth_destination -o smtpd_tls_security_level=may submission inet n - n - - smtpd -o smtpd_tls_wrappermode=yes -o smtpd_sasl_auth_enable=yes -o smtpd_sasl_type=dovecot -o smtpd_sasl_path=private/auth -o smtpd_sender_restrictions=reject_unknown_sender_domain -o smtpd_relay_restrictions=permit_mynetworks,permit_sasl_authenticated,reject_unauth_destination -o smtpd_recipient_restrictions=permit_mynetworks,permit_sasl_authenticated,reject_unauth_destination -o smtpd_tls_security_level=may tlsmgr unix - - n 1000? 1 tlsmgr dovecot unix - n n - - pipe flags=DRhu user=vmail argv=/usr/local/libexec/dovecot/deliver -f {$sender} -d ${recipient}master.cf のこの設定で、smtp(port 25)、smtps(port 465)、submission(port 587) の待ち受けを可能にします。
最後に、aliases の設定をします。
# cd /etc/mail # vi /etc/mail/aliasesaliases の該当行を下記のように変更しておきましょう:
root: me@example.com ↓ root: user@example.jp要するに、実在し、受信できる電子メーるアドレスにします。
無断で他人のメールアドレスを記述したり、存在しないメールアドレスを記述してはいけません。
これを変更したら
# newaliasesとして、データベースを更新しておきます。aliases.db が直近の時刻に変更されていることを ls -al コマンドなどで確認しておいてください。
Postfix の設定は以上です。
2022/12/28(水)メールサーバの中規模改修と基礎知識(6)~ milter-manager
2022/12/28 4:21
日本語の milter-manager サポートページは、2.1.5 (2019/09/10 リリース)で更新が止まっており(但し、大いに参考にはなる)、FreeBSD の Ports は 2.1.6 (2022/01/13 リリース)で更新が止まっているのですが、milter-manager の最新バージョンはどうやら 2.2.5(2022/12/12 リリース)のようです。
milter-manager の概要
今回は、下手くそ(且つ汚ない)な手書きで描いた、下記のような挙動をさせるために使います。
複数の milter アプリケーションを使用する場合、postfix 側で単純に milter の設定を行えば事足ります。
ですが、実際はたった2つでも設定がちょっと煩雑になる。
加えて、将来的に電子メールサービスの付加機能は増えていく傾向にあると思われるため、そのような状況に先回り対処する目的で開発されたのが、この milter-manager です。
milter アプリケーションは、典型的なデーモン形式の造りになっているのが通常で、ソケット通信で電子メールメッセージの授受を行いますが、TCP/IPによるソケット通信では、サーバ負荷が重くなりがちなのです。
なので、通常は unix ソケット通信による手法で代替し、今回も milter-manager とのやりとりは、全て unix ソケット通信にて動作させています。
milter-manager は、postfix からの一度の呼び出しアクションで、バックグラウンドで複数の milter アプリケーション処理を実行する役目を担います。
milter-manager のインストール準備(1)
ここからは、基本的に root アカウントでの作業となります。milter-manager をインストールする場合、FreeBSD13 では、下記のモジュールが事前に必要です。(但し、2022/12/24 現在)
・perl5-5.36.0 (Ports から カテゴリ:lang) ・ruby-3.0.5,1 (Ports から カテゴリ:lang) ・libtool-2.4.7 (Ports から カテゴリ:devel) ・gettext-runtime-0.21 (Ports から カテゴリ:devel) ・gettext-tools-0.21_1 (Ports から カテゴリ:devel) ・libev-4.33,1 (Ports から カテゴリ:devel) ・gmake-4.3_2 (Ports から カテゴリ:devel) ・libxml2-2.10.3_1 (Ports から カテゴリ:textproc) ・glib-2.74.4_2 (Ports から カテゴリ:devel) ・gobject-introspection-1.74.0,1(Ports から カテゴリ:devel) ・intltool-0.51.0_1 (Ports から カテゴリ:textproc) ・rubygem-glib2-4.0.3 (Ports から カテゴリ:devel) ・rubygem-rexml-3.2.5 (Ports から カテゴリ:textproc)milter-manager も結構依存するものが多いのですが、
これらの多くは、Ports や Package でインストールしても、管理上特段問題にはなりません。
ruby で動作させている部分が案外多く、Perl と、何故か gnome ライブラリの一部(glib,gobject) も依存します。
特にに、glib の古いライブラリがサーバ上に残っていると上手く動作しない不具合が確認されています。
更に、インストールに先立ち、milter-manager のセキュリティポリシーに従うため、ユーザ milter-manager を、vipw や useradd コマンドで追加します:
vipw コマンドの場合は、下記の1行を編集画面で追加します。
milter-manager::2005:3000::0:0:milter manager execute user:/home/staff/milter-manager:/usr/sbin/nologin※ ユーザホームディレクトリを内部処理でワークエリア的に使うため、ホームディレクトリを必ず割り当てる
vipw でユーザ追加した場合、/etc/group に下記の1行を例示のように変更しておきます:
mailuser:*:3000:opendkim,milter-manager更に vipw でユーザ追加した場合は、つまらないセキュリティホールを作らないために、下記コマンドも一応実行しておきます:
# passwd milter-manager
milter-manager のインストール準備(2)
先ず、ソースコードの展開を行います。# cp milter-manager-2.2.5.tar.gz /usr/local/src # cd /usr/local/src # tar xvzf milter-manager-2.2.5.tar.gz # cd milter-manager-2.2.5実は、実際にソースコードのコンパイルを実施したところ、FreeBSDにおいては、素のソースコードではエラーが発生し、上手く出来ません。
具体的には、configure スクリプト、binding/ruby/test/run-test.sh、Makefile.in の3本の変更が必要なようです。
これらは、patch コマンドを使用するか、手入力修正して、作業実施前にソースコードの修正を行う必要があります。
ここでは、量が少ないのと、用意が面倒なので手入力で修正しまいます。
FreeBSD12/FreeBSD13 においては、以下のように修正することで、milter-manager 2.2.5 のソースコードでコンパイルできるようになります。(確認済)
binding/ruby/test/run-test.sh 1行目 #!/bin/bash ↓ #!/bin/sh Makefile.in 516行目 milter-manager.pc libmilter.pc $(am__append_1) ↓ milter-manager.pc $(am__append_1) configure 15177 行目 RUBY_GLIB2_CFLAGS="-I$ruby_glib2_gem_dir/ext/glib2" ↓ RUBY_GLIB2_CFLAGS="-I$ruby_glib2_gem_dir/lib"
milter-manager のインストール
以下の手順に従ってインストールしていきます:# setenv CPPFLAGS '-I/usr/local/include -I/usr/include' (configure が上手くライブラリを探せないため) # setenv LDFLAGS '-L/usr/local/lib -L/usr/lib' (configure が上手くライブラリを探せないため) # unsetenv LD_LIBRARY_PATH # ./configure --localstatedir=/varconfigure スクリプトの実行が完了すると、以下のようなサマリーが出力されます:
Configure Result: Package Platform : freebsd Package Options : Default Effective User : Default Effective Group : Default Socket Group : Default Connection Spec : unix:/var/run/milter-manager/milter-manager.sock Default PID File : GLib : 2.74.4 libev : yes Ruby : /usr/local/bin/ruby CFLAGS : -I/usr/local/include/ruby-3.0/amd64-freebsd13 -I/usr/local/include/ruby-3.0/ LIBS : -L/usr/local/lib -fstack-protector-strong -Wl,--compress-debug-sections=zlib -Wl,-E -lruby30 -lm -lpthread -L/usr/local/lib Ruby version : ruby 3.0.5p211 (2022-11-24 revision ba5cf0f7c5) [amd64-freebsd13] Ruby/GLib2 : -I/usr/local/lib/ruby/gems/3.0/gems/glib2-4.0.3/lib Ruby milter PATH : rd2 : rd2-not-found GTK-Doc : no Cutter : LCOV : coverage : coverage report by LCOV : Cutter Source Path : $(top_srcdir)/vendor/cutter-source Launchpad PGP key : GPG UID : 3F09D1EA68E5F18B4EC8FEEAFF2030C057B9884E続いて、下記のコマンドを順に実行し、エラーが無ければ、本体のインストールは完了です。
# gmake # gmake install最後に下記手順で動作環境を準備して、インストール完了です:
# mkdir /home/staff/milter-manager # chown milter-manager:mailuser /home/staff/milter-manager # mkdir /var/run/milter-manager # chown milter-manager:maliuser /var/run/milter-manager
起動・停止スクリプトの設置(FreeBSD に特化している項目)
このスクリプトは一度作っておくと、バージョンアップの際に再作成の必要はありません。○ milter-manager の起動スクリプト
/usr/local/etc/rc.d/ ディレクトリ配下に、milter-manager のファイル名で下記内容を作成します。
実行権限を与えることを忘れないようにしてください:
#!/bin/sh # PROVIDE: milter-manager # REQUIRE: LOGIN # BEFORE: mail # KEYWORD: shutdown # # Add the following lines to /etc/rc.conf to enable milter-manager: # # milter_manager_enable=yes # . /etc/rc.subr name="milter_manager" rcvar="milter_manager_enable" extra_commands="reload" load_rc_config $name : ${milter_manager_enable="NO"} : ${milter_manager_pid_file="/var/run/milter-manager/milter-manager.pid"} if getent passwd milter-manager > /dev/null; then : ${milter_manager_user_name="milter-manager"} else : ${milter_manager_user_name="mailnull"} fi if getent group milter-manager > /dev/null; then : ${milter_manager_group_name="milter-manager"} else : ${milter_manager_group_name="mailuser"} fi : ${milter_manager_socket_group_name="mailuser"} : ${milter_manager_connection_spec=""} : ${milter_manager_debug="NO"} command=/usr/local/sbin/milter-manager pidfile="${milter_manager_pid_file}" command_args="--pid-file ${milter_manager_pid_file}" if test -n "${milter_manager_user_name}"; then command_args="${command_args} --user-name ${milter_manager_user_name}" fi if test -n "${milter_manager_group_name}"; then command_args="${command_args} --group-name ${milter_manager_group_name}" fi if test -n "${milter_manager_socket_group_name}"; then command_args="${command_args} --unix-socket-group ${milter_manager_socket_group_name}" fi if test -n "${milter_manager_connection_spec}"; then command_args="${command_args} --spec ${milter_manager_connection_spec}" fi if test "$milter_manager_debug" = "YES"; then command_args="${command_args} --verbose" else command_args="${command_args} --daemon" fi run_rc_command "$1"今回意図した環境では、FreeBSD においては、デフォルト設定(自動検出)で問題なく動作しますが、実際には試行錯誤があったため、別記事でそのあたりを示していきます。
2022/12/27(火)メールサーバの中規模改修と基礎知識(5)~ OpenDKIM
2022/12/27 5:06
公式公開バージョンは、記事公開日時点では、2.10.3 です。一部のLinux ディストリビューションに 2.11.x が提供されているようですが、これは、RC版(Release Candidate:リリース候補の意)の位置づけの状態です。
OpenDKIM の概要
OpenDKIM は、電子メールメッセージを基に検証鍵を電子メールヘッダに埋め込み、DNSに登録した公開鍵を使って検証することで、電子メール発信元の正当性を確認し、電子メール改ざんがされていないことも確認する一助になります。具体的には、予め送信元DNS情報に下記2つの TXTレコードを公開する形で登録しておき、


電子メール送信の際は、下記のように「DKIM-Signature:」というヘッダ行にて、一定のルールで計算された暗号キーを追加する処理を行います。

受信の際は、このDNS情報を基にメールヘッダに添付されてきたヘッダ暗号キーの検証を行い、この暗号キーに問題が無ければ「メール改ざんが無かった」と見做す、という処理を行うのが OpenDKIM の役割です。
送信の際の「DKIM-Signature:」ヘッダ行追加・受信の際の「DKIM-Signature:」ヘッダ行検証処理は、postfix にて、milter インタフェースを介して行うことになります。
OpenDKIM のインストール準備(1)
この先は、root アカウントにて、一連の作業を行います。OpenDKIM は、公開鍵の管理にPython と Perlを使用しているため、この2つは必須です。
OpenDKIM をインストールする場合、FreeBSD13 では、下記のモジュールが事前に必要です。(但し、2022/12/24 現在)
これらの多くは、Ports や Package でインストールしても、管理上特段問題にはなりません。
・perl5-5.36.0 (Ports から カテゴリ:lang) ・python39-3.9.16 (Ports から カテゴリ:lang) ・lua54-5.4.4 (Ports から カテゴリ:lang) ・autoconf-2.71 (Ports から カテゴリ:devel) ・automake-1.16 (Ports から カテゴリ:devel) ・libltdl-2.4.7 (Ports から カテゴリ:devel) ・libtool-2.4.7 (Ports から カテゴリ:devel) ・gnutls-3.7.8_1 (Ports から カテゴリ:security) ・db5-5.3.28_9 (Ports から カテゴリ:databases) ※ これは BerkeleyDB 5.3.28 ですOpenDKIM 2.10.3 は、OpenSSL 1.0 系までは対応しているものの、OpenSSL 1.1 系には対応していません。
昨今の FreeBSD にて採用されている OpenSSL は1.1 系のため、代替選択として、gnutls のインストールが必要になります。OpenSSL 1.1系対応なら、素直に OpenSSL を使うことで事が足りるのですが。。
更に、インストールに先立ち、OpenDKIM のセキュリティポリシーに従うため、ユーザ opendkim を、vipw や useradd コマンドで追加します:
vipw コマンドの場合は、下記の1行を編集画面で追加します。
opendkim::2006:3000::0:0:OpenDKIM execute user:/var/empty:/usr/sbin/nologinvipw でユーザ追加した場合、/etc/group に下記の1行を例示のように変更しておきます:
mailuser:*:3000:opendkim更に vipw でユーザ追加した場合は、つまらないセキュリティホールを作らないために、下記コマンドも一応実行しておきます:
# passwd opendkim
OpenDKIM のインストール準備(2)
先ず、ソースコードの展開を行います。# cp opendkim-2.10.3.tar.gz /usr/local/src # cd /usr/local/src # tar xvzf opendkim-2.10.3.tar.gz # cd opendkim-2.10.3実は、実際にソースコードのコンパイルを実施したところ、FreeBSDにおいては、素のソースコードでは、GnuTLS 使用環境での構築も上手く出来ません。
具体的には、configure スクリプト、libopendkim/tests/Makefile.in、libopendkim/dkim-canon.c、libopendkim/dkim.c、miltertest/miltertest.c、opendkim/tests/Makefile.in、opendkim/opendkim-crypto.c、 opendkim/opendkim-lua.c の8本の変更が必要なようです。
これらは、patch コマンドを使用するか、手入力修正して、作業実施前にソースコードの修正を行う必要があります。
FreeBSD patch コマンド向けの差分ファイルは、https://ctrl.basekernel.ne.jp/rebase/download.html からダウンロードできるようにしてありますので、『opendkim-2.3.10用 FreeBSD 向け Patch ファイル群』をダウンロードしてみて、使えるようであれば、使ってみてください。
おそらく、以下のように実行すると良いと思います(当方では、この手法で出来ることの確認をしていません)
# cp opendkim-2.10.3.patch.gz /usr/local/src/opendkim-2.10.3 # cd /usr/local/src/opendkim-2.10.3 # tar xvzf opendkim-2.10.3.patch.gz # patch < patch-configure.ac # patch < patch-libopendkim__tests__Makefile.in ・ ・ # patch < patch-opendkim_opendkim-lua.c
OpenDKIM のインストール
以下の手順で実行していきます:# cd /usr/local/src/opendkim-2.10.3 # setenv CPPFLAGS '-I/usr/local/include -I/usr/include' (configure が上手くライブラリを探せないため) # setenv LDFLAGS '-L/usr/local/lib -L/usr/lib -L/usr/local/lib/db5'(configure が上手くライブラリを探せないため) # unsetenv LD_LIBRARY_PATH ※以下、説明のために改行していますが、 ./configure の部分は、改行せずに、半角スペース区切りで、一気に入力。 # ./configure --localstatedir=/var (unix ソケットなどを格納するディレクトリ) --with-gnutls (openssl 1.1.x は未サポートのため、gnutls を使用する) --with-milter (milter インタフェースを構築する) --with-db (BerkeleyDBをサポートする) --with-domain (domain 設定をサポートする) # make # make installここまで、エラー無く出来たら、インストール不具合が1つあるので、下記の要領でファイル修正を行います。
# vi /usr/local/sbin/opendkim-genkey
1行目を下記の要領で変更 #!/usr/bin/perl ↓ #!/usr/local/bin/perl次に設定作業を行います。
# mkdir /usr/local/etc/opendkim # cd /usr/local/etc/opendkim # mkdir example.com.keys (メールサーバ収容ドメイン毎にディレクトリを作成) # cd example.com.keys # /usr/local/sbin/opendkim-genkey --bits=2048 --domain=example.com --selector=sel (--domain:収容ドメイン --selector:任意) ※ --selector の文字列は公開鍵識別子になるので、適当にせずに何等かの規則を作るとよいでしょう。 pop1 とか mx1 とか、メールサーバの付番に対応すると良いと思います。 # cd ../ # chown -R opendkim:mailuser example.com.key # vi KeyTable ※ 以下のように編集をする(複数ドメインになる場合は、行追加) sel._example.com example.com:sel:/usr/local/etc/opendkim/example.com.keys/sel.private # vi SigningTable ※ 以下のように編集をする(複数ドメインになる場合は、行追加) *@example.com sel._domainkey.example.com # chown opendkim:mailuser KeyTable # chown opendkim:mailuser SigningTableここで、KeyTable ファイルへの記述方法ですが、
①._②:①:/usr/local/etc/opendkim/②.keys/①.private
(①= --selector への設定文字列 ②= --domain への設定文字列)
SigningTable ファイルへの記述方法は、
*@② ①._domainkey.②
(①= --selector への設定文字列 ②= --domain への設定文字列) のようにします。
次に、上記で /usr/local/sbin/opendkim-genkey を実行した時に生成された、sel.txt の内容と、取り扱いポリシーをDNSへ登録します。(--selector の指定により、拡張子 .txt は変わりませんが、ファイル名は変わります。)
生成された、sel.txt の内容を見ると、テキスト形式にて、
sel._domainkey IN TXT ( "v=DKIM1; k=rsa; " "p=MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAulH2mMsm8eP7bpAmlXI9EE5TQ8tjWBaMDaSP34zB+0+LLjJhbi9dhGV9T5reppaxaU7lzokGaHJX+l9X4sA53G9PlpzQ0JwsGO5Z1E9LaN1CDijqtGNQWr7bdLpy4AwzfhDThY25rwzMg4Wt4LK74Ba7Q5a2M9m0d/gEqs6ZWrK/6DiQ1qnzU7JTm13SZRBvnNhmLBMnSu1sz3" "Hc8nE+02oAJC04xCjI8XUowu+sxyJQm7OY97MOvOt9HAXt/jbBVyG1scJTggjYsH1JcfC1xbE1VnNiWSkpid2P+4bXy/GIG90nZ7We4KNMshXEby/FbUZPPERHW1ntCyga58rPJQIDAQAB" ) ; ----- DKIM key sel0 for example.jpのような内容になっています。この例に沿うと、example.jp のDNSゾーンに、
・name : sel._domainkey.example.jp.
・type : TXT
・content:"v=DKIM1; .... 以下 .... yga58rPJQIDAQAB" まで
を登録します。もう一つ、example.jp のDNSゾーンに
・name : _adsp._domainkey.example.jp.
・type : TXT
・content:"dkim=unknown"
を登録します。このパラメータの意味は下記のとおりです:
unknown | 該当ドメインからの送信メールには、メール作成者署名(DKIM)がある場合と無い場合がある |
---|---|
all | 該当ドメインからの送信メールには、必ずメール作成者署名(DKIM)がある もしメール作成者署名(DKIM)が得られない場合の処置は受信側の任意。(通常は配送する) |
discardable | 該当ドメインからの送信メールには、必ずメール作成者署名(DKIM)がある。 もしメール作成者署名(DKIM)が得られない場合は、受信者はそのメールを破棄することが望まれる |
起動・停止スクリプトの設置(FreeBSD に特化している項目)
このスクリプトは一度作っておくと、バージョンアップの際に再作成の必要はありません。○ OpenDKIM の起動スクリプト
/usr/local/etc/rc.d/ ディレクトリ配下に、milter-opendkim のファイル名で下記内容を作成します。
実行権限を与えることを忘れないようにしてください:
#!/bin/sh # PROVIDE: milter-opendkim # REQUIRE: DAEMON # BEFORE: mail # KEYWORD: shutdown # Define these milteropendkim_* variables in one of these files: # /etc/rc.conf # /etc/rc.conf.local # /etc/rc.conf.d/milteropendkim # # milteropendkim_enable (bool): Set to "NO" by default. # Set it to "YES" to enable dkim-milter # milteropendkim_uid (str): Set username to run milter. # milteropendkim_gid (str): Set group to run milter. # milteropendkim_profiles (list): Set to "" by default. # Define your profiles here. # milteropendkim_cfgfile (str): Configuration file. See opendkim.conf(5) # # milteropendkim_${profile}_* : Variables per profile. # Sockets must be different from each other. # # milteropendkim_socket_perms (str): # Permissions for local|unix socket. # # all parameters below now can be set in opendkim.conf(5). # milteropendkim_socket (str): Path to the milter socket. # milteropendkim_domain (str): Domainpart of From: in mails to sign. # milteropendkim_key (str): Path to the private key file to sign with. # milteropendkim_selector (str): Selector to use when signing # milteropendkim_alg (str): Algorithm to use when signing # milteropendkim_flags (str): Flags passed to start command. . /etc/rc.subr name="milteropendkim" rcvar=milteropendkim_enable extra_commands="reload" start_precmd="dkim_prepcmd" start_postcmd="dkim_start_postcmd" stop_postcmd="dkim_postcmd" command="/usr/local/sbin/opendkim" _piddir="/var/run/milteropendkim" pidfile="${_piddir}/pid" sig_reload="USR1" load_rc_config $name # # DO NOT CHANGE THESE DEFAULT VALUES HERE # : ${milteropendkim_enable:="NO"} : ${milteropendkim_uid:="opendkim"} : ${milteropendkim_gid:="mailuser"} : ${milteropendkim_cfgfile:="/usr/local/etc/opendkim/opendkim.conf"} : ${milteropendkim_socket_perms:="0775"} # Options other than above can be set with $milteropendkim_flags. # see dkim-milter documentation for detail. extra_commands="reload" start_precmd="dkim_prepcmd" start_postcmd="dkim_start_postcmd" stop_postcmd="dkim_cleansockets" command="/usr/local/sbin/opendkim" sig_reload="USR1" dkim_cleansockets() { case ${milteropendkim_socket%:*} in local|unix) rm -f "${milteropendkim_socket#*:}" ;; esac } dkim_get_pidfile() { if get_pidfile_from_conf PidFile ${milteropendkim_cfgfile#-x }; then pidfile="$_pidfile_from_conf" else pidfile="/var/run/milteropendkim/${profile:-pid}" fi } dkim_prepcmd() { dkim_cleansockets dkim_get_pidfile if [ ! -d "$(dirname "$pidfile")" ]; then mkdir "$(dirname "$pidfile")" fi case ${milteropendkim_socket%:*} in local|unix) socketfile=${milteropendkim_socket#*:} install -d -o ${milteropendkim_uid%:*} -g $milteropendkim_gid \ -m ${milteropendkim_socket_perms} \ ${pidfile%/*} ${socketfile%/*} ;; esac } dkim_start_postcmd() { case ${milteropendkim_socket%:*} in local|unix) # postcmd is executed too fast and socket is not created before checking... sleep 1 chmod -f ${milteropendkim_socket_perms} ${milteropendkim_socket#*:} ;; esac } if [ -n "$2" ]; then profile="$2" if [ -n "${milteropendkim_profiles}" ]; then pidfile="${_piddir}/${profile}.pid" eval milteropendkim_enable="\${milteropendkim_${profile}_enable:-${milteropendkim_enable}}" eval milteropendkim_socket="\${milteropendkim_${profile}_socket:-}" eval milteropendkim_socket_perms="\${milteropendkim_${profile}_socket_perms:-}" if [ -z "${milteropendkim_socket}" ];then echo "You must define a socket (milteropendkim_${profile}_socket)" exit 1 fi eval milteropendkim_cfgfile="\${milteropendkim_${profile}_cfgfile:-${milteropendkim_cfgfile}}" eval milteropendkim_domain="\${milteropendkim_${profile}_domain:-${milteropendkim_domain}}" eval milteropendkim_key="\${milteropendkim_${profile}_key:-${milteropendkim_key}}" eval milteropendkim_selector="\${milteropendkim_${profile}_selector:-${milteropendkim_selector}}" eval milteropendkim_alg="\${milteropendkim_${profile}_alg:-${milteropendkim_alg}}" eval milteropendkim_flags="\${milteropendkim_${profile}_flags:-${milteropendkim_flags}}" if [ -f "${milteropendkim_cfgfile}" ];then milteropendkim_cfgfile="-x ${milteropendkim_cfgfile}" else milteropendkim_cfgfile="" fi if [ -n "${milteropendkim_socket}" ];then _socket_prefix="-p" fi if [ -n "${milteropendkim_uid}" ];then _uid_prefix="-u" if [ -n "${milteropendkim_gid}" ];then milteropendkim_uid=${milteropendkim_uid}:${milteropendkim_gid} fi fi if [ -n "${milteropendkim_domain}" ];then milteropendkim_domain="-d ${milteropendkim_domain}" fi if [ -n "${milteropendkim_key}" ];then milteropendkim_key="-k ${milteropendkim_key}" fi if [ -n "${milteropendkim_selector}" ];then milteropendkim_selector="-s ${milteropendkim_selector}" fi if [ -n "${milteropendkim_alg}" ];then milteropendkim_alg="-S ${milteropendkim_alg}" fi dkim_get_pidfile command_args="-l ${_socket_prefix} ${milteropendkim_socket} ${_uid_prefix} ${milteropendkim_uid} -P ${pidfile} ${milteropendkim_cfgfile} ${milteropendkim_domain} ${milteropendkim_key} ${milteropendkim_selector} ${milteropendkim_alg}" else echo "$0: extra argument ignored" fi else if [ -n "${milteropendkim_profiles}" ] && [ -n "$1" ]; then if [ "$1" != "restart" ]; then for profile in ${milteropendkim_profiles}; do echo "===> milteropendkim profile: ${profile}" /usr/local/etc/rc.d/milter-opendkim $1 ${profile} retcode="$?" if [ "${retcode}" -ne 0 ]; then failed="${profile} (${retcode}) ${failed:-}" else success="${profile} ${success:-}" fi done exit 0 else restart_precmd="" fi else if [ -f "${milteropendkim_cfgfile}" ];then milteropendkim_cfgfile="-x ${milteropendkim_cfgfile}" else milteropendkim_cfgfile="" fi if [ -n "${milteropendkim_socket}" ];then _socket_prefix="-p" fi if [ -n "${milteropendkim_uid}" ];then _uid_prefix="-u" if [ -n "${milteropendkim_gid}" ];then milteropendkim_uid=${milteropendkim_uid}:${milteropendkim_gid} fi fi if [ -n "${milteropendkim_domain}" ];then milteropendkim_domain="-d ${milteropendkim_domain}" fi if [ -n "${milteropendkim_key}" ];then milteropendkim_key="-k ${milteropendkim_key}" fi if [ -n "${milteropendkim_selector}" ];then milteropendkim_selector="-s ${milteropendkim_selector}" fi if [ -n "${milteropendkim_alg}" ];then milteropendkim_alg="-S ${milteropendkim_alg}" fi dkim_get_pidfile command_args="-l ${_socket_prefix} ${milteropendkim_socket} ${_uid_prefix} ${milteropendkim_uid} -P ${pidfile} ${milteropendkim_cfgfile} ${milteropendkim_domain} ${milteropendkim_key} ${milteropendkim_selector} ${milteropendkim_alg}" fi fi run_rc_command "$1"OpenDKIM の設定は、これで終わりです。