A Cloudflare többórás üzemzavara a hibakezelés helytelen megvalósítására vezethető vissza

A Cloudflare közzétette a vizsgálati jelentést az infrastruktúrájuk egyik legnagyobb hibájáról, amelynek következtében a tartalomszolgáltató hálózat nagy része több mint 3 órán keresztül nem volt működőképes. A kiesés egy adatbázis-struktúrában végrehajtott módosítás után következett be a ClickHouse alapú tárolórendszerben. A módosítás eredményeként a botvédelemhez használt paraméterfájl mérete a duplájára nőtt.

Az adatbázisban duplikált táblák keletkeztek, miközben az SQL-lekérdezés, amely a fájl generálását végezte, egyszerűen az összes táblából kiolvasta a kulcs szerinti adatokat anélkül, hogy kiszűrte volna a duplikátumokat:

SELECT
 name,
 type
FROM system.columns
WHERE
 table = 'http_requests_features'
ORDER BY name;
 

A létrehozott fájl ezután szétterjedt a klaszter összes olyan csomópontjára, amelyek a bejövő kéréseket dolgozzák fel. Az azt használó feldolgozó modul a botok által indított kérések felismeréséhez a fájl paramétereit a memóriába töltötte. A túlzott memóriahasználat megakadályozására a kódban be volt állítva egy maximális fájlméret-korlát. Normál esetben a fájl mérete jóval a határérték alatt maradt, de a táblák duplikációja után meghaladta a limitet.

A probléma lényege az volt, hogy a rendszer nem megfelelően kezelte a limit túllépését. Ahelyett, hogy szabályosan jelezte volna a felügyeleti rendszer felé a rendellenes helyzetet, miközben tovább használja a korábbi, érvényes fájlverziót, a feldolgozó modul hibára futott és leállt. Ez a leállás blokkolta a forgalom továbbítását.

A hibát az okozta, hogy a Rust nyelven írt kódban a Result típushoz tartozó unwrap() metódust használták. Ha a Result állapota „Ok”, akkor az unwrap() visszaadja a benne lévő értéket; ha viszont nem sikeres („Err”), a hívás azonnali programösszeomlást eredményez (a „panic!” makró fut le). Az unwrap() általában csak hibakeresés során vagy tesztkódokban ajánlott, és nem javasolt éles rendszerekben.