Serverless Vuls(AWS Lambda)でスキャンできる台数の上限を調べてみた

投稿者: | 2017/12/18

本記事はVuls Advent Calendar 2017 18日目の記事です。
Vuls祭り #3でAWS Lambdaを使ったVulsスキャン(Serverless Vuls)についてのLTをしたところ、「何台までのサーバ台数ならスキャンできますか?」という質問をTwitterでもらいました。
台数の上限に関するテストをしていなかったので、この機会(?)にサーバ台数の上限にチャレンジしてみました。

環境

  • Vuls v0.4.2
  • AWS Lambda 3008MB、最大5分
  • スキャン対象
    • Amazon Linux 2015.09 (ami-383c1956)
    • インスタンスタイプ: t1.micro, t2.nano, t2.micro, t2.small, t2.medium, m3.medium
    • EC2起動数の上限(オンデマンド:20, スポットインスタンス: 50)があるため、インスタンスタイプをばらしてスキャンしました。

実行内容

Lambda関数内で以下のことを行います。

1. ec2-vuls-config

EC2タグからスキャン対象を選定し、コンフィグファイルに書き出します。

./ec2-vuls-config --config ./config.toml --out /tmp/config.toml

2. vuls configtest

コンフィグチェックします。

./vuls configtest -config=/tmp/config.toml -log-dir=/tmp/vuls -ssh-native-insecure

3. vuls scan

メインです。

./vuls scan -config=/tmp/config.toml -results-dir=/tmp/results -log-dir=/tmp/vuls -ssh-native-insecure

4. vuls report -format-one-line-text

ヒットした脆弱件数を出力します。

./vuls report -lang=ja -config=/tmp/config.toml -results-dir=/tmp/results -log-dir=/tmp/vuls -format-one-line-text -cvedb-type=mysql -cvedb-url=hogehoge -refresh-cve

5. vuls report -to-s3

スキャン結果をS3に保存します。

./vuls report -lang=ja -config=/tmp/config.toml -results-dir=/tmp/results -log-dir=/tmp/vuls -to-localfile -format-json -to-s3 -aws-region=ap-northeast-1 -aws-s3-bucket=S3_BUCKET -cvedb-type=mysql -cvedb-url=hogehoge -refresh-cve

準備

スキャンするためのサーバ環境や、Vulsスキャンのセットアップを行う必要がありますが、CloudFormationを公開していますので、これで環境構築します。

ohsawa0515/serverless-vuls

サンプル用VPC、EC2インスタンスの構築

まずは、スキャン対象のサーバ環境を構築します。
CloudFormationのスタック作成画面で sample_vpc.yml を選択し、S3にアップロードします。

cloudformation-setting-1

スタック名(何でも良い)、キーペア(デフォルトのEC2インスタンスで必要)、Vulsスキャンに使用するSSH公開鍵を入力します。

cloudformation-setting-2

「次へ」を押していき、CloudFormationスタックを作成します。
無事作成が完了すると、「出力」タブに生成されたイベントソースが表示されます。
これらの値は、次のCloudFormationで使うのでメモしておきます。

cloudformation-setting-3

Serverless Vuls環境

CloudFormationスタック作成画面で、serverless_vuls.ymlを選択し、S3にアップロードします。

cloudformation-setting-4

必要なパラメータを入力します。サブネットID、セキュリティグループID、KMSのIDなどは先ほどメモしたパラメータをコピペします。

cloudformation-setting-5

スタックの作成が無事完了すると、「出力」タブにスキャンレポートが保存されるS3バケット名が表示されています。

cloudformation-setting-7

go-cve-dictionary の実行

スキャン前に脆弱性情報をDBに貯めておきます。
Step Functionsに飛んで、FetchVulnerabilityDataFromNVDandJVN-xxxxx(画面上は文字が切れていますが・・・)を選択し、「新しい実行」をクリックすると実行されます。完了までに約1時間かかるので気長に待ちましょう。
(goval-dictionaryはまだ未対応で今後対応していきます)

run_fetch_nvd

検証

1台

まずは1台だけスキャンしました。
結果はGistにアップロードしています。

スキャンは1秒で終わっています。激速。vuls report -format-one-line-textも数秒で終わっています。vuls report -to-s3 はS3にアップロードするのが遅いのか、約3分もかかっており、5分というタイムリミットに対して意外とギリギリで終わりました。

30台

30台でやってみました。

スキャン成功です。
スキャン完了まで3秒と超速です。一部のサーバでエラーが出てますが、恐らく設定ミスだと思われるので無視。
すべて同じAMIで生成したのに、検知した件数と [Reboot Required] が付いているサーバが異なるのは不思議ですね。

70台

一気に70台までやってみます。本当は100台までいきたかったのですが、AWSの制限により、オンデマンド20台、スポットインスタンス50台の計70台が限界でした。今回の件と関係ありませんが、複数インスタンスを一気に起動できるSpot FleetとEC2 Template機能が便利ですね。

スキャンが失敗しました。
Too many connectionsで落ちており、vuls report するためにDB接続数が単純に増加していったのだと思います。RDS(MySQL)は db.t2.micro でかなり小さいインスタンスなので、デフォルトで設定されているMax Connectionの値が小さかったのだと思います。
コネクションエラーもありますが、レポート出力する途中で時間切れになってしまったのが最大の要因でした。
スキャンスピードは変わらず3秒程度で完了していました。

結論

今回は時間がなく、中途半端な検証になってしまいましたが、以下のような結論になりました。

  • 30台までは確実にスキャン&レポート出力できる。それ以上はレポート出力がボトルネックになる
  • レポート出力はスキャン対象一台ずつに対してDB接続しているため、Max Connectionのパラメータを上げることで上限を引き上げることができるが限界がある
  • スキャン自体のスピードはとても早く数百台であっても問題ない

次回機会があれば、EC2インスタンスの上限緩和とRDSのチューニングを行って、さらに限界まで挑みたいと思います。

コメントを残す

メールアドレスが公開されることはありません。 * が付いている欄は必須項目です

*

このサイトはスパムを低減するために Akismet を使っています。コメントデータの処理方法の詳細はこちらをご覧ください