はじめに
近年、製品やサービスが複雑化しており、ライセンス管理やセキュリティ対応などの重要性が高まっています。
ソフトウェアの構成情報をやりとりするためのSBOM(Software Bill of Materials)が注目されています。
きっかけとなったのが2021年5月の米国大統領令です。
その発表を受けて、NTIA (米国商務省電気通信情報局)は2021年7月にThe Minimum Elements For a Software Bill of Materials (SBOM)を公開し、SBOMの最小要素を定義しました。
SBOMのフォーマットの1つにSPDXがあります。
SBOMを生成するツールは有償、無償を問わずさまざまなものがあります。
無償のツールとしてはFOSSologyやsyftがあります。
ツールが生成したSBOMをライセンス管理やセキュリティ対応で活用する前に、NTIAが定義するSBOMの最小要素を満たしていることを確認することは重要です。
2023年5月にカーネギーメロン大学で行われたDevSecOps Days 2023で、The Linux FoundationのKateさんの発表(SPDX SBOMs: Enabling Automation of Safety & Security Analysis)でNTIA Conformance Checkerが紹介されていました。
NTIA Conformance CheckerはSPDXのドキュメントがNTIAが定義するSBOMの最小要素を満たすか確認するツールです。
本記事ではSPDXのコミュニティから提供されているNTIA Conformance Checkerを使い、SPDX形式のJSONファイルがNTIAが定義するSBOMの最小要素を満たすか調べる方法をご紹介します。
具体的にはsyftでrpmdbからSPDX形式のJSONファイルを出力し、NTIA Conformance Checkerで調べることにします。
環境情報
macOS上のDockerでRocky Linux 9のコンテナを立ち上げて、その中で作業をします。
今回の環境情報は以下です。
コンポーネント | バージョン | 備考 |
---|---|---|
PC | M1 MacBook Pro | |
OS | macOS Ventura 13.4 | |
Docker | 4.20.0 | 個人以外の用途で使使うときはライセンスにご注意ください |
Rocky Linux | 9.2 | |
syft | v0.82.0 | |
ntia-conformance-checker | 0.3.1 | Python 3.8以降であること |
Rocky Linux 9のコンテナを立ち上げる
Rocky Linux 9のイメージを取得し、コンテナを立ち上げます。
$ docker pull rockylinux:9
$ docker run -it -d --name rockylinux9 rockylinux:9
ログインして、バージョンを確認します。
$ docker exec -it rockylinux9 /bin/bash
# cat /etc/redhat-release
Rocky Linux release 9.2 (Blue Onyx)
syftをインストール
syftをインストールします。
# curl -sSfL https://raw.githubusercontent.com/anchore/syft/main/install.sh | sh -s -- -b /usr/local/bin
バージョンを確認します。
# syft --version
syft 0.82.0
SPDX形式のJSONファイルを生成する
syftでRocky Linux 9のrpmdbからSPDX形式のJSONファイルを出力し、rockylinux9_rpm.jsonという名前で保存します。
# syft /var/lib/rpm -o spdx-json > rockylinux9_rpm.json
ちゃんと出力されたのか、opensslパッケージで確認します。
# cat rockylinux9_rpm.json | jq . | less
(snip)
{
"name": "openssl",
"SPDXID": "SPDXRef-Package-rpm-openssl-980236006ab5b149",
"versionInfo": "1:3.0.7-6.el9_2",
"originator": "Organization: Rocky Enterprise Software Foundation",
"downloadLocation": "NOASSERTION",
"sourceInfo": "acquired package info from RPM DB: rpmdb.sqlite",
"licenseConcluded": "NOASSERTION",
"licenseDeclared": "LicenseRef-ASL-2.0",
"copyrightText": "NOASSERTION",
"externalRefs": [
{
"referenceCategory": "SECURITY",
"referenceType": "cpe23Type",
"referenceLocator": "cpe:2.3:a:rockyenterprisesoftwarefoundation:openssl:1\\:3.0.7-6.el9_2:*:*:*:*:*:*:*"
},
{
"referenceCategory": "SECURITY",
"referenceType": "cpe23Type",
"referenceLocator": "cpe:2.3:a:openssl:openssl:1\\:3.0.7-6.el9_2:*:*:*:*:*:*:*"
},
{
"referenceCategory": "PACKAGE-MANAGER",
"referenceType": "purl",
"referenceLocator": "pkg:rpm/openssl@3.0.7-6.el9_2?arch=aarch64\u0026epoch=1\u0026upstream=openssl-3.0.7-6.el9_2.src.rpm"
}
]
},
(snip)
NTIA Conformance Checkerをインストールする
pipをインストールして、最新版に更新しておきます。
# dnf install python3-pip
# python3 -m pip install -U pip
ntia-conformance-checkerモジュールをインストールします。
# python3 -m pip install ntia-conformance-checker
インストールされたことを確認します。
# python3 -m pip freeze | grep ntia-conformance-checker
ntia-conformance-checker==0.3.1
NTIA Conformance CheckerでSBOMの最小要素を満たすか調べる
ntia-checkerコマンドを使って、先ほど出力したSPDX形式のJSONファイルがNTIAのSBOMの最小要素を満たすか確認します。
# ntia-checker --file rockylinux9_rpm.json
実行結果は以下で、NTIAのSBOMの最小要素を満たしませんでした。
# ntia-checker --file rockylinux9_rpm.json
Is this SBOM NTIA minimum element conformant? False
Individual elements | Status
-------------------------------------------------------
All component names provided? | True
All component versions provided? | True
All component identifiers provided? | True
All component suppliers provided? | False
SBOM author name provided? | True
SBOM creation timestamp provided? | True
Dependency relationships provided? | True
#
なぜNTIAのSBOMの最小要素を満たしていないのか
syftが出力したSPDX形式のJSONファイルはNTIAのSBOMの最小要素を満たしていないのでしょうか。
ntia-checkerの実行結果を見ると、以下の"すべてのコンポーネントでサプライヤーが提供されているか?"という評価項目がFalseになっていることがわかります。
All component suppliers provided? | False
rockylinux9_rpm.jsonはSPDX 2.3を採用しています。
SPDX 2.3の仕様を見ると7.5 Package supplier fieldという項目があるため、SPDX 2.3としてサプライヤーの情報を表現することは可能そうです。
rockylinux9_rpm.jsonのopensslパッケージの項目には7.5 Package supplier fieldに相当する項目が見当たりません。
これがSBOMの最小要素を満たしていない原因のようです。
どうしたらNTIA Conformance CheckerでSBOMの最小要素を満たせるのか
rockylinux9_rpm.jsonのopensslパッケージには、supplierと似たような項目であるoriginatorがあります。
"originator": "Organization: Rocky Enterprise Software Foundation",
rockylinux9_rpm.jsonの元になっているrpmdbを見てみると、opensslパッケージのVenderという項目で提供元であるRocky Enterprise Software Foundationが記載されており、この項目をoriginatorとして出力しているようです。
# rpm -qi openssl
Name : openssl
Epoch : 1
Version : 3.0.7
Release : 6.el9_2
Architecture: aarch64
Install Date: Sat May 13 20:21:29 2023
Group : Unspecified
Size : 1852491
License : ASL 2.0
Signature : RSA/SHA256, Tue May 9 08:01:08 2023, Key ID 702d426d350d275d
Source RPM : openssl-3.0.7-6.el9_2.src.rpm
Build Date : Tue May 9 07:41:06 2023
Build Host : pb-bcdd069a-daaa-4574-ad8c-4665090b05d8-b-aarch64
Packager : Rocky Linux Build System (Peridot) <releng@rockylinux.org>
Vendor : Rocky Enterprise Software Foundation
URL : http://www.openssl.org/
Summary : Utilities from the general purpose cryptography library with TLS implementation
Description :
The OpenSSL toolkit provides support for secure communications between
machines. OpenSSL includes a certificate management tool and shared
libraries which provide various cryptographic algorithms and
protocols.
#
改めて、SPDX 2.3の仕様を確認してみます。
7.5 Package supplier fieldは、パッケージ/ディレクトリの実際の配布元を表現する項目です。
7.6 Package originator fieldは、このパッケージのもともと誰から提供されたものかを表現する項目です。
ソフトウェアはサプライチェインで成り立っています。
opensslパッケージはもともとRocky Enterprise Software Foundationという組織から提供されたものですが、それをさらに配布するときにはその個人または組織が配布元となるのです。
rpmdbには配布元となる個人または組織に相当する情報がないため、syftで7.5 Package supplier fieldに記載する情報を入力してあげることができれば、NTIAのSBOMの最小要素を満たすSBOMを出力できそうです。
NTIAのSBOMの最小要素を満たす
rockylinux9_rpm.jsonのパッケージ情報にサプライヤを追加してみます。
PythonでSPDX形式のファイルを扱うtools-pythonモジュールを使って、 SPDX形式のJSONファイルのパッケージ情報にサプライヤを追加するプログラムを書いてみました。
#!/usr/bin/env python3
from spdx_tools.spdx.model import Actor, ActorType
from spdx_tools.spdx.parser.parse_anything import parse_file
from spdx_tools.spdx.writer.write_anything import write_file
def main():
document = parse_file('rockylinux9_rpm.json')
for p in document.packages:
p.supplier = Actor(ActorType.PERSON, "A Package Supplier")
write_file(document, "rockylinux9_rpm_added_suppliers.json")
if __name__ == "__main__":
main()
上記プログラムを実行し、生成したrockylinux9_rpm_added_suppliers.jsonを確認すると、"supplier"という項目が追加されていることがわかります。
(snip)
{
"SPDXID": "SPDXRef-Package-rpm-openssl-980236006ab5b149",
"copyrightText": "NOASSERTION",
"downloadLocation": "NOASSERTION",
"externalRefs": [
{
"referenceCategory": "SECURITY",
"referenceLocator": "cpe:2.3:a:rockyenterprisesoftwarefoundation:openssl:1\\:3.0.7-6.el9_2:*:*:*:*:*:*:*",
"referenceType": "cpe23Type"
},
{
"referenceCategory": "SECURITY",
"referenceLocator": "cpe:2.3:a:openssl:openssl:1\\:3.0.7-6.el9_2:*:*:*:*:*:*:*",
"referenceType": "cpe23Type"
},
{
"referenceCategory": "PACKAGE_MANAGER",
"referenceLocator": "pkg:rpm/openssl@3.0.7-6.el9_2?arch=aarch64&epoch=1&upstream=openssl-3.0.7-6.el9_2.src.rpm",
"referenceType": "purl"
}
],
"filesAnalyzed": true,
"licenseConcluded": "NOASSERTION",
"licenseDeclared": "LicenseRef-ASL-2.0",
"name": "openssl",
"originator": "Organization: Rocky Enterprise Software Foundation",
"sourceInfo": "acquired package info from RPM DB: rpmdb.sqlite",
"supplier": "Person: A Package Supplier",
"versionInfo": "1:3.0.7-6.el9_2"
},
(snip)
そして、再度NTIA Conformance Checkerでrockylinux9_rpm_added_suppliers.jsonを引数に実行してみると、NTIAのSBOMの最小要素を満たすSBOMになったことがわかります。
# ntia-checker --file rockylinux9_rpm_added_suppliers.json
Is this SBOM NTIA minimum element conformant? True
Individual elements | Status
-------------------------------------------------------
All component names provided? | True
All component versions provided? | True
All component identifiers provided? | True
All component suppliers provided? | True
SBOM author name provided? | True
SBOM creation timestamp provided? | True
Dependency relationships provided? | True
#
最後に
NTIA Conformance Checkerを使い、SPDX形式のJSONファイルがNTIAが定義するSBOMの最小要素を満たすか調べる方法をご紹介しました。
実際にSBOMを活用するためにはNTIAが定義するSBOMの最小要素以外の項目が必要になるとは思います。
しかし、まずはツールが出力したSBOMが最低限の範囲を満たすか確認するためにNTIA Conformance Checkerを利用するのは有効だと思います。
参考情報
- SPDX
- syft
- NTIA Conformance Checker
- tools-python
- SPDX SBOMs: Enabling Automation of Safety & Security Analysis
- オープンソースコンプライアンスの透明性と相互運用性からオートメーションに向けて / From Transparency and Interoperability to Automation in Open Source Compliance
- Software Design 2023年6月号