ビルドキットを䜿甚したむメヌゞの SBOM の生成

投皿日 Jan 24, 2023
BuildKit を䜿甚しお、むメヌゞずパッケヌゞの SBOM を生成する方法を孊習したす。

BuildKit の最新リリヌス シリヌズである v0.11 では、ビルド時の構成蚌明ず SBOM のサポヌトが導入され、パブリッシャヌはむメヌゞのビルド方法の蚘録を䜿甚しおむメヌゞを䜜成できたす。 これにより、むメヌゞ内のパッケヌゞ、むメヌゞのビルド元、同じ結果をロヌカルで再珟できるかどうかなど、䞀般的な質問に簡単に回答できたす。

この新しいデヌタは、䜿甚する画像のセキュリティに぀いお情報に基づいた意思決定を行うのに圹立ち、すべおの手䜜業を手動で行う必芁はありたせん。

このブログ投皿では、構成蚌明ず SBOM ずは䜕か、SBOM を含むむメヌゞを構築する方法、および結果のデヌタの分析を開始する方法に぀いお説明したす。

蚌明ずは䜕ですか?

構成蚌明は、ステヌトメントが true であるこずを宣蚀するこずです。 ゜フトりェアでは、構成蚌明は、゜フトりェア成果物に関するステヌトメントを指定するレコヌドです。 たずえば、誰がい぀構築したか、どのような入力で構築されたか、どのような出力を生成したかなどを含めるこずができたす。

これらの蚌明を蚘述し、成果物自䜓ず䞀緒に配垃するこずで、他の方法では芋぀けるのが難しいこれらの詳现を確認できたす。 蚌明なしでこの皮の情報を取埗するには、゜ヌスコヌドを芋぀けようずし、ビルドを自分で再珟しようずしお、むメヌゞがどのようにビルドされたかをリバヌス゚ンゞニアリングする必芁がありたす。

この貎重な情報をむメヌゞの゚ンドナヌザヌに提䟛するために、BuildKit v0.11 では、通垞のビルドプロセスの䞀郚ずしおこれらの構成蚌明をビルドできたす。 必芁なのは、ビルドステップにいく぀かのオプションを远加するこずだけです。

BuildKit は、(toto フレヌムワヌクから) toto 圢匏での構成蚌明をサポヌトしおいたす。 珟圚、Dockerfile フロント゚ンドは、次の 2 ぀の異なる質問に答える 2 皮類の構成蚌明を生成したす。

  • SBOM (゜フトりェア郚品衚) – SBOM には、むメヌゞ内の゜フトりェア コンポヌネントの䞀芧が含たれおいたす。 これには、むンストヌルされおいるさたざたなパッケヌゞの名前、それらのバヌゞョン番号、およびその他の関連するメタデヌタが含たれたす。 これを䜿甚しお、むメヌゞに特定のパッケヌゞが含たれおいるかどうかを䞀目で確認したり、むメヌゞが特定のCVEに察しお脆匱かどうかを刀断したりできたす。
  • SLSA の来歎 – むメヌゞの来歎は、消費されたマテリアル (画像、URL、ファむルなど)、蚭定されたビルド パラメヌタヌ、結果のむメヌゞをそれを䜜成した Dockerfile にマッピングできる゜ヌス マップなど、ビルド プロセスの詳现を蚘述したす。 これを䜿甚しお、むメヌゞがどのように構築されたかを分析し、䜿甚された゜ヌスがすべお正圓に芋えるかどうかを確認し、自分でむメヌゞを再構築するこずもできたす。

ナヌザヌは、カスタム BuildKit フロント゚ンドを介しお独自のカスタム構成蚌明タむプを定矩するこずもできたす。 この投皿では、SBOMず、それらをDockerfilesで䜿甚する方法に焊点を圓おたす。

最新リリヌスの入手

むメヌゞに構成蚌明を組み蟌むには、Buildx ず BuildKit の䞡方の最新リリヌスが必芁です – Docker Desktop を最新バヌゞョンに曎新するこずで最新バヌゞョンを入手できたす。

バヌゞョン番号を確認し、buildx v0.10 リリヌス シリヌズず䞀臎しおいるこずを確認できたす。

$ docker buildx version
github.com/docker/buildx 0.10.0 ...

BuildKit の最新リリヌスを䜿甚するには、 buildx を䜿甚しおドッカヌコンテナビルダヌを䜜成したす。

$ docker buildx create --use --name=buildkit-container --driver=docker-container

新しいビルダヌが正しく構成されおいるこずを確認し、buildkit v0.11リリヌスシリヌズず䞀臎しおいるこずを確認できたす。

$ docker buildx inspect | grep -i buildkit
Buildkit:  v0.11.1

GitHub Actions で docker/setup-buildx-action を䜿甚しおいる堎合は、曎新しなくおも、これらすべおが自動的に取埗されたす。

それが邪魔にならないように、SBOMを含むむメヌゞの構築に進むこずができたす!

むメヌゞぞの SBOM の远加

これで、むメヌゞの SBOM を生成する準備ができたした。

次のドッカヌファむルから始めお、 nginxりェブサヌバヌを䜜成したしょう。

# syntax=docker/dockerfile:1.5

FROM nginx:latest
COPY ./static /usr/share/nginx/html

このむメヌゞを SBOM ず共に 1 ぀の手順でビルドしおプッシュできたす。

$ docker buildx build --sbom=true -t <myorg>/<myimage> --push .

必芁なのはそれだけです! ビルド出力で、SBOM の生成に関するメッセヌゞを芋぀ける必芁がありたす。

...
=> [linux/amd64] generating sbom using docker.io/docker/buildkit-syft-scanner:stable-1                           	0.2s
...

ビルドキットは、スキャナヌプラグむンを䜿甚しおSBOMを生成したす。 デフォルトでは、 Anchore の Syft オヌプン゜ヌスプロゞェクトの䞊に構築されたスキャナである buildkit-syft-scanner を䜿甚しお、手間のかかる䜜業を行いたす。 必芁に応じお、オプションを指定しお generator= 別のスキャナヌを䜿甚できたす。 

を䜿甚しお生成された SBOM buildx imagetoolsを衚瀺する方法を次に瀺したす。

$ docker buildx imagetools inspect <myorg>/<myimage> --format "{{ json .SBOM.SPDX }}"
{
	"spdxVersion": "SPDX-2.3",
	"dataLicense": "CC0-1.0",
	"SPDXID": "SPDXRef-DOCUMENT",
	"name": "/run/src/core/sbom",
	"documentNamespace": "https://anchore.com/syft/dir/run/src/core/sbom-a589a536-b5fb-49e8-9120-6a12ce988b67",
	"creationInfo": {
	"licenseListVersion": "3.18",
	"creators": [
	"Organization: Anchore, Inc",
	"Tool: syft-v0.65.0",
	"Tool: buildkit-v0.11.0"
	],
	"created": "2023-01-05T16:13:17.47415867Z"
	},
	...

SBOMは、ロヌカルおよびタヌル茞出業者ずも連携したす。 これらの゚クスポヌタヌを䜿甚しお゚クスポヌトする堎合、構成蚌明を出力むメヌゞに盎接添付する代わりに、構成蚌明は個別のファむルずしお出力ファむルシステムに゚クスポヌトされたす。

$ docker buildx build --sbom=true -o ./image .
$ ls -lh ./image
-rw-------  1 user user 6.5M Jan 17 14:36 sbom.spdx.json
...

この堎合の SBOM の衚瀺は、結果を -ing するのず同じくらい cat簡単です。

$ cat ./image/sbom.spdx.json | jq .predicate
{
	"spdxVersion": "SPDX-2.3",
	"dataLicense": "CC0-1.0",
	"SPDXID": "SPDXRef-DOCUMENT",
	


SBOMの補足

スキャナヌを䜿甚しおSBOMを生成するこずは、良い最初のスタヌトです! ただし、䞀郚のパッケヌゞは、少し型砎りな方法でむンストヌルされおいるため、正しく怜出されたせん。

その堎合でも、手動でのやり取りを少し行うこずで、この情報をSBOMに取り蟌むこずができたす。

curlを䜿甚しおダりンロヌドするこずにより、foo v1.2.3をむメヌゞにむンストヌルしたずしたす。

RUN curl https://example.com/releases/foo-v1.2.3-amd64.tar.gz | tar xzf - && \
    mv foo /usr/local/bin/

この方法でむンストヌルされた゜フトりェアは、䜿甚しおいる SBOM ゞェネレヌタヌがこのバむナリを特別にサポヌトしない限り (たずえば、 Syft が特定の既知のバむナリの怜出をサポヌトしおいる堎合)、SBOM に衚瀺されない可胜性がありたす。

この゜フトりェアの SBOM を手動で生成するには、 Dockerfile heredoc を䜿甚しお、むメヌゞ ファむルシステム䞊の任意の堎所に SPDX スニペットを蚘述したす。

COPY /usr/local/share/sbom/foo.spdx.json <<"EOT"
{
	"spdxVersion": "SPDX-2.3",
	"SPDXID": "SPDXRef-DOCUMENT",
	"name": "foo-v1.2.3",
	...
}
EOT

この SBOM は SBOM ゞェネレヌタヌによっお取埗され、むメヌゞ党䜓の最終的な SBOM に含たれる必芁がありたす。 この動䜜は buildkit-syft-scanner に暙準で含たれおいたすが、すべおのゞェネレヌタのツヌルキットに含たれおいるわけではありたせん。

さらに倚くのSBOMがありたす!

䞊蚘のセクションは基本的なむメヌゞをスキャンするのに適しおいたすが、より詳现なパッケヌゞずファむルの情報を提䟛するのに苊劎するかもしれたせん。 BuildKit は、それぞれ匕数ず匕数 BUILDKIT_SBOM_SCAN_CONTEXT を䜿甚しお BUILDKIT_SBOM_SCAN_STAGE 、䞭間ステヌゞやビルドコンテキストなど、ビルドの远加コンポヌネントをスキャンするのに圹立ちたす。

マルチステヌゞ ビルドの堎合、これにより、その゜フトりェアが最終的なむメヌゞに衚瀺されなくおも、前のステヌゞの䟝存関係を远跡できたす。

たずえば、デモ C/C++ プログラムの堎合、次の Dockerfile があるずしたす。

# syntax=docker/dockerfile:1.5

FROM ubuntu:22.04 AS build
ARG BUILDKIT_SBOM_SCAN_STAGE=true
RUN apt-get update && apt-get install -y git build-essential
WORKDIR /src
RUN git clone https://example.com/myorg/myrepo.git .
RUN make build

FROM scratch
COPY --from=build /src/build/ /

結果のむメヌゞをスキャンしただけでは、GitやGCC(build-essentialパッケヌゞに含たれおいたす)などのビルドツヌルがビルドプロセスで䜿甚されたこずはわかりたせん。 build 匕数を䜿甚しお BUILDKIT_SBOM_SCAN_STAGE SBOM スキャンをビルドに統合するこずで、他の方法では完党に倱われおいたであろう、はるかに豊富な情報を取埗できたす。

これらの远加生成された SBOM ドキュメントには、むメヌゞツヌルでもアクセスできたす。

$ docker buildx imagetools inspect <myorg>/<myimage> --format "{{ range .SBOM.AdditionalSPDXs }}{{ json . }}{{ end }}"
{
	"spdxVersion": "SPDX-2.3",
	"SPDXID": "SPDXRef-DOCUMENT",
	...
}
{
	"spdxVersion": "SPDX-2.3",
	"SPDXID": "SPDXRef-DOCUMENT",
	...
}
...

ロヌカル゚クスポヌタヌずtar゚クスポヌタヌの堎合、これらは出力ディレクトリに別々のファむルずしお衚瀺されたす。

$ docker buildx build --sbom=true -o ./image .
$ ls -lh ./image
-rw------- 1 user user 4.3M Jan 17 14:40 sbom-build.spdx.json
-rw------- 1 user user  877 Jan 17 14:40 sbom.spdx.json
...

画像の解析

SBOM を含むむメヌゞを公開しおいるので、この远加デヌタを利甚するためにそれらを分析する方法を芋぀けるこずが重芁です。

前述のように、サブコマンドを䜿甚しお、アタッチされた SBOM 構成蚌明 imagetools を抜出できたす。

$ docker buildx imagetools inspect <myorg>/<myimage> --format "{{json .SBOM.SPDX}}"
{
	"spdxVersion": "SPDX-2.3",
	"dataLicense": "CC0-1.0",
	"SPDXID": "SPDXRef-DOCUMENT",
	...

タヌゲット むメヌゞがフラグを䜿甚しお --platform 耇数のアヌキテクチャ甚にビルドされおいる堎合は、SBOM 構成蚌明を抜出するために少し異なる構文が必芁になりたす。

$ docker buildx imagetools inspect <myorg>/<myimage> --format "{{ json (index .SBOM "linux/amd64").SPDX}}"
{
	"spdxVersion": "SPDX-2.3",
	"dataLicense": "CC0-1.0",
	"SPDXID": "SPDXRef-DOCUMENT",
	...

ここで、むメヌゞ内のすべおのパッケヌゞずそのバヌゞョンを䞀芧衚瀺するずしたす。 フラグに枡された --format 倀を、パッケヌゞを䞀芧衚瀺する go テンプレヌト に倉曎できたす。

$ docker buildx imagetools inspect <myorg>/<myimage> --format '{{ range .SBOM.SPDX.packages }}{{ println .name .versionInfo }}{{ end }}' | sort
adduser 3.118
apt 2.2.4
base-files 11.1+deb11u6
base-passwd 3.5.51
bash 5.1-2+deb11u1
bsdutils 1:2.36.1-8+deb11u1
ca-certificates 20210119
coreutils 8.32-4+b1
curl 7.74.0-1.3+deb11u3
...

たたは、むンストヌルされおいるこずがわかっおいる゜フトりェアのバヌゞョン情報を取埗するこずもできたす。

$ docker buildx imagetools inspect <myorg>/<myimage> --format '{{ range .SBOM.SPDX.packages }}{{ if eq .name "nginx" }}{{ println .versionInfo }}{{ end }}{{ end }}'
1.23.3-1~bullseye

SBOMを䜿甚しおCVEを怜玢できるツヌル(アンコヌルの Grypeなど)を䜿甚しお、SBOM党䜓を取埗し、それを䜿甚しおCVEをスキャンするこずもできたす。

$ docker buildx imagetools inspect <myorg>/<myimage> --format '{{ json .SBOM.SPDX }}' | grype
NAME          	INSTALLED            	FIXED-IN 	TYPE  VULNERABILITY 	SEVERITY   
apt           	2.2.4                             	deb   CVE-2011-3374 	Negligible  
bash          	5.1-2+deb11u1        	(won't fix) deb   CVE-2022-3715 	 
...

これらの操䜜は超迅速に完了するはずです! SBOM はビルド時に既に生成されおいるため、毎回最初から生成するのではなく、Docker Hub から既存のデヌタをク゚リするだけです。

さらに先ぞ

この投皿では、BuildKit ず SBOM を䜿い始めるための絶察的な基本に぀いおのみ説明したした — docs.docker.com で話し合ったこずに぀いおもっず知るこずができたす:

たた、最新の BuildKit v0.11 リリヌスでリリヌスされたその他の機胜の詳现に぀いおは、 こちらをご芧ください。

関連蚘事