Azure DevOps の Azure Pipelines に Trivy をインストールして Docker コンテナーの脆弱性スキャンをやってみた

世間でソフトウェアの脆弱性が公表され、CVSS スコアが高いので自社が使っている OS やソフトウェア、開発しているアプリは大丈夫なのか？と、その都度対応していたりします。例えば Docker コンテナーを Azure Pipelines でビルドしているなら、パイプラインに脆弱性スキャンを追加して、その時点で脆弱性が含まれる場合は停止して、開発ライフサイクルの最初の方で対処しておけばラクになります。それでは、DevSecOps の一片を Azure Pipelines で実践してみたいと思います。

## Azure DevOps に Trivy エクステンションをインストール

下記サイトの Visual Studio Marketplace より Trivy を Azure DevOps にインストールします。

https://marketplace.visualstudio.com/items?itemName=AquaSecurityOfficial.trivy-official

[ Get it free ] をクリックします。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/675885/e117e7f5-3c27-baea-d817-9702fda9133c.png)

[ Install ] をクリックします。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/675885/4f2e9862-b088-6e41-0d1a-272b476021d2.png)

[ Proceed to organization ] をクリックします。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/675885/0d71ef3c-8c89-c1cd-fa58-5872bba7e937.png)

## Azure Pipelines で Trivy を検証

検証用 Azure Repos リポジトリを作成し、Azure Pipelines で新規に下記のパイプラインを作成します。

```yml:azure-pipelines.yml
trigger:
- main

pool:
  vmImage: ubuntu-latest

jobs:
- job: TrivyContainerScan
  steps:
  - task: trivy@1
    inputs:
     image: centos:7.6.1810
```

[ Save and run ] または [ Run ] で実行してみます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/675885/f5a1ceec-5b74-929a-bc52-831436423c7a.png)

下記のようにパイプラインが失敗します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/675885/c845a34f-800c-0504-14a1-2c2aae387c94.png)

[ Trivy ] タブをクリックすると脆弱性スキャンの結果が確認できます。CRITICAL が 3 件、全部で 1175 件の脆弱性があることがわかります。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/675885/34ab2526-53a1-d41c-bd20-2e4236e3f5f1.png)

## Docker コンテナーをビルドして Azure Container Registory に登録して検証

検証用 Azure Repos リポジトリに下記の Dockerfile を作成します。

```dockerfile:Dockerfile
FROM centos:7.6.1810

RUN yum update -y
```

Azure Pipelines で以下のようにパイプラインを変更します。

※コンテナーレジストリは自身の環境に合わせて変更してください。

```yml:azure-pipelines.yml
trigger:
- main

pool:
  vmImage: ubuntu-latest

jobs:
- job: DockerBuildPush
  steps:
  - task: Docker@2
    inputs:
      containerRegistry: mnrlabo
      repository: test-centos
      command: buildAndPush
      Dockerfile: '**/Dockerfile'
- job: TrivyContainerScan
  steps:
  - task: Docker@2
    inputs:
      containerRegistry: mnrlabo
      command: login
  - task: trivy@1
    inputs:
      image: mnrlabo.azurecr.io/test-centos:$(Build.BuildId)
```

ファイルを保存するとパイプラインが走るので結果を確認します。

以下のエラーで Trivy そのものの動作が失敗しているようです。

```bash
* unable to initialize Podman client
```

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/675885/72a7f4d6-744d-34a3-3bd0-d526e9fabfbf.png)

パイプラインの中で Trivy そのものを Docker からバイナリ実行に変更するため、`docker: false` を追加します。

```yml:azure-pipelines.yml
trigger:
- main

pool:
  vmImage: ubuntu-latest

jobs:
- job: DockerBuildPush
  steps:
  - task: Docker@2
    inputs:
      containerRegistry: mnrlabo
      repository: test-centos
      command: buildAndPush
      Dockerfile: '**/Dockerfile'
- job: TrivyContainerScan
  steps:
  - task: Docker@2
    inputs:
      containerRegistry: mnrlabo
      command: login
  - task: trivy@1
    inputs:
      docker: false
      image: mnrlabo.azurecr.io/test-centos:$(Build.BuildId)
```

Dockerfile 内で `yum update -y` を組み込む事で、脆弱性を 1175 から 861 件に減らす事ができました。また、CRITICAL の脆弱性は無くなりました。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/675885/de03d361-76f1-974b-9c51-1e682d6d3f7e.png)

脆弱性を 0 にする事は簡単ではないようです。