CentOS 7にLinuxのCVE脆弱性検知ツール「Vuls」をインストールする

会社の先輩(というかリーダー)から、sshなどでリモートのLinuxにアクセスし、CVEの脆弱性確認して検知したら自動的にSlackなどで通知してくれるツール「Vuls」というものがあると教えてもらったので、会社の環境に導入する前に自宅環境に入れてみることにした。
Vulsは日本人が作成したツールらしいので、日本語の情報もたんまりとあるのが素晴らしい。
詳細な情報については、以下の記事を見るとわかるだろう。

sshでのアクセスが必要とのことなので、鍵認証が前提になるので注意(パスワード認証はサポート外らしい)。
また、ソフトウェアアップデートは自動的には行ってくれないので、検知して重要度の高い脆弱性であれば、すぐに対応する必要があるだろう。

1.インストール・設定

さて、それでは実際にインストールを行ってみよう。
今回はCentOS 7にインストールを行う。まず、以下のコマンドを実行しインストール前の準備を行う。

sudo yum -y install sqlite git gc wget gcc
wget https://storage.googleapis.com/golang/go1.6.linux-amd64.tar.gz
sudo tar -C /usr/local -xzf go1.6.linux-amd64.tar.gz
mkdir $HOME/go
sudo sh -c 'cat << "EOF" > /etc/profile.d/goenv.sh
export GOROOT=/usr/local/go
export GOPATH=$HOME/go
export PATH=$PATH:$GOROOT/bin:$GOPATH/bin
EOF'
source /etc/profile.d/goenv.sh

事前準備が終わったら、以下のコマンドでvulsをインストールする。

sudo mkdir /var/log/vuls
sudo useradd vuls -b /opt
sudo chown vuls /var/log/vuls
sudo chmod 700 /var/log/vuls
su - vuls
go get github.com/kotakanbe/go-cve-dictionary

脆弱性データベースのダウンロードを行う。
(10~20分くらいかかる)

for i in {2002..2016}; do go-cve-dictionary fetchnvd -years $i; done

データベースのダウンロード後、以下のコマンドでVulsをダウンロードしてくる。

go get github.com/future-architect/vuls

Vulsのダウンロード完了後、設定ファイル(config.toml)を作成する。
デフォルトの設置場所はユーザのホームディレクトリ直下になるので、新規作成する。

$HOME/config.toml

[servers]
[servers.サーバ名]
host = "ホスト名・IPアドレス"
port = "22"
user = "ユーザ名"
keyPath = "鍵ファイルのPATH"

複数台指定する場合は、以下のようにする。

[servers]
[servers.サーバ名1]
host = "ホスト名・IPアドレス"
port = "22"
user = "ユーザ名"
keyPath = "鍵ファイルのPATH"

[servers.サーバ名2]
host = "ホスト名・IPアドレス"
port = "22"
user = "ユーザ名"
keyPath = "鍵ファイルのPATH"

最後に、以下のコマンドでコンフィグテストとスキャン対象サーバに必要なパッケージの導入を行う。

vuls configtest # コンフィグテスト
vuls prepare # パッケージ導入
[root@BS-PUB-CENT7-01 ~]# vuls configtest
[Aug 21 12:32:36]  INFO [localhost] Validating Config...
[Aug 21 12:32:36]  INFO [localhost] Detecting Server/Contianer OS...
[Aug 21 12:32:36]  INFO [localhost] Detecting OS of servers...
[Aug 21 12:32:36]  INFO [localhost] (1/3) Detected: BS-PUB-CENT7-02: centos 7.2.1511
[Aug 21 12:32:37]  INFO [localhost] (2/3) Detected: BS-PUB-UBUNTU-02: ubuntu 16.04
[Aug 21 12:32:40]  INFO [localhost] (3/3) Detected: BS-PUB-UBUNTU-01: ubuntu 14.04
[Aug 21 12:32:40]  INFO [localhost] Detecting OS of containers...
[Aug 21 12:32:40]  INFO [localhost] Checking sudo configuration...
[Aug 21 12:32:40]  INFO [BS-PUB-UBUNTU-01] sudo ... OK
[Aug 21 12:32:40]  INFO [BS-PUB-CENT7-02] sudo ... OK
[Aug 21 12:32:40]  INFO [BS-PUB-UBUNTU-02] sudo ... OK
[Aug 21 12:32:40]  INFO [localhost] SSH-able servers are below...
BS-PUB-CENT7-02 BS-PUB-UBUNTU-02 BS-PUB-UBUNTU-01
[root@BS-PUB-CENT7-01 ~]# vuls prepare
INFO[0000] Start Preparing (config: /root/config.toml)
[Aug 21 12:32:53]  INFO [localhost] Detecting OS...
[Aug 21 12:32:53]  INFO [localhost] Detecting OS of servers...
[Aug 21 12:32:54]  INFO [localhost] (1/3) Detected: BS-PUB-UBUNTU-01: ubuntu 14.04
[Aug 21 12:32:54]  INFO [localhost] (2/3) Detected: BS-PUB-CENT7-02: centos 7.2.1511
[Aug 21 12:32:54]  INFO [localhost] (3/3) Detected: BS-PUB-UBUNTU-02: ubuntu 16.04
[Aug 21 12:32:54]  INFO [localhost] Detecting OS of containers...
[Aug 21 12:32:54]  INFO [localhost] Installing...
[Aug 21 12:32:54]  INFO [BS-PUB-UBUNTU-02] apt-get update...
[Aug 21 12:32:54]  INFO [BS-PUB-UBUNTU-01] apt-get update...
[Aug 21 12:32:55]  INFO [BS-PUB-CENT7-02] Installing yum-plugin-security...
[Aug 21 12:32:56]  INFO [BS-PUB-CENT7-02] Ignored: yum-plugin-changelog already installed
[Aug 21 12:33:24]  INFO [localhost] Success

これでインストールと初期設定は完了。
なお、このときログインするのが一般ユーザの場合、タイムアウトエラーが発生することがある。
これは、apt-getやyumを実行する際にパスワードを求められた場合に対応できないためだ。そのため、/etc/sudoersでvulsのログインユーザではapt-getやyumの際にはパスワードを求めないように以下の内容を追記してやる必要がある。

ログインユーザ ALL=(root) NOPASSWD: /usr/bin/yum, /bin/echo # CentOS, RHEL, Amazon Linuxの場合
ログインユーザ ALL=(root) NOPASSWD: /usr/bin/apt-get, /usr/bin/apt-cache # Ubuntu, Debianの場合

追記後、またコンフィグテストとパッケージの導入コマンドを実行してやればよい。

2.スキャンの実施

さて、これで事前の準備が終わったので、実際にVulsを導入したサーバから脆弱性の検知をするため、以下のコマンドを実行する。

vuls scan -cve-dictionary-dbpath=$PWD/cve.sqlite3
[root@BS-PUB-CENT7-01 ~]# vuls scan -cve-dictionary-dbpath=$PWD/cve.sqlite3
INFO[0000] Start scanning
INFO[0000] config: /root/config.toml
INFO[0000] cve-dictionary: /root/cve.sqlite3
[Aug 21 12:40:15]  INFO [localhost] Validating Config...
[Aug 21 12:40:15]  INFO [localhost] Detecting Server/Contianer OS...
[Aug 21 12:40:15]  INFO [localhost] Detecting OS of servers...
[Aug 21 12:40:16]  INFO [localhost] (1/3) Detected: BS-PUB-UBUNTU-01: ubuntu 14.04
[Aug 21 12:40:16]  INFO [localhost] (2/3) Detected: BS-PUB-CENT7-02: centos 7.2.1511
[Aug 21 12:40:17]  INFO [localhost] (3/3) Detected: BS-PUB-UBUNTU-02: ubuntu 16.04
[Aug 21 12:40:17]  INFO [localhost] Detecting OS of containers...
[Aug 21 12:40:17]  INFO [localhost] Checking sudo configuration...
[Aug 21 12:40:17]  INFO [BS-PUB-CENT7-02] sudo ... OK
[Aug 21 12:40:17]  INFO [BS-PUB-UBUNTU-01] sudo ... OK
[Aug 21 12:40:18]  INFO [BS-PUB-UBUNTU-02] sudo ... OK
[Aug 21 12:40:18]  INFO [localhost] Detecting Platforms...
[Aug 21 12:40:30]  INFO [localhost] (1/3) BS-PUB-UBUNTU-01 is running on other
[Aug 21 12:40:30]  INFO [localhost] (2/3) BS-PUB-CENT7-02 is running on other
[Aug 21 12:40:30]  INFO [localhost] (3/3) BS-PUB-UBUNTU-02 is running on other
[Aug 21 12:40:30]  INFO [localhost] Scanning vulnerabilities...
[Aug 21 12:40:30]  INFO [localhost] Check required packages for scanning...
[Aug 21 12:40:31]  INFO [localhost] Scanning vulnerable OS packages...
[Aug 21 12:40:42]  INFO [BS-PUB-UBUNTU-02] (1/7) Upgradable: gnupg-1.4.20-1ubuntu3 -> 1.4.20-1ubuntu3.1
.....

終了後、検知された脆弱性がズラッと出力される。
そのままだと読みにくいので、以下のコマンドで検知された脆弱性を確認する。

vuls tui

コンソール上から、各ホスト別に検知された脆弱性を確認できる。
選択は上下キーで移動することで選べ、操作するウィンドウを変える場合はTabキーを押下すればよい。

うーん…結構Ubuntu 14.04 LTSだと脆弱性が検知されてるなぁ…

3.Slack・メールでアラートを通知させる

さて、このようにコマンドでCVEに登録されている脆弱性を確認することができるのだけど、Vulsはただコンソール上で確認するだけではなくSlackやメールに通知を出させることができる。
まず、最初にSlackでWebHookの設定を行う。こちらのリンクからアラートを通知させるチャンネルを選択してhookURLに入力するためのURLを生成する。

URL設定後、設定ファイル(config.toml)に以下の内容を追記してやればよい。

[slack]
hookURL = "https://hooks.slack.com/services/abc123/defghijklmnopqrstuvwxyz"
channel = "#channel-name"
#channel = "${servername}"
iconEmoji = ":ghost:"
authUser = "username"
notifyUsers = ["@username"]

[mail]
smtpAddr = "smtp.gmail.com"
smtpPort = "465"
user = "username"
password = "password"
from = "from@address.com"
to = ["to@address.com"]
cc = ["cc@address.com"]
subjectPrefix = "[vuls]"

あとはscan時にslackに通知をさせるよう、「-report-slack(メールは-report-mail)」オプションを追加するだけだ。

vuls scan -cve-dictionary-dbpath=$PWD/cve.sqlite3 -report-slack

あまりにも脆弱性の数が多すぎると通知が飛ばせなくなるので、こまめに対応するようにしよう。
それにしても、勝手にアップデートされたりするわけではないので、これは便利そうだ。社内環境に導入しよう。