やりたいこと
海外からのアクセスのみWAFのルールを適用する
言い換えると
日本からのアクセスは通信を通すようにする
なぜやるか
アプリケーション内での検索クエリがsqlインジェクションルールに引っかかり弾かれてしまった
sqlインジェクションルールの詳細がブラックボックスになっているため、
穴を開ける形を取らないといけなくなった。
国内限定で使うアプリケーションなので海外からのアクセスにのみWAFを適用することにした。
前提
今回適用するルールは
- 日本からの通信か(allow)
- sqlインジェクション(block)
- レートベースルール(block)
albにアタッチするところまではやらない
コード
#----------------------------
# WAF ACL
#----------------------------
resource "aws_wafv2_web_acl" "main" {
name = "${var.app_name}-WebACL"
description = "${var.app_name}-WebACL"
scope = "REGIONAL"
default_action {
allow {}
}
# 日本からの通信に関しては通信を通し、日本以外からのアクセスは後続のルールが適用される
rule {
name = "allowJpRule"
priority = 0
action {
allow {}
}
statement {
geo_match_statement {
country_codes = ["JP"]
}
}
visibility_config {
cloudwatch_metrics_enabled = true
metric_name = "allowJpRuleMetric"
sampled_requests_enabled = false
}
}
#DDoS攻撃に対するルール(5分間あたりのlimit(閾値)を超えた場合にblockする)
rule {
name = "AWSRateBasedRule"
priority = 10
action {
block {}
}
statement {
rate_based_statement {
limit = 300
aggregate_key_type = "IP"
}
}
visibility_config {
cloudwatch_metrics_enabled = true
metric_name = "AWSRateBasedRuleWAFMetric"
sampled_requests_enabled = false
}
}
#SQLインジェクション攻撃に対するルール
rule {
name = "AWSManagedRulesSQLiRuleSet"
priority = 20
override_action {
none {}
}
statement {
managed_rule_group_statement {
name = "AWSManagedRulesSQLiRuleSet"
vendor_name = "AWS"
}
}
visibility_config {
cloudwatch_metrics_enabled = true
metric_name = "AWSManagedRulesSQLiRuleSetWAFMetric"
sampled_requests_enabled = false
}
}
visibility_config {
cloudwatch_metrics_enabled = true
metric_name = "${var.app_name}-WebACL"
sampled_requests_enabled = false
}
}
ポイント
# 日本からの通信に関しては通信を通し、日本以外からのアクセスは後続のルールが適用される
rule {
name = "allowJpRule"
priority = 0
action {
allow {}
}
statement {
geo_match_statement {
country_codes = ["JP"]
}
}
visibility_config {
cloudwatch_metrics_enabled = true
metric_name = "allowJpRuleMetric"
sampled_requests_enabled = false
}
}
priority = 0
こうすることで一番最初に実行される
action {
allow {}
}
こうすることで通信を通すということになるので
JPからのアクセスは後続のルールを適用せずに通信を通すということができる。
補足
ルール内で追加の条件を書くこともできるが
terraformがand_statement
やor_statement
内での
rate_based_statement
managed_rule_group_statement
をサポートしていなかったため(2022/02/07)
別でルールを適用する必要があった。
ので
今回のような形になった。
素朴な疑問
これ作ってみて思ったことは、
国内限定で使用することが前提のアプリケーションの場合
海外からのアクセスは完全に断ち切ればいいのでは?
金額も安く済みますし😅
と思いました。
何かデメリットとかるのでしょうかね。