はじめに
本記事は前編と後編の2部構成となります。
- 前編: ClamAVのリアルタイムスキャンをAzure Filesに実施するコンテナイメージを作成する
- 後編: 前編で作成したイメージを、AKSにデプロイする
後編では、前編で作成したコンテナイメージを、AKS上で稼働させるところまで実施します。
前提
- ClamAVがインストールされたコンテナイメージがあること
- コンテナイメージがContainer Registoryに格納されていること
- AKSクラスターが構築済みであること
- 既にAsure Filesをマウントしたアプリケーション用Podが稼働していること
- clamonaccが検知した際に隔離する用のAzure Filesが作成済みであること
マニフェストファイル
まずはマニフェストファイルの全体像を記載します。
apiVersion: apps/v1
kind: Deployment
metadata:
name: clamav
labels:
k8s-app: clamav-host-scanner
spec:
replicas: 1
strategy:
type: Recreate
selector:
matchLabels:
name: clamav
template:
metadata:
labels:
name: clamav
spec:
nodeSelector:
"kubernetes.io/os": linux
containers:
- name: clamav-scanner
image: myregistry.azurecr.io/<コンテナイメージ>:<タグ名>
securityContext:
capabilities:
add:
- SYS_ADMIN
resources:
~~(略)~~
volumeMounts:
- name: azure-storage
mountPath: /mnt/scan # ClamAVスキャン対象
readOnly: false
- name: azure-storage-secondary # 隔離用
mountPath: /mnt/data
readOnly: false
volumes:
- name: azure-storage
persistentVolumeClaim:
claimName: azurefile
- name: azure-storage-secondary # 隔離用
persistentVolumeClaim:
claimName: azurefile-secondary
---
apiVersion: v1
kind: PersistentVolume
metadata:
annotations:
pv.kubernetes.io/provisioned-by: file.csi.azure.com
name: azurefile-secondary # 隔離用
spec:
capacity:
storage: 5Gi
accessModes:
- ReadWriteMany
persistentVolumeReclaimPolicy: Delete
storageClassName: azurefile-csi
csi:
driver: file.csi.azure.com
volumeHandle: mystorageaccount#secondary-share # 隔離用
volumeAttributes:
resourceGroup: my-resource-group # リソースグループ名
storageAccount: mystorageaccount # ストレージアカウント名
shareName: secondary-share # Azure Files名(隔離用)
nodeStageSecretRef:
name: azure-storage-secret
namespace: default
mountOptions:
- dir_mode=0700
- file_mode=0600
- uid=0
- gid=0
- mfsymlinks
- cache=strict
- nosharesock
- nobrl
---
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: azurefile-secondary # 隔離用
spec:
accessModes:
- ReadWriteMany
storageClassName: azurefile-csi
volumeName: azurefile-secondary # 隔離用
resources:
requests:
storage: 5Gi
各項目について補足します。
Deployment(ClamAV Pod)
replicas: 1
strategy:
type: Recreate
- daemonsetを使用してノード毎に1つのPodをデプロイする設計だと、1つしかないAzure Filesに対して複数のスキャンが動作してしまうことを懸念して単一Podで運用。
- 既存のPodを完全に削除してから新しいPodを起動する更新。ダウンタイムが発生するが、同じAzure Filesを使用する複数Podの同時実行を防ぐために明示的に指定。
セキュリティ設定
securityContext:
capabilities:
add:
- SYS_ADMIN
- SYS_ADMIN権限を付与。root権限で動作するclamonaccがファイルシステムイベントを監視するために必要
ボリュームマウント
volumeMounts:
- name: azure-storage
mountPath: /mnt/scan # ClamAVスキャン対象
readOnly: false
- name: azure-storage-secondary # 隔離用
mountPath: /mnt/data
readOnly: false
ClamAVが稼働するpodにスキャン対象となるボリュームのマウントパスと、隔離用ボリュームのマウントパスを記載して、ボリュームマウントしています。
PersistentVolume(隔離用)
事前に作成した隔離用のAzure Filesを新規ボリュームとして作成し、Podにマウントさせます。
csi:
driver: file.csi.azure.com
volumeHandle: mystorageaccount#secondary-share # 隔離用
- Azure Files CSIドライバーを使用
- volumeHandle形式:ストレージアカウント名#ファイル共有名
マウントオプション
mountOptions:
- dir_mode=0700
- file_mode=0600
- uid=0
- gid=0
| オプション | 説明 |
|---|---|
dir_mode=0700 |
ディレクトリはroot(所有者)のみアクセス可能 |
file_mode=0600 |
ファイルはroot(所有者)のみ読み書き可能 |
uid=0, gid=0
|
rootユーザー/グループで実行 |
PersistentVolumeClaim(隔離用)
spec:
volumeName: azurefile-secondary # 隔離用
storageClassName: azurefile-csi
- 静的バインディング: 特定のPVを明示的に指定
- 動的プロビジョニングではなく、事前作成したAzure Filesを使用
動作確認
以下コマンドを実施して作成したマニフェストファイルをAKSへデプロイします。
kubectl apply -f <マニフェストファイル名>
続いてpodの起動状態を確認します。
以下コマンドを叩いて、「clamav」と付くpod名のSTATUSが「Runnning」となっていることを確認します。
kubectl get pods
続いてログの確認です。
上記コマンドで「clamav」と付くpod名のNAMEが分かるので、そのNAMEを利用して以下のコマンドを叩きます。
kubectl logs <pod名>
clamonaccまで起動ができており、clamdによる10分周期のDB更新が動いています(ログ内の日時は変更しています)。
=== Updating virus database ===
ClamAV update process started at Thu Jan 1 00:00:00 2025
~~(略)~~
Database test passed.
=== Starting freshclam daemon ===
=== Starting clamd ===
~~(略)~~
Thu Jan 1 00:00:00 2025 -> Self checking every 600 seconds.
=== Starting clamonacc ===
Thu Jan 1 00:00:00 2025 -> SelfCheck: Database status OK.
EICARファイルを検知対象フォルダに作成してアクセスしてみます。
Azure公式ドキュメントにEICARファイルの作成方法が記載されていたため、それを参照します。
kubectl exec -it <pod名> -- sh -c 'echo "X5O!P%@AP[4\PZX54(P^)7CC)7}\$EICAR-STANDARD-ANTIVIRUS-TEST-FILE!\$H+H*" > /<マウントパス>/eicar.txt'
EICARファイルが作成できたら、ファイルの読み取りを実施します。
kubectl exec <pod名> -- cat /<マウントパス>/eicar.txt
ClamAVのログに検出したことが記載されているか確認します。
kubectl logs <pod名> | grep FOUND
FOUNDという単語で検知したかを検索しています。
/<マウントパス>/eicar.txt: Eicar-Signature FOUND
隔離用フォルダにも移動したか確認します。
kubectl exec <pod名> -- ls /<隔離用フォルダ>
隔離用フォルダにEICARファイルが移動していれば動作確認完了です。
最後に
やはり一番は、Azure FilesにもDefender for Cloudを適用してくれることです(今後に期待)。
SMB/NFS経由でファイルをアップロードする際のマルウェアスキャンや、異常なアクセスパターンの検知をAzure側で実施してくれると大変助かりますよね。
他のStorageサービスと同じレベルのセキュリティ保護を提供してくれることを願っています。