脆弱性検知ツール「Vuls」を試してみた 〜Docker+Vulsctlで簡単インストール/レポートのSlack通知〜

脆弱性検知ツール「Vuls」を試してみた 〜Docker+Vulsctlで簡単インストール/レポートのSlack通知〜
Page content

第一歩はセキュリティの現状把握

管理下の各サーバがどのような脆弱性を内包しているか、サーバ管理者は最新の情報に照らして適時調査して把握しておく必要がある。この調査を簡単に行うためのOSS (オープンソースソフトウェア) な脆弱性検知ツールとして、対象サーバ側にエージェントが不要という「Vuls」を試してみることにした。VulsはIPAのIPAテクニカルウォッチ「脆弱性対策の効果的な進め方(ツール活用編)」に取り上げられてもいる。

本記事でのVulsのインストールは、Vuls公式サイト Vuls · Agentless Vulnerability Scanner for Linux/FreeBSD にある次のドキュメントに沿って進める。

Vulsを動作させるまでの手順

Step-1. ホストとしてUbuntuサーバを用意

Vulsを動作させる実験用のホストとして次のようなスペックの仮想マシンを用意し、Ubuntu Server 22.04 LTSをインストールする。

項目内容備考
OSUbuntu Server 22.04 LTS
CPUx86_64 (amd64), 8coreaarch64 (arm64) 環境でも動作OKでした
メモリ4GBたとえば2GBでは不足でswapが発生、データベース処理が苦しそう
ストレージ32GBDBファイル (sqlite3) のサイズが数GBに達する模様
ユーザ名TESTUSER

Step-2. Setup Docker (Rootless)

ホストではDockerが動作している必要がある。Dockerの環境構築で楽するためにスクリプトでインストールする。

$ curl -fsSL https://get.docker.com -o get-docker.sh
$ sudo sh ./get-docker.sh --dry-run
# Executing docker install script, commit: a8a6b338bdfedd7ddefb96fe3e7fe7d4036d945a
apt-get update -qq >/dev/null
DEBIAN_FRONTEND=noninteractive apt-get install -y -qq apt-transport-https ca-certificates curl >/dev/null
mkdir -p /etc/apt/keyrings && chmod -R 0755 /etc/apt/keyrings
curl -fsSL "https://download.docker.com/linux/ubuntu/gpg" | gpg --dearmor --yes -o /etc/apt/keyrings/docker.gpg
chmod a+r /etc/apt/keyrings/docker.gpg
echo "deb [arch=amd64 signed-by=/etc/apt/keyrings/docker.gpg] https://download.docker.com/linux/ubuntu jammy stable" > /etc/apt/sources.list.d/docker.list
apt-get update -qq >/dev/null
DEBIAN_FRONTEND=noninteractive apt-get install -y -qq docker-ce docker-ce-cli containerd.io docker-compose-plugin docker-ce-rootless-extras docker-buildx-plugin >/dev/null

$ time sudo sh ./get-docker.sh
(snip)
To run Docker as a non-privileged user, consider setting up the
Docker daemon in rootless mode for your user:

    dockerd-rootless-setuptool.sh install

Visit https://docs.docker.com/go/rootless/ to learn about rootless mode.
(snip)
real	0m27.630s
user	0m0.002s
sys	0m0.007s

Dockerはrootless modeで使ってみる。指示に沿ってDockerのインストールを進めると、今回の環境の場合はuidmapパッケージが必要とわかったので併せてインストールする。

$ dockerd-rootless-setuptool.sh install
[ERROR] Missing system requirements. Run the following commands to
[ERROR] install the requirements and run this tool again.

########## BEGIN ##########
sudo sh -eux <<EOF
# Install newuidmap & newgidmap binaries
apt-get install -y uidmap
EOF
########## END ##########

$ sudo apt-get install -y uidmap
$ dockerd-rootless-setuptool.sh install
(snip)
[INFO] Installed docker.service successfully.
[INFO] To control docker.service, run: `systemctl --user (start|stop|restart) docker.service`
[INFO] To run docker.service on system startup, run: `sudo loginctl enable-linger TESTUSER`

[INFO] Creating CLI context "rootless"
Successfully created context "rootless"
[INFO] Use CLI context "rootless"
Current context is now "rootless"

[INFO] Make sure the following environment variables are set (or add them to ~/.bashrc):

export PATH=/usr/bin:$PATH
Some applications may require the following environment variable too:
export DOCKER_HOST=unix:///run/user/1000/docker.sock

上記の出力結果 (の趣旨) を確認し、必要な環境変数を~/.bashrcに追記しておく。

$ diff ~/.bashrc.original ~/.bashrc
117a118,120
> 
> # CUSTOM
> export DOCKER_HOST=unix:///run/user/$(id -u)/docker.sock

ユーザの実行権限でDockerが起動していることを確認する。

$ systemctl --user status docker.service
● docker.service - Docker Application Container Engine (Rootless)
     Loaded: loaded (/home/TESTUSER/.config/systemd/user/docker.service; enabled; vendor preset: enabled)
     Active: active (running) since Fri 2023-04-07 14:33:37 UTC; 4min 21s ago
(snip)

追記 [2023-10-20]: システム起動時にrootless modeのDockerを起動

システム起動時にrootless modeのDockerを起動させるためには、次のコマンドを実行する。

$ sudo loginctl enable-linger TESTUSER

Step-3. Clone Vulsctl

「Easy setup tool for Vuls」であるvulsctlをGitHubからクローンする。

$ git clone https://github.com/vulsio/vulsctl.git
$ cd vulsctl

Step-4. Fetch Vulnerability Databases

クローンしたリポジトリ内のdockerディレクトリに移動して、update-all.shを実行する。脆弱性データベースの取得完了までは数十分の時間がかかる。

$ cd docker
$ time ./update-all.sh
(snip)
real	22m27.931s
user	0m3.153s
sys	0m2.466s

Vulsを使って脆弱性をスキャンする手順

Step-1. config.tomlの準備

スキャンの対象サーバを定義するファイルとして、リポジトリ内のdockerディレクトリにconfig.tomlを作成する。対象サーバはファイル内に複数記述することができる。リモートの対象サーバに対しては公開鍵認証を使ったSSHログインが行われるので、その際にyes/noのキー入力を要求されないように、事前にSSHログインを手動で行っておく (=ホストの~/.ssh/known_hostsに対象サーバを登録しておく)。

$ cat config.toml 
[default]
user     = "TESTUSER"
port     = "22"
keyPath  = "/root/.ssh/id_ed25519"
scanMode = ["fast"]

[servers]

## localhostをスキャンする例
[servers.localhost]
host     = "127.0.0.1"
port     = "local"

## リモートサーバをスキャンする例
[servers.server1]
host     = "server1.example.com"
port     = "1234"

[servers.server2]
host     = "server2.example.com"

Step-2. configのテスト

脆弱性スキャンを実施する前に、configの内容をテストする。ちなみに上記の「known_hostsへの登録」を行っていないサーバがスキャン対象にある場合、本テストの段階でエラーが発生してくれるので対応する。

## vuls configtest の代わりとして
$ ./config-test.sh

Step-3. 脆弱性スキャンの実行とレポートの確認

次の3つのコマンドを実行すると、脆弱性スキャンが実施されてresultsディレクトリにスキャン結果が保存され、レポートが確認できるTUI (Terminal-based User Interface) が表示される。

$ ./scan.sh
$ ./report.sh
$ ./tui.sh

Web UIでレポートを確認する場合は、tui.shの代わりにvulsrepo.shを実行する。

$ ./vulsrepo.sh 

$ docker ps
CONTAINER ID   IMAGE               COMMAND             CREATED         STATUS         PORTS                                       NAMES
04f95db27414   ishidaco/vulsrepo   "vulsrepo-server"   6 minutes ago   Up 6 minutes   0.0.0.0:5111->5111/tcp, :::5111->5111/tcp   suspicious_almeida

その後にhttp://DockerホストのIPアドレス:5111/ へウェブブラウザでアクセスすると、Vulsのレポートを表や棒グラフの形で見ることができる。ちなみにVulsRepoのオンラインデモが https://monocosel.jp/vulsrepo/ で公開されているので、事前に実際の操作感を確認できる。

実用編: CVSSスコアが一定以上の最新レポートをSlack通知

公式ドキュメントの次の2つを参照すると、

ずばり私がやりたい、「定期的に、“CVSSスコアが7.0以上 (深刻度が重要以上) のCVEに関してのみ、かつ、unfixed (未修正) なものは除外した内容”をSlack通知する」仕組みを実現するためには、まずはSlack https://api.slack.com/ からIncoming WebHooksを使うAppを新規追加して (参考ページ)、config.tomlに次のようなWebhook設定を追加し、

## config.tomlへの追加分
[slack]
hookURL  = "https://hooks.slack.com/services/XXXXXXXXX/XXXXXXXXXXX/XXXXXXXXXXXXXXXXXXXXXXXX"
channel  = "#alert_vuls"
authUser = "vulsrepo"

さらに次の3つのコマンドを定期的にcronで実施すれば良い。

$ ./update-all.sh
$ ./scan.sh
$ ./report.sh -cvss-over=7.0 -ignore-unfixed -to-slack

感想

サーバに対する脆弱性スキャンを専用エージェントなしで、サーバ台数に関わらず一箇所から行えるVuls + Vulsctlというツールは、「なぜ今まで手元になかったのか」と逆に言いたくなるくらい必須の存在になりうると感じている。スケーラブルだし、良いものですね。(そしてもちろん、脆弱性対応はパッチを当てる運用までが大切!)

参考画面キャプチャ

参考リンク

Vlus

その他