Pro pochopení tohoto článku je nutné alespoň v hrubých rysech znát principy protokolu BGP. Pokud takovouto znalostí nevládnete, doporučujeme vám k přečtení úvod předchozího článku o útoku na BGP, který takový jednoduchý nástin problematiky BGP obsahuje.
Pro nás je v současné chvíli podstatné, že pokud se BGP router rozhoduje o tom, která cesta je pro paket pro určitou destinaci výhodnější, použije tu, která je kratší z hlediska počtu autonomních systémů, nikoliv z hlediska fyzické vzdálenosti, počtu routerů po cestě či propustnosti trasy (ve skutečnosti je rozhodovací proces mírně složitější, ale to v tuto chvíli můžeme zanedbat). Problém nastává, pokud má poskytovatel připojení (ISP) dvě linky do světa a rád by nějak balancoval jejich vytížení. Z podstaty routingu může poměrně snadno ovlivňovat rozložení toků, které jsou posílány směrem od daného ISP do světa. V případě, že se jedna linka ISP přetěžuje, začne prostě některé sítě směrovat tou druhou. Mnohem složitější je ovšem směr příchozí. Ovlivnit směrování mnoha vzdálených sítí jen tak jednoduše nejde. Používá se tedy jednoduchý trik, kterému se říká AS path prepending. Ten spočívá v tom, že do směrovací informace, kterou o své síti šíří do světa (své AS path), přidá jeden nebo více čísel svého autonomního systému, jako by si sám sobě poskytoval konektivitu. Například do linky nadřazeného ISP A posílám informaci, že má síť 217.31.192.0/20 je dostupná přes AS25192 a druhému ISP B posílám informaci, že stejná síť je dostupná přes AS25192 AS25192 AS25192. Tímto trikem se jedna z cest uměle prodlouží a tím donutím routery ostatních sítí preferovat cestu přes ISP A.
Protože je protokol BGP poměrně starý, trpí klasickým problémem starších protokolů. Inženýři, kteří BGP navrhovali, byli poměrně konzervativní a pro ASN (tedy číslo AS) použili pouze 16-bitů, tedy číslo AS může nabývat hodnot od 1 do 65535. A tak, jako začaly docházet IPv4 adresy, začaly docházet i ASN. Proto vzniklo rozšíření BGP protokolu, které definuje dvojnásobnou (bitovou) velikost, což zvětší použitelný rozsah ASN až na číslo okolo 4 miliard. Způsob rozšíření se poměrně povedl a z hlediska stávajících implementací, které nové 32-bitové ASN nepodporují, je toto rozšíření transparentní. I staré implementace BGP protokolu jsou schopné informace o IP adresách a číslech AS přijímat a posílat dále. Přesné vysvětlení tohoto mechanismu jde za rámec tohoto článku, nicméně tomuto tématu se věnovala jedna z přednášek konference Internet a Technologie 08.
Nyní už máme veškerou teorii popsanou a můžeme se podívat, co se vlastně stalo. V Africké Káhiře připravovali pořadatelé konferenci správců sítí AfNOG. Pro připojení účastníků této konference byl vyhrazen IP rozsah 196.200.208.0/20 s 32 bitovým číslem autonomního systému AS327686 (nebo také AS5.6). Mimochodem nasazením 32 bitového čísla AS chtěli demonstrovat, že tato čísla fungují a že se správci nemusí obávat je použít. Protože měli k dispozici dvě konektivity do Internetu a jednu chtěli mít jako záložní, provedli AS path prepend. Díky protokolu BGP se tato AS path pochopitelně okamžitě rozšířila do celého světa. Bohužel se ukázalo, že poměrně hojně používaná UNIXová implementace dynamického routingu (Quagga) obsahuje chybu, která způsobila pád tohoto démona a tedy rozpad routingu na mnoha sítích v celém světě. Ostatní hardwarové routery jakož i ostatní UNIXové implementace routingu jako BIRD či OpenBGPD problémy nevykazovaly. Analýza na serveru Renesys ukazuje, že takto bylo postiženo asi 6000 sítí, které používají softwarové routery s démonem Quagga. Smutné je, že v příslušné části kódu je komentář, který vyjmenovává, že k chybě může dojít. Problém je v tom, že v alokaci prostoru pro AS path se v kódu předpokládá, že délka čísla AS je 5 znaků (v dekadickém ASCII zápisu). To platí pro 16-ti bitová čísla AS a pro 32 bitová, menší než 100000. Pro každý AS path si pak program alokoval v paměti prostor (5+1) krát počet AS plus ukončovací znaky. Z toho vyplývá, že problém nastane pouze v případě, že průměrná délka AS v AS path je větší než 5. Pokud by například AS path byla AS1 AS1000000, tak se chyba neprojeví, protože průměrná délka označení AS je 4. Naneštěstí technici AfNOGu exportovali takovýto AS path 24863 327686 327686 327686 327686 327686 327686 327686 327686 327686 327686 37095. Snadno si jistě spočítáte, že průměrná délka textového zápisu AS je přibližně 5,8. Inu příslušný programátor byl zjevně trochu flegmatik. Sám za sebe myslím hovoří tento jeho komentář v kódu:
/* We might need to increase str_buf, particularly if path has
* differing segments types, our initial guesstimate above will
* have been wrong. need 5 chars for ASN, a seperator each and
* potentially two segment delimiters, plus a space between each
* segment and trailing zero.
*
* This may need to revised if/when significant numbers of
* ASNs >= 100000 are assigned and in-use on the internet...
*/
Problematický kus kódu následuje hned za tímto komentářem:
#define SEGMENT_STR_LEN(X) (((X)->length * ASN_STR_LEN) + 2 + 1 + 1)
if ( (len + SEGMENT_STR_LEN(seg)) > str_size)
{
str_size = len + SEGMENT_STR_LEN(seg);
str_buf = XREALLOC (MTYPE_AS_STR, str_buf, str_size);
}
#undef ASN_STR_LEN
#undef SEGMENT_STR_LEN
Zde se mimochodem analýza Renesysu plete, protože uvádí první podobný komentář, kde si ale programátor pouze připravuje místo v paměti, které následně ve výše uvedeném kusu kódu zvětšuje, pokud je to potřeba. Bohužel díky chybnému předpokladu (5 znaků na AS) usoudí, že zvětšení není zapotřebí a do další části programu vstupuje s příliš malým rezervovaným místem. Naštěstí programátor nebyl natolik líný, takže se využití místa kontroluje. Program tak neskončí nechvalně známým přetečením zásobníku („buffer/stack overflow“), což je vážná bezpečnostní chyba, ale pouze vypíše chybu a ukončí se.
Bylo jen otázkou času, kdy se chyba projeví. Na druhou stranu, velkou výhodou open source je, že opravy chyb se objevují s obrovskou rychlostí, takže téměř okamžitě vznikla záplata, byť nad její kvalitou se zkušený programátor možná mírně podivuje. Ještě takovou perličkou je, že člověk, který byl za nastavení příslušné sítě zodpovědný, se v listu uživatelů démona Quagga omluvil a v té omluvě vzpomenul podobnou chybu, která se stala u směrovacího démona Gated. Pochopitelně zrovna on se neměl za co omlouvat, protože propagoval do světa zcela korektní cestu, podobně jako v minulé „české“ kauze.
Jak je vidět, chyby se nevyhýbají žádnému typu routeru. V minulém problému s exportem dlouhého AS path byla hlavní příčinou závada v hardwarových routerech Cisco, nyní šlo o chybu v démonu Quagga. Programy píší pouze lidé a ti dělají chyby. Otázkou spíše je, jak tomu čelit. Asi nejlepším způsobem je mít dvě různé nezávislé platformy. Jak ve světě hardwarových tak i softwarových směrovačů alternativy existují. Multiplatformnost sice nezaručuje, že k žádnému problému dojít nemůže, ale rozhodně výrazně zvyšuje robustnost sítě. Bohužel i toto řešení má svá úskalí. Prvním je pochopitelně cena, místo jednoho dodavatele potřebuje ISP dva, u kterých má menší objem nákupu jistě vliv na poskytnutou slevu. Používání dvou různých směrovacích platforem vyžaduje více proškolenou obsluhu a to tedy ve svém důsledku zvyšuje náklady na správu sítě. Druhým problémem může být vzájemná nekompatibilita použitých zařízení, která je zvláště problematická u uzavřených komerčních řešení, kde jsou často využívány proprietární standardy zatížené řadou patentů.