Firewalld: filtrování ICMP, pomocníci a bohatá pravidla

7. 2. 2023
Doba čtení: 9 minut

Sdílet

 Autor: Depositphotos
V dnešním článku si popíšeme poslední důležité komponenty, které se využívají ke konfiguraci Firewalld. Naučíme se omezovat protokol ICMP, používat pomocníky (helper) a doplňovat do firewallu vlastní pravidla.

předchozím článku z naší série o Firewalld jsme se zabývali prací se zónami, vytvořením vlastní zóny a definováním sady adres. Dnes se naučíme pracovat s dalšími sadami informací, které firewall ke své činnosti potřebuje.

Co se dozvíte v článku
  1. Pravidla pro ICMP
  2. Blokace zpráv ICMP
  3. Otočení blokační logiky
  4. Pomocníci (helpers)
  5. Bohatá pravidla
  6. Příklady pravidel
  7. Příště

Pravidla pro ICMP

ICMP (Internet Control Message Protocol) je velmi důležitý protokol, který slouží k výměně servisních zpráv a chybových hlášení v IP síti. Jeho prostřednictvím se šíří například informace o tom, že počítač či síť jsou nedosažitelné nebo že je určitá služba nedostupná. Díky ICMP nám funguje například také známý příkaz ping, který generuje zprávy ICMP Echo Request a přijímá odpovědi ICMP Echo Replay.

Pro správné fungování IP sítě je provoz ICMP velmi důležitý, přestože neslouží k přenášení dat mezi počítači. Díky ICMP se například vysílací strana dozví, že na síti nastal nějaký problém, který je možné vhodnou úpravou dalších paketů řešit. Blokovat ICMP jako celek tedy rozhodně není dobrý nápad. Přesto může být v některých situacích rozumné omezit určité typy zpráv, které by mohly například příliš prozrazovat o naší síti.

K tomu ve Firewalld slouží takzvané ICMP Type, tedy pravidla rozlišující jednotlivé typy zpráv. V systému už je jich spousta připravených, takže si je můžeme vypsat:

# firewall-cmd --get-icmptypes
address-unreachable bad-header beyond-scope communication-prohibited
destination-unreachable echo-reply echo-request failed-policy
fragmentation-needed host-precedence-violation host-prohibited host-redirect
host-unknown host-unreachable ip-header-bad neighbour-advertisement
neighbour-solicitation network-prohibited network-redirect network-unknown
network-unreachable no-route packet-too-big parameter-problem port-unreachable
precedence-cutoff protocol-unreachable redirect reject-route
required-option-missing router-advertisement router-solicitation source-quench
source-route-failed time-exceeded timestamp-reply timestamp-request
tos-host-redirect tos-host-unreachable tos-network-redirect
tos-network-unreachable ttl-zero-during-reassembly ttl-zero-during-transit
unknown-header-type unknown-option

Některé z typů jsou platné pro IPv4, další pro IPv6 a některé pro oba typy sítě. Z hlediska IP jde totiž o různé protokoly, které mají také různé identifikátory. ICMP (pro IPv4) má číslo 1, zatímco IPv6-ICMP má číslo 58. Na tuto informaci se pro každý typ můžeme dotázat.

# firewall-cmd --info-icmptype=redirect
redirect
  destination: ipv4 ipv6

Informace o typech jsou uloženy v /usr/lib/firewalld/icmptypes/  a uživatelské úpravy opět v  /etc/firewalld/icmptypes/.

Blokace zpráv ICMP

Jednotlivé typy zpráv ICMP je možné zablokovat, což vede k jejich odmítnutí. Jejich odesílatelé se tedy dozvědí, že zpráva neprošla. Následující příkaz vypíše seznam blokovaných ICMP typů, který je ve výchozím stavu prázdný, takže komunikace není omezována.

# firewall-cmd --list-icmp-blocks

Můžeme se také přímo zeptat na konkrétní typ a Firewalld nás informuje o tom, zda je typ právě blokován či ne.

# firewall-cmd --query-icmp-block=echo-reply
no

Pokud chceme daný typ ICMP ve vybrané zóně zablokovat, stačí zavolat následující příkaz. Pozor na to, že pak musíme znovu načíst konfiguraci z disku do paměti.

# firewall-cmd --permanent --zone=public --add-icmp-block=echo-request
# firewall-cmd --reload

Pokud si nyní zobrazíme informace o dané zóně, najdeme tam poznámku o blokaci.

# firewall-cmd --zone=public --list-all
…
icmp-blocks: echo-request
…

Blokaci můžeme samozřejmě kdykoliv zase odebrat.

# firewall-cmd --permanent --zone=public --remove-icmp-block=echo-request
# firewall-cmd --reload

Otočení blokační logiky

Ve výchozím stavu platí, že pokud není konkrétní typ ICMP zablokován, bude procházet bez překážek. Tuto logiku ale můžeme ve Firewalld otočit a pak místo nastavování blokací budeme konkrétní typy povolovat. Co nebude povoleno, bude naopak zakázáno.

# firewall-cmd --permanent --zone=public --add-icmp-block-inversion
# firewall-cmd --reload

Změna se projeví ve výpisu dané zóny, kde bude přepnutá položka zapnuté inverze.

# firewall-cmd --zone=public --list-all | grep icmp
  icmp-block-inversion: yes
  icmp-blocks: echo-request

Na stav se můžeme také kdykoliv přeptat a zase ho vypnout.

# firewall-cmd --zone=public --query-icmp-block-inversion
yes
# firewall-cmd --permanent --zone=public --remove-icmp-block-inversion
# firewall-cmd --reload
# firewall-cmd --zone=public --query-icmp-block-inversion
no

Pomocníci (helpers)

Některé protokoly aplikační vrstvy používají pro komunikaci více síťových portů, jejichž použití vyjednávají v úvodním seznámení. To komplikuje práci firewallu, protože ten nemůže zůstat statický, ale musí situaci průběžně sledovat a reagovat na změny.

Linuxové jádro v rámci svého sledování spojení (connection tracking) používá takzvané protokolové pomocníky (protocol helpers), které nahlížejí do vybraných protokolů vyšších vrstev a zjišťují, které porty budou součástí nově vznikajícího spojení. Tyto informace jsou pak doplněny do příslušných tabulek a firewall je pak může dynamicky zahrnout do svých povolovacích pravidel.

Podporu pro tyto pomocníky má samozřejmě i Firewalld, konkrétně na úrovni služby. Práci se službami jsme si ukazovali ve třetím díle. Součástí definice služby může být volitelně také odkaz na pomocníka (helper). Ty jsou uloženy v /usr/lib/firewalld/helpers/  a můžeme si je nechat vypsat.

# firewall-cmd --get-helpers
Q.931 RAS amanda ftp h323 irc netbios-ns pptp proto-gre sane sip snmp tftp

Informace o některém z nich si můžeme také hned vyžádat.

# firewall-cmd --info-helper=ftp
ftp
  family:
  module: nf_conntrack_ftp
  ports: 21/tcp

Definice je velmi jednoduchá, obsahuje vlastně jen informace o použitém modulu jádra a TCP portu. Pomocník je pak vázán vždy na službu, což si můžeme opět ukázat na příkladu FTP.

# firewall-cmd --info-service=ftp
ftp
  ports: 21/tcp
  protocols:
  source-ports:
  modules:
  destination:
  includes:
  helpers: ftp

Pomocníky je opět možné spravovat pomocí utility firewall-cmd, je možné je vytvářet, upravovat či odstraňovat. Stejně tak je možné je přiřazovat ke konkrétním službám pomocí --service=service --add-helper=helper. Nemá smysl tu omílat znovu celou sadu příkazů, v případě potřeby vás odkážu na manuálovou stránku man firewall-cmd nebo přímo  man firewalld.helper.

Bohatá pravidla

Při definici pravidel jsme si zatím ukázali jen to základní: definici služby pomocí portu. To nám může v mnoha jednoduchých případech stačit, ale často pro popis potřebujeme lepší vyjadřovací schopnosti. K tomu ve Firewalld slouží jazyk bohatých pravidel (rich rules), který vychází ze syntaxe jaderného firewallu.

S pomocí těchto pravidel můžeme definovat filtraci za pomocí IP adres, protokolů, portů a dalších vlastností. Zatímco u běžných služeb jsme se pohybovali na velmi abstraktní úrovni, tady už můžeme vytvářet něco, co připomíná klasická firewallová pravidla. Syntaxe vypadá takto:

rule [family="rule family"]
    [ source [NOT] [address="address"] [mac="mac-address"] [ipset="ipset"] ]
    [ destination [NOT] address="address" ]
    [ element ]
    [ [ log [prefix="prefix text"] [ level="log level"] [ limit value="rate/duration"] ]
    [ audit ]
    [ action ]

Už z toho je vidět, jaké jsou asi schopnosti tohoto typu pravidel. Pro plné pochopení ale musíme projít a vysvětlit všechny položky. První sekce family určuje rodinu protokolů, tedy buď ipv4 nebo ipv6. Pokud tuto položku neuvedeme, použije se pravidlo na obě rodiny a bude příjemně univerzální. V tom případě ovšem nemůžeme použít v pravidle žádné IP adresy.

Položky pod source mohou obsahovat IP či MAC adresy, nebo už v seriálu probíranou sadu adres. Může jít o jednotlivé adresy nebo celé rozsahy pokryté maskou či přímo vypsáním rozsahu. Není tu povoleno uvádět doménová jména. Všimněte si možného klíčového slova  NOT, které invertuje smysl vypsaných adres. Podobně se chová i sekce destination, ale tu nelze použít v kombinaci se všemi elementy.

Element

Sekce element umožňuje vložit pouze jednu z následujících variant: service, port, protocol, masquerade, icmp-block, forward-port a source-port. Určujeme zde to hlavní, tedy jak budeme s daným paketem zacházet. Každý z těchto elementů má pak ještě další podvolby, které doplňují parametry daného elementu.

Například service dovoluje v parametru name= zvolit název služby, která je ve Firewalld definovaná. Pozor na to, že tady může dojít ke konfliktu cílové adresy mezi službou a námi zadávaným pravidlem. V tom případě se to projeví chybou a nemůžeme takto konfliktní pravidlo vložit, protože by to nedávalo smysl.

Volba port umožňuje zadat port či jejich rozsah v parametru port=. Kromě toho je možné také doplnit protokol pomocí volby protocol=, která může nabývat hodnoty tcp nebo  udp.

Volba protocol dovoluje v parametru value= zapsat číslo protokolu v IP hlavičce. Míní se tím volba protokolu čtvrté síťové vrstvy, tedy těch hodnot, které v systému najdete v souboru  /etc/protocols.

Volba icmp-block dovoluje v parametru name= zablokovat určitý interně definovaný typ zprávy ICMP, jak jsme si je popsali výše. V případě této volby není možné uvést akci, která se má s daným paketem provádět. Pokud takto vybraný paket dorazí, je automaticky odmítnut.

Zajímavá volba masquearade zapne v tomto pravidle překlad adres. Je možné s ní definovat také zdrojovou adresu, na kterou se pravidlo omezí a v takovém případě pak pouze tyto zadané zdroje budou moci překlad adres použít. Nelze tu uvádět cílovou adresu a samozřejmě ani akci.

Volba forward-port slouží k přesměrování některého místního portu či rozsahu portů protokolu TCP či UDP na jiný místní port nebo na port vzdáleného stroje. Nelze tu zvolit žádnou akci, ta je vždy nastavená na ACCEPT. Syntaxe obsahuje několik voleb:

forward-port port=number_or_range protocol=protocol to-port=number_or_range to-addr=address

Poslední použitelný element se jmenuje source-port a umožňuje pomocí voleb port= a protocol= vybrat cílový port či jejich rozsah, přičemž je možné jako protokoly uvést udp či  tcp.

Logování a audit

Logování pomocí volby log umožňuje zaznamenávat události do systémového logu. Je možné připsat ke každé události prefix a vybrat si z úrovní logování: emerg, alert, crit, error, warning, notice, info či debug. Vedle toho je nutné nastavit limit. Celá syntaxe vypadá takto:

log [prefix=prefix text] [level=log level] limit value=rate/duration

Kromě logování je možné alternativně použít také zasílání do auditd  pomocí volby audit. Ta nemá žádné další volby, ale je možné tu volitelně připsat také limity.

Akce

Poslední část pravidla pak popisuje akci, tedy co se má s daným paketem provést. Varianty jsou accept, reject, drop nebo mark. V případě odmítnutí je možné uvést typ, označení vyžaduje nastavení konkrétní značky.

Toto je jen hrubý nástřel principu bohatých pravidel, pro podrobnější dokumentaci a celý popis všech voleb doporučuji manuálovou stránku  man firewalld.richlanguage.

Příklady pravidel

Následující pravidla se zapisují pomocí firewall-cmd a jeho parametru --add-rich-rule="pravidlo". Je možné klasicky přidat a parametr --permanent, zvolit jinou než výchozí zónu pomocí --zone= a třeba také vytvořit dočasné pravidlo zadáním časového omezení v parametru --timeout=, který ale není možné kombinovat s parametrem  --permanent.

Celý zápis příkazu na řádce bude vypadat například takto:

# firewall-cmd --permanent --add-rich-rule='rule family=ipv4 source address=192.168.1.0/24 port port=22 protocol=tcp reject'

Následující příklady už budou jen demonstrovat zápis některých pravidel, vynechám proto celé obalení příkazem firewall-cmd včetně jeho parametrů a začnu až klíčovým slovem  rule.

Můžeme například povolit použití služby FTP a zároveň zajistit logování rychlostí jedné položky za minutu:

rule service name="ftp" log limit value="1/m" audit accept

Můžeme otevřít službu TFTP pouze z vybraného rozsahu adres a opět pokusy logovat:

bitcoin_skoleni

rule family="ipv4" source address="192.168.1.0/24" service name="tftp" log prefix="tftp" level="info" limit value="1/m" accept

Užitečné bude si také ukázat přesměrování portů:

rule family=ipv4 forward-port to-port=8080 protocol=tcp port=80

Příště

V následujícím článku si ukážeme koncept politik, které doplňují nám známé zóny a umožňují definovat pravidla pro provoz mezi různými rozhraními. Umožní nám tedy použít firewall nejen lokálně, ale i pro síť nebo třeba prostředí s kontejnery.

Autor článku

Petr Krčmář pracuje jako šéfredaktor serveru Root.cz. Studoval počítače a média, takže je rozpolcen mezi dva obory. Snaží se dělat obojí, jak nejlépe umí.