コンテナ内のソフトウェアの脆弱性をスキャンするClairを試してみた


コンテナイメージ内の各種ソフトウェアの既知の脆弱性をチェックできる
CoreOS社製のClairというOSSがv1.0になったというニュースを見たので、
どのようなものなのか試してみました。

https://github.com/coreos/clair

導入手順
--------

ReadmeにはKubernetes、Docker Compose、Docker、Sourceの4種類の導入方法が記載されていましたが、
詰まった時にどこが原因か調査するだけのDockerの知識が無かったので今回は一旦Source Installで進めました。
多分KubernetesやDocker Composeを使うともっと楽なのだと思います。
環境はAWS上で素のAmazon Linuxを利用しています。

### 各種前提ソフトウェアの導入

Source Installの場合は事前にDocker, PostgreSQL, Golangを導入しておく必要があります。
あわせてPostgreSQLのclair用のユーザとデータベースも作っておきます。

```
sudo yum install docker
sudo service docker start
sudo chkconfig docker on
sudo usermod -aG docker $USER
exec $SHELL -l

sudo yum install postgresql94-server
sudo service postgresql94 initdb
sudo service postgresql94 start
sudo chkconfig postgresql94 on
sudo -u postgres psql
postgres=# CREATE ROLE clair WITH LOGIN PASSWORD 'clair_password';
postgres=# CREATE DATABASE clair OWNER clair;
postgres=# \q

sudo yum install golang
mkdir $HOME/go
echo 'export GOPATH=$HOME/go' >> $HOME/.bashrc
echo 'export PATH=$PATH:$GOPATH/bin' >> $HOME/.bashrc
exec $SHELL -l
```

### Clairの導入

Source Installでも特に難しい所はありません。
APIではなくCLIから脆弱性調査を行えるようにanalyze-local-imagesも導入します。

```
go get github.com/coreos/clair
go install github.com/coreos/clair/cmd/clair
sudo mkdir /etc/clair
sudo curl -L https://raw.githubusercontent.com/coreos/clair/master/config.example.yaml -o /etc/clair/config.yaml
sudo vi /etc/clair/config.yaml
  # databaseのsourceの欄に先ほど導入したPostgreSQLへの接続情報を記載
  source: postgresql://clair:clair_password@localhost:5432/clair?sslmode=disable
go get -u github.com/coreos/clair/contrib/analyze-local-images
```

### Clairの起動と脆弱性データの更新

Clairを起動するとAPIサービスが立ち上がり、脆弱性データの更新が始まります。
初回は全脆弱性データを取得してくる必要があるため、"update finished"のログが出るまでこの環境だと2時間半ほどかかりました。起動したら更新が終わるまで気長に待ちましょう。

```
clair -config=/etc/clair/config.yaml
```

```
2016-03-30 17:27:03.167474 I | pgsql: running database migrations
goose: no migrations to run. current version: 20151222113213
2016-03-30 17:27:03.170695 I | pgsql: database migration ran successfully
2016-03-30 17:27:03.170881 I | notifier: notifier service is disabled
2016-03-30 17:27:03.170902 I | api: starting main API on port 6060.
2016-03-30 17:27:03.170975 I | api: starting health API on port 6061.
2016-03-30 17:27:03.171108 I | updater: updater service started. lock identifier: d38ed9fa-96c5-44bb-bc32-cd161a3f4c50
2016-03-30 17:27:03.184416 I | updater: updating vulnerabilities
2016-03-30 17:27:03.184493 I | updater: fetching vulnerability updates
2016-03-30 17:27:03.184584 I | updater/fetchers/ubuntu: fetching Ubuntu vulnerabilities
2016-03-30 17:27:03.185061 I | updater/fetchers/rhel: fetching Red Hat vulnerabilities
2016-03-30 17:27:03.185136 I | updater/fetchers/debian: fetching Debian vulnerabilities
2016-03-30 17:39:58.645278 I | updater: adding metadata to vulnerabilities
2016-03-30 20:19:15.077583 I | updater: update finished
```

### Clairを使って脆弱性をチェック

更新が終わったら早速どのように動くのか試してみます。
今回はclair自身のコンテナイメージを取得して脆弱性をチェックしてみました。

```
docker pull quay.io/coreos/clair:latest
analyze-local-images quay.io/coreos/clair:latest
```

出力されたレポートの一部がこちら。

```
Clair report for image quay.io/coreos/clair:latest (2016-03-31 00:04:19.092317228 +0000 UTC)
CVE-2013-7445 (High)
        The Direct Rendering Manager (DRM) subsystem in the Linux kernel through 4.x
        mishandles requests for Graphics Execution Manager (GEM) objects, which allows
        context-dependent attackers to cause a denial of service (memory consumption)
        via an application that processes graphics data, as demonstrated by JavaScript
        code that creates many CANVAS elements for rendering by Chrome or Firefox.

        Package:       linux @ 3.16.7-ckt20-1+deb8u4
        Link:          https://security-tracker.debian.org/tracker/CVE-2013-7445
        Layer:         15672e997cd19c35cbbc274eb5880e077438008167477e34e8715c6af61c3aa8

CVE-2015-8803 (High)
        The ecc_256_modp function in ecc-256.c in Nettle before 3.2 does not properly
        handle carry propagation and produces incorrect output in its implementation of
        the P-256 NIST elliptic curve, which allows attackers to have unspecified impact
        via unknown vectors, a different vulnerability than CVE-2015-8805.

        Package:       nettle @ 2.7.1-5
        Link:          https://security-tracker.debian.org/tracker/CVE-2015-8803
        Layer:         6b3946d5b32374682bec537311ebc5d616a82d37ff3b745ea014c3956f66faaa
(後略)
```

どのようなCVEが該当しているかを、Critical/High/Medium/Low/Negligibleの5段階に分けて出力してくれます。
CentOSのイメージに対して試した場合は、RHSAの情報が参照されていました。

脆弱性データはClairを起動しておくと定期的に更新されるように見えるので、
CIなどに組み込んでおくといち早く脆弱性に気付けて便利そうです。