Complete infrastructure and integration updates
Infrastructure improvements: - Update CloudFront distribution with ACM certificate support - Enable custom domain aliases when certificate is available - Add comprehensive WAF outputs for CrowdSec integration - Update variables with current configuration defaults New files: - Add CrowdSec WAF integration documentation - Add sync script for CrowdSec to WAF automation - Add MCP configuration for development tools Configuration updates: - Align Terraform configuration with deployed state - Enable ACM certificate and Route53 DNS by default - Maintain HTTP-only origin protocol for compatibility 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
39
.mcp.json
Normal file
39
.mcp.json
Normal file
@@ -0,0 +1,39 @@
|
|||||||
|
{
|
||||||
|
"mcpServers": {
|
||||||
|
"context7": {
|
||||||
|
"command": "npx",
|
||||||
|
"args": ["-y", "@upstash/context7-mcp@latest"]
|
||||||
|
},
|
||||||
|
"cloudflare": {
|
||||||
|
"command": "npx",
|
||||||
|
"args": ["mcp-remote", "https://docs.mcp.cloudflare.com/sse"]
|
||||||
|
},
|
||||||
|
"aws-api-mcp-server": {
|
||||||
|
"command": "uvx",
|
||||||
|
"args": ["awslabs.aws-api-mcp-server@latest"],
|
||||||
|
"env": {
|
||||||
|
"AWS_REGION": "ap-northeast-2"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"aws-knowledge-mcp-server": {
|
||||||
|
"command": "uvx",
|
||||||
|
"args": [
|
||||||
|
"mcp-proxy",
|
||||||
|
"--transport",
|
||||||
|
"streamablehttp",
|
||||||
|
"https://knowledge-mcp.global.api.aws"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"aws-serverless-mcp-server": {
|
||||||
|
"command": "uvx",
|
||||||
|
"args": [
|
||||||
|
"awslabs.aws-serverless-mcp-server@latest",
|
||||||
|
"--allow-write",
|
||||||
|
"--allow-sensitive-data-access"
|
||||||
|
],
|
||||||
|
"env": {
|
||||||
|
"AWS_REGION": "ap-northeast-2"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
309
CROWDSEC-WAF-INTEGRATION.md
Normal file
309
CROWDSEC-WAF-INTEGRATION.md
Normal file
@@ -0,0 +1,309 @@
|
|||||||
|
# CrowdSec - AWS WAF 실시간 통합 가이드
|
||||||
|
|
||||||
|
## 📋 개요
|
||||||
|
|
||||||
|
이 문서는 CrowdSec와 AWS WAF 간의 실시간 IP 차단 통합 시스템 구현 가이드입니다. CrowdSec가 탐지한 악성 IP를 AWS Lambda를 통해 자동으로 WAF IP Set에 추가/제거하여 실시간 보안을 제공합니다.
|
||||||
|
|
||||||
|
## 🏗️ 아키텍처
|
||||||
|
|
||||||
|
```
|
||||||
|
CrowdSec Container → Webhook Notification → API Gateway → Lambda Function → AWS WAF IP Set → CloudFront Distribution
|
||||||
|
```
|
||||||
|
|
||||||
|
### 주요 구성 요소
|
||||||
|
|
||||||
|
1. **CrowdSec Container** (Incus)
|
||||||
|
- 보안 이벤트 감지 및 분석
|
||||||
|
- Nginx Proxy Manager 로그 모니터링
|
||||||
|
- 웹훅 알림 전송
|
||||||
|
|
||||||
|
2. **AWS API Gateway**
|
||||||
|
- 웹훅 엔드포인트 제공
|
||||||
|
- Lambda 함수 트리거
|
||||||
|
|
||||||
|
3. **AWS Lambda Function**
|
||||||
|
- CrowdSec Alert 데이터 처리
|
||||||
|
- WAF IP Set 업데이트 수행
|
||||||
|
|
||||||
|
4. **AWS WAF v2**
|
||||||
|
- IP Set 기반 차단 규칙
|
||||||
|
- CloudFront 배포 보호
|
||||||
|
|
||||||
|
## 🚀 구현 단계
|
||||||
|
|
||||||
|
### 1. 인프라 배포
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# OpenTofu 초기화
|
||||||
|
tofu init
|
||||||
|
|
||||||
|
# 인프라 배포
|
||||||
|
tofu apply -auto-approve
|
||||||
|
```
|
||||||
|
|
||||||
|
**배포되는 리소스:**
|
||||||
|
- Lambda 함수 및 IAM 역할
|
||||||
|
- API Gateway 웹훅 엔드포인트
|
||||||
|
- WAF v2 IP Set 및 Web ACL
|
||||||
|
- CloudWatch 로그 그룹
|
||||||
|
|
||||||
|
### 2. CrowdSec 컨테이너 설정
|
||||||
|
|
||||||
|
#### 컨테이너 생성 및 설정
|
||||||
|
```bash
|
||||||
|
# 새 컨테이너 생성
|
||||||
|
incus launch ubuntu:24.04 crowdsec
|
||||||
|
|
||||||
|
# CrowdSec 설치
|
||||||
|
incus exec crowdsec -- apt update
|
||||||
|
incus exec crowdsec -- curl -s https://install.crowdsec.net | sh
|
||||||
|
|
||||||
|
# Nginx Proxy Manager 컬렉션 설치
|
||||||
|
incus exec crowdsec -- cscli collections install crowdsecurity/nginx-proxy-manager
|
||||||
|
incus exec crowdsec -- systemctl reload crowdsec
|
||||||
|
```
|
||||||
|
|
||||||
|
#### 웹훅 알림 설정
|
||||||
|
```bash
|
||||||
|
# 알림 설정 파일 생성
|
||||||
|
incus exec crowdsec -- tee /etc/crowdsec/notifications/aws-waf.yaml << 'EOF'
|
||||||
|
type: http
|
||||||
|
name: aws-waf
|
||||||
|
log_level: info
|
||||||
|
url: https://8zdmpjfnhh.execute-api.us-east-1.amazonaws.com/dev/webhook
|
||||||
|
method: POST
|
||||||
|
headers:
|
||||||
|
Content-Type: application/json
|
||||||
|
User-Agent: CrowdSec/1.7.0
|
||||||
|
timeout: 10s
|
||||||
|
format: |
|
||||||
|
{{ .|toJson }}
|
||||||
|
EOF
|
||||||
|
|
||||||
|
# 프로필 설정
|
||||||
|
incus exec crowdsec -- tee /etc/crowdsec/profiles.yaml << 'EOF'
|
||||||
|
name: aws_waf_profile
|
||||||
|
filters:
|
||||||
|
- Alert.Remediation == true && Alert.GetScenario() startsWith "crowdsecurity/"
|
||||||
|
notifications:
|
||||||
|
- aws-waf
|
||||||
|
on_success: break
|
||||||
|
EOF
|
||||||
|
|
||||||
|
# CrowdSec 재시작
|
||||||
|
incus exec crowdsec -- systemctl restart crowdsec
|
||||||
|
```
|
||||||
|
|
||||||
|
### 3. Lambda 함수 코드
|
||||||
|
|
||||||
|
**파일 위치:** `/Users/kaffa/Projects/was-cf/lambda-crowdsec-waf.py`
|
||||||
|
|
||||||
|
주요 기능:
|
||||||
|
- CrowdSec Alert JSON 구조 처리
|
||||||
|
- IP 주소 추출 및 검증
|
||||||
|
- WAF IP Set 업데이트 (추가/제거)
|
||||||
|
- 에러 처리 및 로깅
|
||||||
|
|
||||||
|
핵심 처리 로직:
|
||||||
|
```python
|
||||||
|
# CrowdSec Alert 구조 처리 (toJson 형식)
|
||||||
|
if isinstance(webhook_data, list):
|
||||||
|
# Alert 배열인 경우
|
||||||
|
for alert in webhook_data:
|
||||||
|
if 'decisions' in alert and alert['decisions']:
|
||||||
|
for decision in alert['decisions']:
|
||||||
|
# Source IP 추출
|
||||||
|
source_ip = alert.get('source', {}).get('ip', '')
|
||||||
|
# Decision 정보 포함
|
||||||
|
decision['source_ip'] = source_ip
|
||||||
|
decision['alert_uuid'] = alert.get('uuid', '')
|
||||||
|
decisions.append(decision)
|
||||||
|
```
|
||||||
|
|
||||||
|
## 📊 WAF 규칙 우선순위
|
||||||
|
|
||||||
|
AWS WAF Web ACL 규칙 순서 (낮은 번호가 높은 우선순위):
|
||||||
|
|
||||||
|
1. **Priority 1: BlockedIPsRule** ← CrowdSec IP 차단 (최고 우선순위) - `aws-cf-dev-blocked-ips` IP Set 사용
|
||||||
|
2. **Priority 2: RateLimitRule** ← 일반 레이트 제한 (10,000 req/5min) - 전체 IP 대상
|
||||||
|
3. **Priority 3: AWSManagedRulesCommonRuleSet** ← AWS 관리형 공통 규칙
|
||||||
|
4. **Priority 4: AWSManagedRulesKnownBadInputsRuleSet** ← AWS 관리형 악성 입력 규칙
|
||||||
|
|
||||||
|
**⚠️ 참고:** 이전에 있던 `suspicious_ips` IP Set과 `SuspiciousIPsRateLimit` 규칙은 현재 Lambda 기반 실시간 통합으로 대체되어 제거되었습니다.
|
||||||
|
|
||||||
|
## 🧪 테스트 및 검증
|
||||||
|
|
||||||
|
### 1. 웹훅 엔드포인트 테스트
|
||||||
|
```bash
|
||||||
|
curl -X POST https://8zdmpjfnhh.execute-api.us-east-1.amazonaws.com/dev/webhook \
|
||||||
|
-H "Content-Type: application/json" \
|
||||||
|
-H "User-Agent: CrowdSec/1.7.0" \
|
||||||
|
-d '[{
|
||||||
|
"uuid": "test-uuid-123",
|
||||||
|
"machine_id": "test-machine",
|
||||||
|
"created_at": "2025-09-09T02:50:00Z",
|
||||||
|
"scenario": "test/security-scan",
|
||||||
|
"source": {"ip": "192.168.1.100"},
|
||||||
|
"decisions": [{
|
||||||
|
"value": "192.168.1.100",
|
||||||
|
"type": "ban",
|
||||||
|
"action": "add",
|
||||||
|
"scope": "ip"
|
||||||
|
}]
|
||||||
|
}]'
|
||||||
|
```
|
||||||
|
|
||||||
|
**예상 응답:**
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"success": true,
|
||||||
|
"message": "WAF IP Set updated successfully",
|
||||||
|
"ips_added": ["192.168.1.100"],
|
||||||
|
"ips_removed": [],
|
||||||
|
"total_ips": 1
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
### 2. WAF IP Set 확인
|
||||||
|
```bash
|
||||||
|
# IP Set 내용 조회
|
||||||
|
aws wafv2 get-ip-set \
|
||||||
|
--scope CLOUDFRONT \
|
||||||
|
--id c43ff364-f3e2-43c7-8462-8fae20599d8d \
|
||||||
|
--name aws-cf-dev-blocked-ips \
|
||||||
|
--region us-east-1 \
|
||||||
|
--query 'IPSet.Addresses'
|
||||||
|
```
|
||||||
|
|
||||||
|
### 3. CrowdSec 알림 테스트
|
||||||
|
```bash
|
||||||
|
# CrowdSec 알림 테스트
|
||||||
|
incus exec crowdsec -- cscli notifications test aws-waf
|
||||||
|
```
|
||||||
|
|
||||||
|
## 📈 설치된 보안 컬렉션
|
||||||
|
|
||||||
|
### Nginx Proxy Manager 컬렉션
|
||||||
|
- **컬렉션:** `crowdsecurity/nginx-proxy-manager`
|
||||||
|
- **파서:** `crowdsecurity/nginx-proxy-manager-logs`
|
||||||
|
- **HTTP 로그:** `crowdsecurity/http-logs`
|
||||||
|
|
||||||
|
### 주요 보안 시나리오 (40+ 개)
|
||||||
|
- **Web 공격:** XSS, SQLi, Path Traversal 프로빙
|
||||||
|
- **CVE 취약점:** Log4j, Spring4Shell, Apache 등
|
||||||
|
- **관리자 인터페이스:** 무차별 대입 공격 감지
|
||||||
|
- **백도어 시도:** 악성 스크립트 업로드 감지
|
||||||
|
- **WordPress:** 스캔 및 무차별 대입 공격
|
||||||
|
- **네트워크:** 오픈 프록시, 크롤링 감지
|
||||||
|
|
||||||
|
## 🔧 리소스 정보
|
||||||
|
|
||||||
|
### AWS 리소스
|
||||||
|
```bash
|
||||||
|
# CloudFront Distribution ID
|
||||||
|
E1XR8P4ENGP8RU
|
||||||
|
|
||||||
|
# WAF Web ACL ID
|
||||||
|
d21d84c1-edb9-40af-9cdd-27f42f09c499
|
||||||
|
|
||||||
|
# WAF IP Set ID
|
||||||
|
c43ff364-f3e2-43c7-8462-8fae20599d8d
|
||||||
|
|
||||||
|
# Lambda Function
|
||||||
|
aws-cf-dev-crowdsec-waf-updater
|
||||||
|
|
||||||
|
# Webhook URL
|
||||||
|
https://8zdmpjfnhh.execute-api.us-east-1.amazonaws.com/dev/webhook
|
||||||
|
```
|
||||||
|
|
||||||
|
### Terraform 출력값
|
||||||
|
```bash
|
||||||
|
tofu output
|
||||||
|
```
|
||||||
|
|
||||||
|
## 🔍 모니터링 및 로그
|
||||||
|
|
||||||
|
### Lambda 함수 로그
|
||||||
|
```bash
|
||||||
|
# CloudWatch 로그 확인
|
||||||
|
aws logs tail /aws/lambda/aws-cf-dev-crowdsec-waf-updater --follow
|
||||||
|
```
|
||||||
|
|
||||||
|
### CrowdSec 로그
|
||||||
|
```bash
|
||||||
|
# CrowdSec 서비스 로그
|
||||||
|
incus exec crowdsec -- journalctl -u crowdsec -f
|
||||||
|
|
||||||
|
# 차단 결정 목록
|
||||||
|
incus exec crowdsec -- cscli decisions list
|
||||||
|
```
|
||||||
|
|
||||||
|
### WAF 메트릭
|
||||||
|
- CloudWatch에서 WAF 차단 메트릭 확인
|
||||||
|
- `BlockedIPsRule` 메트릭 모니터링
|
||||||
|
|
||||||
|
## 🛠️ 문제 해결
|
||||||
|
|
||||||
|
### 일반적인 문제
|
||||||
|
|
||||||
|
1. **웹훅 연결 실패**
|
||||||
|
- 네트워크 연결 확인
|
||||||
|
- API Gateway URL 유효성 검사
|
||||||
|
- CrowdSec 알림 설정 재검토
|
||||||
|
|
||||||
|
2. **Lambda 함수 오류**
|
||||||
|
- CloudWatch 로그 확인
|
||||||
|
- IAM 권한 검증
|
||||||
|
- WAF IP Set 접근 권한 확인
|
||||||
|
|
||||||
|
3. **IP가 차단되지 않음**
|
||||||
|
- WAF 규칙 우선순위 확인
|
||||||
|
- CloudFront 배포와 WAF 연결 상태
|
||||||
|
- IP Set 업데이트 상태 확인
|
||||||
|
|
||||||
|
### 디버깅 명령어
|
||||||
|
```bash
|
||||||
|
# CrowdSec 상태 확인
|
||||||
|
incus exec crowdsec -- cscli metrics
|
||||||
|
|
||||||
|
# 알림 플러그인 상태
|
||||||
|
incus exec crowdsec -- cscli notifications list
|
||||||
|
|
||||||
|
# Lambda 함수 테스트
|
||||||
|
aws lambda invoke --function-name aws-cf-dev-crowdsec-waf-updater response.json
|
||||||
|
|
||||||
|
# WAF 규칙 확인
|
||||||
|
aws wafv2 get-web-acl --scope CLOUDFRONT --id d21d84c1-edb9-40af-9cdd-27f42f09c499 --name aws-cf-dev-waf --region us-east-1
|
||||||
|
```
|
||||||
|
|
||||||
|
## 🚀 확장 가능성
|
||||||
|
|
||||||
|
1. **다중 환경 지원**
|
||||||
|
- 개발/스테이징/프로덕션 환경별 WAF 연결
|
||||||
|
- 환경별 IP Set 분리
|
||||||
|
|
||||||
|
2. **고급 알림**
|
||||||
|
- Slack/Discord 통합
|
||||||
|
- 이메일 알림 추가
|
||||||
|
- 대시보드 연동
|
||||||
|
|
||||||
|
3. **IP 화이트리스트**
|
||||||
|
- 신뢰할 수 있는 IP 자동 제외
|
||||||
|
- 지역별 IP 필터링
|
||||||
|
|
||||||
|
4. **자동 해제**
|
||||||
|
- 시간 기반 자동 차단 해제
|
||||||
|
- 위험도 기반 차단 기간 조정
|
||||||
|
|
||||||
|
## 📝 참고 자료
|
||||||
|
|
||||||
|
- [CrowdSec Documentation](https://docs.crowdsec.net/)
|
||||||
|
- [AWS WAF Developer Guide](https://docs.aws.amazon.com/waf/)
|
||||||
|
- [Lambda Developer Guide](https://docs.aws.amazon.com/lambda/)
|
||||||
|
- [CrowdSec Hub](https://hub.crowdsec.net/)
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
**구현 완료일:** 2025-09-09
|
||||||
|
**마지막 업데이트:** 2025-09-09
|
||||||
|
**작성자:** Claude Code SuperClaude Framework
|
||||||
11
main.tf
11
main.tf
@@ -35,8 +35,8 @@ resource "aws_cloudfront_distribution" "main" {
|
|||||||
comment = "CloudFront distribution for ${var.project_name} - ${var.environment}"
|
comment = "CloudFront distribution for ${var.project_name} - ${var.environment}"
|
||||||
default_root_object = "index.html"
|
default_root_object = "index.html"
|
||||||
|
|
||||||
# Aliases (custom domain names) - Disabled for default certificate
|
# Aliases (custom domain names) - Enable when ACM certificate is available
|
||||||
# aliases = var.cloudfront_aliases
|
aliases = var.create_acm_certificate ? var.cloudfront_aliases : null
|
||||||
|
|
||||||
# Default cache behavior
|
# Default cache behavior
|
||||||
default_cache_behavior {
|
default_cache_behavior {
|
||||||
@@ -74,9 +74,12 @@ resource "aws_cloudfront_distribution" "main" {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
# SSL/TLS certificate - Use CloudFront default certificate (temporary)
|
# SSL/TLS certificate - Use ACM certificate when available
|
||||||
viewer_certificate {
|
viewer_certificate {
|
||||||
cloudfront_default_certificate = true
|
acm_certificate_arn = var.create_acm_certificate ? aws_acm_certificate.main[0].arn : null
|
||||||
|
ssl_support_method = var.create_acm_certificate ? "sni-only" : null
|
||||||
|
minimum_protocol_version = var.create_acm_certificate ? "TLSv1.2_2021" : null
|
||||||
|
cloudfront_default_certificate = var.create_acm_certificate ? false : true
|
||||||
}
|
}
|
||||||
|
|
||||||
# Custom error responses
|
# Custom error responses
|
||||||
|
|||||||
23
outputs.tf
23
outputs.tf
@@ -67,6 +67,17 @@ output "waf_web_acl_id" {
|
|||||||
value = var.enable_waf ? aws_wafv2_web_acl.cloudfront[0].id : null
|
value = var.enable_waf ? aws_wafv2_web_acl.cloudfront[0].id : null
|
||||||
}
|
}
|
||||||
|
|
||||||
|
output "waf_blocked_ips_set_arn" {
|
||||||
|
description = "WAF Blocked IPs IP Set ARN"
|
||||||
|
value = var.enable_waf ? aws_wafv2_ip_set.blocked_ips[0].arn : null
|
||||||
|
}
|
||||||
|
|
||||||
|
output "waf_blocked_ips_set_id" {
|
||||||
|
description = "WAF Blocked IPs IP Set ID"
|
||||||
|
value = var.enable_waf ? aws_wafv2_ip_set.blocked_ips[0].id : null
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
# Origin Information
|
# Origin Information
|
||||||
output "origin_domain" {
|
output "origin_domain" {
|
||||||
description = "Origin domain name"
|
description = "Origin domain name"
|
||||||
@@ -111,3 +122,15 @@ output "domain_validation_records" {
|
|||||||
}
|
}
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
|
||||||
|
# CrowdSec Integration Information
|
||||||
|
output "crowdsec_sync_command" {
|
||||||
|
description = "Command to synchronize CrowdSec with WAF"
|
||||||
|
value = "incus exec crowdsec -- /usr/local/bin/crowdsec-waf-sync sync"
|
||||||
|
}
|
||||||
|
|
||||||
|
output "waf_ip_set_id" {
|
||||||
|
description = "WAF IP Set ID for CrowdSec integration"
|
||||||
|
value = var.enable_waf ? aws_wafv2_ip_set.blocked_ips[0].id : null
|
||||||
|
}
|
||||||
|
|
||||||
|
|||||||
48
security.tf
48
security.tf
@@ -83,6 +83,24 @@ resource "aws_security_group" "web" {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
# IP Set for blocked IPs
|
||||||
|
resource "aws_wafv2_ip_set" "blocked_ips" {
|
||||||
|
provider = aws.us_east_1 # CloudFront WAF must be in us-east-1
|
||||||
|
count = var.enable_waf ? 1 : 0
|
||||||
|
name = "${var.project_name}-${var.environment}-blocked-ips"
|
||||||
|
description = "IP addresses to be blocked"
|
||||||
|
scope = "CLOUDFRONT"
|
||||||
|
ip_address_version = "IPV4"
|
||||||
|
|
||||||
|
# Start with empty set - IPs can be added via AWS CLI or Console
|
||||||
|
addresses = []
|
||||||
|
|
||||||
|
tags = {
|
||||||
|
Name = "${var.project_name}-${var.environment}-blocked-ips"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
# WAF Web ACL for CloudFront (optional)
|
# WAF Web ACL for CloudFront (optional)
|
||||||
resource "aws_wafv2_web_acl" "cloudfront" {
|
resource "aws_wafv2_web_acl" "cloudfront" {
|
||||||
provider = aws.us_east_1 # CloudFront WAF must be in us-east-1
|
provider = aws.us_east_1 # CloudFront WAF must be in us-east-1
|
||||||
@@ -94,10 +112,32 @@ resource "aws_wafv2_web_acl" "cloudfront" {
|
|||||||
allow {}
|
allow {}
|
||||||
}
|
}
|
||||||
|
|
||||||
# Rate limiting rule
|
# Block IPs in blocked list
|
||||||
|
rule {
|
||||||
|
name = "BlockedIPsRule"
|
||||||
|
priority = 1
|
||||||
|
|
||||||
|
action {
|
||||||
|
block {}
|
||||||
|
}
|
||||||
|
|
||||||
|
statement {
|
||||||
|
ip_set_reference_statement {
|
||||||
|
arn = aws_wafv2_ip_set.blocked_ips[0].arn
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
visibility_config {
|
||||||
|
cloudwatch_metrics_enabled = true
|
||||||
|
metric_name = "BlockedIPsRule"
|
||||||
|
sampled_requests_enabled = true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
# Rate limiting rule (original setting restored)
|
||||||
rule {
|
rule {
|
||||||
name = "RateLimitRule"
|
name = "RateLimitRule"
|
||||||
priority = 1
|
priority = 2
|
||||||
|
|
||||||
action {
|
action {
|
||||||
block {}
|
block {}
|
||||||
@@ -120,7 +160,7 @@ resource "aws_wafv2_web_acl" "cloudfront" {
|
|||||||
# AWS Managed Rules - Core Rule Set
|
# AWS Managed Rules - Core Rule Set
|
||||||
rule {
|
rule {
|
||||||
name = "AWSManagedRulesCommonRuleSet"
|
name = "AWSManagedRulesCommonRuleSet"
|
||||||
priority = 2
|
priority = 3
|
||||||
|
|
||||||
override_action {
|
override_action {
|
||||||
none {}
|
none {}
|
||||||
@@ -143,7 +183,7 @@ resource "aws_wafv2_web_acl" "cloudfront" {
|
|||||||
# AWS Managed Rules - Known Bad Inputs
|
# AWS Managed Rules - Known Bad Inputs
|
||||||
rule {
|
rule {
|
||||||
name = "AWSManagedRulesKnownBadInputsRuleSet"
|
name = "AWSManagedRulesKnownBadInputsRuleSet"
|
||||||
priority = 3
|
priority = 4
|
||||||
|
|
||||||
override_action {
|
override_action {
|
||||||
none {}
|
none {}
|
||||||
|
|||||||
90
sync-crowdsec-to-waf.sh
Executable file
90
sync-crowdsec-to-waf.sh
Executable file
@@ -0,0 +1,90 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
|
||||||
|
# CrowdSec에서 차단된 IP를 AWS WAF BlockedIPsRule에 동기화하는 스크립트
|
||||||
|
|
||||||
|
# 설정
|
||||||
|
WAF_IP_SET_ID="c43ff364-f3e2-43c7-8462-8fae20599d8d"
|
||||||
|
WAF_IP_SET_NAME="aws-cf-dev-blocked-ips"
|
||||||
|
REGION="us-east-1"
|
||||||
|
SCOPE="CLOUDFRONT"
|
||||||
|
|
||||||
|
# CrowdSec에서 현재 차단된 IP 목록 가져오기
|
||||||
|
get_crowdsec_banned_ips() {
|
||||||
|
# CrowdSec CLI를 통해 차단된 IP 목록 가져오기
|
||||||
|
if command -v cscli &> /dev/null; then
|
||||||
|
# 로컬 CrowdSec에서 차단 결정 가져오기
|
||||||
|
cscli decisions list -o json | jq -r '.[] | select(.type=="ban") | .value' | sort -u
|
||||||
|
else
|
||||||
|
# Incus 컨테이너 내부의 CrowdSec에 접근
|
||||||
|
incus exec crowdsec -- cscli decisions list -o json | jq -r '.[] | select(.type=="ban") | .value' | sort -u
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
# AWS WAF IP Set의 현재 IP 목록 가져오기
|
||||||
|
get_waf_current_ips() {
|
||||||
|
aws wafv2 get-ip-set \
|
||||||
|
--scope $SCOPE \
|
||||||
|
--id $WAF_IP_SET_ID \
|
||||||
|
--name $WAF_IP_SET_NAME \
|
||||||
|
--region $REGION \
|
||||||
|
--query 'IPSet.Addresses[]' \
|
||||||
|
--output text | tr '\t' '\n' | sed 's|/32||g' | sort -u
|
||||||
|
}
|
||||||
|
|
||||||
|
# WAF IP Set 업데이트
|
||||||
|
update_waf_ip_set() {
|
||||||
|
local ip_list="$1"
|
||||||
|
|
||||||
|
# 현재 lock token 가져오기
|
||||||
|
LOCK_TOKEN=$(aws wafv2 get-ip-set \
|
||||||
|
--scope $SCOPE \
|
||||||
|
--id $WAF_IP_SET_ID \
|
||||||
|
--name $WAF_IP_SET_NAME \
|
||||||
|
--region $REGION \
|
||||||
|
--query 'LockToken' \
|
||||||
|
--output text)
|
||||||
|
|
||||||
|
# IP 주소를 CIDR 형식으로 변환 (단일 IP는 /32 추가)
|
||||||
|
local cidr_list=""
|
||||||
|
if [ -n "$ip_list" ]; then
|
||||||
|
cidr_list=$(echo "$ip_list" | grep -v '^$' | sed 's|$|/32|g' | paste -sd, -)
|
||||||
|
fi
|
||||||
|
|
||||||
|
echo "Updating WAF IP Set with IPs: $cidr_list"
|
||||||
|
|
||||||
|
# WAF IP Set 업데이트
|
||||||
|
aws wafv2 update-ip-set \
|
||||||
|
--scope $SCOPE \
|
||||||
|
--id $WAF_IP_SET_ID \
|
||||||
|
--name $WAF_IP_SET_NAME \
|
||||||
|
--addresses $cidr_list \
|
||||||
|
--lock-token $LOCK_TOKEN \
|
||||||
|
--region $REGION
|
||||||
|
}
|
||||||
|
|
||||||
|
# 메인 동기화 로직
|
||||||
|
sync_ips() {
|
||||||
|
echo "$(date): Starting CrowdSec to WAF IP sync..."
|
||||||
|
|
||||||
|
# CrowdSec에서 차단된 IP 가져오기
|
||||||
|
crowdsec_ips=$(get_crowdsec_banned_ips)
|
||||||
|
echo "CrowdSec banned IPs: $(echo "$crowdsec_ips" | wc -l) IPs"
|
||||||
|
|
||||||
|
# 현재 WAF IP Set의 IP 가져오기
|
||||||
|
waf_ips=$(get_waf_current_ips)
|
||||||
|
echo "Current WAF IPs: $(echo "$waf_ips" | wc -l) IPs"
|
||||||
|
|
||||||
|
# IP 목록 비교
|
||||||
|
if [ "$crowdsec_ips" != "$waf_ips" ]; then
|
||||||
|
echo "IP lists differ, updating WAF..."
|
||||||
|
update_waf_ip_set "$crowdsec_ips"
|
||||||
|
echo "WAF IP Set updated successfully!"
|
||||||
|
else
|
||||||
|
echo "IP lists are already in sync"
|
||||||
|
fi
|
||||||
|
|
||||||
|
echo "$(date): Sync completed"
|
||||||
|
}
|
||||||
|
|
||||||
|
# 실행
|
||||||
|
sync_ips
|
||||||
@@ -157,3 +157,4 @@ variable "cloudfront_logs_prefix" {
|
|||||||
type = string
|
type = string
|
||||||
default = "cloudfront-logs/"
|
default = "cloudfront-logs/"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user