Initial commit

This commit is contained in:
Zhongwei Li
2025-11-29 18:18:15 +08:00
commit e85b8b73e8
9 changed files with 1928 additions and 0 deletions

View File

@@ -0,0 +1,12 @@
{
"name": "cloudflare-troubleshooting",
"description": "Investigate and resolve Cloudflare configuration issues using API-driven evidence gathering. Use when troubleshooting ERR_TOO_MANY_REDIRECTS, SSL errors, DNS issues, or any Cloudflare-related problems",
"version": "0.0.0-2025.11.28",
"author": {
"name": "daymade",
"email": "daymadev89@gmail.com"
},
"skills": [
"./skills/cloudflare-troubleshooting"
]
}

3
README.md Normal file
View File

@@ -0,0 +1,3 @@
# cloudflare-troubleshooting
Investigate and resolve Cloudflare configuration issues using API-driven evidence gathering. Use when troubleshooting ERR_TOO_MANY_REDIRECTS, SSL errors, DNS issues, or any Cloudflare-related problems

64
plugin.lock.json Normal file
View File

@@ -0,0 +1,64 @@
{
"$schema": "internal://schemas/plugin.lock.v1.json",
"pluginId": "gh:daymade/claude-code-skills:cloudflare-troubleshooting",
"normalized": {
"repo": null,
"ref": "refs/tags/v20251128.0",
"commit": "f3354e95bdc12cac7c7318d9f9a2474dc7ecfe50",
"treeHash": "5b104d7fb8b9902806d947cec1eafa57d44cde501cf9481cc1c7e7f91f4a7047",
"generatedAt": "2025-11-28T10:16:14.473354Z",
"toolVersion": "publish_plugins.py@0.2.0"
},
"origin": {
"remote": "git@github.com:zhongweili/42plugin-data.git",
"branch": "master",
"commit": "aa1497ed0949fd50e99e70d6324a29c5b34f9390",
"repoRoot": "/Users/zhongweili/projects/openmind/42plugin-data"
},
"manifest": {
"name": "cloudflare-troubleshooting",
"description": "Investigate and resolve Cloudflare configuration issues using API-driven evidence gathering. Use when troubleshooting ERR_TOO_MANY_REDIRECTS, SSL errors, DNS issues, or any Cloudflare-related problems"
},
"content": {
"files": [
{
"path": "README.md",
"sha256": "e16bb5d3670b339cedb840b0b74b54341246d21c26c3b6f1f034e780a9dbd365"
},
{
"path": ".claude-plugin/plugin.json",
"sha256": "0b532cfe10501cc14f7f6e2b21ca667919444b54003485b0e2df66dc9b987193"
},
{
"path": "skills/cloudflare-troubleshooting/SKILL.md",
"sha256": "d9c5b1f38e55067a090c10abe4679ca507bdf69e1998d792869f0e3f0dd41e17"
},
{
"path": "skills/cloudflare-troubleshooting/references/ssl_modes.md",
"sha256": "5cf6d9d5c76a903fc9e5cc11469a7b1c16fa6f775c00945feb3f15045ecde392"
},
{
"path": "skills/cloudflare-troubleshooting/references/common_issues.md",
"sha256": "6a35f9bec753487a4961a2a9e8b0cf38f329cc1a69b388446aa44ec8d41942b5"
},
{
"path": "skills/cloudflare-troubleshooting/references/api_overview.md",
"sha256": "4dbe6aef7402cd26a30a166252335f64a952ee5ec3b307cb105218a0064fe59d"
},
{
"path": "skills/cloudflare-troubleshooting/scripts/fix_ssl_mode.py",
"sha256": "e9f48e283189137f0402cde63d826afa560a2566c5ed1707fb47597ddd3024d1"
},
{
"path": "skills/cloudflare-troubleshooting/scripts/check_cloudflare_config.py",
"sha256": "af949f88d1db660125ff9a977bf15fb55796a244a92d00f049123b80decd46c6"
}
],
"dirSha256": "5b104d7fb8b9902806d947cec1eafa57d44cde501cf9481cc1c7e7f91f4a7047"
},
"security": {
"scannedAt": null,
"scannerVersion": null,
"flags": []
}
}

View File

@@ -0,0 +1,325 @@
---
name: cloudflare-troubleshooting
description: Investigate and resolve Cloudflare configuration issues using API-driven evidence gathering. Use when troubleshooting ERR_TOO_MANY_REDIRECTS, SSL errors, DNS issues, or any Cloudflare-related problems. Focus on systematic investigation using Cloudflare API to examine actual configuration rather than making assumptions.
---
# Cloudflare Troubleshooting
## Core Principle
**Investigate with evidence, not assumptions.** Always query Cloudflare API to examine actual configuration before diagnosing issues. The skill's value is the systematic investigation methodology, not predetermined solutions.
## Investigation Methodology
### 1. Gather Credentials
Request from user:
- Domain name
- Cloudflare account email
- Cloudflare Global API Key (or API Token)
Global API Key location: Cloudflare Dashboard → My Profile → API Tokens → View Global API Key
### 2. Get Zone Information
First step for any Cloudflare troubleshooting - obtain the zone ID:
```bash
curl -s -X GET "https://api.cloudflare.com/client/v4/zones?name=<domain>" \
-H "X-Auth-Email: <email>" \
-H "X-Auth-Key: <api_key>" | jq '.'
```
Extract `zone_id` from `result[0].id` for subsequent API calls.
### 3. Investigate Systematically
For each issue, gather evidence before making conclusions. Use Cloudflare API to inspect:
- Current configuration state
- Recent changes (if audit log available)
- Related settings that might interact
## Common Investigation Patterns
### Redirect Loops (ERR_TOO_MANY_REDIRECTS)
**Evidence gathering sequence:**
1. **Check SSL/TLS mode:**
```bash
curl -X GET "https://api.cloudflare.com/client/v4/zones/{zone_id}/settings/ssl" \
-H "X-Auth-Email: email" \
-H "X-Auth-Key: key"
```
Look for: `result.value` - tells current SSL mode
2. **Check Always Use HTTPS setting:**
```bash
curl -X GET "https://api.cloudflare.com/client/v4/zones/{zone_id}/settings/always_use_https" \
-H "X-Auth-Email: email" \
-H "X-Auth-Key: key"
```
3. **Check Page Rules for redirects:**
```bash
curl -X GET "https://api.cloudflare.com/client/v4/zones/{zone_id}/pagerules" \
-H "X-Auth-Email: email" \
-H "X-Auth-Key: key"
```
Look for: `forwarding_url` or `always_use_https` actions
4. **Test origin server directly (if possible):**
```bash
curl -I -H "Host: <domain>" https://<origin_ip>
```
**Diagnosis logic:**
- SSL mode "flexible" + origin enforces HTTPS = redirect loop
- Multiple redirect rules can conflict
- Check browser vs curl behavior differences
**Fix:**
```bash
curl -X PATCH "https://api.cloudflare.com/client/v4/zones/{zone_id}/settings/ssl" \
-H "X-Auth-Email: email" \
-H "X-Auth-Key: key" \
-H "Content-Type: application/json" \
--data '{"value":"full"}'
```
Purge cache after fix:
```bash
curl -X POST "https://api.cloudflare.com/client/v4/zones/{zone_id}/purge_cache" \
-H "X-Auth-Email: email" \
-H "X-Auth-Key: key" \
-d '{"purge_everything":true}'
```
### DNS Issues
**Evidence gathering:**
1. **List DNS records:**
```bash
curl -X GET "https://api.cloudflare.com/client/v4/zones/{zone_id}/dns_records" \
-H "X-Auth-Email: email" \
-H "X-Auth-Key: key"
```
2. **Check external DNS resolution:**
```bash
dig <domain>
dig @8.8.8.8 <domain>
```
3. **Check DNSSEC status:**
```bash
curl -X GET "https://api.cloudflare.com/client/v4/zones/{zone_id}/dnssec" \
-H "X-Auth-Email: email" \
-H "X-Auth-Key: key"
```
**Look for:**
- Missing A/AAAA/CNAME records
- Incorrect proxy status (proxied vs DNS-only)
- TTL values
- Conflicting records
### SSL Certificate Errors
**Evidence gathering:**
1. **Check SSL certificate status:**
```bash
curl -X GET "https://api.cloudflare.com/client/v4/zones/{zone_id}/ssl/certificate_packs" \
-H "X-Auth-Email: email" \
-H "X-Auth-Key: key"
```
2. **Check origin certificate (if using Full Strict):**
```bash
openssl s_client -connect <origin_ip>:443 -servername <domain>
```
3. **Check SSL settings:**
- Minimum TLS version
- TLS 1.3 status
- Opportunistic Encryption
**Common issues:**
- Error 526: SSL mode is "strict" but origin cert invalid
- Error 525: SSL handshake failure at origin
- Provisioning delay: Wait 15-30 minutes for Universal SSL
### Origin Server Errors (502/503/504)
**Evidence gathering:**
1. **Check if origin is reachable:**
```bash
curl -I -H "Host: <domain>" https://<origin_ip>
```
2. **Check DNS records point to correct origin:**
```bash
curl -X GET "https://api.cloudflare.com/client/v4/zones/{zone_id}/dns_records" \
-H "X-Auth-Email: email" \
-H "X-Auth-Key: key"
```
3. **Review load balancer config (if applicable):**
```bash
curl -X GET "https://api.cloudflare.com/client/v4/zones/{zone_id}/load_balancers" \
-H "X-Auth-Email: email" \
-H "X-Auth-Key: key"
```
4. **Check firewall rules:**
```bash
curl -X GET "https://api.cloudflare.com/client/v4/zones/{zone_id}/firewall/rules" \
-H "X-Auth-Email: email" \
-H "X-Auth-Key: key"
```
## Learning New APIs
When encountering issues not covered above, consult Cloudflare API documentation:
1. **Browse API reference:** https://developers.cloudflare.com/api/
2. **Search for relevant endpoints** using issue keywords
3. **Check API schema** to understand available operations
4. **Test with GET requests** first to understand data structure
5. **Make changes with PATCH/POST** after confirming approach
**Pattern for exploring new APIs:**
```bash
# List available settings for a zone
curl -X GET "https://api.cloudflare.com/client/v4/zones/{zone_id}/settings" \
-H "X-Auth-Email: email" \
-H "X-Auth-Key: key"
```
## API Reference Overview
Consult `references/api_overview.md` for:
- Common endpoints organized by category
- Request/response schemas
- Authentication patterns
- Rate limits and error handling
Consult `references/ssl_modes.md` for:
- Detailed SSL/TLS mode explanations
- Platform compatibility
- Security implications
Consult `references/common_issues.md` for:
- Issue patterns and symptoms
- Investigation checklists
- Platform-specific notes
## Best Practices
### Evidence-Based Investigation
1. **Query before assuming** - Use API to check actual state
2. **Gather multiple data points** - Cross-reference settings
3. **Check related configurations** - Settings often interact
4. **Verify externally** - Use dig/curl to confirm
5. **Test incrementally** - One change at a time
### API Usage
1. **Parse JSON responses** - Use `jq` or python for readability
2. **Check success field** - `"success": true/false` in responses
3. **Handle errors gracefully** - Read `errors` array in responses
4. **Respect rate limits** - Cloudflare API has limits
5. **Use appropriate methods:**
- GET: Retrieve information
- PATCH: Update settings
- POST: Create resources / trigger actions
- DELETE: Remove resources
### Making Changes
1. **Gather evidence first** - Understand current state
2. **Identify root cause** - Don't guess
3. **Apply targeted fix** - Change only what's needed
4. **Purge cache if needed** - Especially for SSL/redirect changes
5. **Verify fix** - Re-query API to confirm
6. **Inform user of wait times:**
- Edge server propagation: 30-60 seconds
- DNS propagation: Up to 48 hours
- Browser cache: Requires manual clear
### Security
- Never log API keys in output
- Warn if user shares credentials in public context
- Recommend API Tokens with scoped permissions over Global API Key
- Use read-only operations for investigation
## Workflow Template
```
1. Gather: domain, email, API key
2. Get zone_id via zones API
3. Investigate:
- Query relevant APIs for evidence
- Check multiple related settings
- Verify with external tools (dig, curl)
4. Analyze evidence to determine root cause
5. Apply fix via appropriate API endpoint
6. Purge cache if configuration change affects delivery
7. Verify fix via API query and external testing
8. Inform user of resolution and any required actions
```
## Example: Complete Investigation
When user reports "site shows ERR_TOO_MANY_REDIRECTS":
```bash
# 1. Get zone ID
curl -s -X GET "https://api.cloudflare.com/client/v4/zones?name=example.com" \
-H "X-Auth-Email: user@example.com" \
-H "X-Auth-Key: abc123" | jq '.result[0].id'
# 2. Check SSL mode (primary suspect for redirect loops)
curl -s -X GET "https://api.cloudflare.com/client/v4/zones/ZONE_ID/settings/ssl" \
-H "X-Auth-Email: user@example.com" \
-H "X-Auth-Key: abc123" | jq '.result.value'
# If returns "flexible" and origin is GitHub Pages/Netlify/Vercel:
# 3. Fix by changing to "full"
curl -X PATCH "https://api.cloudflare.com/client/v4/zones/ZONE_ID/settings/ssl" \
-H "X-Auth-Email: user@example.com" \
-H "X-Auth-Key: abc123" \
-H "Content-Type: application/json" \
--data '{"value":"full"}'
# 4. Purge cache
curl -X POST "https://api.cloudflare.com/client/v4/zones/ZONE_ID/purge_cache" \
-H "X-Auth-Email: user@example.com" \
-H "X-Auth-Key: abc123" \
-d '{"purge_everything":true}'
# 5. Inform user: Wait 60 seconds, clear browser cache, retry
```
## When Scripts Are Useful
The bundled scripts (`scripts/check_cloudflare_config.py`, `scripts/fix_ssl_mode.py`) serve as:
- **Reference implementations** of investigation patterns
- **Quick diagnostic tools** when Python is available
- **Examples** of programmatic API usage
However, **prefer direct API calls via Bash/curl** for flexibility and transparency. Scripts should not limit capability - use them when convenient, but use raw API calls when needed for:
- Unfamiliar scenarios
- Edge cases
- Learning/debugging
- Operations not covered by scripts
The investigation methodology and API knowledge is the core skill, not the scripts.

View File

@@ -0,0 +1,538 @@
# Cloudflare API Overview
## Authentication
### Global API Key (used in examples)
```bash
curl -X GET "https://api.cloudflare.com/client/v4/..." \
-H "X-Auth-Email: user@example.com" \
-H "X-Auth-Key: abc123..."
```
### API Token (recommended for production)
```bash
curl -X GET "https://api.cloudflare.com/client/v4/..." \
-H "Authorization: Bearer <token>"
```
## Response Format
All API responses follow this structure:
```json
{
"success": true/false,
"errors": [],
"messages": [],
"result": { ... },
"result_info": { ... }
}
```
Always check `success` field before processing `result`.
## Core Endpoints by Category
### Zone Management
**List zones:**
```bash
GET /zones?name=<domain>
```
Returns zone information including `id`, `name`, `status`, `name_servers`
**Get zone details:**
```bash
GET /zones/{zone_id}
```
**Get all zone settings:**
```bash
GET /zones/{zone_id}/settings
```
Returns all configurable settings for the zone
### SSL/TLS
**Get SSL mode:**
```bash
GET /zones/{zone_id}/settings/ssl
```
Result: `{"value": "flexible"|"full"|"strict"|"off"}`
**Update SSL mode:**
```bash
PATCH /zones/{zone_id}/settings/ssl
Content-Type: application/json
{"value": "full"}
```
**Get Always Use HTTPS:**
```bash
GET /zones/{zone_id}/settings/always_use_https
```
**Update Always Use HTTPS:**
```bash
PATCH /zones/{zone_id}/settings/always_use_https
{"value": "on"|"off"}
```
**List SSL certificates:**
```bash
GET /zones/{zone_id}/ssl/certificate_packs
```
**Get SSL verification details:**
```bash
GET /zones/{zone_id}/ssl/verification
```
**Get SSL settings (universal, dedicated, etc):**
```bash
GET /zones/{zone_id}/ssl/analyze
```
**TLS 1.3 setting:**
```bash
GET /zones/{zone_id}/settings/tls_1_3
PATCH /zones/{zone_id}/settings/tls_1_3
{"value": "on"|"off"|"zrt"}
```
**Minimum TLS version:**
```bash
GET /zones/{zone_id}/settings/min_tls_version
PATCH /zones/{zone_id}/settings/min_tls_version
{"value": "1.0"|"1.1"|"1.2"|"1.3"}
```
### DNS Records
**List DNS records:**
```bash
GET /zones/{zone_id}/dns_records
```
Returns array of DNS records with type, name, content, proxied status, TTL
**Filter by type:**
```bash
GET /zones/{zone_id}/dns_records?type=A
GET /zones/{zone_id}/dns_records?type=CNAME
```
**Get specific record:**
```bash
GET /zones/{zone_id}/dns_records/{record_id}
```
**Create DNS record:**
```bash
POST /zones/{zone_id}/dns_records
{
"type": "A",
"name": "example.com",
"content": "192.0.2.1",
"ttl": 3600,
"proxied": true
}
```
**Update DNS record:**
```bash
PATCH /zones/{zone_id}/dns_records/{record_id}
{"proxied": true}
```
**Delete DNS record:**
```bash
DELETE /zones/{zone_id}/dns_records/{record_id}
```
**DNSSEC status:**
```bash
GET /zones/{zone_id}/dnssec
```
### Page Rules
**List page rules:**
```bash
GET /zones/{zone_id}/pagerules
```
**Get specific page rule:**
```bash
GET /zones/{zone_id}/pagerules/{rule_id}
```
**Create page rule:**
```bash
POST /zones/{zone_id}/pagerules
{
"targets": [{"target": "url", "constraint": {"operator": "matches", "value": "*example.com/*"}}],
"actions": [{"id": "always_use_https"}],
"priority": 1,
"status": "active"
}
```
**Update page rule:**
```bash
PATCH /zones/{zone_id}/pagerules/{rule_id}
```
**Delete page rule:**
```bash
DELETE /zones/{zone_id}/pagerules/{rule_id}
```
### Cache
**Purge everything:**
```bash
POST /zones/{zone_id}/purge_cache
{"purge_everything": true}
```
**Purge by URL:**
```bash
POST /zones/{zone_id}/purge_cache
{"files": ["https://example.com/style.css", "https://example.com/script.js"]}
```
**Purge by tag:**
```bash
POST /zones/{zone_id}/purge_cache
{"tags": ["tag1", "tag2"]}
```
**Purge by host:**
```bash
POST /zones/{zone_id}/purge_cache
{"hosts": ["example.com", "www.example.com"]}
```
**Cache settings:**
```bash
GET /zones/{zone_id}/settings/cache_level
GET /zones/{zone_id}/settings/browser_cache_ttl
GET /zones/{zone_id}/settings/development_mode
```
### Firewall
**List firewall rules:**
```bash
GET /zones/{zone_id}/firewall/rules
```
**List WAF rules:**
```bash
GET /zones/{zone_id}/firewall/waf/packages
GET /zones/{zone_id}/firewall/waf/packages/{package_id}/rules
```
**IP Access Rules:**
```bash
GET /zones/{zone_id}/firewall/access_rules/rules
POST /zones/{zone_id}/firewall/access_rules/rules
{
"mode": "block"|"challenge"|"whitelist",
"configuration": {"target": "ip", "value": "192.0.2.1"},
"notes": "Blocked malicious IP"
}
```
**Rate limiting:**
```bash
GET /zones/{zone_id}/rate_limits
POST /zones/{zone_id}/rate_limits
```
### Analytics
**Get analytics:**
```bash
GET /zones/{zone_id}/analytics/dashboard
```
**Traffic analytics:**
```bash
GET /zones/{zone_id}/analytics/colos
```
**DNS analytics:**
```bash
GET /zones/{zone_id}/dns_analytics/report
```
### Load Balancers
**List load balancers:**
```bash
GET /zones/{zone_id}/load_balancers
```
**Get load balancer details:**
```bash
GET /zones/{zone_id}/load_balancers/{lb_id}
```
**List pools:**
```bash
GET /accounts/{account_id}/load_balancers/pools
```
**List monitors:**
```bash
GET /accounts/{account_id}/load_balancers/monitors
```
### Workers & Routes
**List worker routes:**
```bash
GET /zones/{zone_id}/workers/routes
```
**List worker scripts:**
```bash
GET /accounts/{account_id}/workers/scripts
```
### Settings (Other Common)
**Development mode:**
```bash
GET /zones/{zone_id}/settings/development_mode
PATCH /zones/{zone_id}/settings/development_mode
{"value": "on"|"off"}
```
**Security level:**
```bash
GET /zones/{zone_id}/settings/security_level
PATCH /zones/{zone_id}/settings/security_level
{"value": "off"|"essentially_off"|"low"|"medium"|"high"|"under_attack"}
```
**Rocket Loader:**
```bash
GET /zones/{zone_id}/settings/rocket_loader
PATCH /zones/{zone_id}/settings/rocket_loader
{"value": "on"|"off"}
```
**Auto minify:**
```bash
GET /zones/{zone_id}/settings/minify
PATCH /zones/{zone_id}/settings/minify
{"value": {"css": "on", "html": "on", "js": "on"}}
```
**Brotli compression:**
```bash
GET /zones/{zone_id}/settings/brotli
```
**HTTP/2:**
```bash
GET /zones/{zone_id}/settings/http2
```
**HTTP/3 (QUIC):**
```bash
GET /zones/{zone_id}/settings/http3
```
**IPv6:**
```bash
GET /zones/{zone_id}/settings/ipv6
```
**Opportunistic Encryption:**
```bash
GET /zones/{zone_id}/settings/opportunistic_encryption
```
**Automatic HTTPS Rewrites:**
```bash
GET /zones/{zone_id}/settings/automatic_https_rewrites
PATCH /zones/{zone_id}/settings/automatic_https_rewrites
{"value": "on"|"off"}
```
## Learning New Endpoints
### Method 1: List All Settings
```bash
curl -s -X GET "https://api.cloudflare.com/client/v4/zones/{zone_id}/settings" \
-H "X-Auth-Email: email" \
-H "X-Auth-Key: key" | jq '.result[] | {id, value}'
```
This returns all available settings with current values. Use setting `id` to construct endpoint:
`/zones/{zone_id}/settings/{id}`
### Method 2: Cloudflare API Docs
Browse official API reference: https://developers.cloudflare.com/api/
**Structure:**
- Operations organized by product/feature
- Each operation shows:
- HTTP method and endpoint
- Required/optional parameters
- Request body schema
- Response schema
- Example requests
**Search strategy:**
1. Identify feature/product (SSL, DNS, Cache, etc.)
2. Find relevant operations (List, Get, Create, Update, Delete)
3. Check request schema for required fields
4. Test with GET before making changes
### Method 3: Explore API Interactively
**Pattern:**
1. Start with zone info to understand structure
2. List resources: `GET /zones/{zone_id}/{resource_type}`
3. Get specific item: `GET /zones/{zone_id}/{resource_type}/{id}`
4. Check available operations in docs
5. Make changes: `PATCH/POST/DELETE`
**Example exploration for unknown feature:**
```bash
# 1. Check if endpoint exists
curl -I "https://api.cloudflare.com/client/v4/zones/{zone_id}/feature_name"
# 2. Try listing (if collection)
curl -X GET "https://api.cloudflare.com/client/v4/zones/{zone_id}/feature_name" \
-H "X-Auth-Email: email" \
-H "X-Auth-Key: key"
# 3. Examine response structure
# 4. Consult docs for modification operations
```
## Error Handling
Common error codes:
- 400: Bad request (check request format)
- 401: Unauthorized (check API credentials)
- 403: Forbidden (insufficient permissions)
- 404: Not found (check zone_id or resource_id)
- 429: Rate limit exceeded (wait before retrying)
- 500: Server error (Cloudflare issue, retry later)
**Error response structure:**
```json
{
"success": false,
"errors": [
{
"code": 1234,
"message": "Error description"
}
],
"messages": [],
"result": null
}
```
## Rate Limits
- Free tier: ~1200 requests per 5 minutes
- Paid tiers: Higher limits based on plan
- If rate limited (429), back off exponentially
## Best Practices
1. **Use jq for readability:**
```bash
curl ... | jq '.result'
```
2. **Extract specific fields:**
```bash
curl ... | jq '.result.value'
curl ... | jq '.result[] | {id, name, value}'
```
3. **Check success before processing:**
```bash
response=$(curl ...)
success=$(echo "$response" | jq -r '.success')
if [ "$success" = "true" ]; then
echo "$response" | jq '.result'
else
echo "$response" | jq '.errors'
fi
```
4. **Store zone_id for reuse:**
```bash
zone_id=$(curl ... | jq -r '.result[0].id')
```
5. **Test with GET first:**
Before modifying configuration, always GET to see current state
## Common Investigation Patterns
### Pattern 1: Settings Investigation
```bash
# Get all settings
curl -X GET "/zones/{zone_id}/settings" | jq '.result[]'
# Filter specific settings
curl -X GET "/zones/{zone_id}/settings" | jq '.result[] | select(.id | contains("ssl"))'
```
### Pattern 2: Resource Listing + Details
```bash
# List resources
curl -X GET "/zones/{zone_id}/dns_records" | jq '.result[] | {id, name, type}'
# Get specific resource
record_id="..."
curl -X GET "/zones/{zone_id}/dns_records/$record_id" | jq '.'
```
### Pattern 3: Multi-Setting Check
```bash
# Check related settings in parallel
curl ... /settings/ssl &
curl ... /settings/always_use_https &
curl ... /pagerules &
wait
```
### Pattern 4: Change + Verify
```bash
# Make change
curl -X PATCH "/zones/{zone_id}/settings/ssl" -d '{"value":"full"}'
# Verify change applied
curl -X GET "/zones/{zone_id}/settings/ssl" | jq '.result.value'
```
## Account-Level vs Zone-Level
Some resources are account-level, not zone-level:
**Account-level:**
- Load balancer pools/monitors: `/accounts/{account_id}/load_balancers/...`
- Workers scripts: `/accounts/{account_id}/workers/...`
- Access policies: `/accounts/{account_id}/access/...`
**Zone-level:**
- DNS records: `/zones/{zone_id}/dns_records`
- SSL settings: `/zones/{zone_id}/settings/ssl`
- Page rules: `/zones/{zone_id}/pagerules`
Get account_id from zone info:
```bash
curl -X GET "/zones?name=example.com" | jq '.result[0].account.id'
```

View File

@@ -0,0 +1,261 @@
# Common Cloudflare Issues and Solutions
## Redirect Loop Errors (ERR_TOO_MANY_REDIRECTS)
### Symptom
Browser displays "This page isn't working" or "ERR_TOO_MANY_REDIRECTS"
### Common Causes
#### 1. SSL Mode Mismatch (Most Common)
**Scenario:** Origin server enforces HTTPS, but Cloudflare SSL mode is "Flexible"
**Explanation:**
- Browser → HTTPS → Cloudflare
- Cloudflare → HTTP → Origin Server (because of Flexible mode)
- Origin Server → Redirects to HTTPS (because it enforces HTTPS)
- Infinite loop
**Affected Platforms:**
- GitHub Pages
- Netlify
- Vercel
- Heroku
- Most modern hosting platforms
**Solution:**
Change SSL mode from "Flexible" to "Full" or "Full (strict)"
```bash
# Diagnose
python scripts/check_cloudflare_config.py example.com user@example.com API_KEY
# Fix
python scripts/fix_ssl_mode.py example.com user@example.com API_KEY full --purge-cache
```
#### 2. Conflicting Page Rules
**Scenario:** Multiple redirect rules that conflict with each other
**Solution:**
- Review Page Rules in Cloudflare Dashboard
- Remove conflicting "Always Use HTTPS" or "Forwarding URL" rules
- Ensure redirect rules don't create loops
#### 3. Origin Server Misconfiguration
**Scenario:** Origin server has incorrect redirect rules in .htaccess or nginx config
**Solution:**
- Check origin server configuration
- Verify redirects don't conflict with Cloudflare settings
- Test direct origin access (bypass Cloudflare)
### Resolution Steps
1. **Check SSL mode:**
```bash
curl -X GET "https://api.cloudflare.com/client/v4/zones/ZONE_ID/settings/ssl" \
-H "X-Auth-Email: email" \
-H "X-Auth-Key: key"
```
2. **Fix SSL mode if needed:**
```bash
python scripts/fix_ssl_mode.py domain.com email API_KEY full
```
3. **Purge cache:**
```bash
curl -X POST "https://api.cloudflare.com/client/v4/zones/ZONE_ID/purge_cache" \
-H "X-Auth-Email: email" \
-H "X-Auth-Key: key" \
-d '{"purge_everything":true}'
```
4. **Clear browser cache or use incognito mode**
---
## DNS Resolution Issues
### Symptom
Website not accessible or showing old content
### Common Causes
#### 1. DNS Not Propagated
**Solution:** Wait 24-48 hours for full DNS propagation
Check propagation:
```bash
dig domain.com
nslookup domain.com
```
#### 2. Incorrect DNS Records
**Solution:**
- Verify A/AAAA/CNAME records point to correct IPs
- For GitHub Pages: Use A records to GitHub IPs or CNAME to username.github.io
- Ensure "Proxied" status matches requirements
#### 3. DNSSEC Issues
**Solution:**
- Check DNSSEC status in Cloudflare Dashboard
- Verify DS records at registrar match Cloudflare's DNSSEC settings
---
## SSL/TLS Certificate Errors
### Symptom
"Your connection is not private" or "NET::ERR_CERT_COMMON_NAME_INVALID"
### Common Causes
#### 1. Universal SSL Certificate Provisioning Delay
**Solution:** Wait 15-30 minutes for Cloudflare to provision certificate
#### 2. CAA Records Blocking Certificate Issuance
**Solution:**
- Check CAA records
- Ensure CAA allows Let's Encrypt: `letsencrypt.org` or Cloudflare CAs
#### 3. Full (Strict) Mode with Invalid Origin Certificate
**Solution:**
- Use "Full" mode instead of "Full (strict)" if origin cert is self-signed
- Or install valid certificate on origin server
---
## Performance Issues
### Symptom
Slow page load times despite using Cloudflare
### Common Causes
#### 1. Cache Not Configured
**Solution:**
- Enable Auto Minify (JS, CSS, HTML)
- Set up Page Rules for cache levels
- Configure Browser Cache TTL
#### 2. Large Assets Not Optimized
**Solution:**
- Enable Cloudflare Image Optimization
- Use WebP format
- Implement lazy loading
#### 3. Too Many Uncached Requests
**Solution:**
- Review cache analytics
- Add cache rules for static assets
- Use Cloudflare Workers for dynamic caching
---
## Access Denied / 403 Errors
### Symptom
"Error 1020: Access Denied" or generic 403
### Common Causes
#### 1. Firewall Rules Blocking Traffic
**Solution:**
- Review Firewall Rules in Security → WAF
- Check IP Access Rules
- Verify Managed Rulesets aren't too strict
#### 2. Rate Limiting
**Solution:**
- Check Rate Limiting rules
- Adjust thresholds if legitimate traffic is blocked
#### 3. Browser Integrity Check
**Solution:**
- Disable "Browser Integrity Check" if needed
- Found in: Security → Settings
---
## Origin Server Errors (502/503/504)
### Symptom
"502 Bad Gateway" or "504 Gateway Timeout"
### Common Causes
#### 1. Origin Server Down
**Solution:**
- Verify origin server is running
- Check origin server logs
- Test direct IP access
#### 2. Origin SSL Certificate Invalid (Full Strict mode)
**Solution:**
- Switch to "Full" mode temporarily
- Fix origin certificate
- Or use Cloudflare Origin Certificate
#### 3. Timeout Issues
**Solution:**
- Increase origin server timeout settings
- Optimize slow queries/code
- Consider using Cloudflare Workers for timeouts
---
## Page Rules Not Working
### Symptom
Page Rules don't seem to apply
### Common Causes
#### 1. Rule Order
**Solution:** Page Rules are executed top-to-bottom; reorder if needed
#### 2. Pattern Matching Issues
**Solution:**
- Use `*` for wildcards correctly
- Test patterns: `example.com/*` vs `*example.com/*`
#### 3. Cache Already Set
**Solution:** Purge cache after creating/modifying Page Rules
---
## Troubleshooting Workflow
### Step 1: Identify the Issue
- Collect error messages and codes
- Note when issue started
- Check if issue is intermittent or consistent
### Step 2: Check Cloudflare Status
- Visit https://www.cloudflarestatus.com
- Verify no ongoing incidents
### Step 3: Run Diagnostics
```bash
python scripts/check_cloudflare_config.py domain.com email API_KEY
```
### Step 4: Review Recent Changes
- Check Cloudflare Audit Log
- Review recent DNS/SSL/Page Rule changes
### Step 5: Test Bypass
- Temporarily set DNS to "DNS Only" (grey cloud)
- Test if issue persists without Cloudflare
### Step 6: Apply Fixes
- Implement specific solutions based on diagnosis
- Purge cache after changes
- Test in incognito/private mode
### Step 7: Monitor
- Verify fix works consistently
- Check analytics for any anomalies
- Document solution for future reference

View File

@@ -0,0 +1,246 @@
# Cloudflare SSL/TLS Modes Explained
## Overview
Cloudflare offers four SSL/TLS encryption modes that determine how traffic is encrypted between visitors, Cloudflare, and your origin server.
```
Visitor ←→ Cloudflare ←→ Origin Server
[A] [B] [C]
[A] Visitor to Cloudflare: Always HTTPS (handled by Cloudflare Universal SSL)
[B] Cloudflare to Origin: Depends on SSL mode setting
```
## The Four SSL Modes
### 1. Off (Not Recommended)
**Encryption:**
- Visitor → Cloudflare: HTTP (unencrypted)
- Cloudflare → Origin: HTTP (unencrypted)
**When to use:** Never. This disables HTTPS entirely.
**Issues:**
- Browser shows "Not Secure" warning
- No encryption between visitor and Cloudflare
- Vulnerable to man-in-the-middle attacks
---
### 2. Flexible
**Encryption:**
- Visitor → Cloudflare: HTTPS (encrypted)
- Cloudflare → Origin: HTTP (unencrypted)
**When to use:**
- Origin server doesn't support HTTPS
- Legacy systems without SSL certificates
- Temporary solution during certificate setup
**Issues:**
- ⚠️ **CAUSES REDIRECT LOOPS** with origins that enforce HTTPS
- Traffic between Cloudflare and origin is unencrypted
- Not recommended for sensitive data
**Common redirect loop scenario:**
```
1. Browser requests https://example.com
2. Cloudflare receives HTTPS request
3. Cloudflare forwards HTTP request to origin (because mode is Flexible)
4. Origin server enforces HTTPS → redirects to https://example.com
5. Back to step 1 → INFINITE LOOP
```
**Affected platforms:**
- GitHub Pages
- Netlify
- Vercel
- Heroku
- Any platform that enforces HTTPS
---
### 3. Full (Recommended for Most Cases)
**Encryption:**
- Visitor → Cloudflare: HTTPS (encrypted)
- Cloudflare → Origin: HTTPS (encrypted)
**When to use:**
- Origin server supports HTTPS (most modern hosting)
- Self-signed certificates on origin
- Default choice for GitHub Pages, Netlify, Vercel, etc.
**Benefits:**
- End-to-end encryption
- No redirect loops with HTTPS-enforcing origins
- Compatible with self-signed certificates
**Important:**
- Cloudflare does NOT validate origin certificate
- Origin can use self-signed or expired certificates
- Still provides encryption, just doesn't verify origin identity
---
### 4. Full (Strict) (Most Secure)
**Encryption:**
- Visitor → Cloudflare: HTTPS (encrypted)
- Cloudflare → Origin: HTTPS (encrypted + validated)
**When to use:**
- Origin has valid SSL certificate from trusted CA
- Maximum security requirements
- Production environments with proper certificates
**Requirements:**
- Origin must have valid certificate from trusted CA
- Certificate must not be expired
- Certificate must match the domain
**Benefits:**
- Maximum security
- Validates origin server identity
- Prevents man-in-the-middle attacks between Cloudflare and origin
**Issues if misconfigured:**
- 526 error if origin certificate is invalid
- 525 error if SSL handshake fails
---
## Decision Matrix
| Origin Supports HTTPS? | Origin Certificate Valid? | Recommended Mode | Why |
|------------------------|---------------------------|------------------|-----|
| No | N/A | Flexible | Only option (but upgrade origin ASAP) |
| Yes | Self-signed/Invalid | Full | Encrypts traffic, doesn't validate cert |
| Yes | Valid from trusted CA | Full (Strict) | Maximum security |
| Yes (enforced) | Any | Full or Full (Strict) | Prevents redirect loops |
## Common Platforms and Recommended Modes
| Platform | Enforces HTTPS? | Recommended Mode | Notes |
|----------|-----------------|------------------|-------|
| GitHub Pages | Yes | Full or Full (Strict) | Full (Strict) preferred |
| Netlify | Yes | Full or Full (Strict) | Has valid certificates |
| Vercel | Yes | Full or Full (Strict) | Has valid certificates |
| Heroku | Yes | Full or Full (Strict) | Has valid certificates |
| Custom VPS | Depends | Full (Strict) if possible | Install Let's Encrypt cert |
| Shared Hosting | Varies | Check with host | Usually Full |
| AWS CloudFront | Configurable | Full (Strict) | Use ACM certificates |
## Troubleshooting SSL Mode Issues
### Redirect Loop (ERR_TOO_MANY_REDIRECTS)
**Cause:** SSL mode is "Flexible" but origin enforces HTTPS
**Solution:**
```bash
# Check current mode
curl -X GET "https://api.cloudflare.com/client/v4/zones/ZONE_ID/settings/ssl" \
-H "X-Auth-Email: email" \
-H "X-Auth-Key: key"
# Change to Full
python scripts/fix_ssl_mode.py domain.com email API_KEY full --purge-cache
```
### Error 526 (Invalid SSL Certificate)
**Cause:** Mode is "Full (Strict)" but origin certificate is invalid
**Solutions:**
1. Install valid certificate on origin (recommended)
2. Switch to "Full" mode temporarily:
```bash
python scripts/fix_ssl_mode.py domain.com email API_KEY full
```
3. Use Cloudflare Origin Certificate (free, only trusted by Cloudflare)
### Error 525 (SSL Handshake Failed)
**Cause:** Origin server SSL/TLS configuration issue
**Solutions:**
1. Check origin server SSL logs
2. Verify origin supports TLS 1.2 or higher
3. Ensure origin port 443 is open
4. Check cipher suite compatibility
## Best Practices
### 1. Start with Full Mode
When in doubt, use "Full" mode for origins that support HTTPS
### 2. Upgrade to Full (Strict) When Possible
Install proper certificates and use Full (Strict) for production
### 3. Never Use Flexible for New Sites
Flexible should only be used for legacy systems during migration
### 4. Use Cloudflare Origin Certificates
For custom origin servers, install Cloudflare Origin Certificates:
- Free
- Valid for 15 years
- Trusted by Cloudflare (enables Full Strict mode)
- Generate at: SSL/TLS → Origin Server → Create Certificate
### 5. Monitor SSL Errors
Set up alerts for SSL-related errors (525, 526) in Cloudflare Analytics
### 6. Test After Changes
- Clear browser cache
- Test in incognito mode
- Purge Cloudflare cache
- Wait 30-60 seconds for edge server updates
## Additional Security Settings
### Always Use HTTPS
- Redirects all HTTP requests to HTTPS
- Located: SSL/TLS → Edge Certificates
- Usually enabled by default
- Can cause loops if misconfigured with Page Rules
### HTTP Strict Transport Security (HSTS)
- Forces browsers to always use HTTPS
- Can't easily revert (browsers cache for months)
- Enable only when HTTPS is stable
- Located: SSL/TLS → Edge Certificates
### Minimum TLS Version
- Set to TLS 1.2 minimum (recommended)
- TLS 1.3 for maximum security
- Located: SSL/TLS → Edge Certificates
### Opportunistic Encryption
- Encrypts traffic when possible
- Good for mixed content
- Located: SSL/TLS → Edge Certificates
## API Reference
### Get SSL Mode
```bash
curl -X GET "https://api.cloudflare.com/client/v4/zones/{zone_id}/settings/ssl" \
-H "X-Auth-Email: user@example.com" \
-H "X-Auth-Key: api_key" \
-H "Content-Type: application/json"
```
### Change SSL Mode
```bash
curl -X PATCH "https://api.cloudflare.com/client/v4/zones/{zone_id}/settings/ssl" \
-H "X-Auth-Email: user@example.com" \
-H "X-Auth-Key: api_key" \
-H "Content-Type: application/json" \
--data '{"value":"full"}'
```
Valid values: `off`, `flexible`, `full`, `strict`

View File

@@ -0,0 +1,293 @@
#!/usr/bin/env python3
"""
Comprehensive Cloudflare configuration checker.
This script diagnoses common Cloudflare issues including:
- SSL/TLS mode mismatches
- DNS configuration problems
- Cache settings
- Page rules and redirect loops
Requires:
- requests library
- Cloudflare API credentials (email + Global API Key OR API Token)
"""
import json
import sys
from typing import Dict, List, Optional, Tuple
def check_ssl_configuration(
zone_id: str, email: str, api_key: str
) -> Tuple[bool, List[str]]:
"""
Check SSL/TLS configuration for common issues.
Returns: (has_issues, issues_list)
"""
try:
import requests
except ImportError:
return True, ["Error: 'requests' library not installed. Install with: pip install requests"]
issues = []
# Get SSL mode
try:
response = requests.get(
f"https://api.cloudflare.com/client/v4/zones/{zone_id}/settings/ssl",
headers={"X-Auth-Email": email, "X-Auth-Key": api_key},
timeout=30
)
if not response.ok:
return True, [f"API Error: {response.status_code} - {response.text}"]
data = response.json()
if not data.get("success"):
return True, [f"API Error: {data.get('errors', 'Unknown error')}"]
ssl_mode = data["result"]["value"]
# Check Always Use HTTPS setting
https_response = requests.get(
f"https://api.cloudflare.com/client/v4/zones/{zone_id}/settings/always_use_https",
headers={"X-Auth-Email": email, "X-Auth-Key": api_key},
timeout=30
)
always_https = "off"
if https_response.ok:
https_data = https_response.json()
if https_data.get("success"):
always_https = https_data["result"]["value"]
# Analyze configuration
if ssl_mode == "flexible":
issues.append(
f"⚠️ SSL Mode is 'flexible' - this can cause redirect loops if your origin "
f"server enforces HTTPS (common with GitHub Pages, Netlify, Vercel, etc.)"
)
issues.append(
" Recommendation: Change SSL mode to 'full' or 'full (strict)' if your "
"origin supports HTTPS"
)
if ssl_mode == "off":
issues.append("⚠️ SSL is disabled - visitors will see 'Not Secure' warnings")
# Report current configuration
if not issues:
issues.append(f"✅ SSL Mode: {ssl_mode} - Configuration looks good")
issues.append(f" Always Use HTTPS: {always_https}")
return len([i for i in issues if i.startswith("⚠️")]) > 0, issues
except requests.RequestException as e:
return True, [f"Network Error: {str(e)}"]
except Exception as e:
return True, [f"Unexpected Error: {str(e)}"]
def check_dns_records(
zone_id: str, domain: str, email: str, api_key: str
) -> Tuple[bool, List[str]]:
"""
Check DNS configuration for common issues.
Returns: (has_issues, issues_list)
"""
try:
import requests
except ImportError:
return True, ["Error: 'requests' library not installed"]
issues = []
try:
response = requests.get(
f"https://api.cloudflare.com/client/v4/zones/{zone_id}/dns_records",
headers={"X-Auth-Email": email, "X-Auth-Key": api_key},
timeout=30
)
if not response.ok:
return True, [f"API Error: {response.status_code}"]
data = response.json()
if not data.get("success"):
return True, [f"API Error: {data.get('errors')}"]
records = data["result"]
# Check for root domain records
root_records = [r for r in records if r["name"] == domain]
if not root_records:
issues.append(f"⚠️ No DNS records found for root domain '{domain}'")
# Check proxy status
proxied_records = [r for r in records if r.get("proxied")]
if proxied_records:
issues.append(f"✅ Found {len(proxied_records)} proxied record(s) (Cloudflare CDN enabled)")
unproxied_important = [
r for r in records
if not r.get("proxied") and r["type"] in ["A", "AAAA", "CNAME"]
]
if unproxied_important:
issues.append(
f" Found {len(unproxied_important)} non-proxied record(s) - "
"these bypass Cloudflare's CDN and security features"
)
return len([i for i in issues if i.startswith("⚠️")]) > 0, issues
except Exception as e:
return True, [f"Error checking DNS: {str(e)}"]
def check_page_rules(
zone_id: str, email: str, api_key: str
) -> Tuple[bool, List[str]]:
"""
Check Page Rules for potential redirect loops.
Returns: (has_issues, issues_list)
"""
try:
import requests
except ImportError:
return True, ["Error: 'requests' library not installed"]
issues = []
try:
response = requests.get(
f"https://api.cloudflare.com/client/v4/zones/{zone_id}/pagerules",
headers={"X-Auth-Email": email, "X-Auth-Key": api_key},
timeout=30
)
if not response.ok:
return True, [f"API Error: {response.status_code}"]
data = response.json()
if not data.get("success"):
return True, [f"API Error: {data.get('errors')}"]
rules = data["result"]
if not rules:
issues.append("✅ No Page Rules configured")
return False, issues
# Check for redirect rules
redirect_rules = []
for rule in rules:
actions = rule.get("actions", [])
for action in actions:
if action.get("id") in ["forwarding_url", "always_use_https"]:
redirect_rules.append({
"url": rule.get("targets", [{}])[0].get("constraint", {}).get("value"),
"action": action.get("id"),
"status": rule.get("status")
})
if redirect_rules:
issues.append(f" Found {len(redirect_rules)} redirect Page Rule(s):")
for r in redirect_rules:
issues.append(f" - {r['url']}: {r['action']} (status: {r['status']})")
issues.append(
" Note: Conflicting redirect rules can cause redirect loops"
)
else:
issues.append("✅ No redirect Page Rules found")
return False, issues
except Exception as e:
return True, [f"Error checking Page Rules: {str(e)}"]
def main():
"""Main diagnostic function."""
if len(sys.argv) < 4:
print("Usage: python check_cloudflare_config.py <domain> <email> <api_key>")
print("\nExample:")
print(" python check_cloudflare_config.py typeof.tech user@example.com abc123...")
print("\nGet your Global API Key from:")
print(" https://dash.cloudflare.com/profile/api-tokens")
sys.exit(1)
domain = sys.argv[1]
email = sys.argv[2]
api_key = sys.argv[3]
try:
import requests
except ImportError:
print("Error: 'requests' library not found")
print("Install with: pip install requests")
sys.exit(1)
print(f"\n🔍 Checking Cloudflare configuration for: {domain}\n")
print("=" * 60)
# Get zone ID
try:
response = requests.get(
f"https://api.cloudflare.com/client/v4/zones?name={domain}",
headers={"X-Auth-Email": email, "X-Auth-Key": api_key},
timeout=30
)
if not response.ok:
print(f"❌ API Error: {response.status_code}")
sys.exit(1)
data = response.json()
if not data.get("success") or not data.get("result"):
print(f"❌ Domain '{domain}' not found in your Cloudflare account")
sys.exit(1)
zone_id = data["result"][0]["id"]
print(f"✅ Found zone: {domain} (ID: {zone_id})\n")
except requests.RequestException as e:
print(f"❌ Network error: {e}")
sys.exit(1)
# Run all checks
all_issues = []
print("\n📋 SSL/TLS Configuration:")
print("-" * 60)
has_ssl_issues, ssl_issues = check_ssl_configuration(zone_id, email, api_key)
for issue in ssl_issues:
print(issue)
print("\n📋 DNS Configuration:")
print("-" * 60)
has_dns_issues, dns_issues = check_dns_records(zone_id, domain, email, api_key)
for issue in dns_issues:
print(issue)
print("\n📋 Page Rules:")
print("-" * 60)
has_rules_issues, rules_issues = check_page_rules(zone_id, email, api_key)
for issue in rules_issues:
print(issue)
# Summary
print("\n" + "=" * 60)
if has_ssl_issues or has_dns_issues or has_rules_issues:
print("⚠️ Issues found - review the warnings above")
sys.exit(1)
else:
print("✅ No critical issues detected!")
sys.exit(0)
if __name__ == "__main__":
main()

View File

@@ -0,0 +1,186 @@
#!/usr/bin/env python3
"""
Fix Cloudflare SSL/TLS mode to resolve redirect loops.
This script changes the SSL mode to resolve common redirect loop issues
caused by SSL mode mismatches between Cloudflare and origin servers.
Common scenarios:
- GitHub Pages + Flexible mode → Change to Full
- Netlify/Vercel + Flexible mode → Change to Full
- Any HTTPS-enforcing origin + Flexible mode → Change to Full
Requires:
- requests library
- Cloudflare API credentials
"""
import sys
def fix_ssl_mode(zone_id: str, target_mode: str, email: str, api_key: str) -> bool:
"""
Change SSL mode for a zone.
Args:
zone_id: Cloudflare zone ID
target_mode: Target SSL mode ('flexible', 'full', 'full_strict', 'off')
email: Cloudflare account email
api_key: Cloudflare Global API Key
Returns:
True if successful, False otherwise
"""
try:
import requests
except ImportError:
print("Error: 'requests' library not installed")
print("Install with: pip install requests")
return False
# Validate mode
valid_modes = ["flexible", "full", "strict", "off"]
if target_mode not in valid_modes:
print(f"Error: Invalid SSL mode '{target_mode}'")
print(f"Valid modes: {', '.join(valid_modes)}")
return False
# Note: API uses 'strict' but documentation calls it 'full (strict)'
api_mode = target_mode
try:
response = requests.patch(
f"https://api.cloudflare.com/client/v4/zones/{zone_id}/settings/ssl",
headers={
"X-Auth-Email": email,
"X-Auth-Key": api_key,
"Content-Type": "application/json"
},
json={"value": api_mode},
timeout=30
)
if not response.ok:
print(f"❌ API Error: {response.status_code}")
print(f"Response: {response.text}")
return False
data = response.json()
if not data.get("success"):
print(f"❌ Failed to update SSL mode")
print(f"Errors: {data.get('errors', 'Unknown error')}")
return False
new_mode = data["result"]["value"]
print(f"✅ SSL mode successfully changed to: {new_mode}")
print(f"\n⏳ Cloudflare is updating edge servers (typically takes 10-30 seconds)")
print(f"💡 Recommendation: Clear your browser cache or use incognito mode to test")
return True
except Exception as e:
print(f"❌ Error: {str(e)}")
return False
def purge_cache(zone_id: str, email: str, api_key: str) -> bool:
"""Purge all Cloudflare cache for the zone."""
try:
import requests
except ImportError:
return False
try:
response = requests.post(
f"https://api.cloudflare.com/client/v4/zones/{zone_id}/purge_cache",
headers={
"X-Auth-Email": email,
"X-Auth-Key": api_key,
"Content-Type": "application/json"
},
json={"purge_everything": True},
timeout=30
)
if response.ok and response.json().get("success"):
print("✅ Cache purged successfully")
return True
return False
except Exception:
return False
def main():
"""Main function."""
if len(sys.argv) < 5:
print("Usage: python fix_ssl_mode.py <domain> <email> <api_key> <mode> [--purge-cache]")
print("\nSSL Modes:")
print(" flexible - Cloudflare → Origin uses HTTP (can cause loops with HTTPS origins)")
print(" full - Cloudflare → Origin uses HTTPS (recommended for most origins)")
print(" strict - Full + validates origin certificate (most secure)")
print(" off - No encryption (not recommended)")
print("\nExamples:")
print(" # Fix redirect loop for GitHub Pages")
print(" python fix_ssl_mode.py typeof.tech user@example.com abc123... full --purge-cache")
print("\n # Switch to strict mode")
print(" python fix_ssl_mode.py example.com user@example.com abc123... strict")
sys.exit(1)
domain = sys.argv[1]
email = sys.argv[2]
api_key = sys.argv[3]
target_mode = sys.argv[4]
should_purge = "--purge-cache" in sys.argv
try:
import requests
except ImportError:
print("Error: 'requests' library not found")
print("Install with: pip install requests")
sys.exit(1)
print(f"\n🔧 Fixing SSL configuration for: {domain}")
print("=" * 60)
# Get zone ID
try:
response = requests.get(
f"https://api.cloudflare.com/client/v4/zones?name={domain}",
headers={"X-Auth-Email": email, "X-Auth-Key": api_key},
timeout=30
)
if not response.ok:
print(f"❌ API Error: {response.status_code}")
sys.exit(1)
data = response.json()
if not data.get("success") or not data.get("result"):
print(f"❌ Domain '{domain}' not found in your Cloudflare account")
sys.exit(1)
zone_id = data["result"][0]["id"]
print(f"✅ Found zone: {domain}\n")
except requests.RequestException as e:
print(f"❌ Network error: {e}")
sys.exit(1)
# Fix SSL mode
if not fix_ssl_mode(zone_id, target_mode, email, api_key):
sys.exit(1)
# Optionally purge cache
if should_purge:
print(f"\n🗑️ Purging cache...")
purge_cache(zone_id, email, api_key)
print("\n✅ Done! Test your site after 30 seconds.")
sys.exit(0)
if __name__ == "__main__":
main()