Dříve než se pustíme do diskuse o CGN uděláme menší terminologickou odbočku. Pod pojmem NAT (network address translation) rozumíme překlad IP adres na úrovni síťové infrastruktury. Pokud je tento překlad doplněn o čísla portů vyšší vrstvy (TCP, UDP, ...), pak je správné označení tohoto mechanismu PAT (port address translation), NAPT (network address port translation) nebo NAT overload. V běžné praxi se ovšem i pro tuto variantu běžně používá termín NAT. Pokud tedy dneska někdo hovoří o NATu, s největší pravděpodobností je tím myšlen PAT (NAPT, NAT overload). Stejně tak s tímto termínem budeme pracovat i my, tedy NAT v článku znamená NAPT/PAT. Samotný CGN je někdy označován synonymy LNAT/LSN (Large Scale NAT) nebo NAT444.
CGN versus NAT v čem je vlastně rozdíl?
První otázka, která vás možná napadne, bude: V čem se vlastně liší takový CGN od běžného NATu? Z hlediska fungování zde skutečně žádný zásadní rozdíl nenajdeme. Vše funguje na stejném principu jako v přístupovém směrovači za 500 Kč u vás doma a to včetně všech nectností (například nemožnost iniciovat komunikaci z vně sítě). V implementační rovině se však CGN od NATu liší poměrně výrazně:
- U CGN předpokládáme, že bude provádět překlad pro tisíce až miliony uživatelů současně. Úměrně tomu bude odpovídat objem zpracovávaných dat, který se bude pohybovat v jednotkách, čí spíše v desítkách gigabitů za sekundu.
- Oproti našemu domácímu NATu budeme u CGN hodně dbát na vysokou míru spolehlivosti. NAT sám o sobě představuje SPoF (Single Point of Failure), tím pádem je potřeba řešit robustnost, redundancí a monitorování celého systému.
- CGN musí být navržen a dimenzován tak, aby odolal útokům. Na rozdíl od domácího NATu sdílejí případné důsledky útoku všichni uživatelé umístění za CGN.
- V některých prostředích budeme muset řešit právní aspekty zavedení CGN. Implementace musí splňovat zákonné požadavky, zejména povinnost uchovávat provozní a lokalizační údaje.
Technologie NAT není pro většinu administrátorů žádnou převratnou novinkou. Jedná se o v praxi dlouho používanou a dobře prověřenou technologii, která je široce používaná na straně domácích směrovačů nebo ve firemním prostředí. Nasazení CGN by v technické rovině tedy nemělo představovat zásadnější problém. Bohužel tomu tak není. Implementace do existující síťové infrastruktury může přinést lecjaká překvapení, z nichž některá mají tu nepříjemnou vlastnost, že se projeví až časem, tedy v době, kdy jsme přesvědčeni, že jsme vše zvládli na výbornou.
Následující text bude z velké části vycházet ze zkušenosti s implementací CGN v prostředí univerzitní sítě Vysokého učení technického v Brně. Ačkoliv se mnohým může zdát, že univerzitní prostředí musí být zákonitě nějak vyšinuté a výrazně se lišící od běžných sítí, tak ve skutečnosti tomu tak není a můžeme zde najít kombinaci několika síťových světů. Čistě firemní svět, zahrnující interní telefonní síť, přístupové, zabezpečovací a protipožární systémy, systémy inteligentního řízení budov a samozřejmě také připojení pracovišť zaměstnanců univerzity. Část sítě má charakteristiku středně velkého ISP poskytujícího konektivitu pro 6000 přípojek na univerzitních kolejích a v neposlední řadě zde najdeme sítě datových center zahrnující jak servery nutné pro každodenní chod univerzity, tak výpočetní clustery pro řešení náročných vědeckých úloh. V našem textu se budeme zabývat implementací CGN spíše z pohledu operátora. Důvod je prostý. Firemní prostředí již tradičně technologii NAT používá a nasazení CGN v zásadě nedává příliš smysl. V prostředí datacenter lze předpokládat, že jsou zde služby primárně poskytovány veřejně a tedy na veřejných IP adresách. V tomto prostředí se technologie NAT sice používá také, ale primárně k jinému účelu (load-balancing, migrace atp.). Při popisu implementace CGN se nebudeme vázat na žádného konkrétního výrobce ani technologii. Popisované principy platí bez ohledu na to, zda CGN implementujeme na „velkém“ směrovači typu Cisco ASR nebo na něčem „menším“ typu Mikrotik.
CGN na EXITu
Dnešní sítě většiny operátorů jsou tvořeny uzavřeným celkem, kde na jedné straně jsou připojená zařízení u koncových uživatelů (CPE - Customer-premises equipment) a na straně druhé je síť v několika místech propojená s okolními sítěmi (peering) anebo se sítí tranzitního operátora. Pro označení těchto spojnic s okolním světem se často užívá termín EXIT. Zatímco menší sítě mají pouze jeden EXIT prostřednictvím tranzitního dodavatele konektivity, ve středních a větších sítích se můžeme setkat i s desítkami EXITů různě geograficky rozmístěných. Obecně platí, že veškerá výměna dat mezi příslušnou sítí a okolním světem musí nutně projít některým z nich. Jednotlivé EXITy také určují hranice pro definování vnitřní politiky, například stran rozdělení adresního prostoru, směrování bezpečnostních pravidel atd. EXITy se tedy jeví jako velmi vhodné místo právě i pro umístění CGN. Jak to může vypadat v praxi, je zachyceno na následujícím obrázku:
Vidíme zde modelovou situaci, kdy
poskytovatel má v síti připojené dva uživatele. Prvním z nich je domácí síť
používající adresní rozsah 192.168.1.0/24
,
která je připojená prostřednictvím malého směrovače (CPE). Tomuto směrovači
byla na vnějším rozhraní přidělená privátní adresa 10.1.2.3
. Druhým zařízením v sítí je server s přidělenou
veřejnou IP adresou 147.229.3.10
.
Pro jednoduchost budeme zatím uvažovat, že v sítí je pouze jeden EXIT, který je
realizován prostřednictvím hraničního směrovače ISP, který současně provádí
překlad adres (CGN). Překlad adres je aplikován na všechny pakety se zdrojovou
adresou spadající do rozsahu 10.0.0.0/8
.
Pojďme si popsat jednotlivé komunikační scénáře:
1. Průběh komunikace zachycený
zelenou čárou ukazuje případ, kdy zařízení s veřejnou IP adresou (147.229.3.10
) komunikuje se zbytkem
světa. V tomto případě probíhá veškerá komunikace zcela bez účasti mechanismu překladu adres. Pakety jsou směrovány stejným způsobem jako by CGN v sítí vůbec nebyl. Takže zatím nuda.
2. Trošku zajímavější je modrá
čára zachycující situaci, kdy klient z privátní adresy komunikuje se vzdáleným
serverem. Klient v domácí síti vyšle do sítě paket, kde jako zdrojovou adresu použije jemu
přidělenou privátní adresu v domácí síti, tj. 192.168.1.4
,
a zdrojový port si zvolí, řekněme, 5555
.
Vzhledem k tomu, že uživatel chce komunikovat s HTTP serverem na adrese
www.cesnet.cz, tak cílová adresa bude 195.113.144.230
a port 80
. Takto vytvořený paket
doputuje až k domácímu směrovači (CPE). Ten provede překlad, tedy přepíše
zdrojovou IP adresu, IP adresou vnějšího rozhraní CPE, v našem případě
tedy 10.1.2.3
. Pouhým přepisem
adresy ale vše nekončí. NAT musí rovněž identifikovat protokol vyšší vrstvy a
poznamenat si číslo zdrojového TCP či UDP portu. Zde se implementace NATů často
rozcházejí a pracují s danými informacemi různě. Moderní implementace NATu si
pro sebe vytvoří unikátní pětici (protokol, veřejná adresa IP NATu, cílová IP
adresa, zdrojový TCP/UDP port a cílový UDP/TCP port) a snaží se zdrojové porty
neměnit, pokud ve své překladové tabulce je tato pětice unikátní. Zjednodušeně
řečeno, k přepisu zdrojového portu dojde pouze tehdy, pokud se více zařízení
pokouší ze stejného zdrojového portu přistupovat na stejný server a stejný
cílový port ve stejném čase. Některé implementace nicméně zdrojové porty
přepisují vždy. Ke strategii přidělování portů se vrátíme ještě v příštím díle. V našem případě je port přepsán
na 6666
. Současně si NAT uloží
informaci o způsobu překladu privátní adresy (zjednodušeně co přeložil na co)
do tabulky překladů (translation table).
První vrstvu NATu tímto máme za
sebou a transport paketu do cílové sítě může pokračovat dál. Paket dorazí na
hraniční směrovač a CGN poskytovatele, který na základě zdrojové adresy (10.1.2.3
) pozná, že se jedná o paket
odeslaný ze zařízení umístěného v privátní sítí. Podruhé přepíše zdrojovou
adresu, tentokrát na veřejnou adresu CGN (147.229.63.10
). Současně provede případnou modifikaci
portu a odešle paket do Internetu. Stejně jako u domácího NATu si CGN uloží do paměti informaci o tom, jakým způsobem byl proveden překlad adres.
Paket dorazí na cílové místo, kde
vzdálený server bude chtít odeslat zpět paket s odpovědí. Ten sestaví běžným
způsobem, tj. záměnou dvojic zdrojová adresa, zdrojový port s cílovou adresou a
cílovým portem. V našem konkrétním případě bude na pozici zdrojové adresy
uvedeno 195.113.144.230
, port 80
a cílová adresa bude 147.229.63.10
, tedy adresa našeho CGN,
a číslo portu 7777
. V okamžiku,
kdy paket dorazí zpět k CGN se zařízení podívá do tabulky překladů, kde se
pokusí najít záznam odpovídající příslušným portům a adresám. Pokud je záznam
úspěšně nalezen, provede se u paketu přepis cílové adresy a cílového portu dle
tabulky překladů. V našem případě přepíše CGN cílovou adresu na 10.1.2.3
a číslo portu na 6666
. Takto modifikovaný paket je
odeslán do sítě poskytovatele, kde je opět běžným způsobem doručen až k
domácímu NATu. Tam proběhne druhý zpětný překlad a paket může být doručen
koncovému příjemci.
Jak vidíme, kromě toho, že cestou překlad adres provádíme 2x, tak se v principu mechanismus na domácím NATu a v CGN nijak neliší. Stále zatím nic co by nás mělo nějak překvapit. Pojďme se ale podívat na třetí situaci, která je na rozdíl od předchozích dvou v prostředí CGN určitou novinkou.
3. Předpokládejme, že na serveru
s adresou 147.229.3.10
běží
nějaká veřejná služba - například web server. Co se stane v případě, že klient
z domácí sítě bude chtít přistupovat k této službě? Stejně jako v předchozím
případě vytvoří koncové zařízení paket, který následně projde první vrstvou
překladu na domácím NATu. Vzhledem k tomu, že cílový server je umístěn v síti
stejného ISP, je zbytečné tímto provozem zatěžovat CGN, protože výměna dat může
probíhat napřímo, zcela bez jeho účasti. Tento způsob komunikace je někdy
označován termínem CGN bypass. Zde však nastává první problém. Pokud
se podíváme například do logu web serveru, tak příslušný záznam vypadat zhruba
takto:
10.1.2.3 - - [10/Apr/2015:07:08:39 +0200] "GET / HTTP/1.1" 200 8389 "-" "Mozilla/5.0
Jak vidíme, klient je na serveru
identifikován pod privátní adresou 10.1.2.3
.
Z hlediska síťové komunikace to samozřejmě žádný problém není - adresa jak
adresa. V praxi však řada správců serverů vůbec nepředpokládá, že by na server
mohly dorazit pakety z privátních adresových rozsahů. Tento stav považují spíše
za chybu konfigurace a pro jistotu tyto pakety rovnou zahazuji. Výsledkem je,
že se uživatelé ze sítě operátora na tyto služby nedostanou.
Při troše štěstí se možná podaří
správce příslušného serveru přesvědčit, že nemá filtrovat provoz z privátních
rozsahů. Tímto ovšem problém zdaleka nemusí být vyřešen. Mírně si rozšiřme
předchozí příklad o situaci, kdy server na adrese 147.229.3.10
slouží současně jako přístupová brána do
firemní sítě. V takovém případě zajišťuje server kromě vlastních služeb
běžících přímo na něm i směrování paketů a překlad adres - tedy NAT pro firemní
síť. V našem případě si správce firemní sítě zvolil adresový rozsah
10.1.2.0/24
, jak ukazuje následující
obrázek.
Jak bude probíhat komunikace
nyní? Stejně jako v předchozím případě odešle klient paket, který projde první vrstvou NATu a na server dorazí se zdrojovou adresou 10.1.2.3
. HTTP server vytvoří
odpověď a jádro operačního systému připraví paket s odpovědí, kde bude cílová
adresa nastavená na 10.1.2.3. Pro tento paket se algoritmem vyhledávání
nejdelšího prefixu vyhledá ve směrovací tabulce výstupní rozhraní a tímto se
odešle paket ven. Předpokládejme, že směrovací tabulka na serveru bude vypadat
zhruba takto:
Kernel IP routing table
Destination Gateway Genmask Flags MSS Window irtt Iface
147.229.3.0 0.0.0.0 255.255.255.128 U 0 0 0 eth0
10.1.2.0 0.0.0.0 255.255.255.0 U 0 0 0 eth1
0.0.0.0 147.229.3.1 0.0.0.0 UG 0 0 0 eth0
Výchozí brána správně ukazuje na
adresu 147.229.3.1
přes rozhraní
eth0
. Nicméně síť 10.1.2.0/24
je nakonfigurována přímo
na eth1
. Výsledkem je, že paket
s odpovědí se namísto rozhraním eth0
- tedy do Internetu, odešle kamsi do firemní sítě prostřednictvím rozhraní eth1
. Je to způsobeno tím, že jak ISP,
tak správce firemní sítě použili konfliktní adresní rozsahy. Samotná existence
NATu na serveru v tomto příliš nehraje roli.
Na celé věci je rovněž velmi nepříjemné to, že se velmi špatně diagnostikuje. Problémem jsou totiž postižení pouze klienti na těch privátních adresách, kteří mají tu smůlu, že se jejich adresa náhodu trefila do rozsahu sítě použité uvnitř jiné firmy. Jediný typ provozu, kde se chyba projeví je právě vůči tomuto serveru. Vše ostatní, jak v domácí či firemní síti, funguje bez problému. Ne vždy vás tedy hned napadne, že nefunkčnost spojení konkrétního uživatele s konkrétním serverem souvisí s konfliktním použitím adresových rozsahů.
Spása jménem RFC 6598
Kudy z uvedeného problému ven? Možné přečíslování adresových rozsahů, ať už na straně ISP nebo připojené sítě, představuje pouze jakési neúměrně pracné zametení problému pod koberec a navíc v konečném důsledku neřeší jeho podstatu. Správce firemní sítě se časem může rozhodnout použít jinou část privátních adres nebo zcela oprávněně může použít všechny privátní sítě v plném rozsahu, takže nemusí být ani na co přečíslovat.
Dalším možným řešením může být striktní oddělení logické topologie sítě a tím pádem i směrovací politiky pro veřejné a privátní adresové rozsahy. Veškerý provoz z privátních sítí pak vždy putuje přes CGN. Technicky můžeme takové rozdělení realizovat například oddělením prostřednictvím VLAN nebo s využitím VRF. Pomineme-li složitější konfiguraci a údržbu sítě, tak při této variantě může dojít ke zbytečnému zatěžování CGN interním provozem a také mohou některá data po sítí putovat hned 2x - od klienta k CGN a od CGN k serveru. V principu také neřeší konflikt adresového prostoru mezi ISP a koncovou sítí, byť ve striktně odděleném režimu se tento problém řeší o něco lépe.
Jako koncepčnější řešení se může nabízet použití takového adresového rozsahu, který není nijak konfliktní s privátními adresovými rozsahy definovanými v RFC 1918. V dubnu roku 2012 bylo na půdě IETF přijato RFC 6598, které definuje adresový blok označený jako Shared Address Space. Ten je určen právě pro operátory a organizace implementující CGN ve své sítí. Adresový rozsah, který je možné takto použít je:
100.64.0.0/10 - IPv4 Prefix for Shared Address Space
Na Shared Address Space se vztahují obdobná pravidla pro použití jako je tomu u privátních adres dle RFC 1918. Rozsahy mohou být použity pouze uvnitř sítě a nesmí být šířeny do globálních směrovacích tabulek. Na hranici sítě musí být provoz z těchto adres filtrován s výjimkou případů, kdy je tento provoz řešen vzájemnou dohodu mezi dvěma sítěmi. Na straně serverů se uvedený adresový rozsah jeví jako globální IPv4 a jejich správci nemají tendenci tento blok zařazovat do svých filtračních pravidel.
Pokud jste se s uvedeným prefixem doposud nikde
nesetkali, je to dáno tím, že jeho přidělení proběhlo teprve před třemi lety a
řada výrobců zatím existenci tohoto prefixu ještě nepromítla do dokumentace. V
příkladech konfigurace CGN tak u většiny výrobců stále najdete použitý prefix 10.0.0.0/8
.
Jak dimenzovat CGN
Problém s konfliktními IP adresami jsme vyřešili a teď si musíme odpovědět na další otázky stran parametrů CGN. Při pořízení směrovače nás vždy zajímá zejména propustnost v paketech a bitech za vteřinu a počet záznamů, které je možné umístit do směrovací tabulky. V případě CGN nám k těmto údajům přibudou další důležité parametry. Jak jsme si ukázali dříve, CGN (ostatně jako každý NAT) musí pro každé probíhající sezení (session) udržovat jeho stav v tabulce překladů. Pro každý takový záznam je nutné alokovat paměť a je tedy logické, že celkový počet záznamů bude mít na každém zařízení nějaký konečný limit. Maximální počet souběžně probíhajících sezení představuje naprosto stěžejní parametr, který bychom měli znát ještě před pořízením CGN.
Jak ale určit množství souběžných relací v síti? Problémem výpočtu se zabývá například článek Ivana Pepelnjaka, který uvádí, že je potřeba počítat přibližně se 120 tisící záznamy na každý gigabit provozu. Další vodítko může poskytnout již expirovaný draft draft-nishizuka-cgn-deployment-considerations, který zkoumá počet souběžných sezení pro jednotlivé typy aplikací. Reálně se tyto čísla ale v budoucnu mohou snižovat, protože přechodem na HTTP/2 bude HTTP provoz, kterého je majorita, multiplexován na jednom portu a nebude tedy využívat rozdílný port pro každé spojení.
Pro hrubý výpočet na základě počtu aktivních IP adres může také pomoci následující graf získaný během jednoho dne v prostředí počítačové sítě VUT v Brně. Graf ukazuje průměrný počet souběžně běžících sezení připadající na jednu aktivní, unikátní privátní IP adresu. Vidíme, že hodnota se pohybuje někde mezi 10 - 40 souběžnými sezeními. Pokud tedy uvažujeme o nasazení CGN pro síť řekněme s 10 tisíci koncovými zařízeními, musí být náš CGN schopen obsloužit minimálně 400 tisíc souběžných sezení. V praxi však doporučujeme toto číslo vynásobit alespoň deseti, aby vznikla dostatečná rezerva pro případné útočníky a pro vykrytí špiček aplikací s nárazovou potřebou velkého počtu sezení. Ostatně tuto situaci ukazuje i graf, kdy kolem 4 hodiny ranní dochází na 30 minut ke skokovému nárůstu počtu sezení na jednu IP. Tento nárůst je způsoben pouhým jedním PC, které provádí půlhodinovou synchronizaci se vzdáleným serverem. I z tohoto příkladu je vidět, že míra zaplnění tabulky překladů je stěžejní parametr, který se může skokově měnit a je nezbytně nutné jej průběžně monitorovat. Pro úplnost dodejme, že dnešní CGN dokáží obsloužit řádově desítky milionu současných spojení. Shin Miakawa ovšem ve své prezentaci ukazuje, že deklarované katalogové hodnoty se u některých produktů dost podstatně liší od těch skutečných.
CGN tunning
Před vlastním nasazením CGN do sítě je vhodné ještě prověřit některé konfigurovatelné parametry CGN. Množina konfigurovatelných parametrů přirozeně závisí na konkrétním zařízení, zmiňme alespoň některé základní, mající vliv zejména na odstraňování zastaralých záznamů z překladové tabulky. Následující obrázky zachycují některé typické průběhy komunikace. Pojďme se na ně podívat trochu blíže:
1. První situace zachycuje nejběžnější případ komunikace nad protokolem TCP. CGN je zde poměrně v jednoduché situaci, protože z TCP komunikace je možné přímo identifikovat začátek a konec sezení. V okamžiku inicializace spojení zařadí záznam do tabulky překladů a poté, co je spojení ukončeno (ať už FIN nebo RST příznakem), záznam jednoduše zruší.
2. Druhý případ je o něco náročnější. Předpokládejme, že se TCP sezení naváže obvyklým způsobem a po inicializaci komunikace ustane. To může mít dva důvody. Druhá strana nemá aktuálně žádná data, která by poslala, anebo už prostě neexistuje a nestihla řádně ukončit TCP spojení. CGN samozřejmě nemůže tušit, který z těchto dvou případů nastal, proto začne odpočítávat stanovený čas od poslední komunikace v rámci sezení. V okamžiku kdy stanovený čas dosáhne hodnoty 0, dojde k vyřazení příslušného záznamu z tabulky překladů. Pokud se jednalo o probíhající sezení, tak dojde k jeho přerušení. Pro nastavení časovače budeme muset volit vhodnou kompromisní hodnotu. Pokud nastavíme hodnotu časovače příliš nízkou (například 1 minutu), projeví se to tím, že se uživatelům budou „rozpadat“ TCP sezení už po minutě nečinnosti. Běžní weboví uživatelé zřejmě nic nezpozorují, ale projeví se to na aplikacích typu SSH, telnet nebo vzdálená plocha. Pokud hodnotu nastavíme na příliš vysokou (např. 20 dnů), hrozí, že se tabulka překladu bude plnit záznamy „mrtvých“ TCP sezení. Za rozumné hodnoty lze považovat nastavení v řádu několika až několika desítek hodin. Některé aplikace si navíc mnohdy cestu „prošťouchávají“ prostřednictvím keep alive paketů, čímž efektivně udržují záznam v tabulce překladů tak dlouho jak potřebují.
3. Třetí případ není ani tak zajímavý pro samotné uživatelé, ale spíše pro útočníky. Pokud máme útočníka uvnitř sítě, může prostým generováním paketů na různé cílové adresy a porty donutit CGN k vytvoření velkého počtu nových záznamů v tabulce překladů. Časovač pro iniciované, ale ne úspěšně navázané sezení by měl být nastaven na relativně nízkou hodnotu, ale ne zas takovou, že se nebudou úspěšně navazovat řádné TCP sezení například z druhého konce světa, které mají delší odezvu. S útočníkem pak hrajeme klasickou hru na přetahovanou, kde se snažíme jeho záznamy z tabulky překladů odstraňovat rychleji, než on stíhá vytvářet nové. Přiměřená hodnota pro tento časovač by se měla pohybovat někde v rozmezí desítek sekund, maximálně do několika minut. Čistě pro představu, při rychlosti 10 Mb/s na paketech délky 64 B je možné vytvořit cca 19 tisíc nových unikátních záznamů za vteřinu. Během jedné minuty může útočník teoreticky vytvořit přibližně 1,1 miliónu záznamů na CGN i přesto, že kapacita jeho přípojky je pouhých 10 Mb/s.
4. Obdobná situace jako v předchozím případě nastává se všemi nestavovými protokoly, jakými jsou například UDP, ICMP či tunelovací GRE. CGN nemůže identifikovat konec příslušného sezení a tím pádem nezbývá než záznamy těchto sezení odstraňovat na základě expirace časového intervalu, který uběhl od poslední komunikace. Obdobně jako v předchozím případě je možné i tyto protokoly (zejména pak UDP), použít pro cílené útoky. Časovače pro expiraci záznamů těchto protokolů by tak neměly být příliš vysoké.
Závěr
Dnes jsme si ukázali, jaké
potenciální nástrahy nás mohou potkat při implementaci CGN. Mezi stěžejní
závěry patří, že při implementaci CGN bychom měli pro adresaci zařízení
přednostně použít adresový rozsah 100.64.0.0/10
definovaný v RFC 6598 označovaný jako
Shared Address Space. Před pořízením CGN bychom měli znát počet souběžných sezení,
které budeme potřebovat na CGN zpracovat. Kromě paketové a bitové propustnosti je to
další z hlavních parametrů, který určuje velikost CGN a tím i jeho cenu. Příště
se podíváme, jak implementovat zálohované řešení CGN a jaké prostředky budou
nutné pro jeho monitoring.