ClamAVによる定期ウイルススキャンの運用における工夫
はじめに
前回の記事では、CentOS 7のサーバーにおけるClamAVによる定期ウイルススキャンの設定方法について記載しました。
今回は、定期ウイルススキャンの運用において、CPU・メモリリソース使用に関する工夫や、実際にウイルスを検知したときの対処方法について記載します。
ここでは、前回の記事で定期ウイルススキャンの設定を行ったCentOS 7サーバー環境に対して、引き続き設定を追加します。
また、以下の設定作業はrootユーザー(もしくはsudoによるroot権限)で実施します。
定期スキャンの運用における工夫
- メモリ使用量が増える問題への対策
- CPUを占有使用する問題への対策
- プライベートネットワーク内サーバーのウイルス定義更新
- ウイルス検知時の対応
について記載します。
メモリ使用量が増える問題への対策
よくあるケースとして、サーバーのメモリが2GB以下で、Apache+mod_phpを使用しているWebサーバーで定期スキャンの設定を行うと、スワップ領域を常時数百MB程度使用するようになります。
前回の記事でも書きましたが、clamscanコマンドは、メモリを500MB~700MBほど使用します。
これはおそらく、スキャン実行時に読み込むウイルス定義ファイルのサイズが数百MBあるからだと思います。
Apacheプロセスによる実メモリの使用量が大きい状態でウイルススキャンを実行すると、実メモリ上では必要なメモリを確保できないため、既存のApache子プロセスをスワップ領域に追いやるか、もしくはclamscanコマンド自体がスワップ領域を使用するのでしょう。
これを日々繰り返していくと、スワップ領域の使用量がじわじわと増えていきます。
スワップ領域をある程度使用することは、利用頻度の低いページをページアウトすることで実メモリを効率よく使えるようになるので、それ自体は悪いことではありません。
しかし、スワップ領域も上限があるので増え続けるのは好ましくありませんし、ページアウト(実メモリ→スワップへの移動)とページイン(スワップ→実メモリへの移動)が頻発すると、サーバーのパフォーマンスが落ちます。
「サーバーのメモリを1GBぐらい増やす」というのが一番よい解決方法ですが、とくにクラウドで低スペックのサーバーを使用しているときは、
「サーバーのスペック(つまりサーバー料金)は運用前に決められていて増やせない」
とか
「ウイルススキャンのためだけにメモリ(つまりサーバー料金)は増やせない」
といった事情もあるでしょう。
このように「メモリ使用量が増える問題」への対策としては、僕は
「スキャン実行前後に、Apacheを再起動する」
という方法をとっています。
スキャン実行前に再起動することで、Sleep状態のApache子プロセスをクリアして、実メモリの空きを確保します。
また、スキャン実行後に再起動することで、スキャン実行中にスワップに追いやられてしまったApache子プロセスをクリアします。
具体的には、前回設置したスキャン実行スクリプトの前後に、Apacheを再起動するコマンドを挿入します。
# vi /root/bin/scanvirus.sh -- #!/bin/sh # ClamAVによるウイルススキャンスクリプト scanvirus.sh # ウイルススキャンを実行し、ウイルスを検知したときのみ、 # 指定した宛先にアラートメールを送信する。 # 誤検知もあり得るため、検知しても駆除(削除)は実施しない。 # # スキャンの実行前には、ClamAVプログラムおよびウイルス定義を # アップデートする。 # # スキャンの除外対象ディレクトリ、ファイルは、${EXCLUDE_LIST_FILE} # ファイルに1行ずつ記載すること。ディレクトリの末尾には、/ をつける。 # EXCLUDE_LIST_FILE=/root/bin/scanvirus_exclude_list.txt LOGFILE=/var/log/scanvirus.log SCAN_RESULT=/var/log/scanresult.txt MAX_FILESIZE=200M MAX_SCANSIZE=200M MAILTO=xxx@example.com export LANG=C echo "===== Scan Virus =====" >> ${LOGFILE} echo "`date` Scan Virus start" >> ${LOGFILE} # 1. ClamAVプログラムのアップデート echo "`date` Update ClamAV start" >> ${LOGFILE} yum -y --enablerepo=epel update clamav 1>> ${LOGFILE} 2>&1 echo "`date` Update ClamAV end" >> ${LOGFILE} # 2. ウイルス定義の更新 echo "`date` Update Database start" >> ${LOGFILE} /usr/bin/freshclam 1>> ${LOGFILE} 2>&1 echo "`date` Update Database end" >> ${LOGFILE} # 3. Apache子プロセスを再起動(graceful) echo "`date` Restart Apache Process start" >> ${LOGFILE} systemctl reload httpd 1>> ${LOGFILE} 2>&1 sleep 10 echo "`date` Restart Apache Process end" >> ${LOGFILE} # 4. ウイルススキャンの実施 echo "`date` Do Scan Virus start" >> ${LOGFILE} ## スキャン除外リストの展開 while read LINE do if [ $(echo "${LINE}"|grep \/$) ]; then i=`echo ${LINE}|sed -e 's/^\([^ ]*\)\/$/\1/p' -e d` excludeopt="${excludeopt} --exclude-dir=^${LINE}" else excludeopt="${excludeopt} --exclude=^${LINE}" fi done < ${EXCLUDE_LIST_FILE} echo "excludeopt: ${excludeopt}" >> ${LOGFILE} ## ウイルススキャンの実行 /usr/bin/clamscan \ --max-filesize=${MAX_FILESIZE} --max-scansize=${MAX_SCANSIZE} \ --infected --recursive ${excludeopt} / 1> ${SCAN_RESULT} 2>> ${LOGFILE} ## ウイルスを検知したときのみ、アラートメールで通知する [ ! -z "$(grep FOUND$ ${SCAN_RESULT})" ] && \ cat ${SCAN_RESULT} | mail -s "Virus Found in `hostname`" ${MAILTO} cat ${SCAN_RESULT} >> ${LOGFILE} echo "`date` Do Scan Virus end" >> ${LOGFILE} # 5. Apache子プロセスを再起動(graceful) echo "`date` Restart Apache Process start" >> ${LOGFILE} systemctl reload httpd 1>> ${LOGFILE} 2>&1 echo "`date` Restart Apache Process end" >> ${LOGFILE} echo "`date` Scan Virus complete" >> ${LOGFILE} # EOF --
補足します。
「4. ウイルススキャンの実施」の前後に、「3. Apache子プロセスを再起動(graceful)」と「5. Apache子プロセスを再起動(graceful)」を追加しています。
Apacheプロセスの再起動は、
# systemctl reload httpd
で実行します。
restartではなくreloadを使用するのは、CentOS 7 systemd用のhttpd unitファイル /usr/lib/systemd/system/httpd.service では、reloadのときの実行コマンドとして、Apacheのサービス起動オプションgracefulを使用するよう設定されているためです。
# view /usr/lib/systemd/system/httpd.service -- ... [Service] Type=notify EnvironmentFile=/etc/sysconfig/httpd ExecStart=/usr/sbin/httpd $OPTIONS -DFOREGROUND ExecReload=/usr/sbin/httpd $OPTIONS -k graceful ExecStop=/bin/kill -WINCH ${MAINPID} ... --
サービス起動オプションgracefulを使用すると、処理中の子プロセスはその処理を終えてから終了するため、ユーザーから接続中のセッションが切れることはありません。
CentOS 6であれば、
# /etc/init.d/httpd graceful
のように、initスクリプトもしくはserviceコマンドでgracefulを指定します。
親プロセスごと再起動をかけても問題がなければ、restartで再起動をかけてもよいでしょう。
また、「3. Apache子プロセスを再起動(graceful)」の部分のみ、再起動後に10秒間のsleepを入れています。
これは、再起動の命令から実際に子プロセスが終了するまで、少し時間がかかるためです。
この「スキャン実行前後に、Apacheを再起動する」方法の効果については、これまでの運用でもっともうまくいったときは、設定前後でメモリ使用量が以下のとおり改善されました。
Apache再起動設定前 | Apache再起動設定後 | ||
サーバー全体のメモリ使用量 | スキャン実行時 | 1200MB | 750MB |
通常時 | 600MB | 400MB | |
スワップ領域の使用量 | スキャン実行時 | 700MB | 100MB |
通常時 | 600MB | 30MB |
なお、Linuxにおけるメモリ使用、スワップに関する説明や調べ方は、以下の記事がとてもわかりやすいです。
・どうしてメモリはスワップするのか!?
https://heartbeats.jp/hbblog/2014/01/linux-page-swap.html
・Linuxで、どのプロセスがページングを行っているのか調べるには?
https://yakst.com/ja/posts/382
CPUを占有使用する問題への対策
clamscanコマンドはディスク上の全ファイルの検査を行う重い処理ですから、実行時は、1つのCPUをほぼ占有使用します。
CPUが複数あるサーバーであれば、他の処理は空いているCPUを使用できますが、CPUが1つしかないサーバーでは、例えば「Webサイトの表示が遅い」など、ウイルススキャン以外の本来の機能に影響があります。
仮にサーバー監視ツールで「CPU使用率が90%以上のときはアラート通知する」というような設定を行っていれば、「毎日わかっていることなのにアラートがうるさい」ということもあるでしょう。
このように「ウイルススキャン処理がCPUを占有使用する問題」への対策としては、
「CGroupでスキャン実行プロセスのCPU使用を制限する」
という方法があります。
このアイデアと設定方法は、以下の記事を参考にしました。
・ClamAVをCGroupで管理してCPUを節約する
http://dev.classmethod.jp/cloud/aws/clamav-process-controled-by-cgroup/
・可視化して解るcgroupによるCPUリソース制限
https://cloudpack.media/10238
・RHEL6 製品マニュアル, リソース管理ガイド 2.9. コントロールグループ内のプロセスの開始
https://access.redhat.com/documentation/ja-JP/Red_Hat_Enterprise_Linux/6/html/Resource_Management_Guide/Starting_a_Process.html
CGroupは、Linuxカーネルの機能で、プロセスへのCPU使用時間、システムメモリー、ネットワーク帯域幅などのリソース割り当てを制御することができます。
今回は、CGroupを使用して、clamscanコマンドのCPU使用時間を70%に制限する設定を行います。
- libcgroupのインストール
CGroupの機能が含まれる、libcgroupおよびlibcgroup-toolsパッケージをインストールします。
※CentOS 6の場合は、libcgroupパッケージのみでOKです。
# yum install libcgroup libcgroup-tools パッケージ libcgroup-0.41-11.el7.x86_64 はインストール済みか最新バージョンです 何もしません ... インストール: libcgroup-tools.x86_64 0:0.41-11.el7
- CGroupの設定
/etc/cgconfig.conf で、clamscanコマンドのCPU使用時間を70%に制限する「clamscang」グループを定義します。
- cfs_period_us: 単一CPUあたりの、CGroupで管理する実行時間(マイクロsec)
- cfs_quota_us: そのうちこのグループに所属しているプロセスがアクセスできる時間(マイクロsec)
今回使用するサーバーは1CPUですので、以下の設定では、
「1000000マイクロsec=1秒あたり、700000マイクロsec=700msec使用する」
すなわち「CPU使用時間を70%に制限する」
ということになります。
# vi /etc/cgconfig.conf -- 末尾に追記 group clamscang { cpu { cpu.cfs_quota_us = 700000; cpu.cfs_period_us = 1000000; } cpuacct { } } --
cgconfigサービスを起動し、自動起動設定を行います。
# systemctl start cgconfig # systemctl enable cgconfig Created symlink from /etc/systemd/system/sysinit.target.wants/cgconfig.service to /usr/lib/systemd/system/cgconfig.service. # systemctl status cgconfig ● cgconfig.service - Control Group configuration service Loaded: loaded (/usr/lib/systemd/system/cgconfig.service; enabled; vendor preset: disabled) Active: active (exited) since 木 2017-09-14 12:44:46 JST; 10s ago Main PID: 2379 (code=exited, status=0/SUCCESS) 9月 14 12:44:46 clamav_centos7 systemd[1]: Starting Control Group configur.... 9月 14 12:44:46 clamav_centos7 systemd[1]: Started Control Group configura.... Hint: Some lines were ellipsized, use -l to show in full.
- CGroupを使用してClamAVを実行してみる
比較のため、まずCgroupを使用せずに、スキャン実行スクリプトを実行します。
# /root/bin/scanvirus.sh
実行中のCPU使用率をtopコマンドで確認します。
→ clamscanコマンドのCPU使用率は85%から99%ぐらいの間で推移しました。
# top top - 15:44:05 up 3:45, 3 users, load average: 1.19, 0.73, 0.38 Tasks: 100 total, 2 running, 98 sleeping, 0 stopped, 0 zombie %Cpu(s): 90.4 us, 1.7 sy, 0.0 ni, 0.3 id, 7.3 wa, 0.0 hi, 0.0 si, 0.3 st KiB Mem : 1014976 total, 70024 free, 594864 used, 350088 buff/cache KiB Swap: 2097148 total, 2050460 free, 46688 used. 246400 avail Mem PID USER PR NI VIRT RES SHR S %CPU %MEM TIME+ COMMAND 2825 root 20 0 646120 528604 1680 R 92.3 52.1 1:56.60 clamscan
スキャン実行スクリプトのログで、実行結果、実行時間を確認します。
→ 全ディスクのスキャンに2分57秒かかりました。
# tail -f /var/log/scanvirus.log ... ----------- SCAN SUMMARY ----------- Known viruses: 6303613 Engine version: 0.99.2 Scanned directories: 4069 Scanned files: 24681 Infected files: 0 Data scanned: 2272.93 MB Data read: 3700.91 MB (ratio 0.61:1) Time: 177.875 sec (2 m 57 s)
続いて、CGroupを使用してclamscanコマンドを実行するようにします。
先ほど /etc/cgconfig.conf で定義した「clamscang」グループをCPU制御に適用して実行するには、以下のようにcgexecコマンドを使用します。
# cgexec -g cpu:clamscang <適用するコマンド>
スキャン実行スクリプト内で、clamscanコマンドはcgexecコマンドと組み合わせてCPU使用時間を制限して実行するよう修正します。
# vi /root/bin/scanvirus.sh -- 変更前 /usr/bin/clamscan \ --max-filesize=${MAX_FILESIZE} --max-scansize=${MAX_SCANSIZE} \ --infected --recursive ${excludeopt} / 1> ${SCAN_RESULT} 2>> ${LOGFILE} -- -- 変更後 CGROUP_CMD='/bin/cgexec -g cpu:clamscang' ... ${CGROUP_CMD} /usr/bin/clamscan \ --max-filesize=${MAX_FILESIZE} --max-scansize=${MAX_SCANSIZE} \ --infected --recursive ${excludeopt} / 1> ${SCAN_RESULT} 2>> ${LOGFILE} --
CPU使用時間の制限を行ったスキャン実行スクリプトを実行します。
# /root/bin/scanvirus.sh
先ほどと同様に、実行中のCPU使用率をtopコマンドで確認します。
→ clamscanコマンドのCPU使用率は65%から72%ぐらいの間で推移しました。
# top top - 16:03:07 up 4:04, 3 users, load average: 0.00, 0.02, 0.13 Tasks: 94 total, 3 running, 91 sleeping, 0 stopped, 0 zombie %Cpu(s): 67.8 us, 3.7 sy, 0.0 ni, 28.6 id, 0.0 wa, 0.0 hi, 0.0 si, 0.0 st KiB Mem : 1014976 total, 76056 free, 483936 used, 454984 buff/cache KiB Swap: 2097148 total, 2047028 free, 50120 used. 358936 avail Mem PID USER PR NI VIRT RES SHR S %CPU %MEM TIME+ COMMAND 2952 root 20 0 536344 434044 4204 R 70.0 42.8 0:05.58 clamscan
スキャン実行スクリプトのログで、実行結果、実行時間を確認します。
→ 全ディスクのスキャンに3分44秒かかりました。
# tail -f /var/log/scanvirus.log ... ----------- SCAN SUMMARY ----------- Known viruses: 6303613 Engine version: 0.99.2 Scanned directories: 4069 Scanned files: 24682 Infected files: 0 Data scanned: 2272.95 MB Data read: 3700.92 MB (ratio 0.61:1) Time: 224.142 sec (3 m 44 s)
想定どおり、CGroupを使用することで、clamscanコマンドのCPU使用率を70%程度に抑えることができました。
また、CPU使用時間を70%に抑えたため、全ディスクのスキャン時間が2分57秒から3分44秒と約1.27倍に増えました。
100/70 = 1.43ですから、こんなものですかね。
ということで、「CGroupでスキャン実行プロセスのCPU使用を制限する」ことで「ウイルススキャン処理がCPUを占有使用する問題」が改善されることが確認できました。
スキャン処理に要する時間が少し増えることに注意しましょう。
プライベートネットワーク内サーバーのウイルス定義更新
Webシステムを役割ごとの複数台のサーバーで構成する場合、
「WebプロキシサーバーをDMZに設置、バックエンドのアプリケーションサーバーやDBサーバーはプライベートネットワーク内に設置してインターネットにアクセスできないようにする」
というネットワーク構成とすることが多いと思います。
このような場合、バックエンドのサーバーで定期ウイルススキャンの設定はどうやって行えばよいでしょうか?
ClamAVプログラム本体、ライブラリおよび初期状態のウイルス定義は、
clamav, clamav-lib, clamav-filesystem, clamav-data, clamav-update
といったパッケージのRPMファイルを入手してサーバーにアップロードすることでインストールできますね。
また、Webプロキシサーバーなどインターネットにアクセスできる上位のサーバーで、一時的にSquidなどのフォワードプロキシーを起動(インストール作業が終わったら停止)すれば、yumコマンドでインストールできます。
では、その後の運用において、ウイルス定義を最新の状態に更新するのはどうすればよいでしょうか?
インストールのときと同様に、上位のサーバーでフォワードプロキシーが稼働していれば、freshclam.conf でHTTPProxyの設定を行うことで、freshclamコマンドによりウイルス定義が更新できます。
# vi /etc/freshclam.conf -- ... # Proxy settings # Default: disabled HTTPProxyServer <上位サーバーのプライベートIPアドレスまたはホスト名> HTTPProxyPort <上位サーバーのフォワードプロキシーの使用ポート> --
フォワードプロキシーが使用できない場合は、上位サーバーのClamAVが保持している最新のウイルス定義ファイルを何らかの方法で取得すればよいです。
ウイルス定義ファイルは、デフォルトでは、/var/lib/clamav 以下に保存されています。
# ls -l -rw-r--r-- 1 clamupdate clamupdate 766464 Sep 13 15:57 bytecode.cld -rw-r--r-- 1 clamupdate clamupdate 124543488 Sep 15 14:50 daily.cld -rw-r--r-- 1 clamupdate clamupdate 307499008 Sep 13 15:52 main.cld -rw------- 1 clamupdate clamupdate 208 Sep 15 14:50 mirrors.dat
この bytecode.cld, daily.cld, main.cld が、clamscanコマンドがウイルススキャン時に使用するウイルス定義ファイルですので、これらを上位のサーバーからscpコマンドやrsyncコマンドで取得します。
例えば、インターネットにアクセス可能な上位サーバーを「Webプロキシーサーバー」、インターネットにアクセスできないサーバーを「アプリケーションサーバー」とすると、下図のようなイメージです。
長くなってしまうので、詳しい設定手順はここでは記載しませんが、上の図の例の設定方針としては以下のような感じです。
- アプリケーションサーバーから、ウイルス定義ファイルの所有者clamupdateユーザーで、Webプロキシーサーバーに対してSSH鍵認証が可能とする。
- スクリプト内で自動実行するため、SSH鍵認証のパスフレーズは空とする。
- Webプロキシーサーバーでは、clamupdateユーザーのSSHに制限を加える。
- アプリケーションサーバーのスキャン実行スクリプト(ここまでの例では、/root/bin/scanvirus.sh)では、ウイルス定義取得処理をfreshclamコマンドからscpまたはrsyncコマンドに置き換える。
- Webプロキシーサーバーがウイルス定義を更新してから取得するよう、アプリケーションサーバーのcronでは、スキャン実行スクリプトの開始時刻を遅らせる(10分とか)。
SSH鍵認証を使用したリモートサーバー間の自動データ転送設定については、以下の記事が参考になります。
・rsync + cron + ssh (rsyncd を立てない編)
http://www2s.biglobe.ne.jp/~nuts/labo/inti/cron-rsync-ssh-nodaemon.html
・ssh scp sftp の正しい自動実行方法
http://sonic64.com/2004-11-17.html
SSH鍵認証を行うため、Webプロキシーサーバーでは、clamupdateユーザーのシェルをデフォルトの /sbin/nologin から /bin/bash に変更する必要があります。
WebプロキシーサーバーでのclamupdateユーザーのSSH制限については、~clamupdate/.ssh/authorized_keys ファイルで、アクセス元IPアドレスの制限をかけると、万一秘密鍵ファイルが漏れても、外部からはSSHできません。
以下のように、from= でアクセス元IPアドレスを限定し、さらに、no-port-forwarding,no-X11-forwarding,no-agent-forwarding,no-pty を追記して転送や端末の割り当てを禁止します。
# vi ~clamupdate/.ssh/authorized_keys -- from="<アプリケーションサーバーのプライベートIPアドレス>",no-port-forwarding,no-X11-forwarding,no-agent-forwarding,no-pty (SSH公開鍵データ)... --
アプリケーションサーバーにおいて、ウイルス定義ファイルを取得するときのコマンドは、実際には、こんな感じになるでしょう
scpコマンドの場合。
# scp -i <SSH秘密鍵ファイルのパス> \ clamupdate@<WebプロキシーサーバーのプライベートIPアドレス>:/var/lib/clamav/*.cld \ /var/lib/clamav/
rsyncコマンドの場合。
# rsync -vv -az -e "ssh -i <SSH秘密鍵ファイルのパス>" \ clamupdate@<WebプロキシーサーバーのプライベートIPアドレス>:/var/lib/clamav/*.cld \ /var/lib/clamav/
やや泥臭い方法になりますが(笑)、プライベートネットワーク内のサーバーでも、インターネットにアクセスできる上位サーバーとのSSH通信が可能であれば、上記のように最新のウイルス定義を使用した自動定期スキャンが可能となります。
(ClamAVパッケージのアップデートは手動で行う必要がありますね。。)
「そもそも、インターネットにアクセスできないサーバーでウイルススキャンを行う必要があるのか?」
という疑問もあるかと思います。
インターネットに公開しているWebサイト、Webサービスの複数台サーバー構成であれば、インターネット公開サーバー経由で、何らかのデータが何らかの形式でバックエンドのサーバーに保存されるのですから、やはりウイルス感染する可能性はゼロではない、といえるのではないでしょうか。
「企業内のクローズなネットワーク内のサーバーやPCでウイルス感染した」
という事例もわりとよくありますし。
ウイルス検知時の対処
前回の記事で行った定期ウイルススキャンの設定では、ウイルス検知時は、スキャン実行スクリプトで指定したメールアドレスに、ウイルススキャン結果およびウイルス検知ファイル名を送信することで、通知してくれます。
ClamAVのウイルス検知は、実際には誤検知で、本当はウイルスではないことがあります。
といいますか、僕の経験では、検知の頻度はサーバー1台あたり1年に数回ありますが、95%以上は誤検知で、本当にウイルスのようだったことは1回だけしかありません。
このため、ウイルス検知時は、運用担当者自身が、検知したファイルの内容、タイムスタンプや、インターネット上の情報等をチェックし、本当にウイルスか、あるいは誤検知か、判断する必要があり、その作業はなかなか大変です。
ファイルのタイムスタンプを確認して、ずっと前から更新されていないのに、ある日突然ウイルスとみなされた場合は、誤検知の可能性が高いです。
この場合は、GoogleやTwitterなど、インターネット上で通知メールに記載されたメッセージ(何のウイルスか)で、検索してみるとよいでしょう。
誤検知であれば、他のユーザーも同じメッセージに遭遇し、掲示板等で質問をしているケースが多いです。
誤検知の場合は、ウイルス定義の不具合ですので、数日後のウイルス定義更新で修正されます。
修正後、自動的にウイルスと判定されなくなりますので、少し待ちましょう。
明らかにウイルスではないのに、ずっとウイルスとみなされる場合は、ウイルススキャンの除外リストファイル(今回の設定では /root/bin/scanvirus_exclude_list.txt)に該当ファイルを追記するとよいでしょう。
誤検知ではなく、ウイルスの可能性が高そうなら、ファイルを削除するか、少なくともWeb公開ディレクトリ以外の箇所に退避すべきでしょう。
僕が経験した、2017年7月の誤検知の例をあげます。
このときは、以下のようなウイルス検知がありました。
(ファイルパスは実際のものから変更しています)。
/var/www/html/image/koukoku201501.pdf: BC.Pdf.Exploit.CVE_2017_3032-6316401-6 FOUND
「BC.Pdf.Exploit.CVE_2017_3032-6316401-6 ClamAV」でGoogle検索しても、とくに情報は出てきませんでしたが、lsコマンドで確認すると、ファイルのタイムスタンプは2016年3月で、ずっと前からこのサーバーに存在したのにこの日初めて検知したので、誤検知の可能性が高いと判断しました。
念のため、このファイルをPCにダウンロードして、PDFファイルを開いて、中身が普通のデータで、PCのアンチウイルスソフトがウイルス検知しないことも確認しました。
(本当にウイルスだったら、実は危険!)
ClamAVのウイルス定義の変更内容は、以下のメーリングリストアーカイブで確認できます。
・GT.net ClamAV VirusDB Mailing List Archive
https://lists.archive.carbon60.com/clamav/virusdb/
ここで確認すると、「BC.Pdf.Exploit.CVE_2017_3032-6316401-6」のルールは「bytecode – 307」で追加されたことがわかりました。
https://lists.archive.carbon60.com/clamav/virusdb/70317
... New Detection Signatures: * BC.Pdf.Exploit.CVE_2017_3032-6316401-6 ...
このときは、ウイルス定義から削除されるのを待つことにして、実際に5日後に削除され、ウイルス検知がなくなりました。
先ほどのメーリングリストアーカイブを確認すると、「BC.Pdf.Exploit.CVE_2017_3032-6316401-6」のルールは「bytecode – 308」で削除(Drop)されたことがわかります。
https://lists.gt.net/clamav/virusdb/70362
... Dropped Detection Signatures: ... * BC.Pdf.Exploit.CVE_2017_3032-6316401-6 ...
この例で、もしスキャン対象から除外するのであれば、以下のように、除外リストファイル /root/bin/scanvirus_exclude_list.txt に追記します。
# vi /root/bin/scanvirus_exclude_list.txt -- /sys/ /proc/ /dev/ /var/www/html/image/koukoku201501.pdf --
なお、clamscanコマンドのスキャン除外指定であるexludeオプションでは、正規表現を使用することができます。
例えば、/var/www/html/image/ 配下の拡張子「.pdf」のファイルをすべて除外するのであれば、以下のように追記します。
/var/www/html/image/(.*).pdf
僕のこれまでの運用経験では、日本語ファイル名の場合はうまくマッチしない(文字コードの問題かもしれませんが)ようなので、ディレクトリやファイル名を限定したうえで、正規表現を使用するとよいでしょう。
まとめ
今回の記事では、ClamAVによる定期ウイルススキャンの運用において工夫するポイントや、実際に検知したときの対処方法について記載しました。
ClamAVは無償で利用できますし、インターネット上に多くの導入手順がみられるとおり、サーバーへのインストール、定期スキャン設定は比較的簡単です。
例えば、不特定ユーザーからファイルをアップロードさせる機能を持つようなWebサーバーの場合は、悪意を持ったユーザーがウイルスファイルをアップする可能性がゼロではありません。
また、ウイルス感染した関係者のPCから、CMSの管理画面を経由してウイルスがサーバーにアップロードされるという可能性もあるでしょう。
ClamAVを導入すると、そういったウイルス感染を未然に防ぐことはできませんが、比較的早く気づくことはできるはずです。
しかし、本番環境で長期にわたって運用を続ける場合は、CPU、メモリリソースを多く消費するので、とくに低スペックのサーバーでは工夫が必要です。
また、誤検知がときどき発生し、そのたびに調査、判断が必要となるので、運用担当者の負担も発生します。
そういった運用コストを踏まえたうえで、導入の可否を判断されるとよいと思います。
また、オンアクセススキャンや、より精度の高いスキャンが必要な場合は、トレンドマイクロ社、シマンテック社等の商用アンチウイルスソフトのご利用をおすすめします。
(関連記事)
・ClamAVによる定期ウイルススキャンの設定
https://inaba-serverdesign.jp/blog/20170913/clamav_scan_virus_install.html
・ClamAVによるリアルタイムスキャンの設定
https://inaba-serverdesign.jp/blog/20210409/clamav-realtime-scan.html
・ClamAV 0.103.0でウイルススキャンが遅くなった問題の対応 (CentOS 8)
https://inaba-serverdesign.jp/blog/20210129/clamav_scan_slow.html