コンテナを前提としたDevSecOpsを実現する手段について調べていたらTrivy(トリビー)に出会った。
Trivy(トリビー)とは?
Trivy(トリビー)は、GitHubでソースコードが公開されているOSSのコンテナイメージ脆弱性診断ツールです。
もともとイスラエルいくべぇ@knqyf263さんが趣味で作ったツールをイスラエル企業のAqua Security Software Ltd.(以降「Aqua社」と呼ぶ)が買収した経緯があるそうです。
ツールも進化してコンテナイメージの脆弱性スキャンだけでなくファイルシステムのスキャンもできるようです(※未検証)
公式情報
作者の情報
イスラエルいくべぇ(福田鉄平)さん
Aqua社で唯一の日本人。Trivyの開発者。Aqua Open Source Team所属。
作者は、現在Aqua社へ入社して唯一の日本人エンジニアとして活躍しているということらしく、物語としても胸アツです。(※以下、作者ブログ参照)
作者のストーリー
やったこと
セットアップの手間を省き、かつ、どの環境でも同じく実行できるようTrivyの公開コンテナイメージ
https://hub.docker.com/r/aquasec/trivy/
を使用した脆弱性スキャンを試してみました。
その1:最新Dockerhub公式イメージをスキャン
Linux系の最新の公式イメージが安全なのか調べてみます。(※下記URL参照)
https://hub.docker.com/search?type=image&image_filter=official&operating_system=linux
docker run aquasec/trivy image ubuntu:latest
docker run aquasec/trivy image alpine:latest
docker run aquasec/trivy image debian:latest
:(※省略)
デフォだと脆弱性レベルが高いものから低いものまで全て表示されて見にくいのでフィルタしてみる。(CRITICAL,HIGHのみ)
docker run aquasec/trivy image --severity CRITICAL,HIGH ubuntu:latest
:(※中略)
ubuntu:latest (ubuntu 22.04)
===========================
Total: 0 (HIGH: 0, CRITICAL: 0)
docker run aquasec/trivy image --severity CRITICAL,HIGH alpine:latest
:(※中略)
alpine:latest (alpine 3.15.4)
=============================
Total: 0 (HIGH: 0, CRITICAL: 0)
docker run aquasec/trivy image --severity CRITICAL,HIGH debian:latest
:(※中略)
debian:latest (debian 11.3)
===========================
Total: 14 (HIGH: 14, CRITICAL: 0)
+--------------+------------------+----------+-------------------+-------------------+---------------------------------------+
| LIBRARY | VULNERABILITY ID | SEVERITY | INSTALLED VERSION | FIXED VERSION | TITLE |
+--------------+------------------+----------+-------------------+-------------------+---------------------------------------+
| e2fsprogs | CVE-2022-1304 | HIGH | 1.46.2-2 | | e2fsprogs: out-of-bounds |
| | | | | | read/write via crafted filesystem |
| | | | | | -->avd.aquasec.com/nvd/cve-2022-1304 |
+--------------+------------------+ +-------------------+-------------------+---------------------------------------+
| gzip | CVE-2022-1271 | | 1.10-4 | 1.10-4+deb11u1 | gzip: arbitrary-file-write |
| | | | | | vulnerability |
| | | | | | -->avd.aquasec.com/nvd/cve-2022-1271 |
+--------------+------------------+ +-------------------+-------------------+---------------------------------------+
| libc-bin | CVE-2021-3999 | | 2.31-13+deb11u3 | | glibc: Off-by-one buffer |
| | | | | | overflow/underflow in getcwd() |
| | | | | | -->avd.aquasec.com/nvd/cve-2021-3999 |
+--------------+ + + +-------------------+ +
| libc6 | | | | | |
| | | | | | |
| | | | | | |
+--------------+------------------+ +-------------------+-------------------+---------------------------------------+
| libcom-err2 | CVE-2022-1304 | | 1.46.2-2 | | e2fsprogs: out-of-bounds |
| | | | | | read/write via crafted filesystem |
| | | | | | -->avd.aquasec.com/nvd/cve-2022-1304 |
+--------------+ + + +-------------------+ +
| libext2fs2 | | | | | |
| | | | | | |
| | | | | | |
+--------------+------------------+ +-------------------+-------------------+---------------------------------------+
| libgcrypt20 | CVE-2021-33560 | | 1.8.7-6 | | libgcrypt: mishandles ElGamal |
| | | | | | encryption because it lacks |
| | | | | | exponent blinding to address a... |
| | | | | | -->avd.aquasec.com/nvd/cve-2021-33560 |
+--------------+------------------+ +-------------------+-------------------+---------------------------------------+
| liblzma5 | CVE-2022-1271 | | 5.2.5-2 | 5.2.5-2.1~deb11u1 | gzip: arbitrary-file-write |
| | | | | | vulnerability |
| | | | | | -->avd.aquasec.com/nvd/cve-2022-1271 |
+--------------+------------------+ +-------------------+-------------------+---------------------------------------+
| libss2 | CVE-2022-1304 | | 1.46.2-2 | | e2fsprogs: out-of-bounds |
| | | | | | read/write via crafted filesystem |
| | | | | | -->avd.aquasec.com/nvd/cve-2022-1304 |
+--------------+------------------+ +-------------------+-------------------+---------------------------------------+
| libtinfo6 | CVE-2022-29458 | | 6.2+20201114-2 | | ncurses: segfaulting OOB read |
| | | | | | -->avd.aquasec.com/nvd/cve-2022-29458 |
+--------------+------------------+ +-------------------+-------------------+---------------------------------------+
| logsave | CVE-2022-1304 | | 1.46.2-2 | | e2fsprogs: out-of-bounds |
| | | | | | read/write via crafted filesystem |
| | | | | | -->avd.aquasec.com/nvd/cve-2022-1304 |
+--------------+------------------+ +-------------------+-------------------+---------------------------------------+
| ncurses-base | CVE-2022-29458 | | 6.2+20201114-2 | | ncurses: segfaulting OOB read |
| | | | | | -->avd.aquasec.com/nvd/cve-2022-29458 |
+--------------+ + + +-------------------+ +
| ncurses-bin | | | | | |
| | | | | | |
+--------------+------------------+ +-------------------+-------------------+---------------------------------------+
| perl-base | CVE-2020-16156 | | 5.32.1-4+deb11u2 | | perl-CPAN: Bypass of verification |
| | | | | | of signatures in CHECKSUMS files |
| | | | | | -->avd.aquasec.com/nvd/cve-2020-16156 |
+--------------+------------------+----------+-------------------+-------------------+---------------------------------------+
さすがに最新の公式イメージにCRITICALはありませんでしたが、debianにはHIGHの脆弱性が14 件あるようでした。(※2022/05/06時点)
その2:古いDockerhub公式イメージをスキャン
Linux系の古い公式イメージが安全なのかをいくつか調べてみます。
docker run aquasec/trivy image --severity CRITICAL,HIGH debian:10.12
:(※中略)
debian:10.12 (debian 10.12)
===========================
Total: 39 (HIGH: 31, CRITICAL: 8)
:(※省略)
docker run aquasec/trivy image --severity CRITICAL,HIGH debian:10.12-slim
:(※中略)
debian:10.12-slim (debian 10.12)
================================
Total: 39 (HIGH: 31, CRITICAL: 8)
:(※省略)
やはり古いコンテナイメージだとHIGHだけでなくCRITICALの脆弱性が多数含まれているようです。
その3:Trivyの公開コンテナイメージをスキャン
そもそもTrivyの公開コンテナイメージに脆弱性がないのか気になったので、TrivyでTrivyの公開コンテナイメージをスキャンしてみました。
docker run aquasec/trivy image aquasec/trivy
aquasec/trivy (alpine 3.15.4)
=============================
Total: 4 (UNKNOWN: 0, LOW: 1, MEDIUM: 3, HIGH: 0, CRITICAL: 0)
+---------+------------------+----------+-------------------+---------------+---------------------------------------+
| LIBRARY | VULNERABILITY ID | SEVERITY | INSTALLED VERSION | FIXED VERSION | TITLE |
+---------+------------------+----------+-------------------+---------------+---------------------------------------+
| libcurl | CVE-2022-22576 | MEDIUM | 7.80.0-r0 | 7.80.0-r1 | curl: OAUTH2 bearer bypass |
| | | | | | in connection re-use |
| | | | | | -->avd.aquasec.com/nvd/cve-2022-22576 |
+ +------------------+ + + +---------------------------------------+
| | CVE-2022-27774 | | | | curl: credential leak on redirect |
| | | | | | -->avd.aquasec.com/nvd/cve-2022-27774 |
+ +------------------+ + + +---------------------------------------+
| | CVE-2022-27776 | | | | curl: auth/cookie leak on redirect |
| | | | | | -->avd.aquasec.com/nvd/cve-2022-27776 |
+ +------------------+----------+ + +---------------------------------------+
| | CVE-2022-27775 | LOW | | | curl: bad local IPv6 connection reuse |
| | | | | | -->avd.aquasec.com/nvd/cve-2022-27775 |
+---------+------------------+----------+-------------------+---------------+---------------------------------------+
さすが、HIGH以上の脆弱性はありませんでした。素晴らしいですね。(※2022/05/06時点)
その4:ArgoCDの公開コンテナイメージをスキャン
もともとやりたかったことがこれです。k8sで運用中のコンテナイメージの脆弱性に自動で気付ける仕組みが欲しかったので、、、
例えば以前デモ用に作成したArgoCD
blog.orinbou.info
がいい感じで古くなっているのですが、このデモの中で古いArgoCDのコンテナイメージを参照しています。
https://github.com/orinbou/argocd-demo/blob/main/argocd/install.yaml
上記k8sマニフェストから参照しているコンテナイメージをスキャンしてみました。
docker run aquasec/trivy image --severity CRITICAL,HIGH argoproj/argocd:v1.7.9
argoproj/argocd:v1.7.9 (debian 10.6)
====================================
Total: 346 (HIGH: 290, CRITICAL: 56)
:(※中略)
Python (python-pkg)
===================
Total: 3 (HIGH: 2, CRITICAL: 1)
:(※中略)
usr/local/bin/argocd (gobinary)
===============================
Total: 5 (HIGH: 5, CRITICAL: 0)
:(※中略)
usr/local/bin/argocd-application-controller (gobinary)
======================================================
Total: 5 (HIGH: 5, CRITICAL: 0)
:(※中略)
usr/local/bin/argocd-darwin-amd64 (gobinary)
============================================
Total: 5 (HIGH: 5, CRITICAL: 0)
:(※中略)
usr/local/bin/argocd-repo-server (gobinary)
===========================================
Total: 4 (HIGH: 4, CRITICAL: 0)
:(※中略)
usr/local/bin/argocd-server (gobinary)
======================================
Total: 6 (HIGH: 6, CRITICAL: 0)
:(※中略)
usr/local/bin/argocd-util (gobinary)
====================================
Total: 5 (HIGH: 5, CRITICAL: 0)
:(※中略)
usr/local/bin/argocd-windows-amd64.exe (gobinary)
=================================================
Total: 5 (HIGH: 5, CRITICAL: 0)
:(※中略)
usr/local/bin/helm (gobinary)
=============================
Total: 12 (HIGH: 12, CRITICAL: 0)
:(※中略)
usr/local/bin/kustomize (gobinary)
==================================
Total: 11 (HIGH: 11, CRITICAL: 0)
:(※省略)
エグイほどの数の脆弱性が検出されました。が、気付きたかった下記の脆弱性が検出できませんでした。何故だ、、、
まとめ
コマンドラインで実行可能なシンプルなツールなので、CI/CDパイプラインへ簡単に組み込むことができそうです。
しかし、デプロイ時に気付けてもあまり意味がないので、利用しているコンテナイメージを対象にした脆弱性スキャンを定期実行(1日1回くらい)するのが良さげです。
あとは、誤検知や同じ脆弱性が複数回通知されないような仕組みも必要かと思いますが、その辺の自作はそこまで大変ではなさそう。(でもマネージドサービス欲しい)
また、実運用を考えると今回気付きたかったArgoCDの脆弱性(CVE-2022-24348)が何故検出できなかったか、などについてもう少し調べてみる必要がありそうです。
参考