ClamXavのエンジン(ClamAV)を最新化
参照:ClamAV
やっと自宅サーバ(Mac mini G4, MacOS X 10.4.11 Tiger)のアンチウィルスソフトを最新版に入れ替えることができた
この自宅サーバ(Mac mini G4, MacOS X 10.4.11 Tiger)ではウィルスの監視、駆除を ClamXav というオープンソース(無料)のアンチウィルスソフトを使用している。しかし、MacOS X 10.4.11 Tiger で使用可能な ClamXav は Ver.2.2.1 までであり、MacOS X 10.4.11 Tiger用 ClamXav についてのアップデートは完全に途絶えている。
とは言え、ClamXavは単なるGUIの皮であり、本体(エンジン)は "/usr/local/clamXav" 配下にインストールされている ClamAV というオープンソースである。ClamXav Ver.2.2.1 が内包している ClamAV は Ver.0.97.1であり、現在では ClamAV が古く、既に最新のウィルス定義ファイルと適合しなくなっている。
ClamAVが古いままウィルス定義ファイルを更新すると、ログに以下のような警告メッセージが出るようになる。
[LibClamAV] ***********************************************************
[LibClamAV] *** This version of the ClamAV engine is outdated. ***
[LibClamAV] *** DON'T PANIC! Read http://www.clamav.net/support/faq ***
[LibClamAV] ***********************************************************
daily.cld updated (version: 21314, sigs: 1822285, f-level: 63, builder: neo)
WARNING: Your ClamAV installation is OUTDATED!
WARNING: Current functionality level = 61, recommended = 63
DON'T PANIC! Read http://www.clamav.net/support/faq
|
『このバージョンの ClamAV エンジンは古くて役に立たないよ。でもパニックになるな!"http://www.clamav.net/support/faq" を読め。』と言われているわけだが、要するに ClamAV を最新化しなければどうにもならない。そこで ClamAV を最新版(現時点の最新版は Ver.0.99.0)にアップデートしたいと思うのだが、以前にも試みたとおり、先ず gcc をアップデートしなければならないという高いハードルがある。gccのアップデートについては何度かトライしてみたが、死ぬほど時間がかかる(本当に死にやしないけどね)上に、どうしてもビルドが途中で失敗するので、結局挫けていた。
ところが、Memorandum : Building ClamAV® - Clam AntiVirus on Mac OS X 10.4 through OS X 10.11というホームページを見つける事ができ、基本的にこのとおりにやれば ClamAV を最新化できる事が分かった。このホームページの記述とは少し異なる事点や、追加で行った作業もあるので、以下にその備忘録を記しておく。
- 上記URLのMemorandum 4 : Building ClamAV on Mac OS X 10.4 (PPC)に従って以下をダウンロードしてインストールする。
http://llvm.org/releases/の Version 2.3 から
LLVM のビルドには ネイティブの gcc-4.0 が使われる。LLVMのビルドにはすごく時間がかかり、これが失敗するようなら以後の作業は無意味になるので、先ずLLVMのビルドからやってみるのが良いだろう。(*1)
$ tar xvxf llvm-2.3.tar.gz
$ cd llvm-2.3
$ ./configure CPPFLAGS="-I/usr/local/include -I/usr/include" LDFLAGS="-L/usr/local/lib -L/usr/lib"
$ make
$ sudo make install
|
次に、LLVMベースのgcc-4.2をインストールする。これは解凍するだけなので、すぐに終わる。
$ cd /usr/local
$ sudo tar zxf ~/llvm-gcc4.2-2.3-ppc-darwin8.11.0.tar.gz
|
上でインストールしたllvm-gcc-4.2にPATHを通しておく。
$ export PATH=/usr/local/llvm-gcc4.2-2.3-ppc-darwin8.11.0/bin:$PATH
|
- bzip2をインストールする。
ホームページでは MacPorts を使ってインストールしているが、今回は自力でインストールしてみた。
- http://www.bzip.org/ から "bzip2-1.0.6.tar.gz" をダウンロードしてビルド
$ tar xvzf bzip2-1.0.6.tar.gz
$ cd bzip2-1.0.6
$ make
$ sudo make install
|
- "Makefile-libbz2_so"ファイルの修正
上ではbzip2のコマンド群と、スタティックリンクライブラリ("/usr/local/lib/libbz2.a")しかインストールされない。ダイナミックリンクライブラリをインストールする場合は、"Makefile-libbz2_so" を用いてビルドする必要があるのだが、一般的なUNIX/Linuxのダイナミックリンクライブラリを作成するための Makefile になっているので、MacOS Xでは以下のように修正する必要があった。
CFLAGS=-fpic -fPIC -Wall -Winline -O2 -g $(BIGFILES)
PREFIX=/usr/local
OBJS= blocksort.o
huffman.o
crctable.o
randtable.o
compress.o
decompress.o
bzlib.o
all: $(OBJS)
$(CC) -v $(CFLAGS) -dynamiclib
-install_name $(PREFIX)/lib/libbz2.1.0.6.dylib
-Wl,-compatibility_version,1.0.0
-Wl,-current_version,1.0.6
-o libbz2.1.0.6.dylib $(OBJS)
$(CC) $(CFLAGS) -o bzip2-shared bzip2.c libbz2.1.0.6.dylib
rm -f libbz2.1.0.dylib libbz2.1.dylib libbz2.dylib
ln -s libbz2.1.0.6.dylib libbz2.1.0.dylib
ln -s libbz2.1.0.6.dylib libbz2.1.dylib
ln -s libbz2.1.0.6.dylib libbz2.dylib
clean:
rm -f $(OBJS) bzip2.o libbz2.1.0.6.dylib libbz2.1.0.dylib libbz2.1.dylib libbz2.dylib bzip2-shared
install: libbz2.1.0.6.dylib
if ( test ! -d $(PREFIX)/lib ) ; then mkdir -p $(PREFIX)/lib ; fi
cp -f libbz2.1.0.6.dylib $(PREFIX)/lib/libbz2.1.0.6.dylib
chmod a+r $(PREFIX)/lib/libbz2.1.0.6.dylib
ln -s -f $(PREFIX)/lib/libbz2.1.0.6.dylib $(PREFIX)/lib/libbz2.1.0.dylib
ln -s -f $(PREFIX)/lib/libbz2.1.0.6.dylib $(PREFIX)/lib/libbz2.1.dylib
ln -s -f $(PREFIX)/lib/libbz2.1.0.6.dylib $(PREFIX)/lib/libbz2.dylib
|
- 修正した "Makefile-libbz2_so" を用いてビルド、インストール
$ make -f Makefile-libbz2_so
$ sudo make -f Makefile-libbz2_so install
|
- ClamAVのインストール
http://www.clamav.net/ の Download からソースをダウンロードしてビルドする。現時点での最新版は Ver.0.99.0。ホームページでは Ver.0.98.x で書かれているが、最新版(Ver.0.99.0) でも同じ方法でビルドできた。
$ tar xvf clamav-0.99.tar.gz
$ cd clamav-0.99
$ vi shared/output.c # off_t を unsigned int に変更する
$ vi shared/output.h # 同上
$ export CFLAGS="-O3"
$ export CXXFLAGS="-O3"
$ export LDFLAGS="-L/usr/local/lib -L/usr/lib"
$ export CC=/usr/local/llvm-gcc4.2-2.3-ppc-darwin8.11.0/bin/powerpc-apple-darwin8-gcc-4.2.1
$ ./configure --prefix=/usr/local/clamXav --enable-llvm
$ make
$ make check
$ sudo make install
|
- "/usr/local/clamXav/etc/clamd.conf" の作成、編集
"/usr/local/clamXav/etc/clamd.conf" を作成、編集する。ClamXav Ver.2.2.1 が作成した既存のものでも問題ないかもしれないが、念のため。
$ su
# cd /usr/local/clamXav/etc
# cp clamd.conf.sample clamd.conf
# chmod 644 clamd.conf
# vi clamd.conf
|
修正個所は以下。(nnn: は行番号)
007: # Comment or remove the line below.
008: #Example
〜
074: DatabaseDirectory /usr/local/clamXav/share/clamav
〜
085: LocalSocket /tmp/clamd.socket
|
008行目のExampleが残っていると設定が有効にならないので注意(実はこれでハマった)。削除してしまっても良い。
- "/usr/local/clamXav/etc/freshclam.conf" の作成、編集
$ su
# cd /usr/local/clamXav/etc
# cp freshclam.conf.sample freshclam.conf
# chmod 0600 freshclam.conf
# chown clamav:wheel freshclam.conf
# vi freshclam.conf
|
ポイントは "freshclam.conf" ファイルのオーナーとパーミッション。オーナーを clamav にして、オーナーしか読めないようにパーミッションを設定する。"freshclam.conf" 内に Proxyのパスワードを記述する場合、このようにセキュリティ対策しないと読み込んでもらえない。パスワードを記述していない場合には、そこまで要求されないようだが念のため。
"freshclam.conf" ファイルの修正箇所は以下。(nnn: は行番号)
007: # Comment or remove the line below.
008: #Example
〜
013: DatabaseDirectory /usr/local/clamXav/share/clamav
〜
056: DatabaseOwner clamav
〜
079: DatabaseMirror database.clamav.net
080: DatabaseMirror db.jp.clamav.net
081: DatabaseMirror db.us.clamav.net
〜
121: HTTPProxyServer proxy.address.com
122: HTTPProxyPort 3128
123: HTTPProxyUsername username
124: HTTPProxyPassword password
|
008行目のExampleは "clamd.conf" と同様、残っていると設定が有効にならないので、コメントアウトするか削除する。HTTPProxy〜設定は、会社など Proxy 内で使用する場合に記述する。Proxyを使っていない場合は不要。
- clamdの再起動
StartupItemsやLaunchDaemonsの中を調べても clamd の起動スクリプトは見あたらない。どうやら clamd は ClamXav Sentry 経由で起動、停止されるらしい。
で clamdが動いているようなら、メニューバーにある「ClamXav Sentryを終了」を選択すると clamd も終了する。その後、ClamXav の「ClamXav Sentryを起動」すると clamd も動き出す。
- ウィルス定義ファイルの更新
ClamXav でウィルス定義ファイルを更新させても良いが、手動で更新させるには以下のようにする。
$ sudo /usr/local/clamXav/bin/freshclam --config-file=/usr/local/clamXav/etc/freshclam.conf --verbose
|
"--verbose" オプションを指定しているので、ウィルス定義更新の詳しい様子を見る事ができる。もし更新がうまくできない場合は、この方法で出力される結果を見ると何かヒントが得られるかもしれない。
自宅サーバは、自分でできる限りセキュリティ対策も講じているつもりなのだけど、ウィルス監視、駆除ができなくなって、もうそろそろ限界かなぁと思っていたけど、これで少し延命できたかな。まぁ、こんなレガシーなマシン、OSを狙うようなウィルスも無いだろうけど。
(*1):ところでLLVMって何?と思ってWiKiで調べてみたら次のように書かれていた。以下はその引用だ。
LLVM とは、コンパイル時、リンク時、実行時などあらゆる時点でプログラムを最適化するよう設計された、任意のプログラミング言語に対応可能なコンパイラ基盤である。
〜略〜
LLVM は、JavaとJava VMの関係のように、まず仮想機械をターゲットとした中間コード(ビットコード)を生成し、その仮想機械向けコードを特定のマシンの機械語に変換する。この時言語やプラットフォームとは独立した最適化を行う。この方法によってLLVM は言語からもアーキテクチャからも独立しており、それぞれに特化した、プログラミング言語固有のモジュールと、マシン向けコード生成部を用意することにより様々な言語アーキテクチャーに対応する。 LLVM は積極的にプロシージャ間最適化を行うとともに、静的コンパイラとしてもJITコンパイラとしても使え、開発の様々な段階で使える多数の部品を持っている(JavaバイトコードとMSILフロントエンド、Pythonフロントエンド、グラフ彩色式のレジスタ割り付けモジュール、など)。JITコンパイラの場合、実行時に不要な静的分岐を最適化する機能があり、これはプログラムが様々な実行時オプションを持っている場合、強力な最適化手法(部分評価)となる。
う〜む・・・難しいが、要するに実マシンのCPU命令とは無関係な、独自の命令体系を持った仮想マシンなので、どのような言語でもコンパイル、リンク、実行の際の実行基盤になり得るらしい。一般的に仮想マシン上で動作させると、命令列を変換するオーバヘッドのために実マシンのネイティブ命令で実行するよりも実行性能が低下するものなのだが、強力な最適化機能などによって高性能な実行を可能にしていると思えば良いかな?
また、この高度な最適化機能は静的にも動的にも使えるようなので、一旦この仮想マシン向けの命令にコンパイルしてから実マシンのCPU(PowerPCやIntel x86/x64等)に変換させることもできるし、実行時にその都度変換しながら動作させることもできると言うことか。
理解するには、先ずはコンピュータ言語についての基礎知識が必要だな。コンピュータ言語は大きく、
の2つに分けることができる。インタプリタ言語はプログラムに書かれた命令を1つづつ実行時に解釈しながら実行するもので、shell, Perl, Python, Ruby等のスクリプト言語や、JavaもJava VMの命令列にコンパイルしてから実行するが、Java VMが実行時に命令を解釈しながら実マシンの命令に変換してから実行する(JIT : Just In Timeコンパイラと言う)という事からインタプリタ言語に含めて良いと思う。インタプリタ言語は実行時に命令を解釈、変換してから実行する必要があるため、オーバヘッドが大きく、どうしても実行性能が落ちてしまう。
一方、コンパイラ言語は実行前にプログラムを全て実マシンの命令列に変換してしまうため、コンパイル(翻訳)という処理が必要になるが(厳密に言えば、その後にリンクして実行可能形式に変換する処理も必要)、一旦コンパイルされてしまえばプログラムが変更されない限り再度コンパイルする必要はないため、実行時のオーバヘッドは無く高速に実行される。コンパイラ言語には C, C++, Fortran, COBOL等々がある。
LLVMは静的にも動的にも使用できると言うことなので、インタプリタ言語とコンパイル言語のどちらにも適応できるようだが、今回使用した GCC はコンパイラ言語なので、話をコンパイラ言語に絞ろう。
プログラムをコンパイル(翻訳)するというのは、簡単に言ってしまえば人間が理解しやすいプログラム(高級言語とも言う)を実マシンの命令(機械語とも言う)に変換する処理のことだが、これはそう簡単にできるものではない。プログラムをコンパイル(翻訳)する処理は、大きく以下の3ステップに分けられる。
- 字句解析、構文解析(フロントエンド)
- 最適化(ミドルエンド)
- データ・レジスタ割付け、命令生成(バックエンド)
いっぺんに機械語に変換するのは難しいし、無駄な命令を出力してしまうことにもなるので、ちょっとづつ変換しながら最終的に出来るだけ実行効率の良い(と思われる)機械語に変換して行くのである。で、これらの処理の間でやりとりするための言語、命令列はコンパイラの内部だけで使われるために、中間言語とか中間コードとか呼ばれる。LLVM は、この中間コードを入力として最適化を行い、実マシンの命令列(機械語)に変換するエンジンと考えて良いだろう。
と言うことで、おそらく LLVM-GCC 4.2 Front End は、LLVMの命令(中間コード)を生成するGNU C/C++コンパイラ(と言うか、フロントエンドと言っているから、つまりは字句・構文解析区)であり、これを使って ClamAV のソースプログラムを LLVMの命令(中間コード)にコンパイルした後、LLVMで最適化してPowerPC命令に静的変換させているのではないかと思う。
LLVMベースの言語として Apple が Clang の開発に積極的に取り組んでいると言うし、今後は LLVMベースのコンパイラの方が主流になっていくのかもしれないな。
|