diff --git a/networking/troubleshooting.md b/networking/troubleshooting.md index e7108be..579be0c 100644 --- a/networking/troubleshooting.md +++ b/networking/troubleshooting.md @@ -927,6 +927,74 @@ ssh npm-pihole "docker start pihole" # This is industry standard DNS HA behavior ``` +## Pi-hole Blocklist Blocking Legitimate Apps + +### Facebook Blocklist Breaking Messenger Kids (2026-03-05) +**Symptoms**: iPad could not connect to Facebook Messenger Kids. App would not load or send/receive messages. Disconnecting iPad from WiFi (using cellular) restored functionality. + +**Root Cause**: The `anudeepND/blacklist/master/facebook.txt` blocklist was subscribed in Pi-hole, which blocked all core Facebook domains needed by Messenger Kids. + +**Blocked Domains (from pihole.log)**: +| Domain | Purpose | +|--------|---------| +| `edge-mqtt.facebook.com` | MQTT real-time message transport | +| `graph.facebook.com` | Facebook Graph API (login, contacts, profiles) | +| `graph-fallback.facebook.com` | Graph API fallback (blocked via CNAME chain) | +| `www.facebook.com` | Core Facebook domain | + +**Allowed Domains** (not on the blocklist, resolved fine): +- `dgw.c10r.facebook.com` - Data gateway +- `mqtt.fallback.c10r.facebook.com` - MQTT fallback +- `chat-e2ee.c10r.facebook.com` - E2E encrypted chat + +**Diagnosis**: +```bash +# Find blocked domains for a specific client IP +ssh pihole "docker exec pihole grep 'CLIENT_IP' /var/log/pihole/pihole.log | grep 'gravity blocked'" + +# Check which blocklist contains a domain +ssh pihole "docker exec pihole pihole -q edge-mqtt.facebook.com" +# Output: https://raw.githubusercontent.com/anudeepND/blacklist/master/facebook.txt (block) +``` + +**Resolution**: Removed the Facebook blocklist from primary Pi-hole (secondary didn't have it). The blocklist contained ~3,997 Facebook domains. + +**Pi-hole v6 API - Deleting a Blocklist**: +```bash +# Authenticate and get session ID +SID=$(curl -s -X POST 'http://PIHOLE_IP:PORT/api/auth' \ + -H 'Content-Type: application/json' \ + -d '{"password":"APP_PASSWORD"}' \ + | python3 -c 'import sys,json; print(json.load(sys.stdin)["session"]["sid"])') + +# DELETE uses the URL-encoded list ADDRESS as path parameter (NOT numeric ID) +# The ?type=block parameter is REQUIRED +curl -s -X DELETE \ + "http://PIHOLE_IP:PORT/api/lists/URL_ENCODED_LIST_ADDRESS?type=block" \ + -H "X-FTL-SID: $SID" +# Success returns HTTP 204 No Content + +# Update gravity after removal +ssh pihole "docker exec pihole pihole -g" + +# Verify domain is no longer blocked +ssh pihole "docker exec pihole pihole -q edge-mqtt.facebook.com" +``` + +**Important Pi-hole v6 API Notes**: +- List endpoints use the URL-encoded blocklist address as path param, not numeric IDs +- `?type=block` query parameter is mandatory for DELETE operations +- Numeric ID DELETE returns 200 with `{"took": ...}` but DOES NOT actually delete (silent failure) +- Successful address-based DELETE returns HTTP 204 (no body) +- Must run `pihole -g` (gravity update) after deletion for changes to take effect + +**Future Improvement (TODO)**: Implement Pi-hole v6 group/client-based approach: +- Create a group for the iPad that bypasses the Facebook blocklist +- Re-add the Facebook blocklist assigned to the default group only +- Assign the iPad's IP to a "Kids Devices" client group that excludes the Facebook list +- This would maintain Facebook blocking for other devices while allowing Messenger Kids +- See: Pi-hole v6 Admin -> Groups/Clients for per-device blocklist management + ## Service Discovery and DNS Issues ### Local DNS Problems