1. 概要

Dockerを使ってVulsの環境を構築し、スキャン実行、Vuls Repoの表示、Slackとの連携、Cronで自動実行を試してみます。

環境は以下の通りです。

OS
Vuls実行サーバCentOS 7.3
スキャン対象サーバCentOS 6.8

2. 事前準備

Vulsのセットアップは以下の3パターンがあります(by公式マニュアル)。

  • Dockerコンテナ上にセットアップ
  • Chef(構成管理ツール)でセットアップ
  • 手動でセットアップ

その他、IDCFクラウド、さくらのクラウドで構築手段が用意されています。

IDCFのテンプレートも試してみましたが、Vuls と Vuls Repo が構築済みの環境が瞬時に手に入ります!
Vuls用のユーザなども作ってあり、あとはスキャンを実行するばかり。
利用方法は、OSイメージを選択する代わりにコミュニティテンプレートを選択するだけ。簡単便利!

さて、(テンプレートではやることが無いので)今回はDocker を使った構築を試してみたいと思います。

2.1 Vuls実行サーバのセットアップ

2.1.1 Vuls実行用ユーザーの追加・設定

Vuls実行用のユーザーにはSUDO権限が必要です。
まず、ユーザを追加します。

$ sudo useradd vuls

作成したユーザーに対し、SUDO可能な権限を追加します。
OSによって設定が違いますので、公式マニュアルの Check /etc/sudoers のサンプルを参考にしてください。

root@server# visudo
vuls ALL=(ALL) NOPASSWD: \
	/usr/bin/yum --color=never repolist, \
	/usr/bin/yum --color=never --security updateinfo list updates, \
	/usr/bin/yum --color=never --security updateinfo updates

2.1.2 Dockerをインストール

Dockerをインストールし、起動します。
こちらの Dockerの日本語ドキュメント を参考にすると良いと思います。

2.1.3 docker グループの作成

vulsユーザが docker を起動できるようにしておきます。

$ sudo usermod -aG docker vuls

sudo を使わずに docker が実行できることを確認します。

$ sudo su - vuls
$ docker run hello-world

以降の手順は、vulsユーザのホームで実行します。

$ pwd
/home/vuls

2.1.4 CVEデータベースの取得

最新の脆弱性情報を取得します。時間がかかるので注意しましょう。

for i in `seq 2002 $(date +"%Y")`; do \
    docker run --rm -it \
    -v $PWD:/vuls \
    -v $PWD/go-cve-dictionary-log:/var/log/vuls \
    vuls/go-cve-dictionary fetchnvd -years $i; \
  done

スキャン結果を日本語で出力したい場合は、JVNも取得しておきます。

for i in `seq 1998 $(date +"%Y")`; do \
    docker run --rm -it \
    -v $PWD:/vuls \
    -v $PWD/go-cve-dictionary-log:/var/log/vuls \
    vuls/go-cve-dictionary fetchjvn -years $i; \
  done

2.2 スキャン対象サーバー側のセットアップ

2.2.1 パッケージインストール

対象のホストによってインストールが必要なパッケージがあります。
公式マニュアル を参考に、インストールしておきます。 今回はCentOSなので、以下をインストール。

$ sudo yum install -y yum-plugin-changelog, yum-utils

2.2.2 Vuls実行用ユーザーの追加・設定

スキャン対象サーバー側にもSSHでログインするためvulsユーザを作成して、sudo権限を追加します。

$ sudo useradd vuls
root@server# visudo
vuls ALL=(ALL) NOPASSWD: \
	/usr/bin/yum --color=never repolist, \
	/usr/bin/yum --color=never --security updateinfo list updates, \
	/usr/bin/yum --color=never --security updateinfo updateso

2.3 SSHの準備

Vuls実行サーバからスキャン対象サーバへSSHで接続できるようにしておきます。

2.3.1 【Vuls実行サーバ側】SSHキーを作成

ssh-keygenで公開鍵と秘密鍵のペアを作ります。
秘密鍵は、今回は id_rsa_vals という名前でホームディレクトリの.sshに保存します。
パスフレーズは入力せずに作成してください。

$ mkdir ~/.ssh
$ chmod 700 ~/.ssh
$ cd ~/.ssh/
$ ssh-keygen -t rsa -f id_rsa_vuls
$ chmod 600 id_rsa_vuls

2.3.2 【スキャン対象サーバ側】公開鍵の登録

作成した公開鍵をスキャン対象サーバ側に設置します。
2.2.2で作成したVulsユーザのホームディレクトリの.sshディレクトリ配下にauthorized_keysを置きます。

$ mkdir ~/.ssh
$ chmod 700 ~/.ssh
$ mv id_rsa_vuls.pub ~/.ssh/authorized_keys
$ chmod 600 ~/.ssh/authorized_keys

すでにauthorized_keysがある場合は、公開鍵を追記します。

$ cat id_rsa_vuls.pub >> authorized_keys

ここまでできたら、Vuls実行サーバからスキャン対象サーバへSSHできるはずです。
2.2.2で作成した vulsユーザ でアクセスできるか、確認しておきましょう。

$ ssh -i ~/.ssh/id_rsa_vuls vuls@***.***.***.***

3. スキャン

以下の作業は、vulsのホームディレクトリで行います。

3.1 スキャン対象を設定

設定ファイルにスキャン対象のサーバーを設定します。

config.toml

[servers]
 
[servers.****]
host = "***.***.***.***"            # 対象サーバーのIPアドレス
port = "22"
user = "vuls"                       # 2.2.2で作成したユーザー
keyPath = "/root/.ssh/id_rsa_vuls"  # ※dockerコンテナ内でのパスである点に注意!

3.2 コンフィグのテスト

設定ファイルの内容で正しく接続できるか確認します。

$ docker run --rm -it\
    -v ~/.ssh:/root/.ssh:ro \
    -v $PWD:/vuls \
    -v $PWD/vuls-log:/var/log/vuls \
    vuls/vuls configtest \
    -config=./config.toml
  • -v オプションでホスト側のディレクトリ( : の左)とdockerコンテナ内のディレクトリ( : の右)をマウントしています。ホスト側のディレクトリのパスは環境によって変更してください。

3.3 スキャン実施

$ docker run --rm -it \
    -v ~/.ssh:/root/.ssh:ro \
    -v $PWD:/vuls \
    -v $PWD/vuls-log:/var/log/vuls \
    -v /etc/localtime:/etc/localtime:ro \
    vuls/vuls scan \
    -config=./config.toml

One Line Summary
================
vulstest        centos6.8       31 CVEs 127 updatable packages

CVEに載っている脆弱性が31件、更新対象が127件 という結果が出ました。

4. レポート出力

4.1 CUI

$ docker run --rm -it \
     -v ~/.ssh:/root/.ssh:ro \
     -v $PWD:/vuls \
     -v $PWD/vuls-log:/var/log/vuls \
     -v /etc/localtime:/etc/localtime:ro \
     vuls/vuls report \
     -cvedb-path=/vuls/cve.sqlite3 \
     -format-short-text \
     -config=./config.toml -lang=ja
  • 日本語で出力する場合は-lang=jaを付けます。
  • -format-short-textの部分を変更すると、レポートの詳しさを変更できます。
    • format-one-line-text
    • format-short-text
    • format-full-text

4.2 TUI(Terminal-Based User Interface)

$ docker run --rm -it \
    -v ~/.ssh:/root/.ssh:ro \
    -v $PWD:/vuls \
    -v $PWD/vuls-log:/var/log/vuls \
    -v /etc/localtime:/etc/localtime:ro \
    vuls/vuls tui \
    -cvedb-path=/vuls/cve.sqlite3

4.3 Web

Vuls Repo を実行します。

$ docker run -dt \
     -v $PWD:/vuls \
     -p 80:80 \
     vuls/vulsrepo

Webブラウザで http://IPアドレス/vulsrepo/ にアクセスすると、結果が確認できます。

初期状態ではこんな感じに表示されました。表の項目を変更して出力形式を変えたり、棒グラフにしたりもできます。

5. Slackとの連携

5.1 Slackの準備

Slack側で以下の準備をしておきます。

  • Slackのteamと投稿したいchannelを作る
  • SlackのIncoming WebHookの設定ページで投稿用URLを発行する
  • 先ほど作ったchannel名をプルダウンメニューから選択し、 Add Incoming WebHooks integration を押す。
  • 発行されたWebhookURLを控えておく。

5.2 Vulsの設定

config.tomlにslackの設定を追記します。

[slack]
hookURL      = "https://hooks.slack.com/services/xxxxxxxx/xxxxxxxx/xxxxxxx"
channel      = "チャンネル名"
iconEmoji    = ":ghost:"
authUser     = "vuls"
notifyUsers  = ["@username"]

5.3 レポート出力

-to-slack のオプションをつけてレポートを実行します。

$ docker run --rm -it \
     -v ~/.ssh:/root/.ssh:ro \
     -v $PWD:/vuls \
     -v $PWD/vuls-log:/var/log/vuls \
     -v /etc/localtime:/etc/localtime:ro \
     vuls/vuls report \
     -cvedb-path=/vuls/cve.sqlite3 \
     -format-short-text \ 
     -config=./config.toml \
     -lang=ja -to-slack

… slackに通知が来ました!

6. Cronの設定

自動実行するために、Cronに登録しておきます。
CUIから実行するときとほとんど変わりませんが、 -it のオプションは外さないとエラーになります。

$ crontab -e
# 過去2年間の最新情報を取得
* 5 * * * docker run --rm -v /home/vuls:/vuls -v /home/vuls/go-cve-dictionary-log:/var/log/vuls vuls/go-cve-dictionary fetchnvd -last2y
# 最新の日本語脆弱性辞書を更新
* 6 * * * docker run --rm -v /home/vuls:/vuls -v /home/vuls/go-cve-dictionary-log:/var/log/vuls vuls/go-cve-dictionary fetchjvn -latest
# スキャン実行
* 7 * * * docker run --rm -v /home/vuls/.ssh:/root/.ssh:ro -v /home/vuls:/vuls -v /home/vuls/vuls-log:/var/log/vuls -v /etc/localtime:/etc/localtime:ro vuls/vuls scan -config=./config.toml
# レポートをSlackへ
* 8 * * * docker run --rm -v /home/vuls/.ssh:/root/.ssh:ro -v /home/vuls:/vuls -v /home/vuls/vuls-log:/var/log/vuls -v /etc/localtime:/etc/localtime:ro vuls/vuls report -cvedb-path=/vuls/cve.sqlite3 -format-one-line-text -config=./config.toml -lang=ja -to-slack