Hlavní navigace

Síťový stack v Linuxu: nejen pro router a NAT

Tomáš Hlaváček

Linuxový síťový stack vysoce převyšuje základní požadavky pro připojení aplikací běžících v operačním systému k síti. Počítač s Linuxem může sloužit v rolích různých síťových prvků.

Linux v síťových prvcích

Linux v roli síťových prvků se používá odjakživa v situacích, kdy je zapotřebí například router pro nepříliš velkou kancelář. Vedle routování může takový router provádět i NAT, obsahovat jednoduchý firewall a k tomu na něm lze provozovat serverové služby pro vnitřní i vnější použití.

Vedle víceméně amatérského použití PC a Linuxu jako routerů se začal Linux dostávat do dedikovaných síťových zařízení, jako základ jejich firmwaru a postupně vytlačil z části těchto zařízení různé proprietární operační systémy. Nevýhodou těchto nasazení Linuxu je ovšem často jejich uzavřenost, zastaralost použitého linuxového jádra, minimalistický userspace a zapouzdření do málo použitelného webového rozhraní. Tyto omezení možností daného zařízení lze překonat v některých případech instalací alternativního firmware. Nejznámějším příkladem takového alternativního firmware je projekt OpenWRT.

Dalším, poněkud modernějším, použitím pokročilých možností síťování v Linuxu je virtualizace síťového stacku pro potřeby provozu kontejnerů (paravirtualizace) a s ní související propojení virtualizovaných síťových stacků s fyzickými interfacy na úrovni L2 anebo L3.

Zajímavým trendem je i subsystém DSA (Distributed Switch Architecture) v jádře, která přináší podporu switchů, které mohou být malé 10/100/1000 čipy v SOHO routerech, ale i 10G a rychlejší switche pro použití v datacentrech. Zajímavostí DSA je, že místo zavádění nového API a nástrojů pro správu switchů do Linuxu se naopak chápání switche přizpůsobuje linuxovému stacku. Všechny porty switche figurují jako linuxové rozhraní (eth0, eth1, …) a nad těmito rozhraními lze vytvářet virtuální VLAN rozhraní. Všechna rozhraní lze následně pospojovat do bridgů. Všechno toto nastavení DSA transparentně promítne do nastavení hardwaru, aby switchování probíhalo bez účasti hlavního CPU a zajišťuje také čtení counterů z hardwaru a jejich promítání do virtuálních interfaců v systému.

Linux se také používá jako platforma na prototypování nových protokolů různých vrstev, včetně nových přenosových technologií. Díky Linuxu je možné udělat plně softwarovou implementaci pro prvotní experimenty a napojit jí bez velkých problémů na kompletní a snadno rozšiřitelný síťový stack.

Linux pohledem programátora a administrátora

Linux nabízí aplikacím standardní API odvozené od de facto standardu Berkley sockets, které bylo převzaté do standardu POSIX. Linuxová implementace standard v některých aspektech rozšířila nebo modifikovala kvůli rozšíření možností popř. zvýšení výkonu, kterého lze dosáhnout minimálními úpravami na straně aplikací. Příkladem takového rozšíření může být volba SO_REUSEPORT.

Vedle standardního aplikačního API existuje pro Linux několik vysoce výkonných alternativ na nižší úrovni. Patří mezi ně především Netmap, PF_RING a DPDK. Přestože jsou tyto rozhraní určena původně pro výzkum vysokorychlostních sítí a mezi jejich primární použití patří zachytávání packetů v IDS a Netflow sondách, objevily se projekty, které se pokouší s jejich pomocí překonat rychlost TCP/IP stacku v linuxovém jádře v kombinaci s obyčejnými aplikacemi, které využívají standardní Berkley sockets API. V těchto případech se však stává nutností použít userspace TCP/IP stack, který lze optimalizovat pro konkrétní aplikaci. Proti tomutu přístupu ovšem existují pádné argumenty. Hlavním z nich je malá obecnost takového řešení a celkově velké náklady na údržbu celého řešení. Přitom dosažení vysokého výkonu je možné za určitých okolností i přes standardní linuxový TCP/IP stack.

Administrátoři, zvyklí na tradiční UNIX, v současných linuxových distribucích stále nacházejí známé nástroje ifconfig, route, arp a netstat, které jsou dohromady známé jako net-tools. Tyto nástroje, které vychází z BSD, jsou v Linuxu považovány za zastaralé, nadále se nevyvíjí a některé distribuce je již označily za „deprecated".

Moderní nástroje pro správu sítě využívají sadu nástrojů iproute2, která se liší návrhem, syntaxí, možnostmi a také použitým API mezi jádrem a samotným nástrojem. Zatímco nástroje z rodiny net-tools používají rozhraní založené na voláních ioctl a přenos informací z a do jádra přes soubory v /proc , moderní iproute2 používá Netlink protocol.

Z praktického hlediska mají obě rodiny nástrojů své problémy.Net-tools nepodporují nastavování více směrovacích tabulek, tradiční způsob nastavení více IPv4 adres na jednom rozhraní přes ifconfig je matoucí a nepřehledný a dokonce některé funkce související s IPv6 jsou přes net-tools nedostupné. Nástroje z balíčku iproute2 však nejsou také bez chyby. V rámci změny preferovaného rozhraní na Netlink byly označeny za zastaralé i utility jako brctl,vconfig nebo ifenslave. Část jejich funkcionality byla převedena do nástroje ip a pro zbývající část vznikly nové programy. Nástroji ip lze vytknout například nepřehlednost výstupů, krkolomnou syntaxi při nastavování VLAN rozhraní i bondingu a celkovou složitost a náchylnost k chybám při nastavování bridgů.

Vedle low-level nástrojů se administrátoři setkávají s distribučními skripty a nástroji pro konfiguraci sítě, jako jsou například ifup a ifdown u Debianu nebo Ubuntu. Nově se prosazuje systemd-networkd a podobné nástroje typu vše v jednom, jako Network Manager, netctl a další. Znalost stiných stránek těchto nástrojů je bohužel důležitým předpokladem pro rutinní provoz serverů, ale sama o sobě příliš nepomáhá s debugováním problémů, a proto je pro správce stále neocenitelná znalost low-level nástrojů a jejich použití k odhalování a řešení problémů.

Debugovací nástroje

Síťování na Linuxu přináší nejen možnost komplikovaných konfigurací a spojování různých jaderných mechanismů na všech úrovních, ale i bezprecedentní náhled dovnitř TCP/IP stacku a prozkoumávání přenášených packetů. Pro náhled do datových struktur TCP/IP stacku se hodí zejména nastroj netstat, který se doplňuje občas informacemi z nástroje lsof a stavem, který lze vyčíst ze souborů v /proc/net . Neocenitelným nástrojem pro debugování aplikací, nastavení sítě, protokolů i například analýzu útoků je tcpdump. Vedle tcpdumpu je nesmírně užitečný grafický nástroj Wireshark. Nástroje pro mimořádnou nízkoúrovňovou manipulaci s packety a TCP/IP stackem se však neomezují jen na pasivní čtení stavu. Vedle možností aktivně zasahovat do rozličných parametrů místního systému mají linuxové distribuce i řadu nástrojů pro generování TCP spojení a nebo samotných packetů. Nejtypičtější představitelé této množiny jsou univerzální nástroje typu netcat (nc) a socat, které lze používat k simulaci L5-L7 protokolů. Významný nástroj nižší úrovně je pak tcpreplay, který slouží k injektování packetů v pcap souborech do sítě. Tento nástroj se obvykle používá společně s tcpdumpem a nástrojem pro masové úpravy zachycených packetů tcprewrite. Další možností, jak snadno připravit packety s vlastním obsahem je použití Python knihovny Scapy.

Další množinou debugovacích nástrojů jsou programy na měření propustnosti sítě a ev. na generování packetů ve velkých objemech, zejména kvůli zátěžovým testům. Jedním z nich je již zmíněný tcpreplay, který na normálním jádru zvládne saturovat minimálními 1 Gbps linku a s pomocí Netmap knihovny i 10 Gbps. Jinou výkonnou, ale poněkud omezenější možností je jaderný modul pktgen. Naopak velmi pohodlná a snadno použitelná aplikace iperf může být výkonem nedostačující měřené síti a zbytečně podhodnocuje.

Pokročilá nastavení

Komplexita síťování v Linuxu z hlediska administrátora i z hlediska technických možností může spočívat ve využívání mnoha za sebe zřetězených vstev, ve kterých je těžké se vyznat, a které můžou přinášet nepředvídané interakce. Tyto interakce můžou vést ke snížení výkonu a nebo i nefunkčnosti některých částí řešení. V Linuxu je například snadné spustit BGP daemon, který se má spojit přes IP-in-IP tunel, který posílá enkapsulované packety přes bridge rozhraní postavený nad VLAN rozhraním, který stojí nad „fyzickým" rozhraním uvnitř virtuálního stroje KVM, který na hostiteli ústí opět bridge a z něj do jiného VLAN rozhraní a až pak do fyzické síťové karty. Problémů v takovém řešení, které mohou vést k nefunkčnosti BGP, může být celá řada. Patří mezi ně chyby v konfiguraci VLAN ID, chybně nastavené MTU resp. překročení MTU po několikanásobné enkapsulaci, TTL inherit na IP-in-IP tunelu a tak dále. Debugovat takové nastavení pak představuje řádově větší výzvu, než odstranění toho samého problému v jednoduchém nastavení.

Podobný příklad, kdy se komplexita nastavení rychle zvyšuje je kombinace mechanismů pro řízení toku packetů na různých úrovních referenčního modelu. V Linuxu je možné řídit routing pomocí tabulky pravidel a jednotlivé packety routovat přes různé směrovací tabulky. Vyplňování těchto směrovacích tabulek může být práce pro směrovací protokoly běžící v userspace daemonech. A rozdělování packetů do různých směrovacích tabulek podle tabulky pravidel může záviset, mimo jiné, i na značkách z firewallu (fwmark). Tím lze dosáhnout značné komplexity rozhodovacích pravidel a přesáhnout možnosti jiných implementací policy-based routingu. Cenou za to je opět nízká přehlednost řešení.

Dalším aspektem je technická komplexita, kterou představují počty záznamů v různých tabulkách a datových strukturách jádra. Nejedná se zdaleka jen o směrovací tabulku, která naopak díky šikovné stromové implementaci zvládne obrovské množství rout. Problémem může být ale například velké množství pravidel firewallu, složitá a obsáhlá pravidla shaperu, velké množství pravidel pro policy based routing i množství různých směrovacích tabulek, mezi kterými se rozhoduje právě podle PBR pravidel.

Jiný příklad technické komplikace je udržování velkého množství dynamických záznamů o stavu spojení. To se týká především tabulky spojení connection trackingu nebo v určitých případech i počtu navázáných TCP session na místní server. Experimenty ukázaly, že statisíce lokálně navázaných spojení nebo statistíce záznamů v tabulce conntracku Linux zvládne na přiměřeně rychlém hardwaru s dostatkem paměti bez problémů, zatímco miliony záznamů už představují pro použité datové struktury problém. Nemusí jít ale ani tak o samotný počet záznamů, jako spíš o frekvenci změn v dané datové struktuře.

Vývoj a využívání síťových technologií v Linuxu

Současný Linux nabízí v jádře podporu mnoha různých L1/2 technologií a vedle nejpoužívanějšího Ethernetu, WiFi a PPP lze nalézt ovladače pro skutečné speciality. Vývoj softwaru probíhá aktivně na všech úrovních. V současnosti se začíná etablovat nový linuxový firewall nftables, který má v budoucnu nahradit iptables, ip6tables, arptables a ebtables. Do Linuxu přibyl v nedávné minulosti i protokol L2TPv3 a podpora MPLS, což slibuje přiblížit Linux úrovni sofistikovaných komerčních routerů.

Na vyšších vrstvách je vývoj protokolů usnadněn snadným přenesením práce z jádra do userspace pomocí tun a tap interfaců, které používá například i populární OpenVPN. Linux je také platformou pro Open vSwitch, který významně překonává funkcionalitu linuxového bridge a může Linux postavit funkcionalitou mezi sofistikované komerční switche. A na Linuxu probíhá i prototypování a vývoj nových protokolů pro mesh networking.

Vývoj linuxového jádra i userspace utilit a řídících nástrojů pokračuje na jednu stranu velmi rychle, na mnoha místech a v rámci různých projektů s odlišným zaměřením. Na druhou stranu je základní funkcionalita síťového stacku z velké části téměř neměnná a její změny, pokud vůbec, tak nastávají velmi pomalu a klade se při nich důraz na kompatibilitu a dlouhodobou udržitelnost a průhlednost.

Pro nasazování nebo vývoj pokročilých funkcí síťového stacku je zapotřebí mít nejen základní přehled o síťové teorii a protokolech, ale i o implementačních principech v jádře i mimo něj. Jednou z možností, jak takový přehled získat za pomoci řady praktických cvičení, kterým předchází výklad relevantní teorie, je kurz Akademie CZ.NIC nazvaný Pokročilé síťování v Linuxu.

Našli jste v článku chybu?