引越しの箱詰めから考える SBOMとlog4shellのお話

# 突然ですが、引っ越しました。そしてSBOMが大事と思いました。

最近住居を引っ越して、今大量の段ボールを少しづつ開梱しています。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/666491/0fc15f81-05c5-dfb7-e5a7-5368e603bf3d.png)


さて、私の性格の問題なのですが

- 段ボールの中身について、適当に"本"とか"CD"とか表に書いていた
- 引越し前日の最後のほうはさらに面倒になり、中身について何も書かない箱が多数

箱を詰めているときは「まぁ、なんとかなるさ」と思っていたのですが、引越し初日で最初の地獄をみました。
深夜１時、息子の保育園セットがみつからなくなってしまいました。引越しで疲れているのに、泣く泣く深夜にすべての段ボールを一個一個あけていました。なお、オチですが「ハンガー」とかかれている箱から見つけ出すことに成功しました。

これをやっているときに、思ったこと、それが「箱にちゃんと内容物書くべきだなー」と「**SBOMって大事だなー！**」でした。

え、SBOM?

# SBOM?

さて、ここからはSBOMの話です。SBOMとはSoftware Bill of Materialsの略称です。主に、この用語が登場するのが、不正なファイルやOSSライブラリ含まれていないかセキュリティスキャニングのシーンです。

元来セキュリティスキャニングはファイルシステムを総スキャニングが前提でした。この方式は先ほどの引越しでいうところの箱に何が入っているのがわからないので、とりあえず箱全部開けて中身を確認する方式です。予想ができるとおりで、この方式は非常に負荷が高く環境で動いているすべてのアプリケーションの検索をやっていくのには不向きでした。

そこで登場しているのが、SBOMとよばれる技術です。これは、箱を全て開けずとしても、その箱の中身を詳細に記載したファイルだけをみて内容物を確認する方法です。引っ越しでいえば、箱をあけなくても何が含まれている詳細にわかるようになっている状態です。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/666491/d2888cfe-a8af-b29b-7752-fe835e200245.png)

このSBOMによって期待されているのが以下の効果です。

- CI/CDのパイプラインにより気軽にセキュリティスキャンを導入（ファイルシステムスキャンだと分単位のため、重いパイプラインになりやすい）
- 肥大化した環境でも脆弱なOSSライブラリを高速に発見
- ライセンス管理など、開発環境における統制

コンテナの登場によってこの技術がさらに注目されています。手動の構成変更を前提にしている仮想マシンなどですと、この構成がかかれているファイルのメンテが非常に高コストになります。Immutable、つまり構成変更ができない前提コンテナですと、このSBOMの考え方がよりマッチしてきます。

# よくわからないけど気軽に始められないの？

SBOMの存在を私が知ったのは、コンテナイメージを簡単につくることができる`Cloud Native Buildpacks`、そしてコミュニティメンテナンスしている`packeto buildpacks` によってでした。Packetoのページにも[BOMのConcept](https://paketo.io/docs/concepts/bom/)として紹介されています。

気軽にためすのであれば、以下のコマンドで試せます。
まず、いかに従い`pack cli`を入手してください。

https://buildpacks.io/docs/tools/pack/

完了したら以下のコマンドを実行します。

```
git clone https://github.com/paketo-buildpacks/samples && cd samples/java/maven
pack build demo-java --buildpack gcr.io/paketo-buildpacks/java:5.21.1
```

しばらくすると、コンテナイメージが出来上がるので、以下のコマンドを実行します。`--bom`が重要です。

```
pack inspect demo-java --bom
```

長い出力中段あたりに以下のような出力が確認できるかと思います。

```
    {
      "name": "dependencies",
      "metadata": {
        "dependencies": [
          {
            "name": "HdrHistogram",
            "sha256": "9b47fbae444feaac4b7e04f0ea294569e4bc282bc69d8c2ce2ac3f23577281e2",
            "version": "2.1.12"
          },
          {
            "name": "LatencyUtils",
            "sha256": "a32a9ffa06b2f4e01c5360f8f9df7bc5d9454a5d373cd8f361347fa5a57165ec",
            "version": "2.0.3"
          },
          {
            "name": "jackson-annotations",
            "sha256": "517926d9fe04cadd55120790d0b5355e4f656ffe2969e4d480a0e7f95a983e9e",
            "version": "2.12.5"
          },
          {
            "name": "jackson-core",
            "sha256": "0c9860b8fb6f24f59e083e0b92a17c515c45312951fc272d093e4709faed6356",
            "version": "2.12.5"
          },
          {
            "name": "jackson-databind",
            "sha256": "d49cdfd82443fa5869d75fe53680012cef2dd74621b69d37da69087c40f1575a",
            "version": "2.12.5"
          },
          {
            "name": "jackson-datatype-jdk8",
            "sha256": "8a622d3ee65bf02b41bce57aa5b5eadfbf093b99446ec7d4566026a7800262a1",
            "version": "2.12.5"
          },
          {
            "name": "jackson-datatype-jsr310",
            "sha256": "fc8af8cae7520f324b68506d74cb6df1513299040469a331c0f38b6f5bc31ceb",
            "version": "2.12.5"
          },
          {
            "name": "jackson-module-parameter-names",
            "sha256": "220b1b72a4f56d896c3a427a7ff4e690434fc2e28ef3ceff24dc3a656b1ac315",
            "version": "2.12.5"
          },
          {
            "name": "jakarta.annotation-api",
            "sha256": "85fb03fc054cdf4efca8efd9b6712bbb418e1ab98241c4539c8585bbc23e1b8a",
            "version": "1.3.5"
          },
          {
            "name": "jul-to-slf4j",
            "sha256": "6dee8d85ad6943aff0600f14897c469e64bae0413ee33a15c448af00432c0642",
            "version": "1.7.32"
          },
```

さらに[今話題のlog4jのパッケージ](https://wired.jp/2021/12/15/log4j-log4shell/)なんかも見えてヒヤヒヤします。(下自体は無関係なパッケージですが)

```
          {
            "name": "log4j-api",
            "sha256": "8caf58db006c609949a0068110395a33067a2bad707c3da35e959c0473f9a916",
            "version": "2.14.1"
          },
          {
            "name": "log4j-to-slf4j",
            "sha256": "8ba1d1b1c8313731ee053368371b9606c1d71436ac010b0bf91b4c7fc643a1bf",
            "version": "2.14.1"
          },
```

Javaのアプリケーションのビルドの際のOSSのライブラリのバージョンやハッシュ値がこのように格納されており、これがまさにSBOMです。これを使えば、コンテナにログインしたり、ファイルシステムをスキャンしなくても脆弱なOSSライブラリが含まれているか否かをみることができます。

なお、最後に、この上のデモの方法ですが、残念ながらDeprecatedになってしまいました。というのも[コンテナに含めるべきBOMの保管方法が大幅に変わってしまったため](https://buildpacks.io/docs/reference/spec/migration/platform-api-0.7-0.8/#new-standardized-sbom-format)です。今後近いうちに違う手段でSBOMを検索することになるかとおもいますが、あくまでここで紹介した方法は今一番シンプルにSBOMをみることのできる手段と思ってください。

# そして、log4shellの話

このSBOMの話ですが、いまいちお客様に対して説明しても反応が薄かったのですが、最近発表された[log4shell](https://gigazine.net/news/20211215-840000-attacks-log4j-flaw/)で改めてこの考え方が重要視されてきた印象です。

残念ながらlog4shellの脆弱性スキャンにすぐに使える状態かというと仕様がまだぶれたり、機能が不足している状況です。ただ、重要なのは、log4shell nextです。このときに

• 仮想マシンなどの手動変更がいくらでも変更できるインフラがやめられるか
• 自分の環境のOSSライブラリを即座にリストアップできるか
• パッチの適用が迅速にできるか

これらが今後現れる脆弱性に対して、非常に有効な手段であること、それにはSBOMが使えるのでは？と思っているのが私の仮説です。

# そして、引越しの話

プライベートでも、なんでもかんでもカバンや箱に詰め込めずに、丁寧に管理できる仕組みって改めて重要だな、、、と思います。