Files
was-cf/CLAUDE.md
kappa d5440630f5 Update documentation with current infrastructure state
- Update all resource IDs to match current deployment
- CloudFront Distribution: EATJ1HDQU8V51
- WAF Web ACL: d61073b6-27b1-473e-aa9f-d2aa4a4c75a6
- WAF IP Set: a9e47946-c186-4b28-83a8-fe3aeb9c296b
- ACM Certificate: b011e60a-1ea1-4dd3-844f-e0851ece4784
- Route53 Zone: Z01934581JQAF2GS71GG
- Reflect enabled ACM certificate and Route53 DNS management
- Update all AWS CLI commands with correct resource IDs

🤖 Generated with [Claude Code](https://claude.ai/code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-09-09 15:32:35 +09:00

10 KiB

CLAUDE.md

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

# Initialize OpenTofu (required after cloning)
tofu init

# Plan changes
tofu plan

# Apply changes
tofu apply

# Destroy infrastructure
tofu destroy

Backend Setup (S3 + CloudFront Logs)

# Set up S3 backend and CloudFront logging buckets
./setup-backend.sh

# Migrate state to S3 backend (one-time operation)
echo "yes" | tofu init -migrate-state

Validation and Formatting

# Validate configuration
tofu validate

# Format files
tofu fmt

# Check syntax and validate variables
tofu plan -var-file=terraform.tfvars

AWS Resource Verification

# 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

# Check S3 backend state
aws s3 ls s3://aws-cf-terraform-state-535294143817/aws-cf/

# View CloudFront logs
aws s3 ls s3://aws-cf-cloudfront-logs-535294143817/cloudfront-logs/ --recursive

Architecture Overview

Infrastructure Design

This is an AWS CloudFront CDN deployment using OpenTofu (Terraform fork) with the following key architectural decisions:

Primary Components:

  • 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
  • CrowdSec Integration: Real-time threat detection and IP blocking

Critical Configuration Constraints:

  • Origin server (origin.servidor.it.com) only supports HTTP, not HTTPS
  • Using CloudFront default certificate (not custom ACM certificate)
  • Route53 records disabled due to CAA restrictions
  • DynamoDB state locking disabled due to permission constraints

File Structure and Responsibilities

Core Infrastructure:

  • 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

Configuration Management:

  • backend.tf - S3 remote state configuration (no DynamoDB locking)
  • versions.tf - OpenTofu/Terraform and provider version constraints
  • acm.tf - ACM certificate configuration (currently disabled)
  • terraform.tfvars.example - Variable configuration template

Operational Scripts:

  • setup-backend.sh - Automated S3 backend and logging bucket creation with proper permissions

Key Architectural Patterns

Multi-Environment Design:

  • Variables for project_name and environment enable multiple deployments
  • Resource naming follows ${project_name}-${environment}-${resource} pattern
  • Tags applied consistently across all resources

Security-First Approach:

  • 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
  • API paths (/api/*) specifically configured with caching disabled
  • Static content can be optimized by changing cache policy IDs

Conditional Resource Creation:

  • Most resources controlled by boolean variables for flexible deployment
  • ACM certificates, Route53 records, and CloudFormation stacks can be toggled
  • Allows gradual feature enablement as permissions are acquired

Important Configuration Notes

Critical Settings in terraform.tfvars

  • origin_protocol_policy = "http-only" - Do not change to HTTPS (causes 504 errors)
  • create_acm_certificate = true - ACM certificate enabled for custom domain
  • enable_waf = true - WAF is working and provides important security
  • create_route53_records = true - Route53 DNS management enabled

State Management

  • Backend uses S3 without DynamoDB locking (single developer setup)
  • State bucket: aws-cf-terraform-state-535294143817
  • Logs bucket: aws-cf-cloudfront-logs-535294143817

Security Considerations

  • WAF provides protection against common attacks and rate limiting
  • Origin-to-CloudFront traffic is unencrypted (HTTP-only constraint)
  • SSH access defaults to 0.0.0.0/0 in variables - restrict in production
  • CloudFront logs stored in S3 with 90-day lifecycle policy

Performance Optimization

  • Price class set to PriceClass_100 (US, Canada, Europe)
  • Compression enabled for all content types
  • Custom error pages redirect 404/403 to index.html for SPA support

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:

# 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:

# 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:

# 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:

# 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:

# 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
  • 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):

  • CloudFormation VPC stack (permission constraints)
  • 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:

# 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.