【Vuls】Linuxサーバの脆弱性を検知してみた part1 (Vulsの構築)
管理していたLinuxサーバが知らぬ間に脆弱性の危機に・・・
何てことがないように脆弱性を検知してくれる仕組みがあると便利ですよね。
ってことでVulsを構築してみました。
リモートのクライアントサーバを検知させる場合、パッケージ情報を送信する方法としてSSHを使ったリモートスキャンモードがあります。
ただ、今回はSSHを使わないサーバモードにします。
こちらだと鍵自体が不要かつ、指定した任意のportさえ通信を許可すればパッケージ情報を送信できるので非常にシンプルでよいですね。
目次
1. 前提
2. Vulsサーバ側の事前準備
3. Goインストール
4. go-cve-dictionaryのインストール
5. goval-dictionaryのインストール
6. Vulsのインストール
7. vulsrepoのインストール
8. Vuls,vulsrepoをsystemd化する
9. 脆弱性検知&確認
1. 前提
【Vulsサーバ側】
サーバ名:vuls-server
EC2インスタンスタイプ:t2.medium
EBSボリューム:16GB
OS:Amazon Linux 2
DB:Sqlite3
Go:ver1.21.1
※後ほどの手順にも記載しますが、インストール途中でプロセスがkillされてしまう、またデフォルトのEBSボリュームだと足りなかったため、Vulsサーバ側だけ少しスペック上げてます。
【Vulsクライアント側】
サーバ名:vuls-client
OS:Amazon Linux 2
EC2インスタンスタイプ:t2.micro
EBSボリューム:8GB
また、Vuls関連のインストール手順は公式ドキュメントを参考に進めていきます。
vuls.io
2. Vulsサーバ側の事前準備
基本設定や必要パッケージをインストールしていきます。
ちなみにVulsクライアント側は脆弱性検知をさせたいので敢えてアップデートせずにそのままにしておきます。
getenforce >Disabled timedatectl set-timezone Asia/Tokyo yum -y update yum -y install git gcc make wget vim
3. Goインストール
vulsはgoで作られているみたいなので、Goをインストールします。
最新版のGoをインストールする場合は、公式サイトで都度確認してください。
go.dev
cd /opt wget https://go.dev/dl/go1.21.1.linux-amd64.tar.gz tar -C /usr/local -xzf go1.21.1.linux-amd64.tar.gz rm -rf go1.21.1.linux-amd64.tar.gz
環境変数の設定をします。
vim /etc/profile.d/goenv.sh export GOROOT=/usr/local/go export GOPATH=/opt/go export PATH=$PATH:$GOROOT/bin:$GOPATH/bin source /etc/profile.d/goenv.sh
4. go-cve-dictionaryのインストール
脆弱性データベースのインストール作業となります。
インストールする脆弱性データべースは、アメリカのNISTが管理しているNVD(National Vulnerability Database)と日本のJPCERT/CCとIPAが共同で管理しているJVN(Japan Vulnerability Notes)となります。
mkdir /var/log/vuls chmod 700 /var/log/vuls mkdir -p $GOPATH/src/github.com/vulsio cd $GOPATH/src/github.com/vulsio git clone https://github.com/vulsio/go-cve-dictionary.git cd go-cve-dictionary make install
mkdir /opt/vuls cd /opt/vuls go-cve-dictionary fetch jvn go-cve-dictionary fetch nvd
前提にも記載しましたが、t2.microのEC2インスタンス上でgo-cve-dictionary fetch nvdを実行すると急にkillされてしまいましたので、個人的にはt2.micro以上のスペックで実行することをオススメします。
5. goval-dictionaryのインストール
OVAL(Open Vulnerability and Assessment Language)情報を取得するためのツールです。詳細は下記サイト参考にいただければ。
www.ipa.go.jp
mkdir -p $GOPATH/src/github.com/vulsio cd $GOPATH/src/github.com/vulsio git clone https://github.com/vulsio/goval-dictionary.git cd goval-dictionary make install ln -s $GOPATH/src/github.com/vulsio/goval-dictionary/oval.sqlite3 /opt/vuls/oval.sqlite3
今回は検知対象のサーバがAmaozon Linux 2ですが、念のためすべて入れておきました。
GitHub - vulsio/goval-dictionary: Build a local copy of OVAL. Server mode for easy querying.github.com
goval-dictionary fetch amazon 1 2 2022 2023
6. Vulsのインストール
ようやくVulsのインストールとなります。
mkdir -p $GOPATH/src/github.com/future-architect cd $GOPATH/src/github.com/future-architect git clone https://github.com/future-architect/vuls.git cd vuls make install
cd /opt/vuls vim config.toml [servers] [servers.localhost] host = "localhost" port = "local"
vuls configtestで成功していればOKです。
[root@vuls-server vuls]# vuls configtest [Sep 23 16:54:11] INFO [localhost] vuls-v0.23.4-build-20230922_223515_70fd968 [Sep 23 16:54:11] INFO [localhost] Validating config... [Sep 23 16:54:11] INFO [localhost] Detecting Server/Container OS... [Sep 23 16:54:11] INFO [localhost] Detecting OS of servers... [Sep 23 16:54:11] INFO [localhost] (1/1) Detected: localhost: amazon 2 [Sep 23 16:54:11] INFO [localhost] Detecting OS of containers... [Sep 23 16:54:11] INFO [localhost] Checking Scan Modes... [Sep 23 16:54:11] INFO [localhost] Checking dependencies... [Sep 23 16:54:11] INFO [localhost] Dependencies ... Pass [Sep 23 16:54:11] INFO [localhost] Checking sudo settings... [Sep 23 16:54:11] INFO [localhost] Sudo... Pass [Sep 23 16:54:11] INFO [localhost] It can be scanned with fast scan mode even if warn or err messages are displayed due to lack of dependent packages or sudo settings in fast-root or deep scan mode [Sep 23 16:54:11] INFO [localhost] Scannable servers are below... localhost
7. vulsrepoのインストール
VulsはCUI上でも検知&検知結果の表示ができますが、やはりWEB上で表示できたほうが見やすいのでvulsrepoをインストールします。
mkdir /opt/vuls/results cd /opt git clone https://github.com/ishiDACo/vulsrepo.git
cd /opt/vulsrepo/server cp vulsrepo-config.toml.sample vulsrepo-config.toml vim vulsrepo-config.toml [Server] rootPath = "/opt/vulsrepo" resultsPath = "/opt/vuls/results" serverPort = "5111"
8. Vuls,vulsrepoをsystemd化する
こちらの記事を参考にVulsとvulsrepoをsystemctl化させます。
qiita.com
vim /etc/systemd/system/vulsrepo.service [Unit] Description=vulsrepo daemon Documentation=https://github.com/usiusi360/vulsrepo [Service] ExecStart = /opt/vuls/vulsrepo/server/vulsrepo-server ExecRestart = /bin/kill -WINCH ${MAINPID} ; /opt/vulsrepo/server/vulsrepo-server ExecStop = /bin/kill -WINCH ${MAINPID} Restart = no Type = simple User = root Group = root [Install] WantedBy = multi-user.target
vim /etc/systemd/system/vuls.service [Unit] Description=vuls daemon Documentation=https://github.com/usiusi360/vulsrepo [Service] WorkingDirectory=/opt/vuls ExecStart = /opt/go/bin/vuls server -listen [プライベートIP]:5515 -to-localfile ExecRestart = /bin/kill -WINCH ${MAINPID} ; /opt/go/bin/vuls server -listen [プライベートIP]:5515 -to-localfile ExecStop = /bin/kill -WINCH ${MAINPID} Restart = no Type = simple User = root Group = root [Install] WantedBy = multi-user.target
systemctl daemon-reload systemctl start vulsrepo vuls systemctl enable vulsrepo vuls systemctl status vulsrepo vuls
以上でVulsサーバ側の構築は完了です。
それではブラウザからアクセスしてみます。
9. 脆弱性検知&確認
最後にvulsクライアントを検知してみましょう。
クライアント側にパッケージ情報を送信する方法はcurlコマンドでPOSTするだけなのですが、検知対象のサーバのOSによってリクエストヘッダが異なります。
せっかくなのでシェルにしておきます。
[root@vuls-client bin]# cat vuls-send.sh #!/bin/bash VULS_SERVER='[プライベートIP]' AMAZON_LINUX_RELEASE=$(awk '{if ($0 ~ /Amazon\ Linux\ release\ 2023/) for (i=4; i<=NF; i++) printf("%s ", $i); else if ($0 ~ /Amazon\ Linux\ 2023/) for (i=3; i<=NF; i++) printf("%s ", $i); else if ($0 ~ /Amazon\ Linux\ release\ 2022/) for (i=4; i<=NF; i++) printf("%s ", $i); else if ($0 ~ /Amazon\ Linux\ 2022/) for (i=3; i<=NF; i++) printf("%s ", $i); else if ($0 ~ /Amazon\ Linux\ release\ 2/) printf("%s %s",$4, $5); else if ($0 ~ /Amazon\ Linux\ 2/) for (i=3; i<=NF; i++) printf("%s ", $i); else if (NF==5) print $5}' /etc/system-release) curl -X POST -H "Content-Type: text/plain" -H "X-Vuls-OS-Family: `awk '{print tolower($1)}' /etc/system-release`" -H "X-Vuls-OS-Release: $AMAZON_LINUX_RELEASE" -H "X-Vuls-Kernel-Release: `uname -r`" -H "X-Vuls-Server-Name: `hostname`" --data-binary "`repoquery --all --pkgnarrow=installed --qf="%{NAME} %{EPOCH} %{VERSION} %{RELEASE} %{ARCH} %{UI_FROM_REPO}"`" http://${VULS_SERVER}:5515/vuls > /dev/null if [ $? -ne 0 ]; then logger 'vuls scan is error.' fi
スクリプトを実行します。
[root@vuls-client bin]# bash vuls-send.sh % Total % Received % Xferd Average Speed Time Time Time Current Dload Upload Total Spent Left Speed 100 113k 0 94355 100 21805 20722 4788 0:00:04 0:00:04 --:--:-- 25512
先ほど送信されたパッケージ情報に対して検知した脆弱性がserverity別に表示されました。
もっと詳細に見ていくと、どのパッケージが検知されたのか、推奨されるパッケージのバージョンも表示されるのはよいですね。