V 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
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:
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.