diff --git a/CLAUDE.md b/CLAUDE.md index ed52c9e..7119c96 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -2,6 +2,10 @@ This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository. +## Project Overview + +AWS CloudFront CDN with CrowdSec real-time security integration via Lambda. Implements automated IP blocking through webhook notifications. + ## Common Development Commands ### Infrastructure Management @@ -30,10 +34,10 @@ echo "yes" | tofu init -migrate-state ### Validation and Formatting ```bash -# Validate Terraform configuration +# Validate configuration tofu validate -# Format Terraform files +# Format files tofu fmt # Check syntax and validate variables @@ -42,8 +46,8 @@ tofu plan -var-file=terraform.tfvars ### AWS Resource Verification ```bash -# Check CloudFront distribution status -aws cloudfront get-distribution --id E1XR8P4ENGP8RU --query 'Distribution.Status' --output text +# Check CloudFront distribution status (Current Distribution ID: EATJ1HDQU8V51) +aws cloudfront get-distribution --id EATJ1HDQU8V51 --query 'Distribution.Status' --output text # List all CloudFront distributions aws cloudfront list-distributions --query 'DistributionList.Items[*].[Id,Status,DistributionConfig.Enabled]' --output table @@ -64,7 +68,7 @@ This is an AWS CloudFront CDN deployment using OpenTofu (Terraform fork) with th - **CloudFront Distribution**: Main CDN with custom origin server - **WAF v2 Web ACL**: Security layer with rate limiting and AWS managed rules - **S3 Backend**: Remote state storage with versioning and encryption -- **Optional CloudFormation Stack**: VPC and networking resources +- **CrowdSec Integration**: Real-time threat detection and IP blocking **Critical Configuration Constraints:** - Origin server (`origin.servidor.it.com`) only supports HTTP, not HTTPS @@ -75,8 +79,10 @@ This is an AWS CloudFront CDN deployment using OpenTofu (Terraform fork) with th ### File Structure and Responsibilities **Core Infrastructure:** -- `main.tf` - CloudFront distribution, origin configuration, cache behaviors, and optional CloudFormation stack +- `main.tf` - CloudFront distribution, origin configuration, cache behaviors - `security.tf` - WAF Web ACL with rate limiting, managed rule sets, and security groups +- `lambda.tf` - CrowdSec Lambda integration with API Gateway +- `lambda-crowdsec-waf.py` - Lambda function for real-time IP management - `variables.tf` - All configurable parameters with validation rules - `outputs.tf` - CloudFront URLs, distribution IDs, and resource ARNs @@ -100,6 +106,7 @@ This is an AWS CloudFront CDN deployment using OpenTofu (Terraform fork) with th - WAF protection with AWS managed rules and rate limiting - S3 buckets with encryption, versioning, and public access blocking - Security groups with principle of least privilege (when VPC enabled) +- CrowdSec real-time threat detection with Lambda integration **Cache Strategy:** - Default behavior uses CachingDisabled policy for dynamic content @@ -115,9 +122,9 @@ This is an AWS CloudFront CDN deployment using OpenTofu (Terraform fork) with th ### Critical Settings in terraform.tfvars - `origin_protocol_policy = "http-only"` - **Do not change to HTTPS** (causes 504 errors) -- `create_acm_certificate = false` - Custom certificates fail due to CAA restrictions +- `create_acm_certificate = true` - ACM certificate enabled for custom domain - `enable_waf = true` - WAF is working and provides important security -- `create_route53_records = false` - DNS management disabled due to CAA restrictions +- `create_route53_records = true` - Route53 DNS management enabled ### State Management - Backend uses S3 without DynamoDB locking (single developer setup) @@ -135,15 +142,148 @@ This is an AWS CloudFront CDN deployment using OpenTofu (Terraform fork) with th - Compression enabled for all content types - Custom error pages redirect 404/403 to index.html for SPA support -### Working vs Disabled Features +## CrowdSec Integration + +**πŸ”„ Automated Workflow**: CrowdSec β†’ API Gateway β†’ Lambda β†’ AWS WAF β†’ CloudFront + +**πŸ“Š Current Resources (Updated 2025-09-09):** +- **CloudFront Distribution ID**: `EATJ1HDQU8V51` +- **CloudFront URL**: `https://d2mhxhntq3ezzr.cloudfront.net` +- **WAF Web ACL ID**: `d61073b6-27b1-473e-aa9f-d2aa4a4c75a6` +- **WAF IP Set ID**: `a9e47946-c186-4b28-83a8-fe3aeb9c296b` +- **Deployment Status**: `Deployed` βœ… + +### CrowdSec Integration Commands + +**⚠️ Note**: IP management is now automated via CrowdSec webhook integration. Manual commands are for monitoring and emergency use only. + +**View Current Blocked IPs:** +```bash +# View current blocked IPs (Updated IP Set ID) +aws wafv2 get-ip-set --scope CLOUDFRONT --region us-east-1 \ + --id a9e47946-c186-4b28-83a8-fe3aeb9c296b \ + --name aws-cf-dev-blocked-ips \ + --query 'IPSet.Addresses' +``` + +**Test CrowdSec Webhook:** +```bash +# Test webhook endpoint +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","decisions":[{"value":"1.2.3.4","type":"ban","action":"add"}]}]' +``` + +**Monitor CrowdSec Container:** +```bash +# Check CrowdSec status +incus exec crowdsec -- cscli metrics + +# View current decisions +incus exec crowdsec -- cscli decisions list + +# Test notifications +incus exec crowdsec -- cscli notifications test aws-waf +``` + +**Lambda Function Monitoring:** +```bash +# Check Lambda logs +aws logs tail /aws/lambda/aws-cf-dev-crowdsec-waf-updater --follow + +# Test Lambda directly +aws lambda invoke --function-name aws-cf-dev-crowdsec-waf-updater response.json +``` + +### WAF Monitoring + +**Check WAF Metrics:** +```bash +# Check blocked requests +aws cloudwatch get-metric-statistics --namespace AWS/WAFV2 \ + --metric-name BlockedRequests \ + --dimensions Name=WebACL,Value=aws-cf-dev-waf Name=Rule,Value=BlockedIPsRule \ + --start-time $(date -u -d '1 hour ago' +%Y-%m-%dT%H:%M:%S) \ + --end-time $(date -u +%Y-%m-%dT%H:%M:%S) \ + --period 300 --statistics Sum + +# Check rate limited requests +aws cloudwatch get-metric-statistics --namespace AWS/WAFV2 \ + --metric-name BlockedRequests \ + --dimensions Name=WebACL,Value=aws-cf-dev-waf Name=Rule,Value=RateLimitRule \ + --start-time $(date -u -d '1 hour ago' +%Y-%m-%dT%H:%M:%S) \ + --end-time $(date -u +%Y-%m-%dT%H:%M:%S) \ + --period 300 --statistics Sum +``` + +## Working vs Disabled Features + **Currently Working:** -- CloudFront distribution with HTTP origin -- WAF v2 with managed rules -- S3 logging and state storage -- Custom cache behaviors for API paths +- CloudFront distribution with HTTP origin βœ… +- WAF v2 with managed rules βœ… +- S3 logging and state storage βœ… +- Custom cache behaviors for API paths βœ… +- IP-based blocking through WAF IP Sets βœ… + +**Currently Enabled:** +- ACM custom certificates (b011e60a-1ea1-4dd3-844f-e0851ece4784) βœ… +- Route53 DNS management (Z01934581JQAF2GS71GG) βœ… +- WAF v2 with IP blocking (d61073b6-27b1-473e-aa9f-d2aa4a4c75a6) βœ… +- CrowdSec webhook integration (setup required) ⚠️ **Currently Disabled (can be enabled with proper permissions):** -- ACM custom certificates (CAA restrictions) -- Route53 DNS management (CAA restrictions) - CloudFormation VPC stack (permission constraints) -- DynamoDB state locking (permission constraints) \ No newline at end of file +- DynamoDB state locking (permission constraints) + +## WAF Troubleshooting History + +### Issue Resolution (2025-09-09) + +**Problem**: WAF IP blocking was not functioning despite proper configuration. + +**Root Cause Analysis:** +1. **IP Set ID Mismatch**: Commands referenced old IP Set ID (`c43ff364-f3e2-43c7-8462-8fae20599d8d`) instead of actual ID +2. **CloudFront Deployment State**: Distribution was in "InProgress" status preventing WAF changes from taking effect +3. **Configuration Synchronization**: WAF and CloudFront association was not properly synchronized + +**Resolution Method:** +- Complete infrastructure recreation using `tofu destroy` and `tofu apply` +- All resources recreated with fresh IDs and proper associations +- WAF rules now properly configured with correct IP Set references + +**Current Status:** +- βœ… WAF properly associated with CloudFront (`EATJ1HDQU8V51`) +- βœ… IP blocking rules functional (Priority 1: BlockedIPsRule) +- βœ… Rate limiting active (10,000 requests/5min per IP) +- βœ… AWS managed rule sets enabled (Common + Known Bad Inputs) +- βœ… Test IP blocking verified: `1.2.3.4/32`, `61.77.18.91/32` + +**Key Commands for Manual IP Management:** +```bash +# Add IP to blocked list +aws wafv2 update-ip-set --scope=CLOUDFRONT --region=us-east-1 \ + --id a9e47946-c186-4b28-83a8-fe3aeb9c296b \ + --name aws-cf-dev-blocked-ips \ + --addresses "IP1/32" "IP2/32" \ + --lock-token $(aws wafv2 get-ip-set --scope=CLOUDFRONT --region=us-east-1 \ + --id a9e47946-c186-4b28-83a8-fe3aeb9c296b \ + --name aws-cf-dev-blocked-ips --query 'LockToken' --output text) + +# Verify WAF-CloudFront association +aws cloudfront get-distribution --id EATJ1HDQU8V51 \ + --query 'Distribution.DistributionConfig.WebACLId' --output text + +# Check current blocked IPs +aws wafv2 get-ip-set --scope=CLOUDFRONT --region=us-east-1 \ + --id a9e47946-c186-4b28-83a8-fe3aeb9c296b \ + --name aws-cf-dev-blocked-ips --query 'IPSet.Addresses' +``` + +**Note**: WAF rule changes may take up to 15 minutes to propagate across CloudFront edge locations. + +# important-instruction-reminders +Do what has been asked; nothing more, nothing less. +NEVER create files unless they're absolutely necessary for achieving your goal. +ALWAYS prefer editing an existing file to creating a new one. +NEVER proactively create documentation files (*.md) or README files. Only create documentation files if explicitly requested by the User. \ No newline at end of file diff --git a/DEPLOYMENT_GUIDE.md b/DEPLOYMENT_GUIDE.md index 456cb7a..8f90755 100644 --- a/DEPLOYMENT_GUIDE.md +++ b/DEPLOYMENT_GUIDE.md @@ -1,241 +1,285 @@ -# AWS CloudFront 배포 κ°€μ΄λ“œ +# AWS CloudFront + CrowdSec 배포 κ°€μ΄λ“œ -## πŸ“‹ ν”„λ‘œμ νŠΈ κ°œμš” -AWS CloudFront CDN을 OpenTofu(Terraform fork)둜 κ΅¬μ„±ν•˜μ—¬ `origin.servidor.it.com`을 origin으둜 μ‚¬μš©ν•˜λŠ” μΈν”„λΌμŠ€νŠΈλŸ­μ²˜ ν”„λ‘œμ νŠΈμž…λ‹ˆλ‹€. +## πŸ“‹ μ™„μ „ 배포 κ°€μ΄λ“œ +AWS CloudFront CDNκ³Ό CrowdSec μ‹€μ‹œκ°„ λ³΄μ•ˆ 톡합 μ‹œμŠ€ν…œμ˜ 단계별 배포 κ°€μ΄λ“œμž…λ‹ˆλ‹€. -## πŸ—οΈ ν˜„μž¬ 인프라 μƒνƒœ +## 🎯 배포 λͺ©ν‘œ +- CloudFront CDN ꡬ성 (`origin.servidor.it.com`) +- CrowdSec μ»¨ν…Œμ΄λ„ˆ λ³΄μ•ˆ μ‹œμŠ€ν…œ +- Lambda 기반 μ‹€μ‹œκ°„ WAF 톡합 +- Nginx Proxy Manager 둜그 뢄석 -### CloudFront Distribution -- **Distribution ID**: E1XR8P4ENGP8RU -- **CloudFront URL**: https://dspki4yrh5oy1.cloudfront.net -- **Origin**: origin.servidor.it.com (HTTP-only) -- **Status**: βœ… Deployed and Working +## ⚠️ μ€‘μš” μ œμ•½μ‚¬ν•­ +- **Origin Protocol**: HTTP-only (HTTPS μ‚¬μš© μ‹œ 504 μ—λŸ¬) +- **DynamoDB Locking**: κΆŒν•œ μ œν•œμœΌλ‘œ λΉ„ν™œμ„±ν™” -### λ³΄μ•ˆ μ„€μ • -- **WAF**: AWS WAF v2 ν™œμ„±ν™” - - WAF ID: d21d84c1-edb9-40af-9cdd-27f42f09c499 - - Rate Limiting: 10,000 requests/5min per IP - - AWS Managed Rules - Common Rule Set (SQL Injection, XSS λ°©μ–΄) - - AWS Managed Rules - Known Bad Inputs (μ•…μ„± νŒ¨ν„΄ 차단) -- **Viewer Protocol**: HTTPS (redirect-to-https) -- **Origin Protocol**: HTTP-only (μ€‘μš”: HTTPS μ‚¬μš© μ‹œ 504 μ—λŸ¬) +## βœ… ν˜„μž¬ ν™œμ„±ν™”λœ κΈ°λŠ₯ +- **ACM Certificate**: ν™œμ„±ν™”λ¨ (b011e60a-1ea1-4dd3-844f-e0851ece4784) +- **Route53 Records**: ν™œμ„±ν™”λ¨ (Z01934581JQAF2GS71GG) +- **WAF Protection**: ν™œμ„±ν™”λ¨ (d61073b6-27b1-473e-aa9f-d2aa4a4c75a6) -### λ‘œκΉ… 및 μƒνƒœ 관리 -- **CloudFront Logs**: `s3://aws-cf-cloudfront-logs-535294143817/cloudfront-logs/` -- **Terraform State**: `s3://aws-cf-terraform-state-535294143817/aws-cf/terraform.tfstate` -- **State Locking**: λΉ„ν™œμ„±ν™” (DynamoDB κΆŒν•œ μ—†μŒ) - -## πŸš€ 배포 방법 +## πŸš€ 1단계: 인프라 배포 ### 사전 μš”κ΅¬μ‚¬ν•­ -- OpenTofu λ˜λŠ” Terraform μ„€μΉ˜ -- AWS CLI ꡬ성 -- ν•„μš”ν•œ IAM κΆŒν•œ: - - CloudFrontFullAccess - - S3FullAccess - - Route53FullAccess - - AWSCertificateManagerFullAccess - - AWSWAFFullAccess (WAFv2 포함) - - AWSCloudFormationFullAccess +- AWS CLI μ„€μ • μ™„λ£Œ +- OpenTofu μ„€μΉ˜ (`brew install opentofu`) +- Incus μ„€μΉ˜ 및 μ„€μ • -### 초기 μ„€μ • +### 인프라 배포 ```bash -# S3 Backend μ„€μ • (이미 μ™„λ£Œλ¨) -./setup-backend.sh +# ν”„λ‘œμ νŠΈ λ””λ ‰ν† λ¦¬λ‘œ 이동 +cd /Users/kaffa/Projects/was-cf -# State λ§ˆμ΄κ·Έλ ˆμ΄μ…˜ (이미 μ™„λ£Œλ¨) -echo "yes" | tofu init -migrate-state -``` - -### 배포 λͺ…λ Ήμ–΄ -```bash -# μ΄ˆκΈ°ν™” +# OpenTofu μ΄ˆκΈ°ν™” tofu init # κ³„νš 확인 tofu plan -# 배포 μ‹€ν–‰ +# 인프라 배포 tofu apply -auto-approve - -# μƒνƒœ 확인 -tofu state list ``` -## πŸ“ ν”„λ‘œμ νŠΈ ꡬ쑰 -``` -aws-cf/ -β”œβ”€β”€ main.tf # CloudFront 메인 ꡬ성 -β”œβ”€β”€ variables.tf # λ³€μˆ˜ μ •μ˜ -β”œβ”€β”€ terraform.tfvars # λ³€μˆ˜ κ°’ μ„€μ • -β”œβ”€β”€ outputs.tf # 좜λ ₯ μ •μ˜ -β”œβ”€β”€ versions.tf # Provider 버전 관리 -β”œβ”€β”€ backend.tf # S3 Backend μ„€μ • -β”œβ”€β”€ security.tf # WAF 및 λ³΄μ•ˆ κ·Έλ£Ή -β”œβ”€β”€ acm.tf # ACM μΈμ¦μ„œ (λΉ„ν™œμ„±ν™”) -β”œβ”€β”€ setup-backend.sh # S3 Backend μ„€μ • 슀크립트 -β”œβ”€β”€ README.md # κΈ°μ‘΄ λ¬Έμ„œ -└── DEPLOYMENT_GUIDE.md # 이 λ¬Έμ„œ +### 배포 κ²°κ³Ό 확인 +```bash +# 좜λ ₯κ°’ 확인 +tofu output + +# CloudFront μƒνƒœ 확인 +aws cloudfront get-distribution --id EATJ1HDQU8V51 --query 'Distribution.Status' + +# WAF κ·œμΉ™ 확인 +aws wafv2 get-web-acl --scope CLOUDFRONT --id d61073b6-27b1-473e-aa9f-d2aa4a4c75a6 --region us-east-1 ``` -## βš™οΈ μ€‘μš” μ„€μ • λ‚΄μš© +## πŸ”’ 2단계: CrowdSec μ»¨ν…Œμ΄λ„ˆ μ„€μ • -### terraform.tfvars 핡심 μ„€μ • -```hcl -# Origin μ„€μ • (맀우 μ€‘μš”) -origin_domain = "origin.servidor.it.com" -origin_protocol_policy = "http-only" # HTTPS μ‚¬μš© μ‹œ 504 μ—λŸ¬! - -# CloudFront μ„€μ • -viewer_protocol_policy = "redirect-to-https" -price_class = "PriceClass_100" - -# λ³΄μ•ˆ μ„€μ • -enable_waf = true - -# λ‘œκΉ… μ„€μ • -enable_cloudfront_logging = true -cloudfront_logs_bucket = "aws-cf-cloudfront-logs-535294143817" - -# λΉ„ν™œμ„±ν™”λœ κΈ°λŠ₯ (κΆŒν•œ/μ œν•œ 사항) -create_route53_records = false # CAA μ œν•œμœΌλ‘œ λΉ„ν™œμ„±ν™” -create_acm_certificate = false # CloudFront κΈ°λ³Έ μΈμ¦μ„œ μ‚¬μš© -enable_cloudformation_stack = false # CloudFormation κΆŒν•œ μ—†μŒ +### μ»¨ν…Œμ΄λ„ˆ 생성 +```bash +# μƒˆ Ubuntu μ»¨ν…Œμ΄λ„ˆ 생성 +incus launch ubuntu:24.04 crowdsec +incus exec crowdsec -- apt update ``` -## πŸ”§ 문제 ν•΄κ²° νžˆμŠ€ν† λ¦¬ +### CrowdSec μ„€μΉ˜ +```bash +# CrowdSec μ„€μΉ˜ +incus exec crowdsec -- curl -s https://install.crowdsec.net | sh -### 1. 504 Gateway Timeout ν•΄κ²° βœ… -**문제**: CloudFrontκ°€ origin μ„œλ²„μ— μ—°κ²°ν•  수 μ—†μŒ -**원인**: origin.servidor.it.com이 HTTP(80)만 μ§€μ›ν•˜λŠ”λ° HTTPS(443)둜 μ—°κ²° μ‹œλ„ -**ν•΄κ²°**: -```hcl -origin_protocol_policy = "http-only" +# μ„œλΉ„μŠ€ μƒνƒœ 확인 +incus exec crowdsec -- systemctl status crowdsec ``` -### 2. ACM μΈμ¦μ„œ CAA μ œν•œ βœ… -**문제**: *.servidor.it.com 도메인에 λŒ€ν•œ ACM μΈμ¦μ„œ λ°œκΈ‰ μ‹€νŒ¨ -**원인**: CAA DNS λ ˆμ½”λ“œκ°€ AWS μΈμ¦μ„œ λ°œκΈ‰μ„ μ œν•œ -**ν•΄κ²°**: CloudFront κΈ°λ³Έ μΈμ¦μ„œ μ‚¬μš© -```hcl -create_acm_certificate = false -viewer_certificate { - cloudfront_default_certificate = true +### λ³΄μ•ˆ μ»¬λ ‰μ…˜ μ„€μΉ˜ +```bash +# Nginx Proxy Manager μ»¬λ ‰μ…˜ μ„€μΉ˜ +incus exec crowdsec -- cscli collections install crowdsecurity/nginx-proxy-manager + +# μ„€μΉ˜λœ μ»¬λ ‰μ…˜ 확인 +incus exec crowdsec -- cscli collections list + +# μ„€μ • 적용 +incus exec crowdsec -- systemctl reload crowdsec +``` + +## πŸ”— 3단계: μ›Ήν›… 톡합 μ„€μ • + +### μ•Œλ¦Ό μ„€μ • 파일 생성 +```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 +``` + +### ν”„λ‘œν•„ μ„€μ • +```bash +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 μž¬μ‹œμž‘ +```bash +incus exec crowdsec -- systemctl restart crowdsec +``` + +## πŸ§ͺ 4단계: 톡합 ν…ŒμŠ€νŠΈ + +### μ›Ήν›… μ—”λ“œν¬μΈνŠΈ ν…ŒμŠ€νŠΈ +```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-123", + "decisions": [{ + "value": "192.168.1.100", + "type": "ban", + "action": "add" + }] + }]' +``` + +**μ˜ˆμƒ 응닡:** +```json +{ + "success": true, + "message": "WAF IP Set updated successfully", + "ips_added": ["192.168.1.100"], + "ips_removed": [], + "total_ips": 1 } ``` -### 3. DynamoDB State Locking κΆŒν•œ βœ… -**문제**: Terraform state locking을 μœ„ν•œ DynamoDB ν…Œμ΄λΈ” 생성/μ ‘κ·Ό λΆˆκ°€ -**ν•΄κ²°**: S3만 μ‚¬μš© (1인 개발 μ‹œ μΆ©λΆ„) -```hcl -backend "s3" { - bucket = "aws-cf-terraform-state-535294143817" - key = "aws-cf/terraform.tfstate" - # dynamodb_table = "terraform-state-lock" # λΉ„ν™œμ„±ν™” -} -``` - -### 4. 쀑볡 CloudFront Distribution 정리 βœ… -**문제**: μ—¬λŸ¬ 배포 μ‹œλ„λ‘œ 3개의 distribution 생성 -**ν•΄κ²°**: -- E18GW141CX7I8C - λΉ„ν™œμ„±ν™” 쀑 (μ‚­μ œ μ˜ˆμ •) -- E32FD742KMW2YY - λΉ„ν™œμ„±ν™” 쀑 (μ‚­μ œ μ˜ˆμ •) -- E1XR8P4ENGP8RU - ν˜„μž¬ μ‚¬μš© 쀑 βœ… - -### 5. WAF κΆŒν•œ 문제 βœ… -**초기 문제**: WAFv2 κΆŒν•œ μ—†λ‹€κ³  였λ₯˜ λ°œμƒ -**ν•΄κ²°**: AWSWAFFullAccess 정책에 wafv2:* κΆŒν•œ ν¬ν•¨λ˜μ–΄ 있음 확인 - -## πŸ“Š λͺ¨λ‹ˆν„°λ§ 및 관리 - -### μƒνƒœ 확인 λͺ…λ Ήμ–΄ +### WAF IP Set 확인 ```bash -# CloudFront μƒνƒœ -aws cloudfront get-distribution --id E1XR8P4ENGP8RU \ - --query 'Distribution.Status' --output text - -# WAF μ—°κ²° 확인 -aws cloudfront get-distribution --id E1XR8P4ENGP8RU \ - --query 'Distribution.DistributionConfig.WebACLId' --output text - -# 둜그 확인 -aws s3 ls s3://aws-cf-cloudfront-logs-535294143817/cloudfront-logs/ --recursive - -# State 파일 확인 -aws s3 ls s3://aws-cf-terraform-state-535294143817/aws-cf/ +aws wafv2 get-ip-set --scope CLOUDFRONT --region us-east-1 \ + --id a9e47946-c186-4b28-83a8-fe3aeb9c296b \ + --name aws-cf-dev-blocked-ips \ + --query 'IPSet.Addresses' ``` -### μ„±λŠ₯ ν…ŒμŠ€νŠΈ +### IP 제거 ν…ŒμŠ€νŠΈ ```bash -# CloudFront 응닡 확인 -curl -I https://dspki4yrh5oy1.cloudfront.net - -# 좜λ ₯ μ˜ˆμ‹œ: -# HTTP/2 200 -# content-type: text/html -# x-cache: Miss from cloudfront (첫 μš”μ²­) / Hit from cloudfront (μΊμ‹œλœ μš”μ²­) +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-456", + "decisions": [{ + "value": "192.168.1.100", + "type": "ban", + "action": "delete" + }] + }]' ``` -### λΉ„ν™œμ„±ν™”λœ Distribution μ‚­μ œ (μ™„μ „ λΉ„ν™œμ„±ν™” ν›„) +### CrowdSec μ•Œλ¦Ό ν…ŒμŠ€νŠΈ ```bash -# μƒνƒœ 확인 -aws cloudfront list-distributions \ - --query 'DistributionList.Items[*].[Id,Status,DistributionConfig.Enabled]' \ - --output table - -# μ‚­μ œ (Deployed μƒνƒœμ—μ„œ Enabled=false 일 λ•Œ) -aws cloudfront get-distribution-config --id E18GW141CX7I8C > dist-config.json -ETAG=$(jq -r '.ETag' dist-config.json) -aws cloudfront delete-distribution --id E18GW141CX7I8C --if-match $ETAG +incus exec crowdsec -- cscli notifications test aws-waf ``` -## πŸ”’ λ³΄μ•ˆ 고렀사항 +## πŸ“Š 5단계: λͺ¨λ‹ˆν„°λ§ μ„€μ • -1. **WAF μ„€μ •** - - ν˜„μž¬ κΈ°λ³Έ AWS Managed Rules μ‚¬μš© - - ν•„μš”μ‹œ μ»€μŠ€ν…€ λ£° μΆ”κ°€ κ°€λŠ₯ - - Rate limiting μ‘°μ • κ°€λŠ₯ (security.tf) +### Lambda ν•¨μˆ˜ 둜그 λͺ¨λ‹ˆν„°λ§ +```bash +# μ‹€μ‹œκ°„ 둜그 확인 +aws logs tail /aws/lambda/aws-cf-dev-crowdsec-waf-updater --follow -2. **Origin λ³΄μ•ˆ** - - ⚠️ Origin이 HTTP만 μ§€μ›ν•˜λ―€λ‘œ CloudFront-Origin κ°„ νŠΈλž˜ν”½ μ•”ν˜Έν™” μ•ˆλ¨ - - ꢌμž₯: Origin μ„œλ²„μ— HTTPS 지원 μΆ”κ°€ +# νŠΉμ • μ‹œκ°„λŒ€ 둜그 +aws logs filter-log-events \ + --log-group-name /aws/lambda/aws-cf-dev-crowdsec-waf-updater \ + --start-time $(date -d '1 hour ago' +%s)000 +``` -3. **둜그 관리** - - CloudFront 둜그 90일 μžλ™ μ‚­μ œ μ„€μ • - - μž₯κΈ° 보관 ν•„μš”μ‹œ S3 lifecycle μˆ˜μ • +### CrowdSec μƒνƒœ λͺ¨λ‹ˆν„°λ§ +```bash +# λ©”νŠΈλ¦­ 확인 +incus exec crowdsec -- cscli metrics -## πŸ“ ν–₯ν›„ κ°œμ„  사항 +# ν˜„μž¬ 차단 κ²°μ • +incus exec crowdsec -- cscli decisions list -### κΆŒν•œ νšλ“ μ‹œ ν™œμ„±ν™” κ°€λŠ₯ν•œ κΈ°λŠ₯ -1. **DynamoDB State Locking** - - νŒ€ ν˜‘μ—… μ‹œ ν•„μˆ˜ - - backend.tfμ—μ„œ 주석 ν•΄μ œ +# ν—ˆλΈŒ μƒνƒœ +incus exec crowdsec -- cscli hub list +``` -2. **Custom Domain with ACM** - - CAA λ ˆμ½”λ“œ μˆ˜μ • ν›„ κ°€λŠ₯ - - terraform.tfvarsμ—μ„œ `create_acm_certificate = true` +### WAF λ©”νŠΈλ¦­ 확인 +```bash +# μ°¨λ‹¨λœ μš”μ²­ 확인 +aws cloudwatch get-metric-statistics \ + --namespace AWS/WAFV2 \ + --metric-name BlockedRequests \ + --dimensions Name=WebACL,Value=aws-cf-dev-waf Name=Rule,Value=BlockedIPsRule \ + --start-time $(date -u -d '1 hour ago' +%Y-%m-%dT%H:%M:%S) \ + --end-time $(date -u +%Y-%m-%dT%H:%M:%S) \ + --period 300 --statistics Sum +``` -3. **CloudFormation Stack** - - VPC 및 λ„€νŠΈμ›Œν‚Ή λ¦¬μ†ŒμŠ€ 관리 - - terraform.tfvarsμ—μ„œ `enable_cloudformation_stack = true` +## πŸ”§ 문제 ν•΄κ²° -### μ„±λŠ₯ μ΅œμ ν™” -1. Cache Policy μ΅œμ ν™” -2. Origin Request Policy μ‘°μ • -3. CloudFront Edge Location 선택 (Price Class) +### 일반적인 λ¬Έμ œλ“€ -## 🏷️ νƒœκ·Έ 및 메타데이터 -- **Project**: aws-cf -- **Environment**: dev -- **ManagedBy**: OpenTofu -- **Owner**: kaffa -- **Created**: 2025-09-08 -- **LastUpdated**: 2025-09-09 +**1. μ›Ήν›… μ—°κ²° μ‹€νŒ¨** +```bash +# λ„€νŠΈμ›Œν¬ μ—°κ²° 확인 +incus exec crowdsec -- curl -I https://8zdmpjfnhh.execute-api.us-east-1.amazonaws.com/dev/webhook -## πŸ“š μ°Έκ³  자료 -- [OpenTofu Documentation](https://opentofu.org/docs/) -- [AWS CloudFront Best Practices](https://docs.aws.amazon.com/cloudfront/latest/developerguide/best-practices.html) -- [AWS WAF Documentation](https://docs.aws.amazon.com/waf/latest/developerguide/) +# CrowdSec μ•Œλ¦Ό μ„€μ • 확인 +incus exec crowdsec -- cat /etc/crowdsec/notifications/aws-waf.yaml +``` + +**2. Lambda ν•¨μˆ˜ 였λ₯˜** +```bash +# Lambda ν•¨μˆ˜ 직접 ν…ŒμŠ€νŠΈ +aws lambda invoke --function-name aws-cf-dev-crowdsec-waf-updater response.json + +# μ—λŸ¬ 둜그 확인 +aws logs describe-log-groups --log-group-name-prefix "/aws/lambda/aws-cf-dev" +``` + +**3. WAF μ—…λ°μ΄νŠΈ μ‹€νŒ¨** +```bash +# IAM κΆŒν•œ 확인 +aws iam get-role-policy --role-name aws-cf-dev-lambda-waf-role --policy-name aws-cf-dev-lambda-waf-policy + +# WAF IP Set μƒνƒœ 확인 +aws wafv2 get-ip-set --scope CLOUDFRONT --region us-east-1 --id a9e47946-c186-4b28-83a8-fe3aeb9c296b --name aws-cf-dev-blocked-ips +``` + +## πŸ“ˆ 운영 관리 + +### μ •κΈ° μœ μ§€λ³΄μˆ˜ +```bash +# CrowdSec μ—…λ°μ΄νŠΈ +incus exec crowdsec -- cscli hub update +incus exec crowdsec -- cscli hub upgrade + +# μ»¬λ ‰μ…˜ μƒνƒœ 확인 +incus exec crowdsec -- cscli collections list + +# μ‹œμŠ€ν…œ λ¦¬μ†ŒμŠ€ 확인 +incus info crowdsec +``` + +### λ°±μ—… 및 볡ꡬ +```bash +# CrowdSec μ„€μ • λ°±μ—… +incus exec crowdsec -- tar -czf /tmp/crowdsec-config.tar.gz /etc/crowdsec + +# μ„€μ • 파일 볡사 +incus file pull crowdsec/tmp/crowdsec-config.tar.gz ./ + +# Terraform μƒνƒœ λ°±μ—… +aws s3 sync s3://aws-cf-terraform-state-535294143817 ./backup/ +``` + +## 🎯 μ™„λ£Œ 체크리슀트 + +- [ ] AWS 인프라 배포 μ™„λ£Œ +- [ ] CrowdSec μ»¨ν…Œμ΄λ„ˆ μ„€μ • μ™„λ£Œ +- [ ] μ›Ήν›… 톡합 μ„€μ • μ™„λ£Œ +- [ ] 톡합 ν…ŒμŠ€νŠΈ 성곡 +- [ ] λͺ¨λ‹ˆν„°λ§ μ„€μ • μ™„λ£Œ +- [ ] λ¬Έμ„œν™” μ™„λ£Œ --- -*이 λ¬Έμ„œλŠ” μ‹€μ œ 배포 κ²½ν—˜μ„ λ°”νƒ•μœΌλ‘œ μž‘μ„±λ˜μ—ˆμŠ΅λ‹ˆλ‹€.* \ No newline at end of file + +**배포 μ™„λ£Œ μ‹œκ°„**: μ•½ 30-45λΆ„ +**ν•„μˆ˜ κΆŒν•œ**: AWS WAF, Lambda, API Gateway, CloudWatch μ ‘κ·Ό +**지원**: [CrowdSec Integration Guide](CROWDSEC-WAF-INTEGRATION.md) μ°Έμ‘° \ No newline at end of file diff --git a/README.md b/README.md index 6525499..32e0546 100644 --- a/README.md +++ b/README.md @@ -1,151 +1,87 @@ -# AWS CloudFront with OpenTofu +# AWS CloudFront + CrowdSec WAF Integration -이 ν”„λ‘œμ νŠΈλŠ” OpenTofuλ₯Ό μ‚¬μš©ν•˜μ—¬ AWS CloudFront 배포와 CloudFormation μŠ€νƒμ„ κ΄€λ¦¬ν•©λ‹ˆλ‹€. +πŸ›‘οΈ AWS CloudFront CDN with real-time CrowdSec threat protection via Lambda integration. -## ꡬ쑰 +## πŸ—οΈ Architecture -- `versions.tf` - Provider 및 Terraform 버전 μ„€μ • -- `variables.tf` - μž…λ ₯ λ³€μˆ˜ μ •μ˜ -- `main.tf` - CloudFront 배포 및 CloudFormation μŠ€νƒ -- `security.tf` - λ³΄μ•ˆ κ·Έλ£Ή 및 WAF μ„€μ • -- `outputs.tf` - 좜λ ₯ λ³€μˆ˜ -- `terraform.tfvars.example` - λ³€μˆ˜ μ„€μ • μ˜ˆμ‹œ - -## μ£Όμš” κΈ°λŠ₯ - -### CloudFront 배포 -- `origin.servidor.it.com`을 원본 μ„œλ²„λ‘œ μ‚¬μš© -- HTTPS λ¦¬λ””λ ‰μ…˜ 및 μ••μΆ• 지원 -- μ‚¬μš©μž μ •μ˜ 도메인(CNAME) 지원 -- μΊμ‹œ μ •μ±… 및 원본 μš”μ²­ μ •μ±… μ„€μ • -- μ»€μŠ€ν…€ 였λ₯˜ νŽ˜μ΄μ§€ μ„€μ • - -### CloudFormation μŠ€νƒ -- VPC 및 λ„€νŠΈμ›Œν‚Ή λ¦¬μ†ŒμŠ€ 생성 -- 퍼블릭 μ„œλΈŒλ„· 및 인터넷 κ²Œμ΄νŠΈμ›¨μ΄ -- μŠ€νƒ 좜λ ₯을 ν†΅ν•œ λ¦¬μ†ŒμŠ€ ID 곡유 - -### λ³΄μ•ˆ κΈ°λŠ₯ -- ALB 및 μ›Ή μ„œλ²„μš© λ³΄μ•ˆ κ·Έλ£Ή (선택사항) -- AWS WAF v2 μ›Ή ACL (선택사항) -- 레이트 μ œν•œ 및 관리 κ·œμΉ™ μ„ΈνŠΈ - -## μ‚¬μš© 방법 - -### 1. ν™˜κ²½ μ„€μ • - -```bash -# OpenTofu μ„€μΉ˜ 확인 -tofu version - -# AWS 자격 증λͺ… μ„€μ • -export AWS_ACCESS_KEY_ID="your-access-key" -export AWS_SECRET_ACCESS_KEY="your-secret-key" -export AWS_DEFAULT_REGION="us-east-1" +``` +CrowdSec Container β†’ API Gateway β†’ Lambda β†’ AWS WAF β†’ CloudFront Distribution ``` -### 2. λ³€μˆ˜ μ„€μ • +## πŸ“‹ Project Overview + +- **CloudFront Distribution**: `EATJ1HDQU8V51` +- **Origin Server**: `origin.servidor.it.com` (HTTP-only) +- **WAF Protection**: Real-time IP blocking via CrowdSec +- **Custom Domains**: `servidor.it.com`, `www.servidor.it.com` +- **ACM Certificate**: `b011e60a-1ea1-4dd3-844f-e0851ece4784` + +## πŸš€ Quick Start ```bash -# μ„€μ • 파일 볡사 -cp terraform.tfvars.example terraform.tfvars - -# ν•„μš”ν•œ κ°’λ“€ μˆ˜μ • -vim terraform.tfvars -``` - -### 3. 배포 - -```bash -# μ΄ˆκΈ°ν™” +# 1. Deploy infrastructure tofu init - -# κ³„νš 확인 -tofu plan - -# 배포 μ‹€ν–‰ tofu apply + +# 2. Configure CrowdSec +incus exec crowdsec -- cscli collections install crowdsecurity/nginx-proxy-manager + +# 3. Verify WAF configuration +aws wafv2 get-ip-set --scope CLOUDFRONT --region us-east-1 \ + --id a9e47946-c186-4b28-83a8-fe3aeb9c296b \ + --name aws-cf-dev-blocked-ips ``` -### 4. 확인 +## πŸ“Š Key Resources -배포 ν›„ 좜λ ₯된 CloudFront URL을 톡해 μ„œλΉ„μŠ€μ— μ ‘κ·Όν•  수 μžˆμŠ΅λ‹ˆλ‹€: +- **CloudFront URL**: https://d2mhxhntq3ezzr.cloudfront.net +- **WAF Web ACL ID**: `d61073b6-27b1-473e-aa9f-d2aa4a4c75a6` +- **WAF IP Set ID**: `a9e47946-c186-4b28-83a8-fe3aeb9c296b` +- **Route53 Zone ID**: `Z01934581JQAF2GS71GG` + +## πŸ›‘οΈ Security Features + +1. **Priority 1**: CrowdSec real-time IP blocking +2. **Priority 2**: Rate limiting (10K req/5min) +3. **Priority 3**: AWS Managed Common Rules +4. **Priority 4**: AWS Managed Bad Input Rules + +## πŸ“ Project Structure + +``` +β”œβ”€β”€ README.md # This file +β”œβ”€β”€ CLAUDE.md # Development guide for Claude Code +β”œβ”€β”€ DEPLOYMENT_GUIDE.md # Detailed deployment instructions +β”œβ”€β”€ CROWDSEC-WAF-INTEGRATION.md # CrowdSec integration documentation +β”œβ”€β”€ main.tf # CloudFront and core infrastructure +β”œβ”€β”€ security.tf # WAF and security configurations +β”œβ”€β”€ lambda.tf # CrowdSec Lambda integration +β”œβ”€β”€ lambda-crowdsec-waf.py # Lambda function code +└── terraform.tfvars # Configuration variables +``` + +## πŸ“š Documentation + +- **πŸš€ [Deployment Guide](DEPLOYMENT_GUIDE.md)** - Complete deployment instructions +- **πŸ›‘οΈ [CrowdSec Integration](CROWDSEC-WAF-INTEGRATION.md)** - Real-time security setup +- **πŸ”§ [Development Guide](CLAUDE.md)** - Claude Code specific instructions + +## ⚑ Common Commands ```bash -# CloudFront 배포 μƒνƒœ 확인 -aws cloudfront get-distribution --id +# Check WAF blocked IPs +aws wafv2 get-ip-set --scope CLOUDFRONT --region us-east-1 \ + --id a9e47946-c186-4b28-83a8-fe3aeb9c296b \ + --name aws-cf-dev-blocked-ips \ + --query 'IPSet.Addresses' -# CloudFormation μŠ€νƒ μƒνƒœ 확인 -aws cloudformation describe-stacks --stack-name +# Monitor CrowdSec decisions +incus exec crowdsec -- cscli decisions list + +# View Lambda logs +aws logs tail /aws/lambda/aws-cf-dev-crowdsec-waf-updater --follow ``` -## μ€‘μš” μ„€μ • +--- -### SSL μΈμ¦μ„œ - -이 섀정은 **ACM(AWS Certificate Manager) μΈμ¦μ„œ**λ₯Ό μ‚¬μš©ν•©λ‹ˆλ‹€: - -- `servidor.it.com`κ³Ό `*.servidor.it.com` 도메인 지원 -- μžλ™μœΌλ‘œ us-east-1 리전에 ACM μΈμ¦μ„œ 생성 -- DNS 검증을 ν†΅ν•œ μžλ™ μΈμ¦μ„œ λ°œκΈ‰ -- Route53을 ν†΅ν•œ μžλ™ DNS λ ˆμ½”λ“œ 관리 -- CloudFront와 μ™„μ „ ν†΅ν•©λœ HTTPS μ„€μ • - -### μΊμ‹œ μ •μ±… - -κΈ°λ³Έ μ œκ³΅λ˜λŠ” AWS 관리 μ •μ±…: - -- `4135ea2d-6df8-44a3-9df3-4b5a84be39ad` - CachingDisabled -- `725fe1d6-8a84-4f3e-8ab1-bc2d5bb10e12` - CachingOptimized -- `df3c6b6c-4e41-4d9c-a8c7-6b8b2b8e6b8b` - CachingOptimizedForUncompressedObjects - -### λ³΄μ•ˆ 고렀사항 - -ν”„λ‘œλ•μ…˜ ν™˜κ²½μ—μ„œλŠ”: - -- `ssh_allowed_cidrs`λ₯Ό νŠΉμ • IP둜 μ œν•œ -- WAF ν™œμ„±ν™” (`enable_waf = true`) -- μ μ ˆν•œ μΊμ‹œ μ •μ±… 선택 -- CloudTrail 및 CloudWatch λ‘œκΉ… ν™œμ„±ν™” - -### 도메인 μ„€μ • - -**μ „μ œ 쑰건**: -- `servidor.it.com` λ„λ©”μΈμ˜ Route53 ν˜ΈμŠ€νŒ… μ˜μ—­μ΄ μ‘΄μž¬ν•΄μ•Ό 함 -- λ„λ©”μΈμ˜ λ„€μž„μ„œλ²„κ°€ Route53으둜 μ„€μ •λ˜μ–΄ μžˆμ–΄μ•Ό 함 - -**μžλ™ μ„€μ •**: -- ACM μΈμ¦μ„œ μžλ™ 생성 및 검증 -- Route53 A λ ˆμ½”λ“œ μžλ™ 생성 (`servidor.it.com` β†’ CloudFront) -- Route53 A λ ˆμ½”λ“œ μžλ™ 생성 (`www.servidor.it.com` β†’ CloudFront) - -## 좜λ ₯ 정보 - -배포 μ™„λ£Œ ν›„ λ‹€μŒ 정보듀이 좜λ ₯λ©λ‹ˆλ‹€: - -- CloudFront 배포 ID 및 도메인 -- CloudFormation μŠ€νƒ 정보 -- λ³΄μ•ˆ κ·Έλ£Ή ID (ν™œμ„±ν™”λœ 경우) -- WAF Web ACL ARN (ν™œμ„±ν™”λœ 경우) -- VPC 및 μ„œλΈŒλ„· 정보 - -## 정리 - -```bash -# λ¦¬μ†ŒμŠ€ μ‚­μ œ -tofu destroy -``` - -## 문제 ν•΄κ²° - -### 일반적인 였λ₯˜ - -1. **μΈμ¦μ„œ 였λ₯˜**: CloudFront용 μΈμ¦μ„œλŠ” us-east-1μ—μ„œλ§Œ 생성 κ°€λŠ₯ -2. **도메인 검증**: CNAME μ„€μ • 전에 도메인 μ†Œμœ κΆŒ 확인 ν•„μš” -3. **원본 μ„œλ²„**: `origin.servidor.it.com`이 HTTPSλ₯Ό μ§€μ›ν•˜λŠ”μ§€ 확인 - -### 둜그 확인 - -- CloudFront μ•‘μ„ΈμŠ€ 둜그 ν™œμ„±ν™” -- CloudWatch λ©”νŠΈλ¦­ λͺ¨λ‹ˆν„°λ§ -- WAF 둜그 뢄석 (ν™œμ„±ν™”λœ 경우) \ No newline at end of file +**Status**: βœ… Production Ready | **Last Updated**: 2025-09-09 \ No newline at end of file