ケース1 : セキュリティチェックを目的にWAFを導入する
事業会社でWebサービスを開発、運用していると、WAF(Web Application Firewall)を導入する必要に迫られます。そんなとき、どのように全体を進めていけばよいのか、導入・運用ケースを考えていきたいと思います。
これはあくまでフィクションです。
ケース説明
プロジェクトの背景
A社は日本企業向けにB2BのWebサービスを開発、運営している。そしてB社はA社のWebサービスの導入を検討している。現在はまだ導入検討フェーズで、B社からA社へセキュリティチェック(クラウドサービス選定のセキュリティ基準)が行われている。
セキュリティチェックの結果としてA社はB社から追加のセキュリティ対策としてWAFを導入することが求められた。このセキュリティ要件を満たさないと失注になる。(B社はセキュリティを理由に導入を見送る)
方針
A社の経営方針として売上(受注)を最優先としている。そのため、追加のセキュリティ施策を行ってでも、受注するという方針を取っており、売上のためにできるだけ短期間で導入し、低コストにセキュリティチェックの要件を満たしたい
今回の要件
B社のセキュリティ要件には下記があり、A社は受注のために、これを満たす必要がある
- WAFが導入されていること
- DDoS対策がされていること
またA社の都合で下記が決まっている
- 短期間で導入し、低コストであること
- AWS WAFを使用する
WAF導入のゴール
- B社のセキュリティチェックの要件をシステム的に満たしている
- 外部に対して説明ロジックが作れること = セキュリティチェックに回答できること
WAFの導入
1. インフラアーキテクチャを検討
AWS WAFはCloudFrontやALB(Application Load Balancer)などに設定することができます。
よって、Webサービスの現在のインフラアーキテクチャを確認し、どこに導入するか検討し、決めます。
CloudFrontの場合
ALBの場合
2. どの種類のWAFルールを使うか
AWS WAFのルールの種類を大別すると3つあります。
- AWSのマネージドルール
- サードパーティベンダーのマネージドルール
- AWS WAF自動運用サービス(WafCharm)
今回は方針に沿って、低コストである AWSのマネージドルール
を選択します。
3. どのWAFルールを使うか
次にAWSのマネージドルール
の中でどのルールを選択するか、を考えていきます。
ここで目的である、顧客のセキュリティ要件を確認します。
しかし、具体的にどの攻撃が防御できていればよいのかは求められていません。唯一、DDoS対策ができていることとあります。よって、ここではWebアプリケーションにおける一般的なWAFルールを選択していきます。そして追加でアプリケーションレイヤーにおけるDDoS対策のルールを作成することとします。
参考資料
AWSのマネージドルール
こちらに記載のある通り、AWSのマネージドルールもいくつか存在します。
この中から、一般的なWAFルールを選択していきます。
今回は下記4つを選択します。
それぞれAWSドキュメントから引用してきたルール説明になります。
-
AWSManagedRulesCommonRuleSet
OWASP Top 10 などの OWASP の出版物に記載されている、リスクが高く一般的に発生するいくつかの脆弱性を含む、さまざまな脆弱性の悪用に対する保護が提供されます。 -
AWSManagedRulesKnownBadInputsRuleSet
無効であることがわかっており脆弱性の悪用または発見に関連するリクエストパターンをブロックするルールが含まれています。 -
AWSManagedRulesSQLiRuleSet
SQL インジェクション攻撃などの SQL データベースの悪用に関連するリクエストパターンをブロックするルールが含まれています。 -
AWSManagedRulesAmazonIpReputationList
Amazon 内部脅威インテリジェンスに基づくルールが含まれています。
自前ルール
またアプリケーションレイヤーにおけるDDoS対策として一定以上のレートの場合、リクエストをブロックするルールと海外からのアクセスをブロックするルールも自前で作成しておきます。
-
自前ルール1. 5分間に100回同じソースIPアドレスからリクエストがあった場合、ブロックする
- アプリケーションレイヤーにおけるDDoS対策のため
-
自前ルール2. 日本以外からのアクセスはブロックする
- 日本のみにサービス提供するWebアプリケーションのため
3. ログ保存の検討
AWS WAFのダッシュボードでもルールのマッチやどのような処理をしたか(Allow / Block / Count)を見ることができます。しかし、このダッシュボードでは限られたものしか見れなかったり、リクエストの詳細を見れなかったりと分析するには少し情報が足りません。
そこでAWS WAFのログを別途保存することを検討します。
AWS WAFのログ保存先は下記3つあります。
- Amazon S3
- CloudWatch Logs
- Amazon Kinesis Data Firehose
今回はAthenaで分析することからS3を選択します。
※Athenaでログ分析するにはS3に保存する必要があります。
4. WAFの設定
設定手順はわかりやすいサイトがたくさんありますので、そちらを参考に設定をしてください。
設定の肝は前述のマネージドルールになります。設計に沿ってマネージドルールをカウントモードで設定します。
5. テスト
設定した後、実際に有効にしたルールで検知できるか、いくつかテストをします。
ここではAWSManagedRulesCommonRuleSetの中にある2つのルールと自前で作成したルールを1つテストしています。
NoUserAgent_HEADERルールのテスト
User-Agentヘッダーがないリクエストを検知するルールです。
curl https://ドメイン名 -H "User-Agent: "
PCなどからcurlコマンドを実行後、AWS WAFのダッシュボードでログを確認します。
NoUserAgent_HEADERルールでカウントとして検知できていれば大丈夫です。
UserAgent_BadBots_HEADERルールのテスト
nessusやnmapなどの、ポートスキャンや脆弱性スキャンに用いるツールに使用されているUser-Agentからのリクエストを検知するルールです。
curl https://ドメイン名 -H "User-Agent: Mozilla/5.0 (compatible; Nmap Scripting Engine; http://nmap.org/book/nse.html)"
PCなどからcurlコマンドを実行後、AWS WAFのダッシュボードでログを確認します。
UserAgent_BadBots_HEADERルールでカウントとして検知できていれば大丈夫です。
一定以上のレートでのリクエストをブロックするルール
abなどを使用して大量アクセスをします。
AWS WAFのダッシュボードでログを確認します。
大量のリクエストがブロックされていることが分かります。
実際にどのIPアドレスがブロック対象となっているか確認します。
Addressesのところを確認するとIPアドレスが入っていることが分かります。
$ aws wafv2 get-rate-based-statement-managed-keys \
> --scope REGIONAL \
> --web-acl-name [ACL Name] \
> --web-acl-id [ACL ID] \
> --rule-name Rate-based-rule-with-source-ip
{
"ManagedKeysIPV4": {
"IPAddressVersion": "IPV4",
"Addresses": [
"XX.XX.XX.XX/32"
]
},
"ManagedKeysIPV6": {
"IPAddressVersion": "IPV6",
"Addresses": []
}
}
しばらくしたのちに再度確認すると、ブロック対象から自動で外れていることがわかります。
$ aws wafv2 get-rate-based-statement-managed-keys \
> --scope REGIONAL \
> --web-acl-name [ACL Name] \
> --web-acl-id [ACL ID] \
> --rule-name Rate-based-rule-with-source-ip
{
"ManagedKeysIPV4": {
"IPAddressVersion": "IPV4",
"Addresses": []
},
"ManagedKeysIPV6": {
"IPAddressVersion": "IPV6",
"Addresses": []
}
}
外部への説明
ここまででて、B社に対して、下記のように説明できるようになりました。
これでB社の契約も受注できるでしょう。
- WAFは導入済み
- AWS WAFを導入した
- WAFを使用して一般的なWebアプリケーションへの攻撃をブロックできる
- 一般的な攻撃を防御するAWSのマネージドルールを使用した
- DDoS対策済み
- インフラレイヤーとしてはAWS Shield Standardで対策
- アプリケーションレイヤーとしてはレートベースのルールを使用して対策
WAFの運用
さて、導入が終わりました。これでWAFが導入され、DDoS対策もできたと説明できるでしょう。
B社との契約も取れて、よかった、よかった...では終わりません。
ビジネスのために急いで導入しましたが、WAFとしての運用がこれから始まります。
そしてWAFは運用がとても重要です。
ここでは運用のいくつかについて、考えていきましょう。
運用には以下のような内容が考えられます。
- 新しいルールはカウントモードで開始する
- ログをみて、ルールごとにブロックモードへ変更する
- WAFルールのバージョンアップを気にしておく
- 脆弱性対応の中で、すぐにパッチ適用などの対応ができないとき、WAFでブロックするためにルールを追加する
このような運用を行うための設定やヒントを記載していきます。
1. カウントモードでの運用
WAFルールにマッチングしたあとのアクションにはAllow, Block, Countなどが設定できます。
新しいルールを作成したときは、まずカウントモードで運用することをおすすめします。
カウントモードとはルール一致時に検知はするが許可も拒否も行わないモードです。誤検知を減らすため、まずカウントモードで運用を開始して、様子を見てから実際にブロックをしていくと良いです。
そして、カウントからブロックへの判断は難しいです。
判断するにはこれ以降、説明するログを使って判断するのが一般的です。
判断のためのヒントをいくつか提示しておきます。
- 海外からのアクセス
- 海外からのアクセスを想定していなければ、思い切って海外からのアクセスはブロックしてしまって良いでしょう
- 存在しないURIへのアクセス
- 存在しないURIへのアクセスもブロックしてしまって良いでしょう
- ヘッダーのHOST情報
- ヘッダーのHOSTがサービスのFQDNでない場合、ブロックを検討してもよいと思います
2. S3でのログ確認
カウントモードで運用していると、ルール一致したログの詳細を確認したいときがあります。
そんなとき、ログを保存しているとログの詳細が見れます。
ここではS3に保存されているWAFのログの抽出や見方について、簡単に紹介します。
ログの抽出
S3でWAFのログが保存されているバケットから辿っていき、ログファイルを選択します。
ログファイルは以下の階層に保存されています。
web-acl-name/YYYY/MM/dd/HH/mm/xxxx.tar.gz
ログファイルを選択した状態で、[アクション]-[S3 Select]を選択します。
入力形式と出力形式の設定を行い、その後にSQLクエリを設定します。
SQLクエリの例
ここでは2つのSQLクエリ例を紹介します。
カウント処理されたログを抽出
select * from S3Object s where s."action" = 'COUNT'
リクエスト元IPアドレスがXX.XX.XX.XXのログを抽出
select * from S3Object s where s."httpRequest"."clientIp" = 'XX.XX.XX.XX'
クエリを作るときは下記SQLリファレンスを参考にすることをおすすめします。
WAFログの読み方
ログの読み方を簡単に紹介しておきます。
下記のログはWeb ACL名がwaf-xxxxxのWAFで、block-from-overseas-countriesルールにマッチして、ブロックされたことを意味しています。またこのリクエストはポルトガル共和国(PT)のXXX.XXX.XXX.XXX(clientIp)から発信されています。
webaclId
: Web ACLのID
terminatingRuleId
: リクエストを終了したルールのID
action
: AWS WAFがリクエストに適用した終了アクション
httpRequest.clientIp
: リクエスト送信元のIPアドレス
httpRequest.country
: リクエスト送信元の国
詳細はAWSドキュメントに記載されていますのでこちらを参考に読み解いてみてください。
{
"timestamp": 1699977482470,
"formatVersion": 1,
"webaclId": "arn:aws:wafv2:ap-northeast-1:xxxxxxxxxxx:regional/webacl/waf-xxxxx/xxxxx-xxxxx-xxxxx-xxxxx-xxxxx",
"terminatingRuleId": "block-from-overseas-countries",
"terminatingRuleType": "REGULAR",
"action": "BLOCK",
"terminatingRuleMatchDetails": [],
"httpSourceName": "ALB",
"httpSourceId": "xxxxx-app/alb-xxxxx/xxxxx",
"ruleGroupList": [],
"rateBasedRuleList": [],
"nonTerminatingMatchingRules": [],
"requestHeadersInserted": null,
"responseCodeSent": null,
"httpRequest": {
"clientIp": "XXX.XXX.XXX.XXX",
"country": "PT",
"headers": [
{
"name": "Host",
"value": "XXX.XXX.XXX.XXX"
},
{
"name": "User-Agent",
"value": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/60.0.3112.113 Safari/537.36"
},
{
"name": "Accept",
"value": "*/*"
},
{
"name": "Accept-Encoding",
"value": "gzip"
}
],
"uri": "/",
"args": "",
"httpVersion": "HTTP/1.1",
"httpMethod": "GET",
"requestId": "1-6553990a-XXXXXXXXXXXXXXXXXX"
},
"labels": [
{
"name": "awswaf:clientip:geo:country:PT"
},
{
"name": "awswaf:clientip:geo:region:PT-XX"
}
],
"ja3Fingerprint": "XXXXXXXXXXXXXXXXXXXXXXXXXXX"
}
3. Athenaでのログ確認
S3のログだと日付や時刻を辿ってログファイルを特定してからクエリを実行する必要があり、わりと使いにくいです。そこで、日付や時刻を特定しなくてもログを分析できる仕組みとしてAthenanによるログ分析環境を構築しておく。
AthenaによるWAFログの分析環境構築は他のわかりやすいサイトを参考にして設定してください
実際に使用できるクエリを1つ紹介しておきます。
特定期間内でブロックされたリクエストを抽出する
SELECT DATE_FORMAT(FROM_UNIXTIME(waf_furari_logs.timestamp/1000, 'Asia/Tokyo') ,'%Y-%m-%d %h:%i:%s') AS JST, *
FROM waf_furari_logs
WHERE
from_unixtime(timestamp / 1000, 'Asia/Tokyo') >= timestamp '2023-11-15 00:00:00 Asia/Tokyo'
and from_unixtime(timestamp / 1000, 'Asia/Tokyo') <= timestamp '2023-11-15 23:59:59 Asia/Tokyo'
AND action = 'BLOCK';
4. マネージドルールの更新の通知を受け取る
AWSマネージドルールのルールセットは自動的にアップデートされます。アップデートすることで新しい脅威に対応しています。よって、自動アップデートで大丈夫なのですが、稀にアップデートにより突然ブロックされてしまうこともあります。
そのため、マネージドルールの更新通知を受け取るようにして、そのタイミングで正常なアクセスがブロックされていないか、注視したほうがベストです。
更新通知を受け取るための設定手順は他にわかりやすいサイトがあるため、そちらを参考に設定してみてください
まとめ
- セキュリティチェック起因でのWAF導入は存在する
- この場合、短納期での導入、とりあえずの導入になりがちで、ビジネスのための導入になる
- そしてこの場合、運用が忘れ去られてしまい、本質的なセキュリティ対策としては意味がなくなってしまう可能性がある
次の記事で、WAFを本質的なセキュリティ対策という目的で導入するというユースケースを考えていきたいと思います。
Discussion