aimdevel’s blog

勉強したことを書きます

yoctoで作成したOSの脆弱性情報をgithub actionsで取得する

yoctoでビルドしたOSに含まれる脆弱性情報の取得をgithub actionsで行ってみた。

初めに

過去の記事でgithubのDependbot alertに対応したときに、依存の中に脆弱性が含まれている際に通知してくれる仕組みの便利さを味わった。

aimdevel.hatenablog.com

cなどのパッケージマネージャがない言語では、このような仕組みは難しいと思っているが、yoctoでビルドしたイメージの中に脆弱性があるかどうかくらいは通知できるのではないかと思いついた。
実際に過去の記事でcve-checkを使って脆弱性のチェックを行っているし、github actionsと組み合わせれば自動通知の仕組みを作るのはそこまで難しくない気がするし。
いきなり通知するところまで作るのはハードルが高いので、本記事ではyoctoビルド時に得られるcve情報をgithub actionsで取得するところまでを行う。
cve-checkに関しては過去に動作確認を行っている。

aimdevel.hatenablog.com

実施内容

  • self-hosted runnerの作成
  • yoctoビルドのワークフロー作成

それぞれ説明する。

self-hosted runnerの作成

yoctoビルドをgithub actionsで実行したいが、githubがホストしているランナーはあまりスペックが高くない。
yoctoビルドを行うには全く足りていないので、自前のself-hostedなランナーを用意する必要がある。

そこで今回は、yoctoビルド用のself-hostedランナーとして動くdockerコンテナを作成した。
作成に使った資材は以下である。

meta-my-raspberrypi/ci/self-hosted-runner at main · aimdevel/meta-my-raspberrypi · GitHub

使い方は以下。

  • イメージをビルドする。
$ docker build -t yocto-build-runner .
  • sample.envをベースに設定を書く。
    例えば、以下のように編集する。
GITHUB_URL=https://github.com/aimdevel/meta-my-raspberrypi
RUNNER_TOKEN=YOUR_TOKEN
RUNNER_NAME=my-yocto-build-runner
RUNNER_LABELS=self-hosted,linux,yocto-build

RUNNER_TOKENに設定する値を取得するには、runnerを使用するリポジトリで、New self-hosted runnerボタンをクリックする。

そしてプラットフォームなどを選ぶ、とランナーを追加するコマンドが表示されるので、tokenだけ抜きだして使えばよい。
例えば、tokenは以下のように表示されているはずである。

$ ./config.sh --url https://github.com/aimdevel/meta-my-raspberrypi --token <your token>
  • コンテナを開始する 以下を実行して少し待つとランナーがgithubに登録される。
$ docker run -it -d --env-file <your env file> yocto-build-runner

yoctoビルドのワークフロー作成

以下のファイルを作成した。

meta-my-raspberrypi/.github/workflows/cve_check.yml at main · aimdevel/meta-my-raspberrypi · GitHub

以下を行うワークフローになっている。

  • cve-checkを有効化

  • yoctoのcore-image-baseをビルド

  • cve情報を取り出して保存

それぞれ説明する。

cve-checkを有効化

      - name: Add cve-check
        run: |
          echo "INHERIT += \"cve-check\""   >> build/conf/local.conf
          echo "BB_NUMBER_THREADS = '6'"  >> build/conf/local.conf
          echo "PARALLEL_MAKE = '-j 4'"   >> build/conf/local.conf

INHERIT += "cve-check"がcve-checkを有効にする設定。
他の2つはビルド時の並列実行の設定で、今回作ったself-hostedランナーのスペックがそこまでよくないため指定してある。マシンスペックに自信がある場合はこの設定は外したほうがよい。

yoctoのcore-image-baseをビルド

通常通りにビルドする。

      - name: Run cve-check
        run: |
          . layers/poky/oe-init-build-env build/
          bitbake core-image-base

cve情報を取り出して保存

以下の2種類のcve情報を取り出す。

  • 個々のパッケージのcve

  • OSイメージ全体のcve

      - name: Upload cve
        uses: actions/upload-artifact@v4
        with:
          name: cve-result
          path: |
            build/tmp/deploy/cve
            build/tmp/deploy/images/raspberrypi4-64/*.rootfs.json
            build/tmp/deploy/images/raspberrypi4-64/*.rootfs.cve

build/tmp/deploy/cveにはパッケージごとのcve情報が格納されている。
build/tmp/deploy/images/raspberrypi4-64/*.rootfs.jsonbuild/tmp/deploy/images/raspberrypi4-64/*.rootfs.cveには、OSイメージ全体のパッケージ情報が記載されている。
.cveファイルと.jsonファイルがあるが、内容的には同じものだと思う。(未確認)

結果確認

github actionsの実行が成功すると、結果画面からartifactをダウンロードできる。
解凍して中身を確認すると、cve情報を取得できていることがわかる。

終わりに

github actionsを使ってyoctoのcve-checkを有効にしたビルドを行い、その結果を取得できるようにした。
今回の実装では手動で実行して結果のファイルを取得するようになっているが、本来は脆弱性監視のために定期実行と通知の仕組みを入れておくべきだと思っている。今回そうなっていないのは、self-hostedランナーを常時稼働させる環境がないのと、区切りのいいところまでで一度記事にしてしまいたかったという理由。
なので、今後は以下をできるようにしたいと思う。

  • cve情報をチェックして通知を飛ばす

self-hostedランナーの常時稼働+cve-checkの定期実行は、安く使える環境があればやってみたい。自宅のPCでやるのはちょっと厳しい。