#!/usr/bin/env bash # Configure Cloudflare WAF Rule to Allow Only ThirdWeb Traffic # Usage: ./scripts/configure-cloudflare-waf-thirdweb-rule.sh set -euo pipefail SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" PROJECT_ROOT="$(cd "$SCRIPT_DIR/.." && pwd)" # Configuration DOMAIN="defi-oracle.io" ZONE_ID="${CLOUDFLARE_ZONE_ID_DEFI_ORACLE:-}" ACCOUNT_ID="${CLOUDFLARE_ACCOUNT_ID:-}" # Colors RED='\033[0;31m' GREEN='\033[0;32m' YELLOW='\033[1;33m' BLUE='\033[0;34m' NC='\033[0m' log_info() { echo -e "${BLUE}[INFO]${NC} $1"; } log_success() { echo -e "${GREEN}[✓]${NC} $1"; } log_warn() { echo -e "${YELLOW}[WARN]${NC} $1"; } log_error() { echo -e "${RED}[ERROR]${NC} $1"; } # Check for API token if [[ -z "${CLOUDFLARE_API_TOKEN:-}" ]] && [[ -z "${CLOUDFLARE_API_KEY:-}" ]]; then log_error "Cloudflare API credentials not found!" echo "" echo "Set one of:" echo " export CLOUDFLARE_API_TOKEN=\"your-token\"" echo " OR" echo " export CLOUDFLARE_API_KEY=\"your-key\"" echo " export CLOUDFLARE_EMAIL=\"your-email\"" echo "" exit 1 fi # Set up auth headers if [[ -n "${CLOUDFLARE_API_TOKEN:-}" ]]; then AUTH_HEADER="Authorization: Bearer ${CLOUDFLARE_API_TOKEN}" elif [[ -n "${CLOUDFLARE_API_KEY:-}" ]] && [[ -n "${CLOUDFLARE_EMAIL:-}" ]]; then AUTH_HEADER="X-Auth-Email: ${CLOUDFLARE_EMAIL}" AUTH_KEY="X-Auth-Key: ${CLOUDFLARE_API_KEY}" else log_error "Incomplete credentials" exit 1 fi # Get Zone ID if not provided if [[ -z "$ZONE_ID" ]]; then log_info "Getting Zone ID for $DOMAIN..." if [[ -n "${CLOUDFLARE_API_TOKEN:-}" ]]; then ZONE_RESPONSE=$(curl -s -X GET "https://api.cloudflare.com/client/v4/zones?name=$DOMAIN" \ -H "Authorization: Bearer ${CLOUDFLARE_API_TOKEN}") else ZONE_RESPONSE=$(curl -s -X GET "https://api.cloudflare.com/client/v4/zones?name=$DOMAIN" \ -H "X-Auth-Email: ${CLOUDFLARE_EMAIL}" \ -H "X-Auth-Key: ${CLOUDFLARE_API_KEY}") fi ZONE_ID=$(echo "$ZONE_RESPONSE" | jq -r '.result[0].id // empty' 2>/dev/null || echo "") if [[ -z "$ZONE_ID" ]] || [[ "$ZONE_ID" == "null" ]]; then log_error "Failed to get Zone ID for $DOMAIN" exit 1 fi fi log_success "Zone ID: $ZONE_ID" # Create WAF rule to allow ThirdWeb log_info "Creating WAF rule: Allow ThirdWeb Traffic..." # Expression to match ThirdWeb domains EXPRESSION='(http.request.headers["origin"][*] matches "https?://.*\\.thirdweb\\.com(/.*)?$" or http.request.headers["referer"][*] matches "https?://.*\\.thirdweb\\.com(/.*)?$")' RULE_DATA=$(jq -n \ --arg description "Allow traffic from ThirdWeb domains only" \ --arg expression "$EXPRESSION" \ '{ action: "allow", description: $description, expression: $expression }') if [[ -n "${CLOUDFLARE_API_TOKEN:-}" ]]; then RESPONSE=$(curl -s -X POST "https://api.cloudflare.com/client/v4/zones/${ZONE_ID}/firewall/rules" \ -H "Authorization: Bearer ${CLOUDFLARE_API_TOKEN}" \ -H "Content-Type: application/json" \ -d "$RULE_DATA") else RESPONSE=$(curl -s -X POST "https://api.cloudflare.com/client/v4/zones/${ZONE_ID}/firewall/rules" \ -H "X-Auth-Email: ${CLOUDFLARE_EMAIL}" \ -H "X-Auth-Key: ${CLOUDFLARE_API_KEY}" \ -H "Content-Type: application/json" \ -d "$RULE_DATA") fi if echo "$RESPONSE" | jq -e '.success' >/dev/null 2>&1; then log_success "WAF rule created successfully" RULE_ID=$(echo "$RESPONSE" | jq -r '.result.id // empty') log_info "Rule ID: $RULE_ID" else log_error "Failed to create WAF rule" echo "$RESPONSE" | jq -r '.errors[0].message // "Unknown error"' 2>/dev/null || echo "$RESPONSE" exit 1 fi echo "" log_success "═══════════════════════════════════════════════════════════" log_success " WAF RULE CONFIGURED" log_success "═══════════════════════════════════════════════════════════" echo "" log_info "Note: You may also want to create a 'Block All Other' rule" log_info " that blocks traffic not matching the ThirdWeb pattern" echo "" log_info "To create a block rule, go to Cloudflare Dashboard:" log_info " Security → WAF → Custom Rules → Create rule" log_info " Expression: (everything else)" log_info " Action: Block" echo ""