vulsは脆弱性確認を楽にしてくれる可能性を秘めた、サーバー運用者にとって期待のツールです。
前回書いた記事に開発者の @kotakanbe@github さんから有益な情報を頂いたのと、その後有益な記事を参考にしたのとで、大幅に文章を修正しました。 あまりに更新量が多かった (=簡略化できた)ので、別記事としています。
具体的には
- go-cve-dictionaryのdaemon化が不要だった ため、手順を省略しました。
- 日本語脆弱性辞書を扱うようにしました。
- 上記変更に伴い、実行例や実行コマンド例も変えました。
なお、導入手順は基本的にオフィシャルに従えば良いのですが、AWSベースで書かれています。本記事はオンプレ用に端折った手順のメモです。
以下、環境はCentOS7で、2016/06/14に実施した手順です。
本手順で入るgo-cve-dictionaryおよびvulsのバージョンは以下です。
$ go-cve-dictionary -v
go-cve-dictionary 0.1.1
$ vuls -v
vuls 0.1.4
前回の記事で作ったサーバーで入れ直しをしているため、多少手順の記載漏れをしているかもしれません。
事前準備
ここでの作業はCentOS7上で、全てrootユーザーを想定しています。
Go言語環境の構築
事前に必要なパッケージをインストールします。
goはtarでダウンロードするので、ちょっとめんどくさいですね。
$ yum -y install sqlite git gcc
$ wget https://storage.googleapis.com/golang/go1.6.2.linux-amd64.tar.gz
$ tar -C /usr/local -xzf go1.6.linux-amd64.tar.gz
/etc/profile.d/goenv.sh
を作成してこのように記載します。
export GOROOT=/usr/local/go
export GOPATH=$HOME/go
export PATH=$PATH:$GOROOT/bin:$GOPATH/bin
一回ログアウトして再度ログインすれば、goenv.sh
が適用されてgoコマンドが使用できるはずです。
SSH公開鍵認証の設定
vulsはAnsibleやChefのように、公開鍵認証のSSHを使用しているようです。検査対象サーバー(ここではローカルホスト)には事前にSSH周りの設定をしておきましょう。
このあたり、AnsibleやChefなどのSSHユーザー管理の話と同じですので、ここでは割愛します。
私の環境ではAnsibleに使用しているユーザーを使用することにしました。
本手順ではこのユーザーを 「sshuser」 と呼ぶことにします。
なお、以下はSSH公開鍵設定の手順例です。
### 認証用の公開鍵を作る
[[vulsサーバー]]
$ su - sshuser
[sshuser] $ ssh-keygen -t rsa
[sshuser] $ cat ~/.ssh/id_rsa.pub
### この内容を検査対象サーバーのSSHログインユーザーに設定
[[検査対象サーバー]]
[sshuser] $ vim ~/.ssh/authorized_keys
[sshuser] $ chmod 600 ~/.ssh/authorized_keys
sshuserで、SSHで対象サーバーにノーパスで入れることを確認しましょう。
導入手順
ここからの作業は、先ほどのsshuserで作業することを想定しています。
[[vulsサーバー]]
$ su - sshuser
cve-dictionaryの初期構築
go-cve-dictionaryインストール
go-cve-dictionaryをダウンロード&インストールしましょう。結構重たいです。
$ go get github.com/kotakanbe/go-cve-dictionary
### 確認
$ type go-cve-dictionary
go-cve-dictionary is hashed (/home/sshuser/go/bin/go-cve-dictionary)
$ go-cve-dictionary -v
go-cve-dictionary 0.1.1
go-cve-dictionary
がインストールされました。
※ 前回記事と違って、GOPATH(各自のホームディレクトリ以下)に実行ファイルがあれば十分です。
ディレクトリの準備
ログディレクトリおよび辞書ディレクトリを作り、sshuserに書込権限を渡しておきます。
この部分はsudoしないと(root権限を取らないと)、おそらく権限不足で失敗するかと思います。
$ sudo mkdir /var/log/vuls
$ sudo chown sshuser:sshuser /var/log/vuls
$ sudo mkdir -p /var/vuls/dict
$ sudo chown sshuser:sshuser /var/vuls/dict
脆弱性辞書の準備
2002年〜2016年に発生した脆弱性について、辞書を取得します。
数分は時間が掛かるので注意しましょう。
$ for i in {2002..2016}; do go-cve-dictionary fetchnvd -dbpath=/var/vuls/dict/cve.sqlite3 -years $i; done
辞書ディレクトリにsqlite3ファイルができたことを確認します。
$ ls -l /var/vuls/dict/cve.sqlite3
-rw-r--r-- 1 sshuser sshuser 574898176 Jun 1 12:00 cve.sqlite3
日本語の脆弱性情報も追加しておきましょう。 こちらはもっと時間が掛かります。
日本語でなくても良い、という方は、この項目は飛ばしてください。
$ go-cve-dictionary fetchjvn -entire -dbpath=/var/vuls/dict/cve.sqlite3
vulsを準備
vulsを手に入れる・・・のですが、 ここで詰まる可能性がある ので、続く手順を先に眺めてください。
$ go get github.com/future-architect/vuls
CentOSの標準yumリポジトリでは、git-1.X系列しかダウンロード出来ないはずです。
この場合、gitのバージョンが古いためにgo get
が詰まってしまいます。
そこでwandiscoのリポジトリからgit-2.xをインストールします。
git-2.xのインストール
本節の作業はrootユーザーで、あるいはsudoで実行してください。
/etc/yum.repos.d/wandisco.repo
を作成します。
[wandisco-git]
name=WANdisco Distribution of git
baseurl=http://opensource.wandisco.com/centos/7/git/$basearch
enabled=0
gpgcheck=1
gpgkey=file:///etc/pki/rpm-gpg/RPM-GPG-KEY-WANdisco
gitのアップデート
### GPGキーを取り込み
$ rpm --import http://opensource.wandisco.com/RPM-GPG-KEY-WANdisco
$ yum update git --enablerepo=wandisco-git
### バージョンアップ確認
$ git --version
git version 2.8.0
改めてvulsをインストール
では、改めてvulsをgo get
しましょう。
※ sshuserに戻るのを忘れないようにご注意を。
$ go get github.com/future-architect/vuls
### 確認
$ type vuls
vuls is hashed (/home/sshuser/go/bin/vuls)
$ vuls -v
vuls 0.1.4
vuls
も入りました。
※ 前回記事と違って、GOPATH(各自のホームディレクトリ以下)に実行ファイルがあれば十分です。
vulsによる脆弱性検査
vulsの使用準備
vuls設定ファイルの作成
先ほど作ったvulsサーバーにてconfig.toml
ファイルを作成します。
現在のvulsはカレントディレクトリ以下にあるconfig.toml
ファイルを読み、カレントディレクトリ以下に結果を出力するのが基本動作です。-configオプションでconfig.tomlのパスを指定することもできます。
以下は設定毎にディレクトリを作っている例です。
$ mkdir hoge
$ cd hoge
$ vim config.toml
中身はこのように書いていきます。
詳しくはオフィシャルを参照してください。
[servers]
[servers.localhost]
host = "127.0.0.1"
port = "22"
user = "sshuser"
keyPath = "/home/sshuser/.ssh/id_rsa"
脆弱性スキャンの実行
vuls prepare
SSH公開鍵ログイン設定が終わったらvuls prepare
を実行します。
これにより、SSHの動作確認ができるとともに、動作に必要なyumプラグインが検査対象サーバーにインストールされます。
$ vuls prepare
INFO[0000] Start Preparing (config: /root/config.toml)
[May 24 12:29:25] INFO [localhost] Detecting OS...
[May 24 12:29:25] INFO [localhost] (1/1) Detected localhost: centos 6.4
[May 24 12:29:25] INFO [localhost] Detecting Container OS...
[May 24 12:29:25] INFO [localhost] Installing...
[May 24 12:29:25] INFO [localhost] Ignored: yum-plugin-security already installed
[May 24 12:29:25] INFO [localhost] Installing yum-plugin-changelog...
[May 24 12:29:29] INFO [localhost] Installed: yum-plugin-changelog
[May 24 12:29:29] INFO [localhost] Success
vuls scan
ここまで準備出来れば、脆弱性スキャンが実行できます。
config.tomlに書いたサーバーに対しては一気に実行してしまいます ので、稼働中のホストへのスキャンは気をつけてください。
レポートの出力形式はヘルプを見て、適当なものを選びましょう。
$ cd vulsの設定ファイルを作ったフォルダ
$ vuls scan -cve-dictionary-dbpath=/var/vuls/dict/cve.sqlite3 -report-text
### 日本語でレポートを出力する場合は以下
$ vuls scan -cve-dictionary-dbpath=/var/vuls/dict/cve.sqlite3 -report-text -lang=ja
結果は results/current/
ディレクトリに出力されています。
$ ls -1 results/current/*.txt
all.txt
ホスト名.txt
定期的な実行を考える
定期的な実行をし続けることで、運用をもっと楽したいと思います。
脆弱性情報の定期的な更新
とりあえずcronに仕込んじゃいましょう。
コマンドの中身そのものはそれぞれ簡単なワンライナーで、「過去2年間の最新情報を取得する」+「過去1週間の日本語脆弱性辞書を更新する」というものです。
SHELL=/bin/bash
HOME=/home/sshuser
MAILTO=""
# Update CVE dict
37 05 * * * sshuser ${HOME}/go/bin/go-cve-dictionary fetchnvd -last2y -dbpath=/var/vuls/dict/cve.sqlite3 >/dev/null 2>&1
57 05 * * * sshuser ${HOME}/go/bin/go-cve-dictionary fetchjvn -week -dbpath=/var/vuls/dict/cve.sqlite3 >/dev/null 2>&1
HOME
環境変数及び実行ユーザーのsshuser
は環境に合わせてください。
また、実行時間は 負荷をかけないように適当に変えてください。
定期的な脆弱性診断
定期的に診断を実行するなら、どうやって通知するのが適切か考える必要があります。
vulsはslackに投げる機能もあるのですが、脆弱性発見時は結構な文章量になることを想定して、メール通知で始めてみることにしました。
メール通知を設定する
Cronで実行するためのconfigファイルを作成します。
$ mkdir /var/vuls/cron/config.toml
$ vim /var/vuls/cron/config.toml
自動実行して負荷をかけても問題ないサーバーをスキャン対象にしておきましょう。
このとき、configファイルの先頭に[mail]
ブロックを作成します。
詳しくはオフィシャルの設定を見るとして、こんな感じでローカルのsmtpサーバーを使って送信してしまいます。
[mail]
smtpAddr = "localhost"
smtpPort = "25"
from = "xxxxxx@mailaddress.xxxx"
to = ["xxxxxx@mailaddress.xxxx"]
subjectPrefix = "[vuls]"
[servers]
### 以下スキャン対象のサーバーの指定
なお、オフィシャルではsmtpPort
オプションはintegerに見えるのですが、文字列(ダブルクォートで囲む)じゃないとうまく動作しませんでした。この辺は近々直るはずです。
Cronに設定する
この設定ファイルを使ってvuls scan
を実行する設定をCronに仕込みます。
本書の手順では、先ほどのconfigファイルは/var/vuls/cron
に置いているので、vulsコマンド実行前にcd
しています。コマンド末尾の出力言語部分は好みで選んでください。
SHELL=/bin/bash
HOME=/home/sshuser
MAILTO=""
# Scan target machines
37 06 * * * sshuser cd /var/vuls/cron && ${HOME}/go/bin/vuls scan -cve-dictionary-dbpath=/var/vuls/dict/cve.sqlite3 -report-text -report-mail -lang=ja >/dev/null 2>&1
これで 毎朝嫌というほど脆弱性通知メールが来ることが期待できます。
# 当たり障りない脆弱性は対応を手抜きしちゃいますよね・・・
こちらも、 HOME
環境変数及び実行ユーザーのsshuser
は環境に合わせてください ね。
重要な脆弱性だけ知りたい
すべて潰すのがツラい。重要な脆弱性だけ知りたい。
・・・という場合は、-cvss-over=X
というパラメータを付けましょう。
例えば、CVSSスコア7以上だけを通知する場合は以下の様なcron設定になります。
前略
# Scan target machines
37 06 * * * sshuser cd /var/vuls/cron && ${HOME}/go/bin/vuls scan -cve-dictionary-dbpath=/var/vuls/dict/cve.sqlite3 -report-text -report-mail -lang=ja -cvss-over=7 >/dev/null 2>&1
もっとメール量を減らして差分だけを知りたい
という場合はこちらの記事が参考になります。
最後に
以上で、脆弱性を自動スキャンしてメール通知する仕組みを構築しました。
前回の記事よりはすっきりした手順になっているかな、と思います。
数々の気付きを下記の記事から得ました。良い記事をありがとうございます。
改めて、@kotakanbe@github さん、良いツールをありがとうございます!