clamavとclamonaccでウィルススキャンサーバー運用してみる

clamav

約 9 分で読めます。



clamavの常駐デーモンclamdは外部からのスキャン要求も受けられるとのことでやってみました。

構成はこんな感じ。
一般的なクライアント/サーバー構成です。
デフォルトではTCP3310で通信します。



↑の構成にすることで、

clamdが動作するためのメモリ(約1GB)を使うプロセスは1つで済む
 → RAMを気にする必要がなくなり、お財布にも優しい
デバイスすべてにclamavを入れる必要がなくなり、一元管理できる

というメリットがあります。

clamonacc

まずclamonacc側。
↓の記事に書いたマスク変更を入れたかったので、ソースコードからビルドします。



シェルで書くとこんな感じ。

# 必要なパッケージをインストール
sudo apt-get -y install cmake gcc make pkg-config python3 python3-pip python3-pytest valgrind \
	check libbz2-dev libcurl4-openssl-dev libjson-c-dev libmilter-dev \
	libncurses5-dev libpcre2-dev libssl-dev libxml2-dev zlib1g-dev

# clamav専用のユーザーとグループを追加
sudo groupadd clamav
sudo useradd -g clamav -s /bin/false -c "Clam Antivirus" clamav

# ソースコードをダウンロードして展開(ここでは0.104.0とした)
wget https://github.com/Cisco-Talos/clamav/archive/refs/tags/clamav-0.104.0.tar.gz
tar zxf clamav-0.104.0.tar.gz

# マスクを変更
wget https://raw.githubusercontent.com/kurofuku/dotfiles/master/clamav/change_fanotify_mask.diff
patch -p0 < change_fanotify_mask.diff

# ビルドして/usr/local/以下にインストール
cd clamav-clamav-0.104.0
mkdir build && cd build
cmake ..
cmake --build .
sudo cmake --build . --target install

# アンインストールしたい場合はこう
sudo xargs rm < install_manifest.txt

このsetup.shに入れてあるので、興味ある方はどぞ。
 clamav-0.104.0でやっています。
 パッチは十分なテストをしていないので、自己責任でお願いします。

dotfiles/setup.sh at master · kurofuku/dotfiles
Contribute to kurofuku/dotfiles development by creating an account on GitHub.



起動はこんな感じ。
clamdはウィルス定義をメモリにロード完了すると、PINGに対してPONGを返す仕様があるので、これを使ってclamdが起動しているか確認します。
 参考URL

#!/bin/bash

QUARANTINE_DIR=/opt/clamav/quarantine

while [ "zPONG" != "z$( echo PING | nc <clamdが動作しているデバイスのIPアドレス> 3310 )" ];
do
        sleep 1;
done;

if [ ! -d ${QUARANTINE_DIR} ]; then
        mkdir -p ${QUARANTINE_DIR}
fi

/usr/local/sbin/clamonacc --fdpass --move=${QUARANTINE_DIR} --config-file=/usr/local/etc/clamonacc.conf



clamonacc.confはこんな感じ。
TCPAddrで要求先のIPアドレスを、TCPSocketでポート番号を指定します。
OnAccessIncludePathはclamonaccに監視させたいディレクトリを指定します。
 複数行書けば行数分認識する。

TCPSocket 3310
TCPAddr <clamdが動作しているデバイスのIPアドレス> 
OnAccessIncludePath <監視させたいディレクトリ>



これでclamonacc側の準備は完了です。

clamd

clamdは特に何も修正しません。
ソースコードからビルドしても、apt/yumなどで入れてもいいでしょう。

clamd.confはほぼ標準のままでOKです。

TCPSocket 3310
TCPAddr <clamdが動作しているデバイスのIPアドレス> 



起動に関して、ソースコードからビルドしている場合はこう。

sudo clamd



aptなどの場合は例えばこう。

sudo service clamd start



ちゃんと待ち受けているかnetstatで確認。
以下のようにTCP3310で待ち受けていればOK。

netstat -ta
Active Internet connections (servers and established)
Proto Recv-Q Send-Q Local Address           Foreign Address         State      
tcp        0      0 <IPアドレス>:3310       0.0.0.0:*               LISTEN     



clamd側は以上です。
freshclamを動かすのを忘れずに。

課題

これでだいたいうまく動くと思います。
RasperryPi 4でもCPU負荷は5%程度に抑えられていて快調。



一点、課題が見つかりました。

VirusEventでウィルス検出時にメールなどで通知しようとしてもファイル名がinstream(IPアドレス@ポート番号)とかいう意味不明な名前になってしまいます。



これは以下の仕様によるものでしょう。

VirusEventにあるコマンドを実行するのはclamdである。
clamdはスキャンするファイルのパスがわからない。
 clamonaccからはファイルの中身が送られるだけなので
そのため、仕方なくinstreamなどと表示するしかない。



自分もやってみましたが、こんな感じでなんのファイルなのかわかりません。



これではあまり意味がないので、ファイル名がわかるようにコードを変更しました。

具体的にはclamonaccでウィルス検出時のコマンドを実行するようにします。
 clamd側ではVirusEventを定義しない。

こちらにパッチを置きましたので、興味ある方はどぞ。
 clamav-0.104.0用。
 パッチは十分なテストをしていないので、自己責任でお願いします。

dotfiles/add_OnAccessVirusEvent_functionalty.diff at master · kurofuku/dotfiles
Contribute to kurofuku/dotfiles development by creating an account on GitHub.



ウィルス検出時に実行するコマンドはOnAccessVirusEventとしました。

設定ファイルにはこんな感じで書きます。

OnAccessVirusEvent <実行したいコマンド>



やってみました。
ファイルパスが取れています!

終わりに

いかがでしたか。

いまのところ以下のディレクトリを監視させていて、動作が軽くて快調です!

・nextcloudのデータディレクトリ
・WordPressのwp-contentディレクトリ

Comments

タイトルとURLをコピーしました