Vuls on CircleCI

Vuls on CircleCI

Vuls 祭りで Vuls モチベーションが上がったので何かやってみよう!

というわけで CircleCI から Vuls を定期実行してみました。

脆弱性の継続的インテグレーション!

やり方

主な方針。

  • vuls, go-cve-dictionary, goval-dictionary 全部入りの Docker イメージを用意する
    • 公式で各コマンドの Docker イメージがあるがこれを使わない理由は後述
  • CircleCI 2.0 の Scheduled Workflow を使って定期実行する

vuls, go-cve-dictionary, goval-dictionary 全部入りの Docker イメージを用意

各コマンドを利用できる Docker イメージを用意します。

公式の Docker イメージを使わないのは以下の理由です。

  • vuls コンテナを実行する際に .ssh/known_hosts に対象サーバの公開鍵が入っていないといけないのでめんどう
    • CircleCI の環境変数とか使えば行けるかもしれないけどうーむ
  • go-cve-dictionary, goval-dictionary コンテナ実行で保存した辞書データをホストマシン経由で( Docler ボリュームを利用) vuls コンテナに共有する使い方だが、CircleCI 上でそれを行う方法がぱっと見わからず
    • CircleCI は Docker compose も使えるのでやり方はありそう

CircleCI 2.0 の Scheduled Workflow を使って定期実行する

CircleCI 2.0 では cron 形式で Workflow を定期実行できます。

circle.yml

こんな感じの circle.yml を用意しました。

version: 2
jobs:
 build:
  docker:
   - image: lorentzca/vuls-and-dictionary:latest
  steps:
   - checkout
   - add_ssh_keys:
      fingerprints:
       - "<fingerprints>"
   - run:
      name: create my id_rsa
      command: |
       cat ${HOME}/.ssh/id_rsa_* > ${HOME}/.ssh/id_rsa_vuls
       chmod 600 ${HOME}/.ssh/id_rsa_vuls
   - run:
      name: start ssh-agent
      command: |
       eval $(ssh-agent -s)
       ssh-add ${HOME}/.ssh/id_rsa_vuls
   - run:
      name: add host publickey to known_hosts
      command: ssh -oStrictHostKeyChecking=no <target server> ':'
   - run:
      name: update dictionary
      command: |
       for i in `seq 2016 $(date +"%Y")`; do go-cve-dictionary fetchnvd -years $i; done
       goval-dictionary fetch-redhat 7
   - run:
      name: add config.toml
      command: curl -L <config url> > config.toml
   - run:
      name: vuls scan and report
      command: |
       vuls scan -config=/root/project/config.toml
       vuls report \
       -cvedb-path=/root/project/cve.sqlite3 \
       -ovaldb-path=/root/project/oval.sqlite3 \
       -lang=ja \
       -format-short-text \
       -to-slack \
       -cvss-over=9.0 \
       -config=/root/project/config.toml

workflows:
 version: 2
 commit:
  jobs:
   - build
 scheduled-workflow:
  triggers:
   - schedule:
      # Memo 11:00 AM (JST)
      cron: "0 2 * * *"
      filters:
       branches:
        only:
         - master
  jobs:
   - build
  • ssh key の finger print ( <fingerprints> の部分)は以下を参考に取得
  • <target host> の部分はスキャン対象のサーバー
    • known_hosts に追加するために空のコマンドを ssh 越しに実行している
  • <config url> の部分は config.yml を Gist か何かにおいて、それの url を指定している

だいぶぐちゃぐちゃですがとりあえず目的は果たした…。

動作イメージ

CircleCI の管理画面から、毎日午前11時くらいに実行されていることが確認できます。

----------2017-11-04-18.20.27

Slack にもちゃんと通知が来ていますね。 ✨

----------2017-11-04-18.29.58

感想

自前でサーバ持たずに Vuls の定期実行ができた! 🎉

脆弱性がある現実を叩きつけられるとやらなきゃ(使命感)が生まれて良いですね。

課題は以下。

  • 辞書データのキャッシュどうしよう(毎回辞書取得している)
  • できれば公式の Docker イメージを使いたい
  • circle.yml が汎用的じゃない/汚い

しかし好きな Docker イメージが使えて cron 実行もできる CircleCI 2.0 は CI サービス以上の使いみちがありますな…。(便利な cron …。)