Firewall

Průchod packetu firewallem

Pomůžeme si diagramem z dokumentu "Iptables Tutorial 1.2.1", původní autor: Oskar Andreasson, šířeno pod licencí GNU GPL 2.0:

Netfilter simplified flow

Je to sice jen přibližný diagram, ale nám skvěle poslouží. Podrobnější diagram je například na Wikipedii na stránce o Netfilteru, kterou uvádíme v odkazech.

Pro nás je podstatné si říci, co se dá ve které fázi zpracování packetu udělat a jak se liší cesty input , outputa forward.

V první řadě tedy packety, které přijdou ze síťového rozhraní

  • v tabulce raw a řetězci PREROUTING se zejména dá zabránit zpracování packetu conntrackem:

    iptables -t raw -A PREROUTING -p udp --dport 53 -j NOTRACK
    

    nebo

    table ip raw {
    chain PREROUTING {
        type filter hook prerouting priority raw; policy accept;
        meta l4proto udp udp dport 53 counter notrack
    }
    }
    
  • v tabulce mangle a řetězci PREROUTING se dají packetům nastavovat například TOS (Type Of Service) flagy v IP hlavičce a nebo se dá nastavit fw-mark (to je bezrozměrný integer, značka kterou lze pak zpětně vyhledávat v dalších pravidlech a nebo jí lze použít jako klíč pro QoS nebo PBR - Policy Based Routing):

    iptables -t mangle -A PREROUTING -p tcp --dport 22 -j TOS --set-tos 0x10
    iptables -t mangle -A PREROUTING -p tcp --dport 80 -j MARK --set-mark 1
    

    nebo

    meta l4proto tcp tcp dport 22 counter ip dscp set 0x04
    meta l4proto tcp tcp dport 80 counter meta mark set 0x1 
    
  • V tabulce nat a řetězci PREROUTING se zpravidla dělá DNAT - to už známe.

  • Následuje směrovací rozhodnutí - před ním lze v pravidlech matchovat pouze vstupní rozhraní, -i eth0 například, nikoliv však výstupní rozhraní, protože to ještě není známo, dokud se neprovede toto směrovací rozhodnutí; zde se také určí další cesta packetu - buď přes INPUT řetězce do lokálního síťového stacku a nebo přes FORWARD řetězce na výstup - klíčem pro to pochopitelně je, zda je v tomto okamžiku cílová adresa packetu shodná s adresou na některém síťovém rozhraní (důležité je, že v tomto okamžiku - například v případě DNAT byla shodná když packet dorazil, ale my jsme jí včas změnili v tabulce nat v řetězci PREROUTING).

  • Pokud se packet vydá cestou řetězců INPUT, tak v tabulce mangle jde udělat opět změny v havičkách a případně packet omarkovat.

  • V tabulce filter v řetězci INPUT je místo, kam patří pravidla, která chrání místní počítač - tedy v tomto místě by se mělo rozhodnout o tom, zda bude packet propuštěn do síťového stacku a nebo zahozen.

  • Naproti tomu cesta řetězci FORWARD je určená pro packety, které budou routingem přehozeny na next-hop, který byl nalezen při směrovacím rozhodnutí; tabulka mangle a řetězec FORWARD ničím nepřekvapí, jen narozdíl od fáze PREROUTING teď už víme, jaký bude výstupní interface a můžeme ho testovat na shodu v iptables například pomocí -o eth1.

  • Řetězec FORWARD v tabulce filter je místo, kde zajišťujeme bezpečnost sítí, pro které je náš Linux routerem nebo firewallem.

  • Když se nyní podíváme na cestu packetu, co vznikl v lokálním síťovém stacku (ať je to podvěď na request, který k nám přišel a nebo je to request, kterým lokální síťový stack zahajuje spojení), začínáme v tabulce raw v řetězci OUTPUT, ten svým významem kopíruje řetězec PREROUTING, avšak tentokrát né pro příchozí, ale pro lokálně vzniklé packety; lze v něm tedy opět selektivně zabránit zpracování packetu conntrackem.

  • Řetězec OUTPUT v tabulce mangle svým významem nepřínáší překvapení - v tabulce mangle se dá měnit obsah vybraných hlaviček a nastavovat mark, v této situaci se u výstupního packetu někdy uplatňuje možnost nastavit TOC v IP hlavičce, TTL v IP hlavičce a nebo MSS v TCP hlavičce - smysl nastavení TOC je ladění výkonu, na TTL se zpravidla sahá jen v nezvyklých a krajních případech a manipulace s MSS má význam k obejdutí problémů s rozbitým PMTU discovery (vizte minulé kapitoly o ICMP), příklady:

    iptables -t mangle -A OUTPUT -o eth1 -j TTL --ttl-set 32
    iptables -t mangle -A OUTPUT -p tcp -o eth1 -j TCPMSS --set-mss 1460
    

    nebo

    oifname "eth1" meta l4proto tcp counter tcp option maxseg size set 1460
    

    Pro nastavení TTL momentálně (konec roku 2020) nftables podporu nemají.

  • Řetězec OUTPUT v tabulce nat je místem, které jsem zatím nepotřeboval ani v nejpodivnějších scénářích v labech.

  • Řetězec OUTPUT v tabulce filter je místem, které chrání před únikem dat a lze v něm také snadno a rychle zabránit škodám pokud je váš server částečně vyhackován a posílá spousty útočných packetů do Internetu - to se často vídá na různých webhostingových serverech, když se hackerům povede zmanipulovat neprivilegovaně běžící webové skripty a posílat skrz ně různé druhy útoků; pochopitelně to má smysl jen když hackeři neovládnou root účet a i tak je to jen hotfix, aby se nemusel celý server odstavit, než se najde a odstraní hlavní příčina.

  • Pokud jde o společnou část na výstupu, která zpracovává jak routované, tak lokální packety, tak v řetězci POSTROUTING v tabulce mangle opět můžeme měnit TOC, TTL, MSS a teoreticky přidat mark, ale v tento okamžik už markování nemá žádný smysl, protože prakticky vše je už rozhodnuto.

  • A nakonec v tabulce nat v řetězci POSTROUTING se zpravidla dělá SNAT nebo maškarád.

Pro úplnost přikládáme složitější diagram z Wikipedie (autor: Jan Engelhardt, šířeno pod licencí [CC BY-SA 3.0]: https://creativecommons.org/licenses/by-sa/3.0 ).

Netfilter flow

Tady stojí za upozornění, že jsou situace, kdy packet neprochází Linuxovým firewallem přímočaře, ale může se v jiné podobně vrátit - máme na mysli zejména situaci, kdy je packet odeslán do virtuálního rozhraní - tunelu a nebo je na něm provedena IPsec transformace. Přesto tyto okrajové případy už nepatří do základního přehledu a zůstaneme u připomenutí, že předcházející rozbor na základě prvního diagramu byl zkrátka zjednodušený.

Odkazy: