Pozn.: Popis v článku vychází z FortiGate FG-300E s FortiOS verzí 7.2.8. Který je nakonfigurovaný jako FGCP cluster a využívá VDOM. Ale pro tento případ to nemá velký vliv.
NAT Hairpinning
Je situace, kdy zařízení přistupuje k jinému zařízení v interní síti prostřednictvím externí sítě. Dochází ke zpětné smyčce v NATu. Provoz prochází skrze interní rozhraní FortiGate do internetu a pak se vrací zpět do stejného rozhraní (internet), kde je připojena externí IP. FortiGate přesměrovává provoz pomocí Virtual IP na lokální cíl. Provoz nikdy neopouští FortiGate (do internetu reálně neodchází).
Zjednodušeně klient (v LAN s privátní IP) komunikuje na veřejnou IP adresu, kterou obsluhuje FortiGate. Na této adrese je nastaven Destination NAT (DNAT) na privátní IP serveru (v LAN). Dále v článku uvedeme detailní popis s obrázky.
Pozn.: Celý tento popis má podmínku, že se využívají interní IP adresy a překlad adres (Network Address Translation) mezi veřejnými a privátními. Kdybychom používali routing a pouze veřejné IP adresy, tak samozřejmě komplikace NATu neřešíme. Pro FortiGate jde o komunikaci mezi přímo připojenými sítěmi, takže může provádět směrování. V článku neřešíme Central NAT.
Různé scénáře
Obecně se jako Hairpin NAT označuje situace, kdy komunikace odchází z interní sítě (LAN) a skrze externí IP se vrací do stejné sítě (LAN). V případě FortiGate je podobná i situace, kdy se cíl nachází v jiné síti (třeba DMZ) za FortiGate. Pro praxi je důležité, jak se ve všech případech chová Source NAT (SNAT).
Scénářů, kdy narazíme na tuto situaci, je celá řada a FortiGate se může chovat odlišně než některé jiné Firewally. Stejný případ je, když máme topologii LAN - DMZ - WAN. Komunikace z LAN odchází skrze DMZ do internetu. V DMZ máme umístěné servery, a na ně komunikují uživatelé z LAN pomocí veřejné IP adresy.
Před lety, když jsem přešel z jiného FW na FortiGate, jsem zjistil odlišné chování. Při komunikaci na servery v DMZ z LAN (přes veřejnou IP adresu) se na serverech zobrazuje DMZ adresa jako zdrojová (a ne veřejná, na kterou má probíhat SNAT). Vzal jsem to jako fakt a nezkoumal.
Nyní nastala situace, kdy potřebuji, aby komunikace dorazila z NATované veřejné IP adresy. Když se komunikuje mezi dvěma interními sítěmi za FortiGate skrze veřejnou IP. Ondra Večl z Fortinetu mi poradil správný článek Technical Tip: Configuring Hairpin NAT (VIP), který tuto oblast popisuje. Používá se tu termín Hairpin NAT, se kterým jsem se dříve nesetkal.
Související vlastnosti FortiGate
Na úvod si připomeneme pár (základních) vlastností či chování FortiOS, které s popisovanou situací souvisí.
Výběr Firewall politiky
Firewall Policy se aplikují (vybírají) metodou First Fit. Definované politiky se prochází odshora dolů (v zadaném pořadí, které můžeme měnit) a pokud celá politika vyhovuje, tak se použije a nepokračuje se dále v hledání. Na každý paket se může aplikovat pouze jedna politika.
Pokud vytvoříme více specifickou politiku, tak ji musíme zařadit nad obecnější, aby se uplatnila. Na FortiGate můžeme politiky přesouvat přetažením nahoru a dolů.
Zpracování paketů - packet flow
Jak probíhá zpracování paketů, a kudy prochází na vstupu a výstupu, popisuje článek Packet flow ingress and egress: FortiGates without network processor offloading.
Virtual IP a význam Interface (extintf)
Když vytváříme Virtual IP, tak v GUI nastavujeme Interface. Buď můžeme použít any
nebo vybereme některé rozhraní. V CLI se používá příkaz s parametrem set extintf
. Člověk by očekával, že když zvolí určitý interface, tak se tento DNAT (použití VIP) provede pouze na provoz, který z něj přichází. Dokumentace chování nevysvětluje a jasno přináší až článek Technical Tip: Firewall VIP - difference in 'srcintf-filter' and 'extintf'.
Toto nastavení provede pouze to, že v GUI nemůžeme přiřadit VIP k FW politice, kde je jiný zdrojový interface. Nijak neváže VIP na konkrétní rozhraní, takže přijímá připojení z každého rozhraní. Pokud chceme opravdu omezit možná rozhraní, tak musíme použít set srcintf-filter
.
Source NAT a Destination NAT pro server
Pokud pro komunikaci z určité sítě používáme Source NAT s Use Outgoing Interface Address. Pro jinou veřejnou IP adresu vytvoříme Virtual IP, kde mapujeme všechny porty na interní server. Pak odchozí komunikace z tohoto serveru bude odcházet z veřejné IP adresy použité ve VIP.
Pokud chceme, aby komunikace odcházela z určité veřejné IP adresy, tak v politice použijeme Source NAT s Use Dynamic IP Pool. Vytvoříme (například) IP Pool Overload s jednou IP.
Deny Policy a Virtual IP
Pokud máme politiku s Virtual IP, která povoluje komunikaci z externích sítí na interní server (pomocí DNAT). A předřadíme obecnou politiku s akcí DENY, která by měla blokovat komunikaci z určité externí IP. Tak se provoz neblokuje a uplatní se politika s Virtual IP.
Buď musíme udělat politiku, kde bude jako cíl daná Virtual IP a akce DENY. Nebo na obecné DENY politice přidat příkaz v CLI.
set match-vip enable
Více Technical Note : DENY Policy for Virtual IP Firewall Policy, Technical Tip: Firewall does not block incoming (WAN to LAN) connection even though deny policy .
Děkuji za doplnění Ondrovi Hornigovi. Od FortiOS 7.2.4 je pro nově vytvořené politiky s akcí DENY automaticky zapnuté match-vip
. Je to defaultní hodnota, takže se nevypisuje, pokud nepoužijeme show full-configuration
. FortiOS Release Notes – Bug ID 819937.
Popis situací a chování NATu
Klasický Hairpin NAT
Na internetu je popisován NAT Hairpinning, když komunikace odchází z interní sítě (LAN/DMZ) a skrze externí IP adresu se vrací do stejné sítě (LAN/DMZ). Mluví o něm i RFC 5128. Příklad takové situace je na obrázku.
- klient
10.0.0.100
komunikuje na službu200.0.0.10
- skrze default GW dorazí komunikace na FW (DMZ rozhraní)
- FW přeloží adresu
200.0.0.10
na server10.0.0.10
(DNAT) - adresu
200.0.0.10
má na WAN rozhraní (internet), bere paket jako by přišel z WAN - FW odesílá komunikaci na server, zdrojová IP
10.0.0.100
, cílová IP10.0.0.10
Tedy, kdyby byl poslední krok takto, tak máme problém. Server by odpověď posílal na IP 10.0.0.100
, která je ve stejném subnetu. Klient by dostal odpověď z IP 10.0.0.10
místo očekávané 200.0.0.10
, takže by paket zahodil. Proto FortiGate automaticky provádí SNAT na adresu odchozího rozhraní (na jiném FW patrně musíme vytvořit správnou konfiguraci).
Komunikace probíhá:
- FW odesílá komunikaci na server, zdrojová IP
10.0.0.1
(SNAT), cílová IP10.0.0.10
- server odpovídá na adresu
10.0.0.1
, zdrojová IP10.0.0.10
- FW najde komunikaci v NAT tabulce, provede SNAT i DNAT (vrátí přehozené originální adresy) a posílá z IP
200.0.0.10
na IP10.0.0.100
Hairpin NAT a dvě interní sítě
Fortinet jako Hairpin NAT popisuje i situaci, kdy komunikace odchází z interní sítě (LAN/DMZ) a skrze externí IP se vrací do jiné sítě za FortiGate (LAN, DMZ, apod). Příklad takové situace je na obrázku.
- klient
10.0.0.100
komunikuje na službu200.0.0.10
- skrze default GW dorazí komunikace na FW (DMZ rozhraní)
- FW přeloží adresu
200.0.0.10
na server10.1.0.10
(DNAT) - adresu
200.0.0.10
má na WAN rozhraní (internet), bere paket jako by přišel z WAN - FW odesílá komunikaci na server, zdrojová IP
10.0.0.100
, cílová IP10.1.0.10
- server odpovídá na adresu
10.0.0.100
, zdrojová IP10.1.0.10
- FW najde komunikaci v NAT tabulce, vrátí originální adresu jako zdroj a posílá z IP
200.0.0.10
na IP10.0.0.100
Konfigurace na FortiGate
Dvě politiky pro odchozí a příchozí provoz
Jako standardní mi připadá možnost, kdy vytvoříme dvě politiky (Firewall Policy). Jedna řeší obecně komunikaci do internetu a druhá komunikaci na server z internetu. Nijak zvlášť neřešíme, že je klient a server v sousední (stejné) síti.
- povolení vybrané odchozí komunikace z interní sítě/sítí do internetu, využívá se Source NAT
config firewall policy edit 1 set name "DMZ to Internet Web" set srcintf "DMZzone" set dstintf "virtual-wan-link" set action accept set srcaddr "DMZnetwork" set dstaddr "all" set schedule "always" set service "HTTP" "HTTPS" set logtraffic all set nat enable next end
- povolení vybrané příchozí komunikace z internetu do interní sítě (publikace serveru) skrze veřejnou IP adresu, využívá se Destination NAT
config firewall policy edit 2 set name "www - HTTP/S" set srcintf "virtual-wan-link" set dstintf "DMZ2zone" set action accept set srcaddr "all" set dstaddr "200.0.0.10 10.1.0.10 web" set schedule "always" set service "HTTPS" "HTTP" set logtraffic all next end
- pro příchozí komunikaci musíme vytvořit Virtual IP, která může mít nastaven Interface
any
nebo naše internetové rozhraní (Internet1
)
config firewall vip edit "200.0.0.10 10.1.0.10 web" set extip 200.0.0.10 set mappedip "10.1.0.10" set extintf "Internet1" next end
Pozn.: Na FortiGate je skoro stejné chování, jestli je komunikace z interní sítě do té samé (třeba DMZ - DMZ) nebo do nějaké sousední (třeba DMZ - DMZ2). Uvedené příklady jsou vždy pro jednu situaci a mohou být i pro tu druhou.
Nalezení politiky a chování Source NAT
Pokud máme konfiguraci dle popisu výše, tak může SNAT fungovat třemi různými způsoby. Podle toho, kam komunikujeme.
- klient (DMZ) komunikuje do internetu
- klient (DMZ) komunikuje na server ve stejné síti (DMZ) přes veřejnou IP adresu
- klient (DMZ) komunikuje na server v sousední síti (DMZ2) přes veřejnou IP adresu
Jak se nalezne a aplikuje FW politika? V prvním případě se uplatní odchozí politika [1]
s SNAT.
Druhé dva případy jsou složitější. Provoz jakoby prochází přes FortiGate dvakrát, ale na paket se může použít pouze jedna politika.
- komunikace přichází z interního rozhraní (DMZ) a cíl je v internetu
- nalezne se politika pro odchozí komunikaci
[1]
, provoz musí být povolen, ale podle Fortinet informací se neuplatní SNAT, protože ještě není dokončeno zpracování provozu - FortiGate ví, že veřejnou IP adresu překládá na interní, takže najde druhou politiku pro příchozí provoz
[2]
, provede DNAT, ale SNAT nemá definován (uplatňuje se poslední nalezená politika) - pokud je příchozí i odchozí interface stejný (DMZ do DMZ), tak FortiGate automaticky provede SNAT na adresu rozhraní (DMZ
10.0.0.1
), abychom nemuseli nic speciálně konfigurovat a komunikace fungovala (toto jsem nenalezl oficiálně popsané, ale takto se to prakticky chová)
Logování provozu
Na provoz se nějakým způsobem uplatní dvě politiky, ale plně se aplikuje ta poslední (druhá). FortiGate do logu ukládá informace pouze o druhé politice. Pokud první politika nebude existovat (nebude povolen odchozí provoz), tak komunikace nebude fungovat.
Zajímavé je, že nepovolenou (blokovanou) komunikaci nenalezneme v logu. Například když vytvoříme politiku pro blokování odchozí komunikace na danou veřejnou adresu a nastavíme kompletní logování. Ve FortiAnalyzer nenalezneme žádnou zmínku o tomto provozu.
Dopad toho, že se neprovede SNAT
Praktický dopad je takový, že v komunikaci (na cíli i na FW) jsou vidět jako zdrojové adresy naše interní. Když děláme na FortiGate politiku, kde publikujeme službu do internetu a chceme povolit komunikaci pouze z určitých zdrojů. Tak pro naše interní sítě musíme použít patřičné interní adresy místo jednoduššího rozsahu veřejných adres (na které komunikaci do internetu NATujeme).
Osobně by mi připadalo logické, když mám dvě sítě, mezi kterými není povolena přímá komunikace. A komunikujeme skrze veřejnou IP adresu, aby se použil SNAT na veřejnou adresu. To se na FortiGate neděje.
Je řada situací, kdy potřebujeme, aby komunikace odcházela z určité veřejné IP adresy (stejně, jako odchází do internetu). Například, když máme dvě sítě, v každé se nachází poštovní server a máme zapnuté SPF. Pokud posílá jeden server zprávu druhému, tak potřebujeme, aby se použila veřejná IP, kterou používáme pro odesílání do internetu.
Nastavení požadovaného Source NAT překladu
Pokud potřebujeme, aby provoz použil určitou veřejnou IP adresu, tak musíme mít příchozí politiku, kde bude spolu s DNAT nastaven také SNAT na určitý IP Pool (může být i adresa odchozího rozhraní). Mohli bychom SNAT přidat k naší druhé politice [2]
, ale asi nechceme, aby komunikace z internetu měla místo svých veřejných adres tu naši.
Takže musíme vytvořit (duplikovat) stejnou politiku, kde upravíme zdroj (pouze na komunikaci z naší sítě) a zadáme SNAT.
config firewall policy edit 3 set name "www - HTTP/S 2" set srcintf "virtual-wan-link" set dstintf "DMZ2zone" set action accept set srcaddr "DMZnetwork" set dstaddr "200.0.0.10 10.1.0.10 web" set schedule "always" set service "HTTPS" "HTTP" set logtraffic all set nat enable set ippool enable set poolname "SNAT 200.0.0.1" next end
Taková konfigurace není složitá, ale v praxi to může znamenat desítky speciálních politik. Také se nám tím sníží přehlednost konfigurace. Důležité je politiky správně řadit. Když vytváříme objekt adresa pro naši síť (DMZnetwork
), tak nesmíme nastavit Interface na odpovídající rozhraní. Používáme jej v politice, kde je zdrojové rozhraní WAN.
Pokud máme v DMZ2 několik serverů, na které potřebujeme komunikovat přes veřejnou adresu, tak musíme pro každý duplikovat jeho publikační politiku. Pokud máme více sítí (než 2), kde má komunikace odcházet pokaždé z jiné veřejné IP adresy, tak to přidává další politiky. Extrém je, když máme různé servery v DMZ i DMZ2, komunikace z každého odchází přes jeho veřejnou IP, tak musíme vytvořit politiku pro každou dvojici.
Normálně můžeme nastavit SNAT na jednom pravidle pro odchozí komunikaci z celé sítě a vše bude přeloženo na zadanou veřejnou IP. Ale v tomto případě nastavujeme u cíle, takže to znamená mnohem více konfigurace. Pokud to lze, tak je jednodušší počítat s tím, že komunikace přichází z určitých interních adres než vytvářet pravidla pro SNAT.
Jedna politika pro provoz mezi sítěmi
V prvním případě jsme dělali politiky pro DMZ - WAN a WAN - DMZ2 (nebo WAN - DMZ). Nabízí se udělat přímo politiku DMZ - DMZ2 (nebo DMZ - DMZ). Sice komunikujeme přes veřejnou IP adresu (WAN), ale FortiGate si s tím poradí. Podmínka je, že ve Virtual IP musíme mít nastaven Interface any
. Jinak ji nemůžeme přiřadit k politice, kde je zdrojový interface DMZ místo Internet.
Fortinet uvádí, že tuto možnost můžeme použít pouze pro veřejné IP adresy, které nejsou přímo přiřazeny na externí rozhraní (internet). Udělal jsem pár testů a je to tak. Podle příkladu máme IP 200.0.0.1
nastavenu na rozhraní do internetu. Když se pro ni vytvoří Virtual IP a použije v politice, tak komunikace nefunguje. Musíme udělat dvě politiky (DMZ - WAN a WAN - DMZ), aby komunikace fungovala. Když vytvoříme Virtual IP s adresou 200.0.0.10
, tak stačí jedna politika a komunikace funguje.
config firewall policy edit 4 set name "www - HTTP/S" set srcintf "DMZ2zone" set dstintf "DMZ2zone" set action accept set srcaddr "DMZ2network" set dstaddr "200.0.0.10 10.1.0.10 web" set schedule "always" set service "HTTPS" "HTTP" set logtraffic all set nat enable set ippool enable set poolname "SNAT 200.0.0.1" next end
config firewall vip edit "200.0.0.10 10.1.0.10 web" set extip 200.0.0.10 set mappedip "10.1.0.10" set extintf "any" next end
V politice můžeme nastavit Source NAT na jednu ze tří variant:
- vypnutý SNAT - pokud je komunikace do stejné sítě, tak se jako odchozí použije adresa rozhraní (třeba DMZ
10.0.0.1
), jinak zůstane originální adresa - SNAT s adresou odchozího rozhraní - možná překvapivě se použije VIP adresa (
200.0.0.10
), podle pravidla použití SNAT a existující VIP - SNAT s dynamickou adresou - jako odchozí adresa se použije zadaná (třeba
200.0.0.1
)
Zatím zde nejsou žádné komentáře.