深夜2時、PagerDutyのアラートが鳴り響く――。WordPress WebサーバーのCPU使用率は100%に跳ね上がり、アウトバウンドトラフィックは250 Mbpsに達していました。攻撃者によってwp-content/uploadsディレクトリにWebshellが配置され、バックグラウンドでMoneroのマイニングスクリプトが実行されていたのです。このような緊急事態において、最も手軽で頼りになるオープンソースソリューションがClamAVです。Ubuntuのリポジトリから手軽に導入でき、ライセンス費用もかからず、感染したファイルを即座に検知できます。
クイックスタート:5分で導入とスキャンを実行する
サーバーに異常な負荷や遅延が発生しており、不審なファイルを直ちに特定したい場合は、ターミナルを開いて以下のコマンドを順に実行します。
# 1. リポジトリを更新しClamAVパッケージをインストール
sudo apt update
sudo apt install -y clamav clamav-daemon
# 2. プロセスの競合エラーを防ぐためfreshclamサービスを停止
sudo systemctl stop clamav-freshclam
# 3. Cisco Talosから最新のウイルス定義ファイルをダウンロード
sudo freshclam
# 4. 定義ファイルの自動更新プロセスを再起動・有効化
sudo systemctl start clamav-freshclam
sudo systemctl enable clamav-freshclam
# 5. Webディレクトリを再帰的にスキャンし、感染ファイルのみを表示
sudo clamscan -r -i /var/www/html
上記のコマンドにおいて、-r(recursive)オプションはすべてのサブディレクトリを再帰的に走査します。また、-i(infected)オプションを指定することで、問題のないファイルの膨大なログ出力を省き、バックドアやトロイの木馬が仕込まれたファイルのみを画面に表示できます。
ClamAVを構成する各コンポーネントの仕組み
目先の障害対応が完了したら、ClamAVの動作原理を正しく把握しておきましょう。これにより、メモリ不足によるサーバーのクラッシュやディスクI/Oの枯渇といったトラブルを未然に防ぐことができます。
1. clamscanとclamdscanの違い
これら2つのコマンドは、用途やユースケースがまったく異なります。
- clamscan(スタンドアロンCLI):実行されるたびにディスクからウイルス定義データベース全体を読み込んでRAMに展開するため、起動だけで20〜30秒ほど要します。スキャンが完了するとプロセスは終了し、メモリは解放されます。アドホックなオンデマンドスキャンには便利ですが、高頻度で実行するとI/OおよびCPUリソースを激しく消費します。
- clamdscan(Socket経由のClient/Server型):
clamav-daemonと連携して動作します。デーモンがウイルス定義データベースをRAM上に常駐させているため、clamdscan実行時は内部ソケット(/run/clamav/clamd.ctl)経由でファイルパスを渡して処理を委譲するだけです。スキャン速度はclamscanと比較して5〜10倍高速になります。
2. Freshclam:ウイルス定義ファイルの更新メカニズム
ClamAVのシグネチャデータベースは、Cisco Talosによって1時間ごとに更新・管理されています。設定ファイルは/etc/clamav/freshclam.confに配置されています。デフォルトでは、clamav-freshclamデーモンがHTTPS経由で1日24回(1時間に1回)アップデートの有無を確認します。
3. エラー対処:「freshclam is locked by another process」
インストール直後にsudo freshclamを実行すると、ほぼ確実に以下のようなエラーメッセージが表示されます。
ERROR: /var/log/clamav/freshclam.log is locked by another process
ERROR: Problem database update failed.
原因はシンプルです。aptによるインストール完了直後に、Ubuntuがバックグラウンドでclamav-freshclamサービスを自動起動するためです。このサービスがログファイルとデータベースの排他ロックを保持しています。手動でアップデートを行いたい場合は、事前にサービスを一時停止するだけで解決します。
sudo systemctl stop clamav-freshclam
sudo freshclam
sudo systemctl start clamav-freshclam
Cronjobによる自動スキャンとアラート通知の設定
管理者が手動で対処するまでの間、マルウェアの感染拡大を食い止めるには、不審なファイルの自動隔離が不可欠です。
1. 隔離ディレクトリ(Quarantine)の作成
誤検知(フォールスポジティブ)によって正常なソースコードが削除されるリスクがあるため、--removeオプションですぐにファイルを削除するのは避けるべきです。検知された不審なファイルは、厳格なパーミッションを設定した隔離ディレクトリへ退避させましょう。
sudo mkdir -p /var/quarantine
sudo chmod 700 /var/quarantine
2. 自動化Bashスクリプトの作成
実行用スクリプトファイルを/usr/local/bin/clamav-auto-scan.shに作成します。
sudo nano /usr/local/bin/clamav-auto-scan.sh
スクリプトの内容を以下のように記述します(サーバーにmailutilsパッケージ等のメール送信コマンドがセットアップされている必要があります)。
#!/bin/bash
SCAN_TARGET="/var/www /home /tmp"
LOG_FILE="/var/log/clamav/daily-scan.log"
QUARANTINE_DIR="/var/quarantine"
DATE=$(date +"%Y-%m-%d %H:%M:%S")
echo "=== ClamAV スキャン開始日時: $DATE ===" >> "$LOG_FILE"
# 再帰スキャンを実行し、感染ファイルを隔離ディレクトリへ移動、仮想ファイルシステムは除外
clamscan -r -i \
--move="$QUARANTINE_DIR" \
--exclude-dir="^/sys" \
--exclude-dir="^/proc" \
--exclude-dir="^/dev" \
--log="$LOG_FILE" \
$SCAN_TARGET
INFECTED_COUNT=$(grep "Infected files:" "$LOG_FILE" | tail -n 1 | awk '{print $3}')
if [ "$INFECTED_COUNT" -gt 0 ]; then
echo "[警告] $INFECTED_COUNT 個のマルウェアファイルを検出しました! $QUARANTINE_DIR を直ちに確認してください" | mail -s "[ALERT] Virus detected on $(hostname)" [email protected]
fi
作成したスクリプトに実行権限を付与します。
sudo chmod +x /usr/local/bin/clamav-auto-scan.sh
3. 深夜実行のCronjobスケジュール登録
sudo crontab -eを実行してroot権限のcrontabを開き、午前3:00にスキャンを実行する設定を追加します。
0 3 * * * /usr/local/bin/clamav-auto-scan.sh > /dev/null 2>&1
本番環境におけるリソース最適化のノウハウ
Linuxサーバー上でアンチウイルスソフトを実行する際は、稼働中のWebサービスに悪影響を及ぼさないよう慎重なリソース設計が必要です。
1. niceとioniceでプロセスの優先度を下げる
.zipなどの圧縮ファイルや、フレームワークのキャッシュのように大量の小さなファイル群をスキャンすると、CPU使用率が100%に達し、ディスクI/Oがボトルネックになりがちです。スキャンプロセスの優先度を最低レベルまで下げて実行しましょう。
nice -n 19 ionice -c 3 clamscan -r -i /var/www
この設定により、OSはNginxやPHP-FPMなどのWeb処理に優先してCPUを割り当てます。また、ディスクI/Oに関してもサーバーがアイドル状態(Idle – -c 3)のときにのみClamAVへ割り振られます。
2. clamav-daemonのRAM消費対策
ClamAVのシグネチャデータベースには現在850万件以上のウイルス定義が登録されています。これらをメモリ上にロードすると、clamdは実質1.1GB〜1.4GBのRAMを消費します。VPSのメモリが1GBまたは2GB程度しかない場合、メモリ枯渇によってOSのOOM Killerが発動し、MySQLなどの重要プロセスが強制終了されてしまう危険があります。
RAMが2GB以下のサーバーにおける推奨対策:
clamav-daemonを完全に無効化する(sudo systemctl disable --now clamav-daemon)。- 急激なメモリ負荷に耐えられるよう、最低2GBのスワップファイル(Swap)を作成する。
- アクセスが少ない深夜帯(午前2時〜4時)にのみ、Cronjob経由でスタンドアロンの
clamscanを実行する。
3. 仮想ファイルシステムを必ず除外する
ルートディレクトリ(/)からディスク全体をスキャンする場合は、--exclude-dir="^/proc"、--exclude-dir="^/sys"、--exclude-dir="^/dev"といった除外フラグを必ず付与してください。これらのディレクトリにはカーネルがメモリ上に生成した仮想ファイルが含まれています。ここをスキャン対象に含めてしまうと、ClamAVが無限ループに陥り、I/Oを圧迫してサーバーが完全にフリーズする原因になります。

