Cloudflare ECH és a Split DNS

  • Linux
  • 2026. április 23.

Egy ideje egy elég frusztráló problémával küzdök a saját hálózatomon. Jóideje futtatok otthoni szolgáltatásokat (például Home Assistantot) egy saját domainen (nevezzük most okosotthon.sajatdomain.hu-nak), ami a Cloudflare mögött csücsül. Az otthoni hálózat és a Cloudflare között a pfSense routeren futó HAProxy is bonyolítja, a helyi névfeloldást pedig egy Pi-hole végzi (Split DNS). Ez utóbbiban be van állítva, hogy a belső hálózaton a domain a HAProxy belső lábára (egy 192.168.X.X-es IP-re) mutasson, és a pfSense adja hozzá a saját tanúsítványát.

Egy darabig minden tökéletesen ment, aztán valami megváltozott: a belső hálózatról a HomeAssistant időszakosan elérhetetlenné vált. A lokális IP-n/hostnéven hibátlanul töltött be minden, kívülről mobilneten szintén pöpec volt a rendszer, de itthonról egyszerűen nem töltött be a HA felülete.

Belenéztem a böngésző fejlesztői konzoljába, és a következő hibaüzenetek fogadtak:

  • net::ERR_ECH_FALLBACK_CERTIFICATE_INVALID
  • net::ERR_FAILED a manifest.json lekérésekor
  • Szakadó WebSocket (wss://) kapcsolatok

Mi okozta a problémát?

A bűnös a Cloudflare egyik alapértelmezetten bekapcsolt funkciója, az Encrypted Client Hello (ECH) volt.

A modern böngészők egyre agresszívebben használják a DoH-t (DNS over HTTPS), illetve gyorsítótárazzák a HTTPS (Type 65) DNS rekordokat. Ezekből megtudják, hogy a Cloudflare támogatja az ECH-t az adott domainemen, és megkapják a titkosításhoz szükséges publikus kulcsokat. Csakhogy a Pi-hole miatt a lekérés fizikailag a helyi pfSense HAProxy-hoz fut be. A böngésző megpróbálja ráerőltetni a Cloudflare-es ECH kézfogást a helyi proxy-ra, aminek természetesen fogalma sincs erről a kulcsról. Az eredmény: elhasaló TLS kapcsolat és a fent látható hibaüzenetek.

A lehetséges megoldások

Amikor rájöttem az okra, három opció állt előttem:

  1. A böngésző Secure DNS (DoH) kikapcsolása: Ezzel rákényszerítem a böngészőt, hogy szigorúan a Pi-hole-t használja. Hátránya: Eszközspecifikus, minden gépen és telefonon külön kellene állítgatni, ami nem életszerű.
  2. A TYPE65 DNS rekordok szűrése a Pi-hole-ban: Beállíthattam volna, hogy a belső DNS szerver dobja el a HTTPS rekordokra vonatkozó kéréseket. Hátránya: Szintén egy plusz konfigurációs réteg, ami később más gondokat is okozhat.
  3. Az ECH kikapcsolása a Cloudflare-en: Ez a legtisztább, globális megoldás, ami a gyökerénél kezeli a problémát.

Én a harmadik, vagyis a Cloudflare-es kikapcsolás mellett döntöttem. Itt viszont beleütköztem egy falba: a Cloudflare az ingyenes fiókoknál egyszerűen elrejtette az ECH kikapcsoló gombját a grafikus felületről. Szerencsére az API-n keresztül továbbra is van rá lehetőség.

A megoldás: ECH kikapcsolása API-n keresztül

Mivel a gomb eltűnt, parancssorból kellett megoldani. Nincs benne semmi ördöngösség, mindössze három adatra volt szükségem a Cloudflare fiókomból:

  1. Zone ID: A Cloudflare nyitóoldalán (Overview), az adott domain kiválasztása után a jobb oldalsáv alján található.
  2. Global API Key: A profilbeállításokban (My Profile -> API Tokens) lekérhető kulcs.
  3. Account Email: Az e-mail cím, amivel a Cloudflare-be bejelentkezek.

Hogy a dolgot a jövőben is könnyen visszakapcsolhatóra csináljam meg, összedobtam egy gyors shell scriptet.

A Bash Script

Ezt a kis scriptet használtam, amiben csak a felső változókat kellett kitöltenem a saját adataimmal:

#!/bin/sh

# Cloudflare ECH (Encrypted Client Hello) állapot módosító szkript
# Használat: Töltsd ki a változókat a saját adataiddal!

# === VÁLTOZÓK BEÁLLÍTÁSA ===
CF_ZONE_ID="IDE_JÖN_A_ZONE_ID"
CF_EMAIL="IDE_JÖN_AZ_EMAIL_CÍMED"
CF_API_KEY="IDE_JÖN_A_GLOBAL_API_KEY"

# ECH kívánt állapota: "off" (kikapcsolva) vagy "on" (bekapcsolva)
ECH_STATUS="off" 

# === API HÍVÁS ===
echo "Cloudflare ECH beállítás módosítása '${ECH_STATUS}' állapotra a következő zónán: $CF_ZONE_ID ..."

RESPONSE=$(curl -s -w "\nHTTP_STATUS:%{http_code}\n" -X PATCH "https://api.cloudflare.com/client/v4/zones/${CF_ZONE_ID}/settings/ech" \
     -H "X-Auth-Email: ${CF_EMAIL}" \
     -H "X-Auth-Key: ${CF_API_KEY}" \
     -H "Content-Type: application/json" \
     --data "{\"id\":\"ech\",\"value\":\"${ECH_STATUS}\"}")

# Eredmény kiírása
echo "========================================"
echo "Válasz a Cloudflare API-tól:"
echo "$RESPONSE"
echo "========================================"

Létrehoztam a fájlt (nano disable_ech.sh), adtam neki futtatási jogot (chmod +x disable_ech.sh), és lefuttattam. A JSON válaszban azonnal láttam a "success": true üzenetet.

{"result":{"id":"ech","value":"off","modified_on":null,"editable":true},"success":true,"errors":[],"messages":[]}

Körülbelül 5-10 percet kellett várnom, amíg a Cloudflare frissítette az Edge szervereit. Utána nyomtam egy kemény böngésző cache ürítést, és a Split DNS-es otthoni rendszerem újra hibátlanul, szakadások nélkül töltött be a belső hálózatról.

Hogyan ellenőrizheted, hogy az ECH tényleg kikapcsolt-e?

Ha biztosra akarsz menni, és le akarod tesztelni a módosítás eredményét, szerencsére van egy nagyon egyszerű, parancssort sem igénylő módszer.

Nem kell mást tenned, mint megnyitni a böngésződben a Google publikus DNS API-ját a következő linken:

https://dns.google/resolve?name=okosotthon.sajatdomain.hu&type=HTTPS

(A domaint természetesen cseréld ki a sajátodra!)

Ez a link a háttérben lekérdezi a domainedhez tartozó speciális HTTPS (Type 65) DNS rekordokat. A böngésződben egy nyers szöveges (JSON) válasz fog megjelenni.

Mit kell keresned?

Böngészd át a szöveget, különös tekintettel az Answer vagy a data mezők környékére.

Ha már sehol nem látod az ech= paramétert és a hozzá tartozó hosszú, értelmezhetetlen karakterláncot, akkor megnyugodhatsz: az ECH sikeresen ki lett lőve. A lokális hálózatod és a HAProxy újra a régi, jól bevált módon fog működni.

Rontottam ezzel a biztonságomon?

A válasz röviden: nem.

Az ECH kikapcsolásával az adataim és a szerver kommunikációja (például az okosotthon jelszavak, szenzoradatok) továbbra is kőkeményen titkosítva utaznak (TLS 1.2 / 1.3). Bárki is hallgatózik a hálózaton, csak értelmezhetetlen zajt lát.

Az egyetlen dolog, ami megváltozott, hogy a titkosítás felépítése előtt a hálózati csomag “borítékján” most már ismét olvasható a célállomás neve (az SNI, azaz maga a domain név). Ez azonban feltétlenül szükséges ahhoz, hogy a HAProxy tudja, hová kell irányítania a belső forgalmat. Egy self-hosted otthoni szerver esetében ez a minimális metaadat-szivárgás teljesen irreleváns kockázat a stabil helyi elérésért cserébe.