2022/12/24(土)メールサーバの中規模改修と基礎知識(2)~ SpamAssassin
2022/12/25 8:14
具体的には、電子メールヘッダを含めた電子メールメッセージ全体を与え、各種のテストを行い、その結果を spam 度合値として、判定値を提示するような動作になります。
概念図(電子メールメッセージは、① → ② のルートで流れる)
① ①上図のように、サーバサイドでは、spamd をデーモン形式で稼働させておき、spamc というクライアントプログラムにて、受信した電子メールメッセージ全体を、spamd に垂れ流し、メッセージの電子メールヘッダ先頭にその判定値が付加されたものが与えたメッセージ全体と共に出力される挙動になります。
spamc《チェック対象の電子メールメッセージ全体》===> socket通信 ===> spamd(SpamAssassin 本体)
《チェック結果を含む電子メールメッセージ》<=== socket通信 <===
② ②
spamc から見ると、標準入力(stdin) に電子メールメッセージを流し込み、標準出力(stdout)に結果が出てくるような挙動になります。
SpamAssassinは、下図のように X-Spam-Checker-Version・X-Spam-Level・X-Spam-Status という3つのメールヘッダを処理結果として付加します。
このうち、X-Spam-Status というメールヘッダ行が重要で、例示では、「score=-0.6」が spam 度合判定値、「required=4.0」が、spam と見做すしきい値で、この値は別途個別設定出来ます。
電子メール配送の最終段階で、このメールヘッダ部分を参照して、spam メール隔離か通常配送かを決定し、処理する仕組みになります。
「autolearn=ham」というのは、『spam ではないと自動的にパターン学習した』という意味で、spam として見做されると、ここは「autolearn=spam」という表示になります。
「autolearn_force=no」は、SpamAssassin の自動学習機能の如何に関わらず、強制的に「spam である」と学習させる判定値で、この例では「required=4.0」以上の場合に強制的に SpamAssassin に spam メールパターンの学習をさせる挙動になります。
インストール
インストール作業は、必ず root アカウントで行います。また、SpamAssassin は、Perl 上で動作するため、事前に Perl 5.26 以降が必要です。
FreeBSD,NetBSD 他のUnix系OS、Linux系OSにおいては、Perl をパッケージでインストールしても問題はないです。
お勧めは、現時点(2022/12/24 現在)で最新バージョンの Perl 5.36。
FreeBSD だと、Ports で以下の手順でインストールするのが確実。(依存パッケージが先に自動的にインストールされる)
# cd /usr/ports/lang/perl5.36 # make install # make clean
また、インストールに2つの方法がありますが、現状では後者の方法(方法その2)しかまともに出来ないみたいです。(当方の環境にて)
○ 方法その1(動作に必要な依存モジュールは自動的に探してインストールされる):
# perl -MCPAN -e shell cpan> install Mail::SpamAssassinこの方法だと、test 段階で、'spamd が見つからない' とメッセージが出て test自体がなかなか終わらない。
3.4系ではこの問題は出ません。なので、次に示す方法が有効:
○ 方法その2
・まず SpamAssassin の公式ダウンロードページ(https://spamassassin.apache.org/downloads.cgi)から、
Mail-SpamAssassin-4.0.0.tar.gz または、Mail-SpamAssassin-4.0.0.tar.bz2 をダウンロードし、インストール機器上にアップロードする。
・この方法の場合、CPAN で予め、下記モジュールをインストールしておいた方がよい:
# perl -MCPAN -e shell cpan> install NetAddr::IP cpan> install HTML::Parser cpan> install Digest::SHA1 cpan> install IP::Country cpan> install IP::Country::DB_File cpan> install Net::Ident cpan> install IO::Socket::SSL cpan> install LWP::UserAgent cpan> install BSD::Resource cpan> install Mail::SPF cpan> install Mail::DKIM cpan> exit・次に、下記コマンドを順に実行する。
# cp Mail-SpamAssassin-4.0.0.bz2 /usr/locall/src # cd /usr/local/src # tar xvzf Mail-SpamAssassin-4.0.0.bz2 # cd Mail-SpamAssassin-4.0.0 # perl Makefile.PL # make # make installインストール完了後、方法その1・方法その2の何れであっても、必ず以下のコマンドを実行しておきます。
# rehash # sa-update --no-gpgまた、運用時は、SpamAssassin 自体が意図しているセキュリティポリシーに合わせるため、ここで専用のユーザを予めvipw や useradd コマンドで作っておきます。
vipw の場合は、編集画面で、下記の行を追加しておきます:
spamd::783:783::0:0:SpamAssassin Daemon:/nonexistent:/usr/sbin/nologinvipw でユーザ追加した場合は、/etc/group ファイルに下記の行を追加しておきます:
spamd:*:783:ユーザID、グループIDは、783 にこだわる必要はありませんが、当然のことながら、ユーザID・グループIDが他と重複しないように注意です。
更に vipw でユーザ追加した場合は、つまらないセキュリティホールを作らないために、下記コマンドも一応実行しておきます:
# passwd spamdvipw,passwd,useradd コマンドは、どれも必ずroot ユーザ上で行います。
起動・停止スクリプトの設置(FreeBSD に特化している項目)
このスクリプトは一度作っておくと、バージョンアップの際に再作成の必要はありません。○ spamd の起動スクリプト
/usr/local/etc/rc.d ディレクトリ配下に、sa-spamd のファイル名で下記内容を作成します。
1行目から6行目( KEYWORD までの行 ) は、一見するとコメント行そのものですが、意味を持っているため削除しないようにしてください。/usr/local/etc/rc.d ディレクトリ配下のスクリプトは、全てこの挙動になります。
また、実行権限を与えることを忘れないようにしてください:
#!/bin/sh # PROVIDE: spamd # REQUIRE: LOGIN # BEFORE: mail # KEYWORD: shutdown # # Add the following line to /etc/rc.conf to enable spamd: # # spamd_enable="YES" # # You can pass flags to spamd with spamd_flags="..." # To change the user that spamd runs as, use # # spamd_flags="-u USER [-H /path/to/home... we suggest /var/spool/spamd]" # # To keep your user-config in a SQL database, use # # spamd_flags="-Q" # # and remove -c (auto-create user preference files). # . /etc/rc.subr name=spamd rcvar=${name}_enable extra_commands="reload" load_rc_config $name start_precmd="precmd" restart_precmd="precmd" stop_cmd="spamd_stop" pidfile=${spamd_pidfile:-"/var/run/${name}/${name}.pid"} # Set defaults : ${spamd_enable:="NO"} : ${spamd_flags:="-c -u spamd -r ${pidfile} -x --virtual-config-dir=/var/mail/%d/%l/spamassassin/spamd"} command=/usr/local/bin/${name} command_args="-d -r ${pidfile}" command_interpreter="/usr/local/bin/perl" required_dirs="/usr/local/share/spamassassin" precmd() { if [ ! -d /var/run/${name} ]; then mkdir -p /var/run/${name} chown spamd:spamd /var/run/${name} fi } spamd_stop() { kill -INT `cat /var/run/spamd/spamd.pid` echo ' Stop sa-spamd 4.0.0 ' } run_rc_command "$1"あとは、簡単な設定作業が残っていますが、メールサーバ構築作業全体の最後のほうで行います。
なので、とりあえずこのフェーズは完了です。
2022/12/23(金)メールサーバの中規模改修と基礎知識(1)
2022/12/25 4:28
背景や前提条件など
このシリーズは、8回に分けて記事を起こした時点における、今どきのメールサーバ運営管理上のインストール手順や参考情報を掲載します。Portsやバイナリパッケージに頼らず、ソースコードから自力で構築する手順から紹介しています。『時代錯誤だ!』と嘲笑されようが、これを経験することが基礎知識を維持し、育むにはとても重要なのです。
OSは FreeBSD13 ですが、他のLinux 系OSにおいても参考になる部分が多いと思います。
また、ここでは OpenLDAP のインストールや設定を終えており、LDAP 検索にて、電子メールアドレスまたはSASLユーザ名を検索条件として与えると、
・SASL パスワード ・UID ・GID ・homeDirectory ・status〔有効にしている(valid)か、無効にしている(invalid)か〕の情報が得られる仕組みが出来ていることを前提にしています。
実は、約2年前に計画していた改修ですが、
別の企業にて壊れたオンラインシステムの復旧作業・改修作業を事実上一手に引き受けた状態になり、
そちらを優先して、自社システムの細かな不具合がないがしろになっていた状態でした。
当初技術的に先行していた(と自負できる)メールサーバの構成が15年以上経過して色あせてきたことと、
昨今のOutlookやアンチウィルスソフトとの相性が悪くなっているため、中規模改修を行ってこの細かな不具合を出来るだけ解消しようと、やっとのことで実施に移しています。
一口に『メールサーバ』と言っても、知っている人は知っているのですが、構成は複雑です。
サーバ運営・管理的には難易度が高い部類になるかと思います。
上図に(丁寧に作っている暇がないので)手書きで示した構成図を見ても、実に8種類のサーバサイドソフトウェアを使って1つのメールサーバを実現しています。しかも、これは基本的構成に過ぎません。
実際は、このほかにも動作させるために、Perl,ruby,Python といったスクリプト言語や、rust などの新しい言語のライブラリ、各種の補助的ツールを必要とし、メーリングリストの実現なんかは更に、上図で図示していない別のサーバソフトウェアを必要とします。
また、SSL/TLS といった暗号化通信のためには、サーバ証明書の取得・管理だけではなく、OpenSSL,GnuTLS といった暗号化ライブラリが別途必須になります。
こういう構成図(設計図?)を描ける若手エンジニアを昨今では見ませんね。
「クラウド」「クラウド」と、もてはやすおかげで、自力でこのようなものを構築する機会を奪っているから。
ハッキリ言って、この状況では日本のICT技術水準は、自ら周回遅れの状況を作ってしまっています。
ということで、技術継承的な危機感を感じていますが、憂いでも何も変わらないので、せめて構成例の一例として参考にして欲しいということで、自分メモも兼ねて記録に残しています。(つか、こっちがメインかも)
抑えておきたいポート番号とSSL/TLS の対応
皆さまが使う、電子メール送受信ソフトウェア(Outlook,Thunderbird など)にて、サーバの設定におけるポート番号と暗号化通信形式の組み合わせは、一般的に下記の表のようになります。時々「メール送受信が上手く出来ない」という問合わせ受けますが、単純ではないものの、下記の対応が滅茶苦茶になっている設定が案外散見されます。参考にどうぞ。
ポート番号 | 非暗号 | STARTTLS | SSL/TLS | 説明 |
---|---|---|---|---|
25(SMTP) | ○ | ○ | × | 現在はメールサーバ間の通信に使用。 昨今はOP25 対策で、メール送信元で使えない場合が殆ど。 |
587(submission) | ○ | ○ | × | メール送信元にて、メール発信の際に使う。 OP25環境では、メールサーバ間の通信にも使用。 |
465(SMTPS) | × | × | ○ | メール送信元にて、暗号通信を行う際に使用する。 有名どころでは OCN なんかがこれを標準にしているが、 おかげで従来の制御機器が使えなくなるケースも実在する。 |
ポート番号 | 非暗号 | STARTTLS | SSL/TLS | 説明 |
---|---|---|---|---|
110(POP3) | ○ | ○ | × | メール受信者が、メールサーバから電子メールを取り寄せる時に使用。 |
143(IMAP4) | ○ | ○ | × | POP3 と役割は同じだが、メールサーバ上にメールを一定期間残す挙動が標準。 |
993(IMAP4S) | × | × | ○ | IMAP4 を暗号化通信専用にしたようなもの。その他は IMAP4 と同じ。 |
995(POP3S) | × | × | ○ | POP3 を暗号化通信専用したようなもの。その他は POP3 と同じ。 有名どころでは OCN なんかがこれを標準にしているが、 おかげで従来の制御機器が使えなくなるケースも実在する。 |
SSL/TLS は、SSL(Secure Sockets Layer) の後継規格が TLS(Transport Layer Security) というもので、SSL は既に旧規格です。ですが、役割は同じなので、同列に語られます。
SSL は当初、Netscape社が開発したものですが、IETF というインターネット技術の国際標準化組織に引き継ぐ際に名称が変わりました。
と、いうことで次からメールサーバ構築の流れを自分メモ的に記していきます。
2022/03/31(木)postgresql にて、任意の select 文を csv 出力する
2022/03/31 3:38
# psql -h サーバFQDN DB名 -U ユーザ名 -c "《任意のselect 文》;" -A -F , > output.csvサーバFQDN は、ホスト名のほか、IPアドレスでも可能です。自ホストの場合は localhost と指定します。
DB名・ユーザ名は、そのままですね。
任意のselect文は、全体をダブルクォーテーションで括ります。終端には必ずセミコロン「;」を付けます。
select 文中に括弧やダブルクォーテーションが入る場合、エスケープが必要かもしれません。
-A は、「桁揃えなしのテーブル出力」で、これを指定しないと、CSV 出力の際に余計なスペース等が入ってしまいます。
-F は、「桁揃えなし出力時のフィールド区切り文字」で、デフォルトの区切り文字は "|" なので、CSV 出力の場合は、必ずカンマ「,」を指定します。
あとは、リダイレクトで出力ファイル名の指定。
文字コードは、DBの文字コードが適用されます。
2022/02/10(木)Windows 11 にしてみた
2022/02/10 6:50
アップデートの際は、必ずアンチウィルスの動作を無効にしましょう。これがアップデートのときに問題を引き起こします。(下図参照)
これは、当方で有償ライセンスで使用している Avast! の例です。
ハッキリ言って表現が悪いのですが「永久に」というよりは、「再度有効にするまで無効にする」という意味です。
結論から言うと、「今、慌ててやる必要はない」です。
GUI インタフェースはハッキリ言うと「改悪」そのものと言って良い。
改悪の極みはエクスプローラで、
Windows 10 のエクスプローラーだと、右クリックで選択出来たものが、
Windows 11 のエクスプローラでは、「その他の機能」に殆どが移行し、例えば「名前の変更」なんかは、
右クリック1回、「その他の機能」の左クリック1回、ここで始めて「名前の変更」の左クリック。
で、合計3回させられます。
タスクトレイに日時が表示されるのは変わらないですが、勘違いなセキュリティ対策なのか、
タスクトレイの改造が外部ソフトウェアで出来なくなった上に、秒の表示が出来ません。
更に、文字の大きさが小さい。
こうするなら、タスクトレイ改造相当のカスタマイズ機能を標準でサポートするべきです。
唯一の改善点(?)は、同じディスプレイ上で明確に仮想画面を持てるようになったことくらいでしょうか。
「デスクトップ1」「デスクトップ2」というのがそれ。追加できるみたいです。
これ見て思ったのは、「MacOS のパクリ?」というところ。
でも、これは便利です。
まぁ BSD系Unix とかでは昔から普通にあった機能ですけどね。CUI環境でも8画面程度の仮想画面を持っています。
2020/08/22(土)javascript の fetch と XMLHttpRequest
2020/08/22 16:50
fetch も XMLHttpRequest も Javascript 内でWebサーバと通信処理が出来る便利な機能で
ちょっと前は「Ajax」とか言ってもてはやされたものですが、今はほぼ死語でしょうかね。
それでも今はWebサイトでちょっとしたことをするには欠かせなくなってきているもの。
今回は、オンラインでの画像編集機能をサイト内にて実現するために、
最初は fetch による以下のコードを書きました(一部を公開用に変更部分あり):
async function gosub_canvasimg(serial,imgblob) { var responce = await (await fetch('/editor.cgi', { method : 'POST', cache : 'no-cache', headers : {'Content-Type' : 'application/x-www-form-urlencoded' } , body : 'imgblob=' + imgblob ; })).text() ; if (responce != 'valid') { alert(serial + "つめの画像ファイル保存に失敗しました。" ); } }ところが、これだと、
Uncaught (in promise) TypeError: NetworkError when attempting to fetch resource.
というエラーが出て、fetch 自体が実行されないのです。*1これは、拙作のシステムにて「画像があるはずだが、編集画面で表示されない」という現象を作り出す直接原因になっていました。
同期処理でないと、編集時に不具合が更に出るので、こうしています。
『同期処理なんぞ殆ど使われません』と大声で叫ぶサイトなんかも散見されますが、
それはよほど精通している方か、同期処理の必要な案件に出会ったことが無い方なのでしょう。
少なくともハードウェアの制御がシステム全体として絡んで来ると、同期処理はどうやっても必須。
結局、fetch がエラーになる原因は判らず仕舞いで、fetch のところを同じ処理になるように、
async function gosub_canvasimg(serial,imgblob) { var imgxhr = new XMLHttpRequest() ; var msgbody = 'imgblob=' + imgblob ; imgxhr.open('POST', '/editor.cgi', false) ; imgxhr.send(msgbody) ; var responce = imgxhr.response ; if (responce != 'valid') { alert(serial + "つめの画像ファイル保存に失敗しました。" ); } }みたいな感じにすると、エラーは出なくなった模様。
これで不具合は出なくなったと思うが様子見です。
fetch の実装バグなのか、「同期方式」という使い方が悪いのか調べても全く判らないのです。
やっぱり XMLHttpRequest() のほうが断然判りやすい。
fetch は Promise という挙動の概念を理解しなければならず、これが当方にはあまり直感的ではなく判りずらさの極みです。これを使いこなせないのがこの顛末の一因でしょう。
何せ、類似の事例が殆ど表に出てきていない案件なので、エンドユーザに動作検証してもらうという暴挙を敢行するしかないのです。
2020/03/17(火)中華なオシロスコープを使いこなす(2)
2020/03/17 4:00
先日の記事と同じような画になってしまったのですが。。
ブラウン管オシロスコープな時代は、専用の道具を使いつつ、写真撮影していたものです。
USB端子が付いており、そこにUSBメモリを挿すと、オシロスコープ側で保存した画像をコピー&ペーストで取得できます。
ただ、ここからが中華らしい曲者で、、、orz
USBメモリにコピーしたはいいが、PC側で読み込みしようとすると、
「このドライブで問題が見つかりました。今すぐドライブをスキャンして修復してください。」
みたいなメッセージが出る。しかし、スキャンすると・・・「問題は見つかりませんでした。」
なんだこれ、、、更に、右端側のメニューが消えない。邪魔だ、、、
右端側のメニューがない状態で記録出来ないものか。。
ご存知のかた誰か教えてください・・。orz
2020/03/11(水)中華なオシロスコープを使いこなす(1)
2020/03/12 1:06
これは、プロトコルアナライザ。
今も昔も広く使われている RS-232C 信号線で、どういうデータが流れているかを解析した様子。
他にSPI だの I2C だのといったものが使える模様。見慣れないものもあります。
データを取得するときのトリガの掛け方(早い話、データを取得するタイミングをどう設定するか)が今ひとつ慣れていないが、こんなことができるという確認。
間違った解析をしていないのを確認。
あと、リアルタイムで電圧や周波数(周期)なんかも表示できます。
更に、ヒストグラムとFFT機能があるのですが、この2つは使う機会が出てくるのかどうか何とも・・です。
ただ、試作中の技術的評価には使えるかな、といったところ。
2020/03/09(月)中華製なオシロスコープを入手した
2020/03/09 8:08
絶対額が安くはないんですが、業務を全うするのに必要なのです。(この機種でもどちらかといえば安いほう)
これ無いと、電子回路の設計・開発に大きな支障あるんですが、今までこれ無しでやってきたのです。
オシロスコープ使わずに電子回路の設計・開発が出来たのは奇跡以外の何物でもないのです。(本当に、、、)
当然のことながら、受注業務の技術的限界を感じていました。
でもこれ、中華メーカなんだよね。。ただ、評判はそれほど悪くはないようなので・・・
設置場所確保するだけで徹夜になってしまいました。orz
Amazon で購入したんですが、中華なところから成田空港経由の空輸で製造元にて二重梱包されていました。
梱包材破損のクレームが過去にあったからですかね。。
これからセットアップです。
2020/03/08(日)XML ファイルを解析する perl モジュール
2020/03/08 5:32
2年近くずーっと延期していたWeb気象通報サイトの抜本的改築を行おうと考えています。
元データはXML形式のファイルで、技術的にこれを逐次解析処理する必要があります。
そこで作業準備にあたり、どのXMLライブラリを主力にするかの検討からなのです。
現状、Perl5 では下記のXMLライブラリがあり、依存する汎用ライブラリが異なります:
XML::Simple libexpat が必要
XML::Parser libexpat が必要
XML::DOM libexpat が必要
XML::LibXML libxml2 が必要
XML::Feed libxml2 と libexpat の両方必要
#他にもあるが、最終更新日時が古い・事例が殆ど無いなどの理由で最初から却下。
libexpat も libxml2 も XMLを処理するC言語ベースのライブラリで、
Perlで実現するXML処理は、単にこれらのライブラリとの仲介をしているだけに過ぎないです。
ですが、その処理手法が異なっており、libexpat を使うモジュールは、libexpat そのものの構造からして
・巨大なXMLをパース(解析)できない
・複雑なデータ構造のXMLをパースできない
という問題があるようで、これは今回のプロダクションには採用できない(しないほうが無難)模様。
また、XML::Feed は、複雑なデータ構造のXMLパースは機能しないという報告もあり、
昔から標準的で実績豊富とされている XML::LibXML というところに落ち着く形ですね。
ただ、ちょっと使いにくそうです。
2020/03/01(日)XBee のプログラマブルモジュールとノーマルタイプの違い《お勧めは「ノーマルタイプ」!!》
2020/03/01 5:54
昨年からこの無線通信モジュールを使用するシステム開発に関わっています。
実際に関わってみると、何と言っても「これほど判りずらいモジュールはない!!」という印象が強いです。
日本語による情報が殆ど無い、説明書通りの挙動をしない、情報が古い、という現状も判りずらさを助長しています。
更に、名前の紛らわしさが判りずらさを更に助長しています。
XBee (「じぐびいぃ」と発音する模様)は、この無線モジュールの商標だが、ZigBee はXBee が採用している通信規格。発音が日本人に言わせると全く同じ。
更に XBee と書いて別の読み方をする日本メーカの小型乗用車なんかもあって、調べる際に結構な割合で検索結果に混同してきます。
そもそも、ノーマル版とPro版が先ず最初にあり、これは無線通信の電波の強さの違いのようです。
Pro 版の方が高出力で通信距離を稼げます。
要するに、「Pro版」はプログラマブルモジュールのことではなく、「高出力版」ということのようです。
次に、ノーマル版とプログラマブルモジュール版があります。
プログラマブルモジュールは、機能的にはMicrochip社のPIC16FシリーズとPIC18Fシリーズの中間的な機能を有するマイコンが内蔵され、こういうのに欲張りな当方は「値段が殆ど同じなら、プログラマブルモジュールを使う」という選択肢が自然と行くのですが、これは駄目です。全くお勧めできません。とても苦労する羽目になります。
先駆者諸氏のブログ等を拝見すると、当方と同じような思考で結果的に使用を断念してしまったり、間違って購入して苦労しているのを散見します。
両者はよくよく見ないと区別できないのもこの状況を助長しています。
ここで、「ノーマルタイプ」と「プログラマブルモジュール」を並べた様子です。
全く『違い』が判りませんね。実は、裏面を見ると辛うじて判ります:
型番の最後が
「003」になっているのが「プログラマブルモジュールなXBee」、
「004」になっているのが「ノーマルタイプの XBee」なのです。(赤枠で囲った部分)
こういうのは、表に大きな文字で型番を印刷するとか、色を変えるとかして区別できるようにするべきだと個人的には思います。
蛇足ですが、プログラマブルモジュールに内蔵しているマイコンは、Freescale社の MC9508QE32CFT という型番のマイコンのようです。
実は、XBee プログラマブルモジュール用のSDK(プログラム開発ツール)が無償提供されてはいるのですが、
全く使えないのです。どうもCコンパイラが吐き出す命令コードがおかしい。
サブルーチンの前後で引数が突然変わるんです。
何か回避できるトリックがあるのでしょうが、そういうのも見当たらず、一般人には使い物にならない。
これは想定外の大きな誤算でした。
どうりで XBee プログラマブルモジュールの応用事例が殆ど皆無なわけです。
メーカの方でもそういうのは判っていると思うのですが・・・ 現状は何も対策無しです。
なので、プログラマブルモジュールの XBee は、現状ではお勧めできないわけです。