約 11 分で読めます。
Raspberry Pi 4にclamonaccを入れ順調に使っていたのですが、OnAccessPreventionをtrueにしたらリアルタイムスキャンが全く動作しなくなってしまいました😥
この問題を自分なりに調べて解決したので紹介します🖥
clamonaccとは
恐らくこのページを見ているということはclamonaccをご存知と思いますが、一応。
Linux用オープンソースのアンチウィルスclamavのリアルタイムスキャン用プログラムです。
今回取り組む問題は、↑の記事でこのようにコメントしていたコレです。
OnAccessPreventionをtrueにすると、kernelの拡張機能であるFANOTIFYによる監視が動きます。 ですが、今は導入に以下の課題があり、入れることができません。 ・Raspberry Pi OSのkernelはFANOTIFYが無効 ・有効化したkernelで動かしてみたがclamonaccとclamdscanとの通信でエラーになる これは今後トライしてみたいと思います。
OnAccessPreventionを有効にするとどうなるか
OnAccessPreventionはmanで見るとこんな感じ。
FANOTIFYによる防御機構が動きます。
OnAccessPrevention BOOL
Enables fanotify blocking when malicious files are found.
Default: disabled
ただ、デフォルトのRaspberry Pi OSに含まれるkernelではCONFIG_FANOTIFY_ACCESS_PERMISSIONSが無効のため、動かすことができません。
sudo modprobe configs zcat /proc/config.gz | grep FANOTIFY_ACCESS_PERMISSIONS # CONFIG_FANOTIFY_ACCESS_PERMISSIONS is not set
CONFIG_FANOTIFY_ACCESS_PERMISSIONSを有効にする
そこで有効にしたkernelをビルドして入れることにします。
公式ページにkernelビルドの方法が書いてあるので従います。
sudo apt install git bc bison flex libssl-dev make
git clone --depth=1 https://github.com/raspberrypi/linux cd linux exportKERNEL=kernel7l
make bcm2711_defconfig
.configのCONFIG_LOCALVERSIONは一応変えておきます。
CONFIG_LOCALVERSION=”-v7l-MY_CUSTOM_KERNEL”
以下でビルドからインストールまで行います。
Raspberry Pi 4で一時間くらいかかりました。
make -j4 zImage modules dtbs sudo make modules_install sudo cp arch/arm/boot/dts/.dtb /boot/ sudo cp arch/arm/boot/dts/overlays/.dtb* /boot/overlays/ sudo cp arch/arm/boot/dts/overlays/README /boot/overlays/ sudo cp arch/arm/boot/zImage /boot/$KERNEL.img
再起動し、CONFIG_FANOTIFY_ACCESS_PERMISSIONSが有効になったことが確認できました。
sudo modprobe configs zcat /proc/config.gz | grep FANOTIFY_ACCESS_PERMISSIONS CONFIG_FANOTIFY_ACCESS_PERMISSIONS=y
OnAccessPreventionをtrueにしてみる
無事有効化されましたので、この状態でOnAccessPreventionをtrueにして、テストウィルスをダウンロードしてみましたが、以下の通りエラーになりスキャンされません。
ClamFanotif: attempting to feed consumer queue ClamWorker: performing scanning on file '/var/www/html/nextcloud/index.html' ERROR: ClamCom: TIMEOUT while waiting on socket (recv) ClamClient: connection could not be established … return code 12
gdbでいろいろデバッグした結果、clamdへのスキャン依頼ができていないようです。
clamonacc起動時に–fdpassオプションを渡すと期待通り動いてくれました。
–fdpass自体は以下の通りとなっています。
clamd/clamonaccが別々のユーザーで動いているときに有効とありますが、自分の環境では両方ともrootだったので謎です。。。
--fdpass Pass filedescriptor to clamd (useful if clamd is running as a different user)
ちなみに–fdpassにより動くコードはこのあたり。
Unix Domain Socketを使うようにする具合ですかね。
clamonacc/client/client.c cl_error_t onas_setup_client(struct onas_context **ctx) { (略)if (!remote && optget((*ctx)->clamdopts, "LocalSocket")->enabled && (optget(opts, "fdpass")->enabled)) {
if (onas_set_sock_only_once(*ctx) == CL_EWRITE) {
(略)
clamonacc/client/socket.c cl_error_t onas_set_sock_only_once(struct onas_context *ctx) { (略)if (onas_sock.written != 1) {
if (((opt =
optget(ctx->clamdopts, "LocalSocket"))
->enabled) &&
optget(ctx->opts, "fdpass")->enabled) {
memset((void *)&onas_sock, 0, sizeof(onas_sock));
onas_sock.sock.sun_family = AF_UNIX;
strncpy(onas_sock.sock.sun_path, opt->strarg, sizeof(onas_sock.sock.sun_path));
onas_sock.sock.sun_path[sizeof(onas_sock.sock.sun_path) - 1] = '\0';
onas_sock.written = 1;
return CL_SUCCESS;
}
}
これでOnAccessPrevention自体は動くようになったのですが、パフォーマンスが激落ちです。
というのも、読み取りファイルすらスキャンするため。
この記事で少し解説しています。
OnAccessPreventionがfalseなら↑の記事で紹介したパッチが使えるのですが、trueの場合は対応するマスクがないので使えません。ということで諦め。
Chromebookや最近のPCなら問題ないのでしょうが、Raspberry Pi 4では力不足💪⤵
結局OnAccessPreventionはfalseで使うことにしました😅
終わりに
いかがでしたか。
OnAccessPreventionがtrueの場合に–fdpassを指定しなければならないのは仕様なのかバグなのか、はっきりしていませんが、ひとまず動かないという疑問は解けたので良しとします。
また暇なときにでも解析するかもしれません😀
Comments