IPAテクニカルウォッチ「脆弱性対策の効果的な進め方(ツール活用編)」に遭遇。
ちょうど脆弱性検査ツールを検証、導入したいと考えていたので実践してみました。
構築環境
- Windows 10 1809
- Docker Desktop 2.0.0.3 (31259)
- WSL(Dockerの操作に利用)
- Docker version 18.06.0-ce
Dockerイメージ取得
docker pull vuls/go-cve-dictionary
docker pull vuls/goval-dictionary
docker pull vuls/gost
docker pull vuls/vuls
作業ディレクトリの作成
mkdir vuls
cd vuls/
mkdir go-cve-dictionary-log goval-dictionary-log gost-log vuls-log
fetch JVN
JVNより1998年から作業年までの脆弱性情報を取得する。
for i in `seq 1998 $(date +"%Y")`; do docker run --rm -it -v $PWD:/vuls -v $PWD/go-cve-dictionary-log:/var/log/vuls vuls/go-cve-dictionary fetchjvn -years $i; done
fetch NVD
NVDより2002年から作業年までの脆弱性情報を取得する。
for i in `seq 2002 $(date +"%Y")`; do docker run --rm -it -v $PWD:/vuls -v $PWD/go-cve-dictionary-log:/var/log/vuls vuls/go-cve-dictionary fetchnvd -years $i; done
fetch OVAL
OSのOVAL情報を取得する。(OSの脆弱性情報のようです)
docker run --rm -it -v $PWD:/vuls -v $PWD/goval-dictionary-log:/var/log/vuls vuls/goval-dictionary fetch-redhat 5 6 7
fetch gost(Go Security Tracker)
RedhatやDebian等で公開された脆弱性情報を所得するようです。
docker run --rm -it -v $PWD:/vuls -v $PWD/gost-log:/var/log/gost vuls/gost fetch redhat after=2016-01-01
Configuration
リモートサーバの脆弱性検査を行います。ここでやることは、SSHで接続できるように準備を行う感じです。
- 鍵の生成
ssh-keygen -t rsa
- 鍵のコピー
# ssh-copy-id xxx@10.64.xx.xx
/usr/bin/ssh-copy-id: INFO: Source of key(s) to be installed: "/root/.ssh/id_rsa.pub"
The authenticity of host '10.64.xx.xx (10.64.xx.xx)' can't be established.
ECDSA key fingerprint is SHA256:y7rfWbg23FBZC2A0SE/qMJtHAMHQGSYsl2qakQUPpP8.
Are you sure you want to continue connecting (yes/no)? yes
/usr/bin/ssh-copy-id: INFO: attempting to log in with the new key(s), to filter out any that are already installed
/usr/bin/ssh-copy-id: INFO: 1 key(s) remain to be installed -- if you are prompted now it is to install the new keys
Password for xxx@10.64.xx.xx:
Number of key(s) added: 1
Now try logging into the machine, with: "ssh 'xxx@10.64.xx.xx'"
and check to make sure that only the key(s) you wanted were added.
- 接続設定のファイル
[servers]
[servers.10-64-xx-xx]
host = "10.64.xx.xx"
port = "22"
user = "xxx"
keypath = "/root/.ssh/id_rsa"
Configtest
このコマンドでできるらしいがうまくいきませんでした。
# docker run --rm -it -v ~/.ssh:/root/.ssh:ro -v $PWD:/vuls -v $PWD/vuls-log:/var/log/vuls vuls/vuls configtest -config=./config.toml
[Feb 23 03:23:43] ERROR [localhost] Error loading ./config.toml, 10-64-xx-xx is invalid. keypath: /root/.ssh/id_rsa not exists
[Feb 23 03:23:43] ERROR [localhost] If you update Vuls and get this error, there may be incompatible changes in config.toml
[Feb 23 03:23:43] ERROR [localhost] Please check README: https://github.com/future-architect/vuls#configuration
次のようなコマンドでコンテナー内の様子を確認したところ、原因は、/root/.ssh
のパーミッションが間違い、中身がない、ことのようです。
# docker run --rm -it -v ~/.ssh:/root/.ssh:ro -v $PWD:/vuls -v $PWD/vuls-log:/var/log/vuls --entrypoint "/bin/ls" vuls/vuls -al /root
total 8
drwx------ 1 root root 4096 Feb 23 08:52 .
drwxr-xr-x 1 root root 4096 Feb 23 08:52 ..
drwxr-xr-x 2 root root 40 Feb 23 01:55 .ssh
# docker run --rm -it -v ~/.ssh:/root/.ssh:ro -v $PWD:/vuls -v $PWD/vuls-log:/var/log/vuls --entrypoint "/bin/ls" vuls/vuls -al /root/.ssh
total 4
drwxr-xr-x 2 root root 40 Feb 23 01:55 .
drwx------ 1 root root 4096 Feb 23 08:52 ..
うまくできないのは、Windows環境でやっているためでした。
参考:Docker Tip #56: Volume Mounting SSH Keys into a Docker Container
対策として、.ssh
を作業ディレクトリにコピーと、魔法のシェルを準備(リモートサーバの接続設定が増えるたびに、.ssh
をコピーする必要がある)
# cp -rp /root/.ssh .
# cat docker-entrypoint.sh
#!/bin/sh
set -e
cp -R /tmp/.ssh /root/.ssh
chmod 700 /root/.ssh
chmod 644 /root/.ssh/id_rsa.pub
chmod 600 /root/.ssh/id_rsa
exec "$@"
以下のようなDockerコマンドで、パーミッションやファイルが届いていることを確認しました。
# docker run --rm -it -v $PWD/.ssh:/tmp/.ssh -v $PWD:/vuls -v $PWD/vuls-log:/var/log/vuls --entrypoint "sh" vuls/vuls /vuls/docker-entrypoint.sh ls -alR /root
/root:
total 12
drwx------ 1 root root 4096 Feb 23 10:31 .
drwxr-xr-x 1 root root 4096 Feb 23 10:31 ..
drwx------ 2 root root 4096 Feb 23 10:31 .ssh
/root/.ssh:
total 20
drwx------ 2 root root 4096 Feb 23 10:31 .
drwx------ 1 root root 4096 Feb 23 10:31 ..
-rw------- 1 root root 1679 Feb 23 10:31 id_rsa
-rw-r--r-- 1 root root 395 Feb 23 10:31 id_rsa.pub
-rwxr-xr-x 1 root root 222 Feb 23 10:31 known_hosts
ようやくConfigtest
が成功
# docker run --rm -it -v $PWD/.ssh:/tmp/.ssh -v $PWD:/vuls -v $PWD/vuls-log:/var/log/vuls --entrypoint "sh" vuls/vuls /vuls/docker-entrypoint.sh vuls configtest -config=./config.toml
[Feb 23 10:32:48] INFO [localhost] Validating config...
[Feb 23 10:32:48] INFO [localhost] Detecting Server/Container OS...
[Feb 23 10:32:48] INFO [localhost] Detecting OS of servers...
[Feb 23 10:32:49] INFO [localhost] (1/1) Detected: 10-64-xx-xx: freebsd 10.2-RELEASE-p28
[Feb 23 10:32:49] INFO [localhost] Detecting OS of containers...
[Feb 23 10:32:49] INFO [localhost] Checking Scan Modes...
[Feb 23 10:32:49] INFO [localhost] Checking dependencies...
[Feb 23 10:32:50] INFO [10-64-xx-xx] Dependencies... No need
[Feb 23 10:32:50] INFO [localhost] Checking sudo settings...
[Feb 23 10:32:50] INFO [10-64-xx-xx] sudo ... No need
[Feb 23 10:32:50] 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
[Feb 23 10:32:50] INFO [localhost] Scannable servers are below...
10-64-xx-xx
Scan
このコマンドらしいがまたしてもエラー
# docker run --rm -it -v $PWD/.ssh:/tmp/.ssh -v $PWD:/vuls -v $PWD/vuls-log:/var/log/vuls -v /etc/localtime:/etc/localtime:ro -e "TZ=Asia/Tokyo" --entrypoint "sh" vuls/vuls /vuls/docker-entrypoint.sh vuls scan -config=./config.toml
docker: Error response from daemon: OCI runtime create failed: container_linux.go:344: starting container process caused "process_linux.go:424: container init caused \"rootfs_linux.go:58: mounting \\\"/etc/localtime\\\" to rootfs \\\"/var/lib/docker/overlay2/c88697346e932555b2d5c786c2c2d550a999a3bb515a3d97bb9da7a74a7a42e1/merged\\\" at \\\"/var/lib/docker/overlay2/c88697346e932555b2d5c786c2c2d550a999a3bb515a3d97bb9da7a74a7a42e1/merged/etc/localtime\\\" caused \\\"not a directory\\\"\"": unknown: Are you trying to mount a directory onto a file (or vice-versa)? Check if the specified host path exists and is the expected type.
/
(ルート)からファイルをとってくることが難しいのかもしれないので、ホームディレクトリにコピーして実行した
# cp -rp /etc/localtime .
# docker run --rm -it -v $PWD/.ssh:/tmp/.ssh -v $PWD:/vuls -v $PWD/vuls-log:/var/log/vuls -v $PWD/localtime:/etc/localtime:ro -e "TZ=Asia/Tokyo" --entrypoint "sh" vuls/vuls /vuls/docker-entrypoint.sh vu
ls scan -config=./config.toml
[Feb 23 10:39:57] INFO [localhost] Start scanning
[Feb 23 10:39:57] INFO [localhost] config: ./config.toml
[Feb 23 10:39:57] INFO [localhost] Validating config...
[Feb 23 10:39:57] INFO [localhost] Detecting Server/Container OS...
[Feb 23 10:39:57] INFO [localhost] Detecting OS of servers...
なんとか実行できました。
PROXY環境下なので、--http-proxy
を追加しました。
# docker run --rm -it -v $PWD/.ssh:/tmp/.ssh -v $PWD:/vuls -v $PWD/vuls-log:/var/log/vuls -v $PWD/localtime:/etc/localtime:ro -e "TZ=Asia/Tokyo" --entrypoint "sh" vuls/vuls /vuls/docker-entrypoint.sh vuls scan -config=./config.toml --http-proxy="xxx.xx.x.xxx:8080"
検査中に、以下のようなコマンドが発行されるようですが、私の環境ではエラーとなりました。
sshで接続先ユーザのログインシェルがborn shell系である前提のコマンドです。(FreeBSDでは、tcshを愛用している私の環境では使えませんでした。仕方なくログインシェルを変更しました)
http_proxy="xxx.xx.x.xxx:8080" https_proxy="xxx.xx.x.xxx:8080" HTTP_PROXY="xxx.xx.x.xxx:8080" HTTPS_PROXY="xxx.xx.x.xxx:8080" pkg version -v
exitstatus: 1
stdout: http_proxy=xxx.xx.x.xxx:8080: Command not found.
ここまでやって、ようやく結果が出力されました。
One Line Summary
================
10-64-xx-xx freebsd10.2-RELEASE-p28 113 installed, 0 updatable
To view the detail, vuls tui is useful.
To send a report, run vuls report -h.
Scan report
- one-line summary
# docker run --rm -it -v $PWD/.ssh:/tmp/.ssh -v $PWD:/vuls -v $PWD/vuls-log:/var/log/vuls -v $PWD/localtime:/etc/localtime:ro -e "TZ=Asia/Tokyo" --entrypoint "sh" vuls/vuls /vuls/docker-entrypoint.sh vuls report -format-one-line-text
<省略>
One Line Summary
================
10-64-xx-xx Total: 230 (High:89 Medium:136 Low:5 ?:0) 0/230 Fixed 113 installed, 0 updatable 0 exploits en: 0, ja: 2 alerts
160-xx-x-xx Total: 1559 (High:508 Medium:939 Low:112 ?:0) 0/1559 Fixed 643 installed 0 exploits en: 15, ja: 19 alerts
その他のエラー
ERROR [160-xx-x-xx] yum-utils is not installed
検査対象のサーバに、yum-utils
がインストールされている必要がある。入れたくないので、オフラインだと宣言して回避
[servers.160-xx-x-xx]
host = "160.xx.x.xx"
port = "22"
user = "xxx"
keyPath = "/root/.ssh/id_rsa"
scanMode = ["fast", "offline"]
scanMode err: Remove offline scan mode, FreeBSD needs internet connection
FreeBSDの場合、pkg audit -F -r -f /tmp/vuln.db
を実行するので、オンライン接続が必須、回避不可
こんなエラーが出ます
pkg: http://vuxml.freebsd.org/freebsd/vuln.xml.bz2: Operation timed out
pkg: cannot fetch vulnxml file
所感
- Dockerで環境が構築できることはすごく楽
- Docker on Windowsは、ハメられた
- リモート端末に対して検査が行えることはGood
- SSHを要求するため、不特定多数の端末を検査する業務ではしんどい
- Windowsが検査できないので、きっと使わない