1+ data "aws_ssm_parameter" "x_origin_verify" {
2+ name = " /common/CLIENT_HEADER_SECRET"
3+ }
4+
15resource "aws_wafv2_web_acl" "this" {
26 name = " ${ var . project_name } -web-acl"
37 scope = " REGIONAL"
48
59 default_action {
6- allow {}
10+ block {}
11+ }
12+
13+ rule {
14+ name = " Allow-Verified-Server-Requests"
15+ priority = 5
16+ action {
17+ allow {}
18+ }
19+ statement {
20+ and_statement {
21+ statement {
22+ or_statement {
23+ statement {
24+ byte_match_statement {
25+ field_to_match {
26+ single_header {
27+ name = " user-agent"
28+ }
29+ }
30+ search_string = " node"
31+ positional_constraint = " CONTAINS"
32+ text_transformation {
33+ priority = 0
34+ type = " NONE"
35+ }
36+ }
37+ }
38+ statement {
39+ byte_match_statement {
40+ field_to_match {
41+ single_header {
42+ name = " user-agent"
43+ }
44+ }
45+ search_string = " Vercel"
46+ positional_constraint = " CONTAINS"
47+ text_transformation {
48+ priority = 0
49+ type = " NONE"
50+ }
51+ }
52+ }
53+ }
54+ }
55+ statement {
56+ byte_match_statement {
57+ field_to_match {
58+ single_header {
59+ name = " x-origin-verify"
60+ }
61+ }
62+ search_string = data. aws_ssm_parameter . x_origin_verify . value
63+ positional_constraint = " EXACTLY"
64+ text_transformation {
65+ priority = 0
66+ type = " NONE"
67+ }
68+ }
69+ }
70+ }
71+ }
72+ visibility_config {
73+ cloudwatch_metrics_enabled = true
74+ metric_name = " allow-verified-server-requests"
75+ sampled_requests_enabled = true
76+ }
77+ }
78+
79+ rule {
80+ name = " Allow-Browser-Requests"
81+ priority = 10
82+ action {
83+ allow {}
84+ }
85+ statement {
86+ or_statement {
87+ statement {
88+ size_constraint_statement {
89+ field_to_match {
90+ single_header {
91+ name = " origin"
92+ }
93+ }
94+ comparison_operator = " GT"
95+ size = 0
96+ text_transformation {
97+ priority = 0
98+ type = " NONE"
99+ }
100+ }
101+ }
102+ statement {
103+ size_constraint_statement {
104+ field_to_match {
105+ single_header {
106+ name = " referer"
107+ }
108+ }
109+ comparison_operator = " GT"
110+ size = 0
111+ text_transformation {
112+ priority = 0
113+ type = " NONE"
114+ }
115+ }
116+ }
117+ }
118+ }
119+ visibility_config {
120+ cloudwatch_metrics_enabled = true
121+ metric_name = " allow-browser-requests"
122+ sampled_requests_enabled = true
123+ }
7124 }
8125
9- # Rate-based Rule (HTTP Flood)
10126 rule {
11127 name = " Rate-Limit-Rule"
12- priority = 1
128+ priority = 20
13129 action {
14130 block {}
15131 }
@@ -29,7 +145,7 @@ resource "aws_wafv2_web_acl" "this" {
29145 # AWS Managed Core Rule Set
30146 rule {
31147 name = " AWS-Managed-Core-Rule-Set"
32- priority = 10
148+ priority = 30
33149 override_action {
34150 none {}
35151 }
@@ -49,7 +165,7 @@ resource "aws_wafv2_web_acl" "this" {
49165 # Scanners & Probes Protection
50166 rule {
51167 name = " AWS-Managed-Known-Bad-Inputs-Rule-Set"
52- priority = 20
168+ priority = 40
53169 override_action {
54170 none {}
55171 }
@@ -69,7 +185,7 @@ resource "aws_wafv2_web_acl" "this" {
69185 # Reputation Lists Protection
70186 rule {
71187 name = " AWS-Managed-Amazon-IP-Reputation-List"
72- priority = 30
188+ priority = 50
73189 override_action {
74190 none {}
75191 }
@@ -89,84 +205,27 @@ resource "aws_wafv2_web_acl" "this" {
89205 # Bad Bot Protection
90206 rule {
91207 name = " AWS-Managed-Bot-Control-Rule-Set"
92- priority = 40
93-
208+ priority = 60
94209 override_action {
95210 none {}
96211 }
97-
98212 statement {
99213 managed_rule_group_statement {
100214 vendor_name = " AWS"
101215 name = " AWSManagedRulesBotControlRuleSet"
102-
103- rule_action_override {
104- name = " SignalNonBrowserUserAgent"
105- action_to_use {
106- count {}
107- }
108- }
109216 }
110217 }
111-
112218 visibility_config {
113219 cloudwatch_metrics_enabled = true
114220 metric_name = " aws-managed-bot-control"
115221 sampled_requests_enabled = true
116222 }
117223 }
118224
119- # 임시 조치로 ua가 node일 경우만 통과시킴
120- rule {
121- name = " Block-Non-Node-User-Agents"
122- priority = 41
123-
124- action {
125- block {}
126- }
127-
128- statement {
129- and_statement {
130- statement {
131- label_match_statement {
132- scope = " LABEL"
133- key = " awswaf:managed:aws:bot-control:signal:non_browser_user_agent"
134- }
135- }
136-
137- statement {
138- not_statement {
139- statement {
140- byte_match_statement {
141- search_string = " node"
142- field_to_match {
143- single_header {
144- name = " user-agent"
145- }
146- }
147- positional_constraint = " CONTAINS"
148- text_transformation {
149- priority = 0
150- type = " NONE"
151- }
152- }
153- }
154- }
155- }
156- }
157- }
158-
159- visibility_config {
160- cloudwatch_metrics_enabled = true
161- metric_name = " block-non-node-uas"
162- sampled_requests_enabled = true
163- }
164- }
165-
166225 # Anonymous IP list
167226 rule {
168227 name = " AWS-Managed-Anonymous-IP-List"
169- priority = 50
228+ priority = 70
170229 override_action {
171230 none {}
172231 }
@@ -186,7 +245,7 @@ resource "aws_wafv2_web_acl" "this" {
186245 # SQL database
187246 rule {
188247 name = " AWS-Managed-SQLi-Rule-Set"
189- priority = 60
248+ priority = 80
190249 override_action {
191250 none {}
192251 }
0 commit comments