commit e85b8b73e8c14be88d6eedef15fd86ee66032c46 Author: Zhongwei Li Date: Sat Nov 29 18:18:15 2025 +0800 Initial commit diff --git a/.claude-plugin/plugin.json b/.claude-plugin/plugin.json new file mode 100644 index 0000000..81f71af --- /dev/null +++ b/.claude-plugin/plugin.json @@ -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" + ] +} \ No newline at end of file diff --git a/README.md b/README.md new file mode 100644 index 0000000..73df886 --- /dev/null +++ b/README.md @@ -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 diff --git a/plugin.lock.json b/plugin.lock.json new file mode 100644 index 0000000..815b1ec --- /dev/null +++ b/plugin.lock.json @@ -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": [] + } +} \ No newline at end of file diff --git a/skills/cloudflare-troubleshooting/SKILL.md b/skills/cloudflare-troubleshooting/SKILL.md new file mode 100644 index 0000000..72db41b --- /dev/null +++ b/skills/cloudflare-troubleshooting/SKILL.md @@ -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=" \ + -H "X-Auth-Email: " \ + -H "X-Auth-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: " https:// + ``` + +**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 + dig @8.8.8.8 + ``` + +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 :443 -servername + ``` + +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: " https:// + ``` + +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. diff --git a/skills/cloudflare-troubleshooting/references/api_overview.md b/skills/cloudflare-troubleshooting/references/api_overview.md new file mode 100644 index 0000000..5edbdeb --- /dev/null +++ b/skills/cloudflare-troubleshooting/references/api_overview.md @@ -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 " +``` + +## 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= +``` +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' +``` diff --git a/skills/cloudflare-troubleshooting/references/common_issues.md b/skills/cloudflare-troubleshooting/references/common_issues.md new file mode 100644 index 0000000..5033d4d --- /dev/null +++ b/skills/cloudflare-troubleshooting/references/common_issues.md @@ -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 diff --git a/skills/cloudflare-troubleshooting/references/ssl_modes.md b/skills/cloudflare-troubleshooting/references/ssl_modes.md new file mode 100644 index 0000000..274025b --- /dev/null +++ b/skills/cloudflare-troubleshooting/references/ssl_modes.md @@ -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` diff --git a/skills/cloudflare-troubleshooting/scripts/check_cloudflare_config.py b/skills/cloudflare-troubleshooting/scripts/check_cloudflare_config.py new file mode 100644 index 0000000..189e8ed --- /dev/null +++ b/skills/cloudflare-troubleshooting/scripts/check_cloudflare_config.py @@ -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 ") + 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() diff --git a/skills/cloudflare-troubleshooting/scripts/fix_ssl_mode.py b/skills/cloudflare-troubleshooting/scripts/fix_ssl_mode.py new file mode 100644 index 0000000..6248aa2 --- /dev/null +++ b/skills/cloudflare-troubleshooting/scripts/fix_ssl_mode.py @@ -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 [--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()