Skip to content

Commit 813a4be

Browse files
authored
Merge pull request #200 from YAPP-Github/fix/PRODUCT-283
[Fix] 취약점 스캐닝, 크롤링 방지 장기 대응 작업
2 parents 70c9f87 + f1355b0 commit 813a4be

File tree

6 files changed

+204
-1
lines changed

6 files changed

+204
-1
lines changed

terraform/common/locals.tf

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ data "aws_region" "current" {}
44
locals {
55
group_name = "power"
66
project_name = "eatda"
7+
admin_email = "[email protected]"
78

89
policy_arns = [
910
"arn:aws:iam::aws:policy/AdministratorAccess",
@@ -248,3 +249,7 @@ locals {
248249
}
249250
}
250251
}
252+
253+
locals {
254+
request_threshold = 200
255+
}

terraform/common/main.tf

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -51,3 +51,27 @@ module "alb" {
5151
certificate_arn = module.route53.certificate_arn
5252
certificate_validation_complete = module.route53.certificate_validation_complete
5353
}
54+
55+
module "waf" {
56+
source = "./waf"
57+
project_name = local.project_name
58+
request_threshold = local.request_threshold
59+
tags = local.common_tags
60+
}
61+
62+
resource "aws_wafv2_web_acl_association" "this" {
63+
resource_arn = module.alb.alb_arn
64+
web_acl_arn = module.waf.web_acl_arn
65+
}
66+
67+
resource "aws_cloudwatch_log_group" "waf_logs" {
68+
name = "aws-waf-logs-${local.project_name}"
69+
retention_in_days = 7
70+
71+
tags = local.common_tags
72+
}
73+
74+
resource "aws_wafv2_web_acl_logging_configuration" "this" {
75+
log_destination_configs = [trimsuffix(aws_cloudwatch_log_group.waf_logs.arn, ":*")]
76+
resource_arn = module.waf.web_acl_arn
77+
}

terraform/common/waf/main.tf

Lines changed: 156 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,156 @@
1+
resource "aws_wafv2_web_acl" "this" {
2+
name = "${var.project_name}-web-acl"
3+
scope = "REGIONAL"
4+
5+
default_action {
6+
allow {}
7+
}
8+
9+
# Rate-based Rule (HTTP Flood)
10+
rule {
11+
name = "Rate-Limit-Rule"
12+
priority = 1
13+
action {
14+
block {}
15+
}
16+
statement {
17+
rate_based_statement {
18+
limit = var.request_threshold
19+
aggregate_key_type = "IP"
20+
}
21+
}
22+
visibility_config {
23+
cloudwatch_metrics_enabled = true
24+
metric_name = "rate-limit-rule"
25+
sampled_requests_enabled = true
26+
}
27+
}
28+
29+
# AWS Managed Core Rule Set
30+
rule {
31+
name = "AWS-Managed-Core-Rule-Set"
32+
priority = 10
33+
override_action {
34+
none {}
35+
}
36+
statement {
37+
managed_rule_group_statement {
38+
vendor_name = "AWS"
39+
name = "AWSManagedRulesCommonRuleSet"
40+
}
41+
}
42+
visibility_config {
43+
cloudwatch_metrics_enabled = true
44+
metric_name = "aws-managed-common"
45+
sampled_requests_enabled = true
46+
}
47+
}
48+
49+
# Scanners & Probes Protection
50+
rule {
51+
name = "AWS-Managed-Known-Bad-Inputs-Rule-Set"
52+
priority = 20
53+
override_action {
54+
none {}
55+
}
56+
statement {
57+
managed_rule_group_statement {
58+
vendor_name = "AWS"
59+
name = "AWSManagedRulesKnownBadInputsRuleSet"
60+
}
61+
}
62+
visibility_config {
63+
cloudwatch_metrics_enabled = true
64+
metric_name = "aws-managed-bad-inputs"
65+
sampled_requests_enabled = true
66+
}
67+
}
68+
69+
# Reputation Lists Protection
70+
rule {
71+
name = "AWS-Managed-Amazon-IP-Reputation-List"
72+
priority = 30
73+
override_action {
74+
none {}
75+
}
76+
statement {
77+
managed_rule_group_statement {
78+
vendor_name = "AWS"
79+
name = "AWSManagedRulesAmazonIpReputationList"
80+
}
81+
}
82+
visibility_config {
83+
cloudwatch_metrics_enabled = true
84+
metric_name = "aws-managed-ip-rep"
85+
sampled_requests_enabled = true
86+
}
87+
}
88+
89+
# Bad Bot Protection
90+
rule {
91+
name = "AWS-Managed-Bot-Control-Rule-Set"
92+
priority = 40
93+
override_action {
94+
none {}
95+
}
96+
statement {
97+
managed_rule_group_statement {
98+
vendor_name = "AWS"
99+
name = "AWSManagedRulesBotControlRuleSet"
100+
}
101+
}
102+
visibility_config {
103+
cloudwatch_metrics_enabled = true
104+
metric_name = "aws-managed-bot-control"
105+
sampled_requests_enabled = true
106+
}
107+
}
108+
109+
# Anonymous IP list
110+
rule {
111+
name = "AWS-Managed-Anonymous-IP-List"
112+
priority = 50
113+
override_action {
114+
none {}
115+
}
116+
statement {
117+
managed_rule_group_statement {
118+
vendor_name = "AWS"
119+
name = "AWSManagedRulesAnonymousIpList"
120+
}
121+
}
122+
visibility_config {
123+
cloudwatch_metrics_enabled = true
124+
metric_name = "aws-managed-anonymous-ip"
125+
sampled_requests_enabled = true
126+
}
127+
}
128+
129+
# SQL database
130+
rule {
131+
name = "AWS-Managed-SQLi-Rule-Set"
132+
priority = 60
133+
override_action {
134+
none {}
135+
}
136+
statement {
137+
managed_rule_group_statement {
138+
vendor_name = "AWS"
139+
name = "AWSManagedRulesSQLiRuleSet"
140+
}
141+
}
142+
visibility_config {
143+
cloudwatch_metrics_enabled = true
144+
metric_name = "aws-managed-sql-db"
145+
sampled_requests_enabled = true
146+
}
147+
}
148+
149+
visibility_config {
150+
cloudwatch_metrics_enabled = true
151+
metric_name = "${var.project_name}-web-acl"
152+
sampled_requests_enabled = true
153+
}
154+
155+
tags = var.tags
156+
}

terraform/common/waf/outputs.tf

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
output "web_acl_arn" {
2+
value = aws_wafv2_web_acl.this.arn
3+
}

terraform/common/waf/variables.tf

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
variable "project_name" {
2+
type = string
3+
}
4+
5+
variable "request_threshold" {
6+
type = number
7+
description = "Rate-Limit 규칙에 적용할 5분당 IP별 최대 요청 수"
8+
}
9+
10+
variable "tags" {
11+
type = map(string)
12+
}

terraform/prod/terraform.tfvars

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ ecs_services = {
1111
datadog = {
1212
task_definition = "datadog"
1313
launch_type = "EC2"
14-
scheduling_strategy = "REPLICA"
14+
scheduling_strategy = "DAEMON"
1515
}
1616
}
1717

@@ -49,6 +49,9 @@ ecs_task_definitions_base = {
4949
DD_LOGS_CONFIG_CONTAINER_COLLECT_ALL = "true"
5050
DD_APM_RECEIVER_PORT = "8126"
5151
DD_APM_NON_LOCAL_TRAFFIC = "true"
52+
DD_EC2_USE_IMDSV2 = "true"
53+
DD_COLLECT_EC2_TAGS = "true"
54+
DD_COLLECT_EC2_METADATA = "true"
5255
DD_SERVICE = "eatda-api-prod"
5356
DD_ENV = "prod"
5457
DD_VERSION = "v1"

0 commit comments

Comments
 (0)