はじめに
本記事は前編と後編の2部構成となります。
- 前編: ClamAVのリアルタイムスキャンをAzure Filesに実施するコンテナイメージを作成する
- 後編: 前編で作成したイメージを、AKSにデプロイする
Azure Filesのマルウェア保護を検討した当初は「Defender for Cloudを使って保護できるのは?」と思ってたのですが、残念ながらAzure FilesはDefender for Cloudのサポート範囲外でした。
そのため、Azure Filesを保護するには、Defender for Cloud以外の方法が必要となったという経緯がありました。
• サポートされていないサービス: Azure Files はサポートされていません。
別の方法として、「ClamAVをインストールしたコンテナイメージを作成 → AKS上でイメージを稼働 → AKSでマウントしたAzure Filesを保護」という方法を試したので、備忘録までにその内容を記載します。
参照させていただいた記事
AKS・ClamAVを組み合わせた記事が少ない中、とても助けられた記事です。感謝。
イメージ作成ファイル群の全体像
コンテナイメージを作成するためのファイル群の全体像です。
clamAV/
├── Dockerfile # ClamAVコンテナのビルド定義
├── clamd.conf # ClamAVデーモンの設定ファイル
├── freshclam.conf # ウイルス定義更新の設定ファイル
└── entrypoint.sh # コンテナ起動スクリプト
コンテナイメージ関連ファイル
早速ですがdockerfileの全容を以下に記載します。
今回、OSはredhatのubi10を使用します。
FROM registry.access.redhat.com/ubi10/ubi:latest AS builder
EXPOSE 3310
# ~~(略)~~
# システム設定と ClamAV インストール
RUN set -eux; \
# EPEL リポジトリ追加と ClamAV インストール
dnf install -y https://dl.fedoraproject.org/pub/epel/epel-release-latest-10.noarch.rpm; \
dnf install -y \
clamav \
clamav-update \
clamd \
clamav-scanner-systemd \
vim \
wget; \
# キャッシュ削除
dnf clean all; \
rm -rf /var/cache/dnf
# アプリケーション用ユーザーを追加
RUN groupadd -r appuser && useradd -r -g appuser appuser
# ディレクトリの権限設定
RUN chown -R appuser:appuser /var/lib/clamav
# 設定ファイルをコピー
COPY clamd.conf /etc/clamd.d/scan.conf
COPY freshclam.conf /etc/freshclam.conf
# 起動スクリプト
COPY entrypoint.sh /entrypoint.sh
RUN chmod +x /entrypoint.sh
ENTRYPOINT ["/entrypoint.sh"]
ClamAVのインストール部分について詳しく記載します。
EPELリポジトリの使用
dnf install -y https://dl.fedoraproject.org/pub/epel/epel-release-latest-10.noarch.rpm
Red Hat UBI 10の標準リポジトリにはClamAVが含まれていないため、Fedoraプロジェクトが管理する信頼性の高いリポジトリであるEPEL (Extra Packages for Enterprise Linux) を使用しました。
EPELはRHEL系ディストリビューション向けの追加パッケージリポジトリであり、容易に様々なパッケージがインストール出来る点がメリットです。
ClamAV関連パッケージのインストール
今回リアルタイムスキャンを実施したいので、ClamAVの「clamonacc(ClamAV On-Access Scanner)」を使用します。
clamonaccは、ClamAVのリアルタイムスキャン機能を提供するコンポーネントです。ファイルシステムを監視し、自動的にウイルススキャンを実行します。
clamonacc は Linux カーネルのファイルアクセス通知機構であるfanotify を使っているため、ファイルが「開かれる(open)・読み込まれる(read)・実行される(exec)」瞬間に起動し、これは「ファイルが存在すること」ではなく「実際に使われること」に対して検知します。
格納されているだけのファイルを検知したい場合は、アクセス検知ではなく clamdを定期実行してオンデマンドスキャンを行うのが適切かと思います。
dnf install -y \
clamav \ # ← clamonaccはここに含まれる
clamav-update \
clamd \
clamav-scanner-systemd \
vim \
wget
インストールする各項目について簡単に説明します。
-
clamav
- clamonaccが含まれたパッケージ
-
clamav-update
- freshclamコマンドを提供
- 上記コマンドによるウイルス定義データベースの自動更新
- ClamAV公式サーバーから最新の定義ファイルをダウンロード
-
clamd
- ClamAVデーモン(常駐プロセス)
- TCPソケット(ポート3310)でスキャンリクエストを受付
-
clamav-scanner-systemd
- systemdとの統合機能
- サービス管理を容易にする
- コンテナ環境では直接systemdを使わないが、依存関係で必要な場合があるとのことで念のためインストール
設定ファイルについて
- clamd.conf
~~(略)~~
# Log time with each message.
# Default: no
-#LogTime yes
+LogTime yes
~~(略)~~
# Run as another user (clamd must be started by root for this option to work)
# Default: don't drop privileges
#User clamav
+User root
~~(略)~~
# Don't fork into background.
# Default: no
-#Foreground yes
+Foreground yes
~~(略)~~
# Set the exclude paths. All subdirectories are also excluded.
# Default: disabled
#OnAccessExcludePath /home/user
+OnAccessExcludePath <Azure Filesのマウントパス>/<隔離用ディレクトリ>
~~(略)~~
# Set the mount point to be scanned.
# Default: disabled
#OnAccessMountPath /
#OnAccessMountPath /home/user
+OnAccessMountPath <Azure Filesのマウントパス>
~~(略)~~
# With this option you can exclude the root UID (0).
# Default: no
#OnAccessExcludeRootUID no
+OnAccessPrevention yes
+OnAccessExcludeRootUID yes
| 設定項目 | 役割 |
|---|---|
OnAccessMountPath |
監視対象であるAzure Filesのマウントパスを指定 |
OnAccessExcludePath |
隔離用ディレクトリを除外 |
OnAccessPrevention |
ウイルス検出時にアクセスをブロック |
OnAccessExcludeRootUID |
root権限の操作は監視しない |
OnAccessMountPathで指定したAzure Filesのマウントパスを常時監視し、OnAccessExcludePathで指定した隔離用ディレクトリへ検知したファイルを格納させる設計にしています。
- freshclam.conf
本ファイルは特に編集していないので割愛。
未編集ですが、ウイルス定義データベースの自動更新について設定が必要なシーンもあるかと思い、コンテナ運用の性質を鑑みて外出ししてます。
entrypoint.sh
コンテナ起動時に実行されるスクリプトの内容を解説します。
#!/bin/sh
echo "=== Updating virus database ==="
/usr/bin/freshclam 2>&1
echo "=== Starting freshclam daemon ==="
/usr/bin/freshclam -d 2>&1 &
echo "=== Starting clamd ==="
/usr/sbin/clamd -c /etc/clamd.d/scan.conf 2>&1 &
# clamd 起動待ち
sleep 60
echo "=== Starting clamonacc ==="
/usr/sbin/clamonacc \
--foreground \
--move=<隔離用ディレクトリパス> \
--fdpass \
-c /etc/clamd.d/scan.conf 2>&1 &
# コンテナを維持
tail -f /dev/null
ウイルス定義の初回更新
echo "=== Updating virus database ==="
/usr/bin/freshclam 2>&1
- コンテナ起動時に最新のウイルス定義をダウンロード
- 同期実行(完了を待つ)
- 2>&1: 標準エラー出力も標準出力にリダイレクト(コンテナ仕様)
freshclamデーモン起動
echo "=== Starting freshclam daemon ==="
/usr/bin/freshclam -d 2>&1 &
- -d: デーモンモードで起動
- &: バックグラウンド実行
- 役割::定期的にウイルス定義を自動更新(デフォルトだと10分間隔)
clamdデーモン起動
echo "=== Starting clamd ==="
/usr/sbin/clamd -c /etc/clamd.d/scan.conf 2>&1 &
- -c: 設定ファイルを指定
- バックグラウンドで起動
- **役割:**ポート3310でスキャン要求を待機
clamd起動待機
# clamd 起動待ち
sleep 60
- clamdが完全に起動するまで60秒待機
- ウイルス定義のメモリロードに時間がかかるため必要
clamonacc起動(リアルタイムスキャン)
echo "=== Starting clamonacc ==="
/usr/sbin/clamonacc \
--foreground \
--move=<隔離用ディレクトリパス> \
--fdpass \
-c /etc/clamd.d/scan.conf 2>&1 &
| オプション | 説明 |
|---|---|
--foreground |
フォアグラウンド実行 |
--move=<path> |
ウイルス検出時の移動先ディレクトリ |
--fdpass |
ファイルディスクリプタ経由でclamdと通信 |
-c |
設定ファイル指定 |
--fdpass について補足します。
clamonacc は ファイルアクセスをフックする fanotify の利用に root 権限を要するため 、root で動作し、root 権限で検知したファイルを開きます。
その「すでに開かれているファイル」を示すファイルディスクリプタを clamd に渡してスキャンさせることで、clamd を非 root のまま安全にウイルス検査を行います。
そのため、clamonaccはファイルディスクリプタ経由で通信するオプションが必要となります。
以上の項目により、ClamAVが動作するコンテナイメージの材料ができました。
私はこれらをAzure DevOpsを使用してビルドし、Azure Container Registryにプッシュして格納しています(DevOpsを用いたビルドについては割愛します)。
続きは後編にて、AKSで上記コンテナイメージを稼働させたいと思います。