概要
この記事はVulsでDockerコンテナ内のソースコードから導入したパッケージにCPEチェックをしようと検証した時にハマった話になります。
環境については以下のようになっています。
Vulsについて:
Vuls v0.6.3
参照ドキュメントは2019年2月23日時点のもの
「Scan vulnerabilites of non-OS packages」
https://vuls.io/docs/en/usage-scan-non-os-packages.html
検証環境について:
macOS 10.14.2
Vagrantで「bento/centos-7.5(virtualbox, 201808.24.0)」を使用
Dockerコンテナについて:
Dockerは上記CentOSの docker-1.13.1-91.git07f3374.el7.centos.x86_64 パッケージを使用
alpineベースのnginx Dockerイメージ( https://hub.docker.com/_/nginx/ )を使用
起動したコンテナ名を(本記事では) docker_web_1 として説明
CPEでチェックする時のバージョンとして nginx:1.9.0 で確認(古いバージョンでセキュリティ情報が拾えるように)
ハマったポイント1:ドキュメントに書いてある「Container」セクションの設定方法だとレポートにCPE情報が出てこなかった
*検証時点での内容です。最新の情報を確認してください。
ドキュメントに以下のように書いてあったのを参考にして、
[servers]
[servers.172-31-4-82]
host = "172.31.4.82"
user = "ec2-user"
keyPath = "/home/username/.ssh/id_rsa"
containerType = "docker"
containersIncluded = ["${running}"]
[servers.172-31-4-82.containers.dockerA]
cpeNames = [
"cpe:/a:rubyonrails:ruby_on_rails:4.2.1",
"cpe:2.3:a:postgresql:postgresql:9.6.2:*:*:*:*:*:*:*",
]
以下のように記載してみたところ、レポートにnginxの情報が出てこない。
[servers]
[servers.localhost]
host = "localhost"
port = "local"
containerType = "docker"
containersIncluded = ["${running}"]
[servers.localhost.containers.docker_web_1]
cpeNames = [
"cpe:2.3:a:nginx:nginx:1.9.0:*:*:*:*:*:*:*"
]
試しにコンテナ部分ではなくホスト部分の設定箇所にCPE設定を記載するとnginx情報がレポートに出力される。
[servers]
[servers.localhost]
host = "localhost"
port = "local"
containerType = "docker"
containersIncluded = ["${running}"]
cpeNames = [
"cpe:2.3:a:nginx:nginx:1.9.0:*:*:*:*:*:*:*"
]
どういう扱いになっているのかなーとdebugオプションを付けて調査。
$ vuls report -format-one-line-text -debug
[Feb 22 16:07:24] INFO [localhost] Validating config...
[Feb 22 16:07:24] INFO [localhost] Loaded: /home/vagrant/results/2019-02-22T16:07:18Z
[Feb 22 16:07:24] DEBUG [localhost] docker_web_1@localhost (alpine3.3.3) on localhost: config.ServerInfo{
ServerName: "localhost",
User: "",
Host: "localhost",
Port: "local",
KeyPath: "",
KeyPassword: "",
CpeNames: []string{},
ScanMode: []string{
"fast",
},
DependencyCheckXMLPath: "",
OwaspDCXMLPath: "",
ContainersIncluded: []string{
"${running}",
},
ContainersExcluded: []string{},
ContainerType: "docker",
Containers: {
"docker_web_1": config.ContainerSetting{
Cpes: []string{},
OwaspDCXMLPath: "",
IgnorePkgsRegexp: []string{},
IgnoreCves: []string{},
},
},
# 以下略
上記のdebug出力を見てみるとCPE設定について
[servers.localhost] セクションのものは cpeNames 名で設定されている
[servers.localhost.containers.docker_web_1] セクションのものは cpes 名で設定されていそう
ので、以下のように記載。
[servers]
[servers.localhost]
host = "localhost"
port = "local"
containerType = "docker"
containersIncluded = ["${running}"]
[servers.localhost.containers.docker_web_1]
cpes = [
"cpe:2.3:a:nginx:nginx:1.9.0:*:*:*:*:*:*:*"
]
が、これでもまだ情報がレポートに出てこない。
ハマったポイント2:設定部分によって使えるCPEバージョンが違う
上記の通り [servers.localhost.containers.docker_web_1] の部分に cpes として設定を記載した後、report実行すると以下エラーメッセージが出力されるようになった。
読んでみると cpes 指定だと「cpe:/」で始まるCPE 2.2形式での記述が期待されている模様。
[Feb 22 16:18:13] ERROR [localhost] Failed to detect vulns of [cpe:2.3:a:nginx:nginx:1.9.0:*:*:*:*:*:*:*]: Failed to validate uri: Error: URI must start with 'cpe:/'. Given: cpe:2.3:a:nginx:nginx:1.9.0:*:*:*:*:*:*:*: Parse error
ドキュメント例の以下に引きずられて、バージョン新しいCPE 2.3形式の方がいいのかなと安易に使っていたのが仇になってしまっていた。
[servers.172-31-4-82.containers.dockerA]
cpeNames = [
"cpe:/a:rubyonrails:ruby_on_rails:4.2.1",
"cpe:2.3:a:postgresql:postgresql:9.6.2:*:*:*:*:*:*:*",
]
ちなみに、[servers.localhost] 部分の cpeNames 設定では、CPE 2.2と2.3どちらの形式で記載しても処理できるようです。
設定まとめ
最終的に設定ファイルは以下のような記載になりました。
[servers]
[servers.localhost]
host = "localhost"
port = "local"
containerType = "docker"
containersIncluded = ["${running}"]
[servers.localhost.containers.docker_web_1]
cpes = [
"cpe:/a:nginx:nginx:1.9.0"
]
Vulsの開発は頻繁に行われているのでドキュメント内容が少しずれていることもあるかもしれないけど debug とか使って見ていけばなんとかなるよというまとめです。
Vuls便利に使っています。ありがとう。いいツールです。