Hlavní navigace

Velké trable s malým MTU

7. 1. 2013
Doba čtení: 6 minut

Sdílet

 Autor: Depositphotos
Jednou ze základních vlastností internetové sítě je schopnost přenášet datové pakety různých délek. Pokud ale vaše připojení nedokáže obsloužit paket standardní délky 1500 bajtů, máte zaděláno na problém. I když to není vaše chyba, budete nuceni hledat řešení. Právě o tom je dnešní článek.

Jak funguje fragmentace

Naprostá většina přenosových médií používaných v TCP/IP sítích má nějaký limit maximální velikosti přenášených dat, označovaný jako MTU. Typickým příkladem je Ethernet se standardním limitem 1500 bajtů užitečného obsahu v jednom rámci. Fragmentace je vlastnost IP protokolu, umožňující tyto limity překonat tak, aby jimi nebyla velikost datagramu omezena.

Původní představa byla taková, že každý směrovač na cestě, který nebude schopen IP datagram pro jeho velikost poslat dál, jej rozdělí na fragmenty. Takové dělení se může i opakovat, pokud je při dalším přeskoku MTU opět nižší. Přijímající strana všechny fragmenty ukládá do paměti a pokud všechny obdrží (mohou přijít v libovolném pořadí a také se mohou poztrácet), seskládá z nich původní datagram, který pošle vyšším vrstvám. Pokud do určitého časového limitu všechny fragmenty nedorazí, není možné kompletní datagram sestavit. Ten je proto zahozen, včetně již přijatých částí.


Princip fragmentace

Pokud jsou obsahem IP datagramů segmenty protokolu TCP (což je dnes pravděpodobně většina internetového provozu), je používání IP fragmentace nevhodné. Pokud se velikost TCP segmentu nastaví tak, aby se (včetně TCP a IP hlaviček) vešel i do nejmenšího MTU na cestě mezi dvěma systémy, k fragmentaci nebude muset docházet. Přijímající strana tak bude IP datagramy přímo propouštět vyšší vrstvě, v tomto případě TCP protokolu, který převezme zodpovědnost za správné seřazení segmentů. Pokud se během přenosu nějaký segment ztratí, použijí se standardní opravné prostředky TCP k jeho opakovanému odeslání.

Objevování MTU cesty

Zbývá vyřešit problém, jakým způsobem se komunikující strany dozví, jaké je minimální MTU na cestě mezi nimi. K jeho zjištění se používá metoda zvaná Path MTU Discovery (PMTUD), kterou bychom mohli přirovnat ke známé metodě pokusu a omylu. Odesílatel se jakoby na MTU neohlíží a odesílá datagramy s velikostí podle potřeby až do velikosti MTU svého připojení. Datagramy jsou v hlavičce opatřeny příznakem DF, který směrovačům zakazuje fragmentaci. Není-li možné datagram poslat bez fragmentace dál, směrovač jej zahodí a vygeneruje ICMP zprávu Fragmentation required, kterou odesílatele informuje o zahození datagramu a také o maximální velikosti datagramu, který by ještě prošel. Odesílatel na základě této zprávy zmenší velikost datagramu a opakuje pokus. Informace o použitelné velikosti MTU k danému cíli je po omezenou dobu kešována.

Techniku objevování MTU cesty používá většina moderních implementací TCP/IP stacku. Byla převzata i do protokolu IPv6 jako povinná, takže směrovače IPv6 nemají povoleno provádět fragmentaci. Tu může provádět jen odesílatel, například při odesílání UDP zprávy, která je větší než MTU cesty.

Když PMTUD nefunguje

Aby objevování MTU cesty fungovalo, je naprosto nezbytné, aby fungoval přenos ICMP zpráv mezi kterýmkoli směrovačem na cestě a oběma konci spojení. A to bývá obrovský problém. Správci firewallů v zájmu „vyšší bezpečnosti“ blokují třeba i všechny ICMP zprávy. V takovém případě se odesílatel nedozví, že je na cestě problém a tak stále opakuje odesílání stejně velkého datagramu, který je stále zahazován. Po určité době to protokol vyšší vrstvy vzdá s tím, že spojení nefunguje.

I pro odborníka je často problém diagnostikovat problém nefunkčního PMTUD. Interaktivní relace jako SSH nebo telnet fungují bez problému, zatímco přenos souborů prostřednictvím FTP nebo SFTP (tedy stejným spojením jako SSH) selhává. Webové stránky se obvykle načtou částečně, například bez kaskádových stylů nebo obrázků. Uživatelé ale obvykle pouze nahlásí, že „internet funguje nějak divně“ a požadují nápravu.

Čí je to problém?

Velmi často je příčina problému s MTU přesně na opačné straně sítě, než tam, kde se problém doopravdy projevuje. Typickým příkladem je domácí xDSL přípojka, kde je úzkým hrdlem protokol PPPoE, jak znázorňuje následující obrázek.

xdsl

V tomto případě dojde k problému, pokud neprojde ICMP zpráva od DSLAMu směrem k serveru, v důsledku čehož nebude správně fungovat připojení uživatele za xDSL routerem, přestože v síti, kterou tento uživatel spravuje, je všechno nastaveno správně.

Obcházení problému protistrany

Většina uživatelů se ale nespokojí s vysvětlením, že chyba není na jejich straně, zvlášť, když se u jiných druhů připojení problém neprojevuje. Nezbývá tedy než hledat na straně uživatele aplikovatelné workaroundy, které sice konkrétní problém vyřeší, ale za cenu různých kompromisů.

Řešení, které se nabízí, spočívá v manipulaci s hodnotou rozšiřující volby MSS v TCP protokolu. Tou komunikující strana ohlašuje, jak velké segmenty je schopna přijmout. Původně byla tato hodnota určena velikostí bufferu, v současnosti ji ale téměř všechny implementace vyplňují na hodnotu MTU rozhraní, kterým paket odchází, sníženou o 20 bajtů TCP záhlaví a 20/40 bajtů IPv4/IPv6 záhlaví. Pokud tuto hodnotu snížíme, donutíme tím protistranu posílat segmenty rovnou v takové velikosti, aby prošly úzkým hrdlem.

Čistou cestou, kterak snížení hodnoty MSS vynutit, je snížení velikosti MTU na všech koncových zařízeních. To je možné kromě ruční konfigurace provést také automaticky, prostřednictvím volby MTU v protokolu DHCP, či v ohlášení IPv6 směrovače. Drobnou nevýhodou takového řešení je, že nižší hodnota MTU se uplatní na veškerá spojení, tedy i na taková, která úzkým hrdlem neprochází. Například přenosy mezi domácími zařízeními za společným xDSL modemem.

Druhou možností, jak vynutit snížení hodnoty MSS, je přepisování paketů na cestě, tzv. MSS clamping. Jde o techniku velmi rozšířenou, se kterou i navzdory nečisté povaze (síťové zařízení zasahuje do dat vyšší vrstvy!) není příliš mnoho problémů. Technika spočívá v tom, že směrovač při předávání paketu najde v TCP protokolu rozšiřující hlavičku a tu přepíše na nižší hodnotu. V linuxovém netfilteru takového přepsání dosáhneme následujícím pravidlem (postup je použitelný i pro IPv6):

# iptables -t mangle -A FORWARD -p tcp --tcp-flags SYN,RST SYN -j TCPMSS --clamp-mss-to-pmtu

Internet ale není jen TCP

Uvedený workaround ale funguje jen pro protokol TCP, který umožňuje téměř libovolnou volbu velikosti segmentů. Jiné protokoly, jako třeba UDP, takovou volbu nenabízí a pokud je zpráva UDP větší než MTU cesty, je IP fragmentace jediný způsob, jak zprávu dopravit na druhý konec.

Za zmínku stojí například problém s protokolem DNS. Díky rozšíření EDNS0 již nejsou UDP zprávy limitovány délkou 512 bajtů a zvláště při zavedení DNSSEC se může lehce stát, že odpověď na DNS dotaz přesáhne velikost MTU cesty a bude ztracena. Tomuto tématu se na věnoval na RIPE65 Roland van Rijswijk z nizozemské národní sítě vědy a výzkumu SURFnet. Ve své prezentaci (video) doporučuje jako workaround nakonfigurovat polovinu DNS serverů tak, aby protokolem UDP neposkytovaly DNS odpovědi větší než 1232–1472 bajtů. Požaduje-li klient větší odpověď, je donucen použít k dotazu protokol TCP.

Zlepší se to s IPv6?

Problém s filtrováním ICMP zpráv postihuje ve stejné míře IPv4 i IPv6 prostředí. Paradoxně by mohlo správnému přístupu k filtrování ICMPv6 zpráv pomoci i pomalé zavádění nového protokolu. Je-li totiž k zavedení IPv6 použito tunelování, musí tunelovaný provoz pracovat s menší MTU. To je velký rozdíl proti IPv4 světu, kde je nižší MTU cesty spíše výjimečnou záležitostí zejména xDSL přípojek, jejichž koncová zařízení jsou navíc vybavena MSS clampingem.

K implementaci filtrovacích pravidel pro ICMPv6 také vyšlo doporučení RFC 4890, které stručně a jasně informuje, které zprávy je třeba zachovat, aby nedošlo k ohrožení funkčnosti.

UX DAy - tip 2

Závěrem

Situace je neradostná a dalo by se říci, že v tomto ohledu je současný internet velmi rozbitý. Pravděpodobně ho nikdy nikdo neopraví, čemuž pomáhá i přítomnost workaroundů v místech, kde k problémům nedochází. Drobnou naději představuje právě protokol IPv6, který zatím povětšinou funguje dobře (i bez MSS clampingu).

I zde se však objevují názory, že pro zajištění vysoké dostupnosti je nejlepší použít hodnotu MTU rovnu 1280, což je minimální povolená velikost pro IPv6 protokol. Je tedy možné, že jak se posune protokol IPv6 z experimentální do produkční úrovně, začnou se objevovat IPv6 firewally blokující ICMP provoz a historie se zopakuje. Nenechte si to líbit a prověřte nastavení svých systémů ještě dnes!

Byl pro vás článek přínosný?

Autor článku

Ondřej Caletka vystudoval obor Telekomunikační technika na ČVUT a dnes pracuje ve vzdělávacím oddělení RIPE NCC, mezinárodní asociaci koordinující internetové sítě.