Azure Kubernetes ServiceでClamAVを使ってみた(前編: ウィルススキャン)

# 1. はじめに

記事は2部構成になっています。

- **Azure Kubernetes ServiceでClamAVを使ってみた(前編:ウィルススキャン)←本記事**
- Azure Kubernetes ServiceでClamAVを使ってみた(後編:リアルタイム検知)

Azure Kubernetes Serviceにおけるワーカーノードのウィルス対策を検討しました。ClamAVの適用について手順を紹介します。

なお、本記事ではClamAVやAzure Kubernetes Service(以降「AKS」と略します)の基本的な使い方についての説明は割愛します。

# 2. 全体構成

ワーカーノードにアンチウィルスソフトを入れればよいのでは？と思いましたが、Microsoft社のドキュメントによるとそれはNGとの記載がありました。

>ノード VM は従来の VM と同じではないので、一般的な VM ツールを使用することはできません。

>すべてのノードのポッドで実行される DaemonSets に、選択したマルウェア対策ソフトウェアをデプロイする必要があります。

出典：<https://docs.microsoft.com/ja-jp/azure/architecture/reference-architectures/containers/aks-pci/aks-pci-malware#aks-feature-support>

ということで、アンチウィルスソフトをワーカーノードではなく、DaemonSetに入れるようにします。

### AKSにおけるコンテナファイルシステム
ワーカーノードからノード上で動いているコンテナのファイルシステムも見えています。AKSのワーカーノードの場合、下記フォルダでコンテナのファイルシステムが確認できます。

|<font color="red">**/**</font>run/containerd/io.containerd.runtime.v1.linux/k8s.io/\<コンテナーID\><font color="red">**/rootfs**</font>|
|:---:|

:::note info
左端の<font color="red">**/**</font>はワーカーノードのルート、右端の<font color="red">**/rootfs**</font>はコンテナのルートを示します。
:::

上記のコンテナーIDは次のコマンドで確認できます。
```console
$ kubectl get pod (pod名) -oyaml
```
```yaml:出力結果
～～(略)～～
  containerStatuses:
  - containerID: containerd://d26c7d1fxxxxxxxxf7c6ae31yyyyyyyy7d56758fzzzzzzzzc6868a7c38d9caef
    image: <registry-name>.azurecr.io/<repository>:<tag>
    imageID: <registry-name>.azurecr.io/<repository>@sha256:1a662598e09bxxxxxxxx558bee7cyyyyyyyybfcad5cczzzzzzzz270139ad8b86
    lastState: {}
    name: apserver
    ready: true
    restartCount: 0
    started: true
    state:
      running:
        startedAt: "2022-02-28T09:39:01Z"
～～(略)～～
```

上記出力結果では、コンテナーIDは、`containerID`の「containerd://」に続く64桁のIDが該当します。

### 構成図

ClamAVコンテナからワーカーノードのルートをマウントして、Tomcatコンテナのファイルシステムがスキャンできるようにします。

![img1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2369414/4f48cb0c-6b7b-a56d-80fa-b2ebf7198023.png)

# 3. ClamAVコンテナの準備
今回は、公式のClamAVコンテナを使用しました。

```
$ docker image pull clamav/clamav:stable
```
このイメージをAzure Container Registryにプッシュします。
```
$ docker image tag clamav/clamav:stable <registry-name>.azurecr.io/<repository>:<tag>
$ docker image push <registry-name>.azurecr.io/<repository>:<tag>
```

### ClamAVコンテナのデプロイ
それでは、ClamAVコンテナをDaemonSetとしてデプロイします。今回はGoogle Cloud Platform用のサンプルのマニフェストファイルをベースにAKS向けにカスタマイズして使用しました。

<https://github.com/GoogleCloudPlatform/community/blob/master/tutorials/gcp-cos-clamav/clamav-daemonset.yaml>

```yaml:daemonset-sample.yaml(デーモンセット定義サンプル)
apiVersion: apps/v1
kind: DaemonSet
metadata:
  name: clamav
  labels:
    k8s-app: clamav-host-scanner
spec:
  selector:
    matchLabels:
      name: clamav
  template:
    metadata:
      labels:
        name: clamav
    spec:
      tolerations:
      - key: node-role.kubernetes.io/master
        effect: NoSchedule
      nodeSelector:
        "beta.kubernetes.io/os": linux
      containers:
      - name: clamav-scanner
        image: <registry-name>.azurecr.io/<repository>:<tag>
        volumeMounts:
        - name: host-fs
          mountPath: /host-fs
        - name: logs
          mountPath: /logs
      volumes:
      - name: host-fs
        hostPath:
          path: /
      - name: logs
        hostPath:
          path: /var/log/clamav
```
デーモンセット定義サンプルのマニフェストファイルを使用してAKSにClamAVコンテナをデプロイします。
```
$ kubectl apply -f daemonset-sample.yaml
```

# 4. ClamAVでウィルススキャン
アプリケーション(Tomcat)のコンテナに入り、/homeディレクトリに移動します。
```
$ kubectl exec -it ap-server-xxxxxxxxxx-xxxxx /bin/bash
# cd /home
```
テスト用のウィルスファイルをダウンロードして保存します。今回は4つのウィルスファイルを使ってみます。
```
$ wget https://www.eicar.org/download/eicar.com
```
```
$ wget https://www.eicar.org/download/eicar.com.txt
```
```
$ wget https://www.eicar.org/download/eicar_com.zip
```
```
$ wget https://www.eicar.org/download/eicarcom2.zip
```
テスト用ウィルスファイルが保存されていることを確認します。
```
$ ls
eicar.com  eicar.com.txt  eicar_com.zip  eicarcom2.zip
```
ClamAVのコンテナでウィルススキャンを実行します。

```console:
$ kubectl exec -it clamav-xxxxx /bin/bash
# clamscan --infected --remove --recursive --log=/logs/clamav_test.log \
        --exclude-dir=^/sys --exclude-dir=^/proc --exclude-dir=^/dev \
        --exclude-dir=^/host-fs/sys --exclude-dir=^/host-fs/proc \
        --exclude-dir=^/host-fs/dev \
        --exclude-dir=^/host-fs/run/.*/rootfs/sys \
        --exclude-dir=^/host-fs/run/.*/rootfs/proc \
        --exclude-dir=^/host-fs/run/.*/rootfs/dev \
        --max-filesize=4095M --max-scansize=4095M /
```
次の通り、4つのファイルが削除されたことが確認できました。
「検知した」というメッセージ`Win.Test.EICAR_HDB-1 FOUND`と、「削除した」というメッセージ`Removed.`が出力されています。
```console:出力結果
/host-fs/run/containerd/io.containerd.runtime.v1.linux/k8s.io/d26c7d1fda4bf18cf7c6ae31cd20dc317d56758f54f9920ac68a7c38d9caef68/
rootfs/home/eicar.com.txt: Win.Test.EICAR_HDB-1 FOUND
/host-fs/run/containerd/io.containerd.runtime.v1.linux/k8s.io/d26c7d1fda4bf18cf7c6ae31cd20dc317d56758f54f9920ac68a7c38d9caef68/
rootfs/home/eicar.com.txt: Removed.
/host-fs/run/containerd/io.containerd.runtime.v1.linux/k8s.io/d26c7d1fda4bf18cf7c6ae31cd20dc317d56758f54f9920ac68a7c38d9caef68/
rootfs/home/eicarcom2.zip: Win.Test.EICAR_HDB-1 FOUND
/host-fs/run/containerd/io.containerd.runtime.v1.linux/k8s.io/d26c7d1fda4bf18cf7c6ae31cd20dc317d56758f54f9920ac68a7c38d9caef68/
rootfs/home/eicarcom2.zip: Removed.
/host-fs/run/containerd/io.containerd.runtime.v1.linux/k8s.io/d26c7d1fda4bf18cf7c6ae31cd20dc317d56758f54f9920ac68a7c38d9caef68/
rootfs/home/eicar.com: Win.Test.EICAR_HDB-1 FOUND
/host-fs/run/containerd/io.containerd.runtime.v1.linux/k8s.io/d26c7d1fda4bf18cf7c6ae31cd20dc317d56758f54f9920ac68a7c38d9caef68/
rootfs/home/eicar.com: Removed.
/host-fs/run/containerd/io.containerd.runtime.v1.linux/k8s.io/d26c7d1fda4bf18cf7c6ae31cd20dc317d56758f54f9920ac68a7c38d9caef68/
rootfs/home/eicar_com.zip: Win.Test.EICAR_HDB-1 FOUND
/host-fs/run/containerd/io.containerd.runtime.v1.linux/k8s.io/d26c7d1fda4bf18cf7c6ae31cd20dc317d56758f54f9920ac68a7c38d9caef68/
rootfs/home/eicar_com.zip: Removed.

----------- SCAN SUMMARY -----------
Known viruses: 8606965
Engine version: 0.104.2
Scanned directories: 52323
Scanned files: 286674
Infected files: 4
Data scanned: 35302.06 MB
Data read: 24782.20 MB (ratio 1.42:1)
Time: 5296.694 sec (88 m 16 s)
Start Date: 2022:02:28 09:42:24
End Date:   2022:02:28 11:10:41
```
# 5. まとめ
Azure Kubernetes ServiceのDaemonSetにウィルス対策ソフトを適用し、ワーカーノード全体のスキャンができることを確認しました。
リアルタイム検知については後編の記事をご参照ください。

- - -
- Microsoft Azure は，Microsoft Corporation の商標または登録商標です。
- Dockerは、Docker Inc. の米国およびその他の国における登録商標もしくは商標です。
- Kubernetesは、The Linux Foundation の米国およびその他の国における登録商標または商標です。
- Google Cloud Platform は，Google LLC の商標または登録商標です。
- その他、本資料に記述してある会社名、製品名は、各社の登録商品または商標です。