SSTエンジニアブログ

SSTのエンジニアによるWebセキュリティの技術を中心としたエンジニアブログです。

SecurityJAWSのその先。AWS WAFのログ解析基盤の料金を算出してみた。

はじめに

事業開発部と研究開発部に属している宇田川です。

2018/11/08に開催されたSecurity-JAWSで質問がありましたAWS WAFのログ解析基盤の料金を算出してみました。

ちなみに、AWS WAFのログ解析基盤はこのような構成です。

f:id:woodykedner:20181025131507j:plain

で、構築内容は下記を見ていただければと思います。

techblog.securesky-tech.com

techblog.securesky-tech.com

なお、AWS WAFをCloudFrontにデプロイすることが多いことから、北バージニアリージョンでの算出内容となります。
他のリージョンの場合もS3とkinesis data firehoseの従量課金が多少違うだけで、その他のサービスはリージョン間で違いはありませんでした。
全体の料金は大きな差はなかったので、他のリージョンでも参考になると思います。

また、本記事の料金は、2018年11月時点のものとなります。
料金が変わったり、無料枠の拡大はよくあることなので、これを踏まえておいていただければと思います。

AWS サービスごと試算

AWS WAF

まずはAWS WAFから見ていきます。

aws.amazon.com

ウェブ ACL あたり 5 USD/月
ウェブ ACL ごとに 1 ルールあたり 1 USD/月
100 万ウェブリクエストごとに 0.60 USD

例として、OWASPT TOP 10用のルールセットを使うことにします。
Use AWS WAF to Mitigate OWASP’s Top 10 Web Application Vulnerabilities

  • webACL 5 USD/月
  • ルール 10 USD/月

リクエスト数は試算として、月間1万PVあるページでページ当たりのリクエスト数が80と置いています。(完全に決めです。)
なので、月間80万リクエストなので、0 USDとなります。

小計 15 USD/月。

Amazon Kinesis Data Firefose

次は、Kinesis Data Firefoseです。

aws.amazon.com

料金は取り込まれたデータの量に基づきます。 データの量は、このサービスに送信したデータレコードの数に、直近の 5 KB の倍数に切り上げた各レコードのサイズを乗算した値として計算されます。 例えば、データが8KBの場合、直近の 5 KB の倍数の10KBとして計算されます。

kinesis Data firefoseを流れるのは、AWS WAFのログとなりますので、ログのサイズを出したいと思います。 下記、ドキュメントのExample Logから取得します。

docs.aws.amazon.com

無駄な空白を削除しまして、1行にしたバイト数が1058バイトでした。

これをkinesisの料金の計算例にならい、計算していきます。

1058 B のレコードサイズを直近の 5 KB の倍数に切り上げると、5 KB になります。

取り込まれたデータ (GB/月) = 800,000 request/月 * 5KB /request = 4000000 / (1024*1024) = 3.814697266

北バージニアの場合、最初の 500 TB/月 0.029 USDなので、

3.814697266 GB /月 * 0.029 USD / GB = 0.111 USD / 月

と、いうことで、小計 0.111 USD / 月 です。

AWS Lambda

次は、Lambdaです。

aws.amazon.com

Lambdaは、下記2つについて料金がかかります。

  • Lambda関数のリクエスト数
  • Lambda関数のメモリに応じた実行時間

そして、Lambda には下記の無料利用枠があります。

1 か月に 1,000,000 件の無料リクエストおよび 400,000 GB/秒のコンピューティング時間が含まれます。

リクエスト数の方から片づけます。
毎月最初の 1,000,000 件は無料ということで、月間80万リクエスト毎にLambdaが動いても無料枠で収まります。
超えたとしても、 1,000,000 件のリクエストにつき 0.20 USDなので、さほど気にする金額ではないと思います。

次はメモリに応じた実行時間です。 料金の算出に必要なのが、Lambda1回あたりの実行時間と月のリクエスト数とです。

まず関数の実行時間を出しておきます。 下記は、弊社のルール検知率の測定時にcloudwatchのログに出力されたLambdaの実行ログからREPORT の部分を抜き出したものです。 課金対象となるのが、Billed Durationの部分です。
ランダムに10回分の結果を抽出しました。

REPORT RequestId: ....   Duration: 1414.05 ms    Billed Duration: 1500 ms Memory Size: 128 MB    Max Memory Used: 59 MB  
REPORT RequestId: ....  Duration: 1417.51 ms    Billed Duration: 1500 ms Memory Size: 128 MB    Max Memory Used: 59 MB  
REPORT RequestId: ....  Duration: 2082.14 ms    Billed Duration: 2100 ms Memory Size: 128 MB    Max Memory Used: 59 MB  
REPORT RequestId: ....  Duration: 1402.28 ms    Billed Duration: 1500 ms Memory Size: 128 MB    Max Memory Used: 59 MB  
REPORT RequestId: ....  Duration: 1361.38 ms    Billed Duration: 1400 ms Memory Size: 128 MB    Max Memory Used: 59 MB  
REPORT RequestId: ....  Duration: 1322.44 ms    Billed Duration: 1400 ms Memory Size: 128 MB    Max Memory Used: 59 MB  
REPORT RequestId: ....  Duration: 1890.73 ms    Billed Duration: 1900 ms Memory Size: 128 MB    Max Memory Used: 59 MB  
REPORT RequestId: ....  Duration: 3990.06 ms    Billed Duration: 4000 ms Memory Size: 128 MB    Max Memory Used: 77 MB  
REPORT RequestId: ....  Duration: 2662.44 ms    Billed Duration: 2700 ms Memory Size: 128 MB    Max Memory Used: 77 MB  
REPORT RequestId: ....  Duration: 1521.11 ms    Billed Duration: 1600 ms Memory Size: 128 MB    Max Memory Used: 77 MB  

Billed Durationの平均が 1960 msとなったのでこの値を使用します。

次にリクエスト数ですが、kinesis Data FirehoseからLambdaにログデータが流れてくる際、ログが1つ1つに分かれてではなく、ある程度、まとまって流れてきます。 このあたり、予測できないので、WEBのリクエスト分800,000回実行されたものとします。

それでは、計算します。 関数に128MBのメモリ量を割り当てて800,000回実行し、毎回の実行時間が 1960 ミリ秒間 なので、

合計コンピューティング (秒) = 800000 * 1.960 = 1568000 秒

合計コンピューティング (GB-秒) = 1568000 秒 * 128MB / 1024 = 196000 GB-秒

合計コンピューティング – 無料利用枠 = 1 か月の請求コンピューティング秒

196000 GB-秒 – 400,000 GB-秒の無料利用枠 = -204000 GB-秒

この時点でマイナスで無料枠に収まるので、Lambdaは料金がかかりません。

よって、小計 0 USDとなります。

参考までに、この関数でLambdaの料金が発生する実行回数を出してみます。

x * 1.960 * 128 / 1024 – 400,000 = 0 250.88x = 400,000 * 1024 x = 409600000 / 250.88 x = 1,632,653.061

この関数でLambdaを1,632,654以上実行すると料金がかかってきます。 と言っても、

(1,632,654 * 1.960 * 128 / 1024) – 400,000) = 0.23

で、単価を掛けると、

0.23 * 0.00001667 USD = 0.0000038341 USD

ほとんど無視していい金額ですが、この場合、リクエスト数も1,000,000超えており、1,000,000 件のリクエストにつき 0.20 USDなので、足して、

0.2000038341 USD

となります。

Amazon S3

aws.amazon.com

S3 標準ストレージでカスタムログ、オリジナルログ保存用のs3バケットを作成しました。

AWS WAFのログのサイズが1058Bなので

取り込まれたデータ (GB/月) = 800,000 * 1058 / (1024 * 1024 * 1024 ) = 0.788271427 GB /月

カスタムログ、オリジナルログもサイズとしての差は微々たるものなので一緒と考えて、

S3 標準ストレージは最初の 50 TB/月まで0.023USD/GBなので、

0.788271427 GB * 0.023 USD = 0.018130243 USD

カスタムログ、オリジナルログの2バケット分で

= 0.018130243 USD * 2 = 0.036260486 USD

小計 0.036260486 USD

AWS Glue

aws.amazon.com

クローラーとデータカタログを使用します。

データカタログを先に見ていきます。

ストレージ:
    最初の 100 万個のオブジェクトの保存は無料
    100 万個を超えて保存された場合、100,000 個のオブジェクトごとに毎月 1 ドル
リクエスト:
    最初の 100 万回のリクエストは毎月無料
    100 万回を超えた場合は 100 万回のリクエストごとに毎月 1 ドル

データカタログには、AWS WAFログのスキーマ情報が入ります。
オブジェクト数もあっても数十のため無料枠内に収まります。

ややこしいのがクローラの方です。 ドキュメントには、このように記述されています。

AWS Glue が使用可能なすべての AWS リージョン: 
DPU 時間あたり 0.44 ドルが 1 秒単位で課金され、クローラの実行ごとに最低 10 分

分かりにくいので、こういう時はクラスメソッドさんのブログを参考にするのが一番です。

dev.classmethod.jp

クローラは下記の仕様みたいです。

DPU(データ処理ユニット)の時間単位で課金
1DPU = 4vCPUと16GBメモリ
各クローラーには2DPUが割り当て
1DPU 0.44ドル/時
最低10分とし、分単位で切り上げ請求

これを踏まえて、AWS WAFのカスタムログの保存しているS3バケットを毎日10分クロールするとして、

0.44(ドル/時) * 2(DPU) * 1/6(時間) * 30(日) = 4.4 ドル/月

小計 4.4 USD

Amazon Athena

料金 - Amazon Athena | AWS

  • スキャンされたデータ 1 TB あたり 5 USD
  • バイト数はメガバイト単位で切り上げられ、10 MB 未満のクエリは 10 MB と計算
  • CREATE TABLE、ALTER TABLE、DROP TABLE などの Data Definition Language (DDL) ステートメント、パーティションを管理するステートメントは課金無し。
  • 正常に実行されなかったクエリに対しては課金無し。
  • クエリ結果は選択した S3 バケットに保存され、Amazon S3 の標準料金が請求される。別途クエリ結果保存用のS3バケットが必要で、貯まった結果に伴い、料金がかかるということ。

AWS WAFのカスタムログの保存しているS3バケットに保存されるのが、0.788271427 GB。

0.788271427 GBをTBに直すと、0.788271427 / 1024 = 0.000769796 TB

TB あたり 5 USDなので、

0.000769796 TB * 5 USD/TB = 0.00384898 USD

クエリー1回あたりの0.00384898 USD。 この値は後で使います。

Amazon QuickSight

Amazon QuickSight の料金表

エディションは、「Standard」と「Enterprise」があります。 それぞれで料金体系が違います。 今回は、「Standard」で説明を進めます。

  • 年間サブスクリプションでのユーザーあたりの月額料金 9 USD
  • 年間サブスクリプション無しだとユーザーあたりの月額料金 12 USD

利用用途は広いので、年間サブスクリプションでの契約(ユーザーあたりの月額料金 9 USD)とします。

また、QuickSightには、データを一時的に取り込んで高速に処理を完結させるためにSPICE(super-fast parallel in-memory calculation engineの略)という機能を搭載しています。 これの料金が、1 GB あたり 0.25 USDとなります。

と、これだけで結構安価なのは、分かるんですが、QuickSightには、試用期間と無料枠が存在します。 クラスメソッドさんが分かりやすくまとめてくれています。

[https://dev.classmethod.jp/cloud/aws/amazon-quicksight-free-tier-free-trial/:embed:cite]

無料枠として、SPICE 容量が1GB ついてきます。

また、試用期間60日ありまして、ユーザ数を4人まで無料で追加可能でSPICEをユーザ毎10GB利用可能となっています。

このSPICEへのデータの更新ですが、試算として、毎時データを更新するものとします。

1日24回*1か月(30日)Athenaでselectクエリが打たれます。 先ほど、Athenaのところでクエリー1回あたりの0.00384898 USDと算出したので、

24300.00384898 = 2.7712656 USD

となります。こちらはAthenaのところの小計に追加しておきます。

ということで、個人で使う分には、年間サブスクリプションでのユーザーあたりの月額料金 9 USDとなります。

小計 9 USD

まとめ

それでは各サービスの小計をまとめます。

AWS サービス 月額
北バージニア
備考
AWS WAF $15.000 OWASP TOP10のルールセットを使用。
月間80万リクエストで試算
kinesis Data Firehose $0.111 北バージニアの場合、最初の 500 TB/月 0.029 USD
東京の場合、最初の 500 TB/月 0.036 USD
Lambda $0.000 リクエスト数1,632,653まで無料枠で収まるため0USD
S3 $0.036 カスタムログ、オリジナルログ保存用S3バケット
Glue $4.400
Athena $2.771 クエリー1回あたりの0.00384898 USD。
QuickSightから毎時Selectクエリが実行される。
QuickSight $9.000 年間サブスクリプションでの契約
合計(USD) $31.318
合計(JPY) ¥3,539 1USD = 113 円として試算

想定のWEBリクエスト数を倍の160万に増やしてみます。

AWS サービス 月額(北バージニア) 備考
AWS WAF $15.600 OWASP TOP10のルールセットを使用。
月間160万リクエストで試算
kinesis Data Firehose $0.221 北バージニアの場合、最初の 500 TB/月 0.029 USD
東京の場合、最初の 500 TB/月 0.036 USD
Lambda $0.200 リクエスト数1,632,653まで無料枠で収まるため0USD

プラスで1,000,000 件のリクエストにつき 0.20 USD追加"
S3 $0.036 カスタムログ、オリジナルログ保存用S3バケット
Glue $4.400
Athena $5.543 QuickSightから毎時Selectクエリが実行される。
QuickSight $9.000 年間サブスクリプションでの契約
合計(USD) $35.000
合計(JPY) ¥3,955 1USD = 113 円として試算

ここまでは、さほど金額はかかっていません。

では、想定WEBリクエスト数を800万まで増やしてみます。

AWS サービス 月額(北バージニア) 備考
AWS WAF $19.800 OWASP TOP10のルールセットを使用。
月間800万リクエストで試算
kinesis Data Firehose $1.106 北バージニアの場合、最初の 500 TB/月 0.029 USD
東京の場合、最初の 500 TB/月 0.036 USD
Lambda $27.405 1,000,000 件のリクエストにつき 0.20 USD追加
S3 $0.363 カスタムログ、オリジナルログ保存用S3バケット
Glue $4.400
Athena $27.713 QuickSightから毎時Selectクエリが実行される。
QuickSight $9.000 年間サブスクリプションでの契約
合計(USD) $89.787
合計(JPY) ¥10,146 1USD = 113 円として試算

全体的に金額は上がってますが、WEBのリクエスト数が800万リクエストでも1万円を超えるぐらいで、びっくりするような金額にはならなそうです。 また、今回の試算では、WEBのリクエスト数=Lambdaのリクエスト数としていますが、実際のところ、Lambdaの1回のリクエスト内で、複数のWEBリクエストが処理されていたので、Lambdaのリクエスト数はここまで多くはならないと思います。

リクエストを80万ずつ増やした料金のグラフはこのようになります。

f:id:woodykedner:20181121131429j:plain

今回、算出してみましたが、こちらはあくまで2018年の11月現在の参考料金としていただいて、最初のうちは、リクエスト数の少ないサイトで試してみるのとAWS Cost Explorer 等で料金のかかり具合を見ながら、ログ解析環境を使用するのが良いかと思います。

最後まで、ご覧いただきありがとうございました!