- Organized 252 files across project - Root directory: 187 → 2 files (98.9% reduction) - Moved configuration guides to docs/04-configuration/ - Moved troubleshooting guides to docs/09-troubleshooting/ - Moved quick start guides to docs/01-getting-started/ - Moved reports to reports/ directory - Archived temporary files - Generated comprehensive reports and documentation - Created maintenance scripts and guides All files organized according to established standards.
192 lines
6.9 KiB
Bash
Executable File
192 lines
6.9 KiB
Bash
Executable File
#!/usr/bin/env bash
|
|
# Configure Cloudflare DNS and tunnel for Blockscout Explorer
|
|
# Usage: ./configure-cloudflare-explorer.sh
|
|
|
|
set -euo pipefail
|
|
|
|
DOMAIN="${DOMAIN:-d-bis.org}"
|
|
EXPLORER_DOMAIN="explorer.d-bis.org"
|
|
EXPLORER_IP="${EXPLORER_IP:-192.168.11.140}"
|
|
EXPLORER_PORT="${EXPLORER_PORT:-80}"
|
|
|
|
# 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 .env file with Cloudflare credentials
|
|
ENV_FILE="${ENV_FILE:-.env}"
|
|
if [ ! -f "$ENV_FILE" ]; then
|
|
log_error "Environment file not found: $ENV_FILE"
|
|
log_info "Please create $ENV_FILE with:"
|
|
log_info " CLOUDFLARE_API_TOKEN=your-token"
|
|
log_info " DOMAIN=d-bis.org"
|
|
log_info " TUNNEL_TOKEN=your-tunnel-token"
|
|
exit 1
|
|
fi
|
|
|
|
source "$ENV_FILE"
|
|
|
|
if [ -z "${CLOUDFLARE_API_TOKEN:-}" ]; then
|
|
log_error "CLOUDFLARE_API_TOKEN not set in $ENV_FILE"
|
|
exit 1
|
|
fi
|
|
|
|
log_info "Configuring Cloudflare for Blockscout Explorer"
|
|
log_info "Domain: $EXPLORER_DOMAIN"
|
|
log_info "Target: http://$EXPLORER_IP:$EXPLORER_PORT"
|
|
|
|
# Get Zone ID
|
|
log_info "Getting zone ID for $DOMAIN..."
|
|
ZONE_ID=$(curl -s -X GET "https://api.cloudflare.com/client/v4/zones?name=$DOMAIN" \
|
|
-H "Authorization: Bearer $CLOUDFLARE_API_TOKEN" \
|
|
-H "Content-Type: application/json" | jq -r '.result[0].id // empty')
|
|
|
|
if [ -z "$ZONE_ID" ] || [ "$ZONE_ID" = "null" ]; then
|
|
log_error "Failed to get zone ID for $DOMAIN"
|
|
exit 1
|
|
fi
|
|
|
|
log_success "Zone ID: $ZONE_ID"
|
|
|
|
# Extract tunnel ID from tunnel token or configuration
|
|
TUNNEL_ID=""
|
|
if [ -n "${TUNNEL_TOKEN:-}" ]; then
|
|
# Try to extract tunnel ID from token (if it's in the format we expect)
|
|
TUNNEL_ID=$(echo "$TUNNEL_TOKEN" | base64 -d 2>/dev/null | jq -r '.TunnelID // empty' 2>/dev/null || echo "")
|
|
fi
|
|
|
|
# If no tunnel ID found, try to get it from Cloudflare API
|
|
if [ -z "$TUNNEL_ID" ]; then
|
|
log_info "Getting tunnel information..."
|
|
ACCOUNT_ID=$(curl -s -X GET "https://api.cloudflare.com/client/v4/accounts" \
|
|
-H "Authorization: Bearer $CLOUDFLARE_API_TOKEN" \
|
|
-H "Content-Type: application/json" | jq -r '.result[0].id // empty')
|
|
|
|
if [ -n "$ACCOUNT_ID" ] && [ "$ACCOUNT_ID" != "null" ]; then
|
|
TUNNELS=$(curl -s -X GET "https://api.cloudflare.com/client/v4/accounts/$ACCOUNT_ID/cfd_tunnel" \
|
|
-H "Authorization: Bearer $CLOUDFLARE_API_TOKEN" \
|
|
-H "Content-Type: application/json")
|
|
|
|
TUNNEL_ID=$(echo "$TUNNELS" | jq -r '.result[0].id // empty' 2>/dev/null || echo "")
|
|
fi
|
|
fi
|
|
|
|
# Check if DNS record already exists
|
|
log_info "Checking for existing DNS record..."
|
|
EXISTING_RECORD=$(curl -s -X GET "https://api.cloudflare.com/client/v4/zones/$ZONE_ID/dns_records?name=$EXPLORER_DOMAIN&type=CNAME" \
|
|
-H "Authorization: Bearer $CLOUDFLARE_API_TOKEN" \
|
|
-H "Content-Type: application/json" | jq -r '.result[0] // empty')
|
|
|
|
if [ -n "$EXISTING_RECORD" ] && [ "$EXISTING_RECORD" != "null" ]; then
|
|
RECORD_ID=$(echo "$EXISTING_RECORD" | jq -r '.id')
|
|
log_warn "DNS record already exists (ID: $RECORD_ID)"
|
|
log_info "Updating existing record..."
|
|
|
|
if [ -n "$TUNNEL_ID" ] && [ "$TUNNEL_ID" != "null" ]; then
|
|
TARGET="${TUNNEL_ID}.cfargotunnel.com"
|
|
log_info "Using Cloudflare Tunnel: $TARGET"
|
|
else
|
|
TARGET="$EXPLORER_IP"
|
|
log_warn "No tunnel ID found, using direct IP (may not work behind NAT)"
|
|
fi
|
|
|
|
UPDATE_RESULT=$(curl -s -X PATCH "https://api.cloudflare.com/client/v4/zones/$ZONE_ID/dns_records/$RECORD_ID" \
|
|
-H "Authorization: Bearer $CLOUDFLARE_API_TOKEN" \
|
|
-H "Content-Type: application/json" \
|
|
--data "{
|
|
\"type\": \"CNAME\",
|
|
\"name\": \"explorer\",
|
|
\"content\": \"$TARGET\",
|
|
\"proxied\": true,
|
|
\"ttl\": 1
|
|
}")
|
|
|
|
SUCCESS=$(echo "$UPDATE_RESULT" | jq -r '.success // false')
|
|
if [ "$SUCCESS" = "true" ]; then
|
|
log_success "DNS record updated successfully"
|
|
else
|
|
ERROR=$(echo "$UPDATE_RESULT" | jq -r '.errors[0].message // "Unknown error"')
|
|
log_error "Failed to update DNS record: $ERROR"
|
|
exit 1
|
|
fi
|
|
else
|
|
log_info "Creating new DNS record..."
|
|
|
|
if [ -n "$TUNNEL_ID" ] && [ "$TUNNEL_ID" != "null" ]; then
|
|
TARGET="${TUNNEL_ID}.cfargotunnel.com"
|
|
RECORD_TYPE="CNAME"
|
|
log_info "Using Cloudflare Tunnel: $TARGET"
|
|
else
|
|
TARGET="$EXPLORER_IP"
|
|
RECORD_TYPE="A"
|
|
log_warn "No tunnel ID found, using A record with direct IP (may not work behind NAT)"
|
|
fi
|
|
|
|
CREATE_RESULT=$(curl -s -X POST "https://api.cloudflare.com/client/v4/zones/$ZONE_ID/dns_records" \
|
|
-H "Authorization: Bearer $CLOUDFLARE_API_TOKEN" \
|
|
-H "Content-Type: application/json" \
|
|
--data "{
|
|
\"type\": \"$RECORD_TYPE\",
|
|
\"name\": \"explorer\",
|
|
\"content\": \"$TARGET\",
|
|
\"proxied\": true,
|
|
\"ttl\": 1
|
|
}")
|
|
|
|
SUCCESS=$(echo "$CREATE_RESULT" | jq -r '.success // false')
|
|
if [ "$SUCCESS" = "true" ]; then
|
|
log_success "DNS record created successfully"
|
|
else
|
|
ERROR=$(echo "$CREATE_RESULT" | jq -r '.errors[0].message // "Unknown error"')
|
|
log_error "Failed to create DNS record: $ERROR"
|
|
exit 1
|
|
fi
|
|
fi
|
|
|
|
# If we have a tunnel, configure the tunnel route
|
|
if [ -n "$TUNNEL_ID" ] && [ "$TUNNEL_ID" != "null" ] && [ -n "${ACCOUNT_ID:-}" ]; then
|
|
log_info "Configuring Cloudflare Tunnel route..."
|
|
|
|
# Get current tunnel configuration
|
|
TUNNEL_CONFIG=$(curl -s -X GET "https://api.cloudflare.com/client/v4/accounts/$ACCOUNT_ID/cfd_tunnel/$TUNNEL_ID/config" \
|
|
-H "Authorization: Bearer $CLOUDFLARE_API_TOKEN" \
|
|
-H "Content-Type: application/json")
|
|
|
|
# This is complex - for now, log instructions
|
|
log_info ""
|
|
log_info "=== Cloudflare Tunnel Configuration Required ==="
|
|
log_info ""
|
|
log_info "Please configure the tunnel route manually in Cloudflare Zero Trust Dashboard:"
|
|
log_info " 1. Go to: https://one.dash.cloudflare.com/"
|
|
log_info " 2. Navigate to: Zero Trust → Networks → Tunnels"
|
|
log_info " 3. Select your tunnel (ID: $TUNNEL_ID)"
|
|
log_info " 4. Click 'Configure' → 'Public Hostnames'"
|
|
log_info " 5. Add hostname:"
|
|
log_info " - Subdomain: explorer"
|
|
log_info " - Domain: $DOMAIN"
|
|
log_info " - Service: http://$EXPLORER_IP:$EXPLORER_PORT"
|
|
log_info " - Type: HTTP"
|
|
log_info ""
|
|
fi
|
|
|
|
log_success "Cloudflare configuration complete!"
|
|
log_info ""
|
|
log_info "Summary:"
|
|
log_info " - DNS Record: $EXPLORER_DOMAIN → $TARGET (🟠 Proxied)"
|
|
if [ -n "$TUNNEL_ID" ]; then
|
|
log_info " - Tunnel ID: $TUNNEL_ID"
|
|
log_info " - Tunnel Route: Needs manual configuration (see above)"
|
|
fi
|
|
log_info ""
|
|
log_info "Next steps:"
|
|
log_info " 1. Wait for DNS propagation (1-5 minutes)"
|
|
log_info " 2. Test: curl -I https://$EXPLORER_DOMAIN"
|