【FutureVuls応用編】NFSを活用したリモートスキャン

FutureVuls開発チームのLEEです。

今回は、下記のような環境を想定してNFSを活用しスキャン結果を集約・アップロードする方法について紹介します。

  • インターネットにアクセスできるサーバが限定されている(インターネットにアクセスできるサーバは一部のみ)
  • SSHパスワード認証の環境なのでFutureVulsのリモートスキャンが適用できない環境(FutureVulsはセキュリティ面の理由により公開鍵認証のみサポート)

ローカルスキャンとリモートスキャンの制約

FutureVulsのローカルスキャンではスキャナプログラムが各スキャン対象サーバにインストールされ、各スキャン対象サーバから直接FutureVulsに対して結果をUploadします。

インターネットにアクセスできるサーバが限定されているような環境ではリモートスキャンがおすすめです。リモートスキャンはSSH接続により1台のサーバに結果を集約してアップロードできます。

ただし、リモートスキャンにも制約はあります。

image1

FutureVulsのリモートスキャンではスキャナプログラムを1つのスキャン実行サーバにインストールします。
スキャン実行サーバから他のスキャン対象サーバにSSH経由でスキャンをかけ、その結果をアップロードします。
しかしリモートスキャンモードでは、スキャン実行サーバとスキャン対象サーバ間にはSSH接続ができることと、公開鍵認証が前提となっています。

※ FutureVulsではセキュリティ面の理由によりSSHのパスワード認証には対応していません。

NFSを用いたスキャン結果の集約と一括Uploadの方法

image2

もしSSH通信が使えない場合やローカルスキャンを適用できない環境などには、NFSを活用すればリモートスキャンのように結果のJSONを1つのサーバに集約し、そのサーバからUploadできます。
今回紹介するNFSによる方法では、スキャン対象サーバが自らローカルスキャンをした後、その結果はNFSにより共有され、1つのサーバに集約されます。
この場合、各サーバは以下のように動作します。

スキャン対象サーバ

各スキャン対象サーバにはローカルスキャンと同じように、スキャナがインストール、スキャンされますが、アップロードはしません。
また、スキャン実行時のスキャン結果の出力先はNFSをマウントしたディレクトリにしておきます。

1
2
$ cd /opt/vuls-saas
$ ./vuls scan -ips -results-dir {NFS_MOUNT_DIR}

スキャナサーバ → アップロードサーバ

結果をFutureVulsにアップロードするサーバも同じくNFSをマウントし、以下のコマンドで共有されたスキャン結果をアップロードします。

1
2
$ cd /opt/vuls-saas
$ ./vuls saas -results-dir {NFS_MOUNT_DIR}

AWS上で試してみる

image3

今回はAmazonEFS(NFS)をEC2インスタンスにマウントすることでスキャン結果の集約とアップロードを実現してみます。

AmazonEFSの準備

まず、AmazonEFSからマウントするファイルシステムを作ります。
作成されたファイルシステムのネットワークタブから、各AZのセキュリティグループにはNFSのポート(2049)が開いていることを確認してください。

EC2インスタンスの準備

同じVPC上にアップロードサーバとスキャン対象サーバの2つのEC2インスタンスを用意します。

FutureVulsスキャナ設定

アップロードサーバとスキャン対象サーバの両方にFutureVulsの「実機をスキャン」を参考しスキャナをインストールします。

NFSマウント

アップロードサーバとスキャン対象サーバの両方に先程作成したAmazonEFS(NFS)をマウントします。
マウント先はスキャン結果のデフォルトパスである/opt/vuls-saas/resultsを指定します。

今回使ったインスタンスはAmazonLinuxなので、nfs-utilsをインストールしますが、他のOSの場合はEFSマウントヘルパーなどこちらを参考に適宜インストールしてください。

1
2
$ sudo yum install -y nfs-utils
$ sudo mount -t nfs4 -o nfsvers=4.1,rsize=1048576,wsize=1048576,hard,timeo=600,retrans=2,noresvport {EFS_ID}.efs.{REGION}.amazonaws.com:/ /opt/vuls-saas/results

スキャンとアップロード

デフォルト設定のFutureVulsのスキャナは./vuls-saas.shでスキャンとアップロードの両方を行いますが、
この方法ではその2つのプロセスを以下のように分割します。

スキャン対象サーバ上でスキャン

以下のコマンドでローカルスキャンを実行します。

1
$ ./vuls scan -ips

まだFutureVulsにアップロードしてないので、スキャン結果はマウント先のNFSの領域である/opt/vuls-saas/resultsに残ります。

アップロードサーバ上でアップロード

アップロードサーバ上でマウントしているNFS領域である/opt/vuls-saas/resultsを見ると、先程のスキャン結果がNFSにより共有されていることがわかります。
以下のコマンドでアップロードし、FutureVulsコンソール上でスキャン結果を確認します。

1
$ ./vuls saas

注意事項

crontabの調整

FutureVulsで提供している標準のインストーラを実行すると、スキャンとアップロードを定期実行するようにCRONの設定ファイル「/etc/cron.d/vuls-saas-scan」に自動登録します。
今回の応用編ではスキャン対象サーバとアップロードサーバ上でそれぞれ別のコマンドを実行する必要があるので、標準インストーラが設定したCRONの内容を適宜変更してください。

アップロードコマンド

今回、私たちはただ一つのサーバをスキャンしましたが、複数のサーバをスキャンする際には注意が必要です。
複数のサーバをスキャンすると、それぞれのサーバから得られた結果は「results」フォルダ内に、それぞれの日付ごとのディレクトリとして保存されます。そして、アップロードサーバで./vuls saasコマンドを実行すると、’results’フォルダの中で最も新しい日付のディレクトリにあるJSONファイルだけがアップロードされます。アップロードに成功すると、その日付のディレクトリは自動的に削除されます。

再度./vuls saasコマンドを実行すると、今度はその時点で最新の日付のディレクトリがアップロードされ、そのディレクトリも削除されます。つまり、resultsフォルダ内に複数の日付ディレクトリがある場合、ディレクトリの数だけ./vuls saasコマンドを実行する必要があります。

複数のサーバのスキャン結果がアップロードサーバ上に滞納しないようにするには、アップロードサーバのCRON設定を変更し、より頻繁に結果をアップロードするように調整してください。

アップロードサーバのconfig.tomlの設定

スキャン結果をアップロードすると、config.tomlには以下のように対象サーバのUUIDが追加されていることがわかります。

1
2
3
4
5
6
7
8
9
...
[servers]

...

[servers.ip-192-168-0-xxx_ap-northeast-1_compute_internal]
host = "192.168.0.xxx" # <- 生成されない、2回目(UUID生成後)以降アップロードに必要
[servers.ip-192-168-0-xxx_ap-northeast-1_compute_internal.uuids]
ip-192-168-0-xxx_ap-northeast-1_compute_internal = "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx"

これはスキャン結果ファイルの中の(対象)サーバ名が、アップロードサーバのconfig.tomlには記載がなかったため、改めて追加されたものです。追加されたUUIDは、本来の対象サーバのconfig.tomlのものとは異なりますので、アップロードの前に予め設定しておくなど、注意が必要です(FutureVulsコンソールにはアップロードサーバ上のUUIDが登録されます)。

2回目(UUID生成後)のアップロードからは、対象サーバ設定にhostの指定が必要ですので、適当なIPアドレスを指定してください(スキャン時に使われる項目ですので、アップロードには影響しません)。