はじめに#
自分の管理下にある仮想マシンの脆弱性を継続的に管理するのは義務だと思うんです。
New Relicなどの有償のサービスであればメトリクス収集でagentをサーバに仕込んでおけば、追加料金で脆弱性管理までできるみたい。
Get started with Vulnerability Management
自宅サーバにそんなお金はかけていられないので無料で脆弱性が確認できるツールを調べたものの、SBOM管理関連でも語られることの多いTrivyやsyft&grypeはどちらかといえばコンテナimageを対象にしているようで、仮想マシン自体のスキャンという文脈でいうと外れていそうだった。
CiscoがリードしているOpenClarityプロジェクトのvmclarityも気になったが、他の仮想マシンからの脆弱性を収集するところができるかわからなかった。(GitHubのReleaseにてvmclarity-cliが配布されているので、cliで取得した脆弱性情報を管理サーバに送信することはできるかも・・・)
そんななか、国産OSSのVulsはLinuxの脆弱性をスキャンできるようで、remote scanなどにも対応しているとのことで試してみる。
ただ、検出結果の可視化ツールであるVulsRepoは今どきじゃない見た目なのでなんとかGrafanaで可視化したいと思った。
(SaaSとしてFutureさんが商売をしているのであまり力を入れてもしょうがないところなんでしょうけど)
MITライセンスで公開されているprometheus-vuls-exporterを使ってGrafanaのダッシュボードで確認することを目標とする
Vulsのスキャン結果 → prometheus-vuls-exporter → Prometheus → Grafana
時系列データのPrometheusで脆弱性情報を管理するのもナンセンスな気もするので自己責任で。
2024/04/01 追記#
その後New Relicを使い始めたため、Vulsでの脆弱性スキャンはやめてしまいました。
Trivyでも trivy rootfs
にてホストOSの脆弱性スキャンができるのでそちらをおすすめします。
New Relicでメトリクスとログを収集してみた
1. Vulsのインストール#
Prometheusが動いているサーバにVulsをインストール
他サーバへSSHしてスキャンするので専用のvulsユーザを作成しました
Vulsを実行するときにIPアドレスにて接続するため、自身の公開鍵をauthorized_keysに書き込んでおく
1
2
3
4
| sudo adduser vuls
sudo -i -u vuls
sh-keygen -t ed25519
cat id_ed25519.pub >> authorized_keys
|
以下のドキュメントを参考にvulsctlをgit clone
してvulsが動くようにする
exporterはresultのディレクトリが見れればよいため、dockerでもHostOSへのインストールでもどちらでも可
install-with-vulsctl
config.toml
1
2
3
4
5
6
7
8
9
| [servers]
[servers.hostos]
host = "<hostname>"
port = "22"
user = "vuls"
# if ssh config file exists in .ssh, path to ssh config file in docker
sshConfigPath = "/root/.ssh/config"
# keypath in the Vuls docker container
keyPath = "/root/.ssh/id_ed25519"
|
指定したresultフォルダに脆弱性が出力されることを確認しておく
2. cronにて定期実行する#
以下のshを作成したうえでcronに登録している
とても雑なのでもっと良い書き方あると思います。
最後にchmodをしているのは別ユーザで動かしているexporterで結果を読み取るため
※注意 後述するexporter起動中に新たなresultが生成されると、exporterが正しく動かなくなる仕様?不具合がありました。こちらのスクリプトの最後にexporterを再起動させる記述があってもよいかも
1
2
3
4
5
6
7
8
| #!/bin/bash
VULS_PATH="/home/vuls/vulsctl/install-host"
cd $VULS_PATH
bash ./update-all.sh
vuls scan
vuls report -ignore-unfixed
chmod +xr -R ./results
|
3. prometheus-vuls-exporterを設定する#
以下のレポジトリのexporterを使用させていただく
iakovmarkov/prometheus-vuls-exporter
作者の方が386アーキテクチャのものしかReleaseしておらずamd64環境では動作しなかったので、Golangをインストールしてビルドするか、Dockerfileを使ってコンテナイメージを作成する
3.1 コンテナイメージを使用する場合#
私がビルドしたイメージはDockerHub に公開しているのでそちらを使用してもよいです。
Dockerfile
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
| FROM golang:1.22 AS build-stage
WORKDIR /app
COPY go.mod go.sum ./
RUN go mod download
COPY . ./
RUN CGO_ENABLED=0 GOOS=linux go build -o /prometheus-vuls-exporter
# Deploy the application binary into a lean image
FROM gcr.io/distroless/base-debian12 AS build-release-stage
WORKDIR /
COPY --from=build-stage /prometheus-vuls-exporter /prometheus-vuls-exporter
EXPOSE 8080
USER nonroot:nonroot
ENTRYPOINT ["/prometheus-vuls-exporter"]
|
docker-compose.yml
1
2
3
4
5
6
7
8
9
10
11
| prometheus-vuls-exporter:
image: ryomaholiday/prometheus-vuls-exporter:0.1.4
container_name: prometheus-vuls-exporter
restart: unless-stopped
command: ["--reports_dir", "/results"]
expose:
- 8080
volumes:
- /home/vuls/vulsctl/install-host/results:/results
networks:
- monitoring
|
3.2 ビルドしたものを使用する場合#
Golangをインストールした環境にて
1
2
3
4
5
| cd ./src/
go build .
cp prometheus-vuls-exporter /usr/bin/
sudo chmod 755 /usr/bin/prometheus-vuls-exporter
go run . --reports_dir "/home/vuls/vulsctl/install-host/results"
|
Systemd Serviceの例
1
2
3
4
5
6
7
8
9
10
11
12
13
| [Unit]
Description=prometheus vuls exporter
Documentation=https://github.com/iakovmarkov/prometheus-vuls-exporter
[Service]
Restart=always
ExecStart=/usr/bin/prometheus-vuls-exporter --reports_dir "/home/vuls/vulsctl/install-host/results"
ExecReload=/bin/kill -HUP $MAINPID
TimeoutStopSec=20s
SendSIGKILL=no
[Install]
WantedBy=multi-user.target
|
deamon-reloadしてサービスを起動する
1
2
3
| sudo systemctl daemon-reload
sudo systemctl enable prometheus-vuls-exporter
sudo systemctl start prometheus-vuls-exporter
|
4. Prometheusの設定#
prometheus.yml
1
2
3
4
5
6
| - job_name: 'vuls'
scrape_interval: 1m
metrics_path: /metrics
static_configs:
- targets:
- 'prometheus-vuls-exporter:8080'
|
5. Grafanaにて確認#
作者さんのダッシュボードを元に
DataLinkにhttps://nvd.nist.gov/vuln/detail/${__data.fields.cveID}
などを使用するといい感じになります。
おわりに#
今どきはコンテナビルド時のスキャンやk8s上のコンテナ脆弱性管理が流行りですよね。今回調べた中でもsnykや、trivy-operatorなどなど。
クラウドでIaaS利用するならクラウドベンダー側で用意された脆弱性管理サービスを使うので、こういうニーズは減っていくのはわかるけど・・・ちゃんとお金払えってことですよね。