Linux/Linux jako server/IPfilter

Tento článek není vyčerpávajícím návodem ani úvodem. Předpokládá se, že čtenář ví, co je to protokol, port atp. Chci se tu zaměřit spíš na několik tipů, které jsem objevil při studiu, a které by mohly být užitečné.

Příprava

editovat

Nejdříve bude dobré si udělat "hřiště". Navrhuji dávat si skriptíky zde vzniklé do adresáře /usr/local/sbin/. Budou se nám dobře spouštět a nebudou se dobře spouštět nikomu jinému.

Nespěchejte při ladění filtru s nastavováním restriktivních pravidel. Politika DROP je dobrá u produkčního filtru, ale při ladění vám nadělá zbytečně moc práce. Nechte politiku ACCEPT a sledujte pomocí pravidla LOG, co vám sítem pravidel protéká.

Sledování IP filtru

editovat

Příkaz iptables má volbu -L, která vypíše obsah nastaveného filtru:

# iptables -L

Přidáním volby -v dosáhneme zobrazení i množství paketů/dat prošlých každým pravidlem.

# iptables -L -v

Volba -n řekne, aby se vypisovala čísla místo názvů. Týká se to DNS jmen a jmen služeb, místo kterých se budou vypisovat IP adresy a čísla portů.

# iptables -L -v -n

Při přidávání či odebírání pravidel do/z filtru potřebujeme znát i jejich pořadová čísla. To nám zajistí parametr --line-numbers

# iptables -L -v -n --line-numbers

Teď už je ten řádek dost odporně dlouhý na to, abychom si z něj udělali skriptík nebo alias. Než se do toho dáme, možná se nám bude líbit tohle:

# watch "iptables -L -v -n --line-numbers"

To nám zajistí, že se výpis bude po dvou vteřinách obnovovat a my můžeme plynule sledovat, jak se naše řádění s přidáváním/odebíráním pravidel projevuje. Samozřejmě nám to "sežere" jednu konzoli, ale to nám vadit nemusí. Máme jich dost. Činnost sledovače watch ukončujeme klasickým CTRL+C.

Takže si uděláme skriptík s názvem kupř. muj-ipf-watch:

#!/bin/sh
# skript pro sledovani ip filtru

watch "iptables -L -v -n --line-numbers"

Nastavte práva 700, ať máte sichr, že se k tomu dostane jen root.

Automatické shození filtru při ladění po síti

editovat

Je děsná sranda, když ladíte filtr po síti (přes ssh) a nějakou blbostí si zablokujete přístup. Musíte-li se šťourat ve filtru přes síť, doporučuji mít připravený skript, který vám filtr po zadané době shodí, nebo ho uvede do předchozího stavu.

Nicméně začátek, předpokládám, nebudete testovat na dálku, ale na svém počítači u kterého sedíte.

Skript na shození filtru

editovat

Následující skriptík zajistí, že IP filtr bude vyčištěn:

#!/bin/sh
# skript muj-ipf-down
# dame si ho treba do /usr/local/sbin/

# zrusime vsechna pravidla pro vychozi retezec "filter"
iptables -t filter -F
# pripadne i pro nat
iptables -t nat -F

# nastavime vychozi politiku na ACCEPT
iptables -P INPUT ACCEPT -t filter
iptables -P OUTPUT ACCEPT -t filter
iptables -P FORWARD ACCEPT -t filter

exit 0

Samozřejmě si přidáme/ubereme co (ne)potřebujeme. Hlavně nezapomenout nastavit politiku na ACCEPT, protože pokud náš filtr předtím nastaví politiku na DROP, nebude shození filtru jen pomocí volby -F stačit (nastavená politika zůstává)! O DROP jsme si ale něco řekli hned v úvodu.

Bez otestování jsme kaskadéři. V každém textu je aspoň jeden překlep. Takže si uděláme ještě základní testovací filtr:

#!/bin/sh
# skript muj-ipf-btest

# nastaveni restriktivni politiky
iptables -P INPUT DROP
iptables -P FORWARD DROP
iptables -P OUTPUT DROP

# a pravidla vsechna otevreme
iptables -A INPUT -j ACCEPT
iptables -A FORWARD -j ACCEPT
iptables -A OUTPUT -j ACCEPT

Tento skript spustíme a podíváme se do vedlejší konzole, kde nám běží náš muj-ipf-watch, co náš filtr dělá. Můžeme si třeba spustit internetový prohlížeč a načíst nějakou stránku. Všechno by mělo projít pravidlem a politika by se neměla uplatnit.

Teď zkusíme spustit skript muj-ipf-down a koukneme opět do vedlejší konzole. Politiky by měly být všechny "ACCEPT" a pravidla žádná.

Shození filtru při ladění "na dálku"

editovat

Zmrskáme-li něco ve filtru na počítači u kterého sedíme, celkem nic se neděje. Ale ladíme-li filtr na stroji, který je po síti daleko, je opatrnost nutná.

Než se v našem filtru začneme hrabat, zajistíme si nastavení výchozího stavu pro případ, že by server s námi přestal komunikovat. Použijeme nějaký program pro odložené spuštění příkazu. Tedy buď cron, nebo at.

Příkaz at mi přijde pružnější, jenže taky se mi už stalo, že jsem na něj v zápalu boje zapomněl a spustil novou verzi filtru bez sichr spuštění shazovače filtru. Můžeme klidně oba příkazy zkombinovat. cron bude shazovat filtr jednou za hodinu (kdybychom zapomněli na at) a atem si budeme nechávat filtr shazovat pružně dle potřeby.

# at now +5min
at>muj-ipf-down

Nyní můžeme začít řádit. Víme, že at nám za pět minut filtr shodí.

S cronem to uděláme takto:

# crontab -e

A přidáme řádek:

30 * * * * /usr/local/sbin/muj-ipf-down

který nám vždycky v půl shodí firewall.

A teď už se fakt ničeho nebojím (tedy kromě té sovy).

Začínáme tvořit

editovat

Již v úvodu jsem se zmínil, že restriktivní politiku je dobré "nahodit", až když je vše odladěno. Proteče-li něco pravidly filtru tak, že se uplatní politika, je při ladění jedno, jestli je to ACCEPT nebo DROP. ACCEPT ale zabrání případnému zamrznutí komunikace.

#!/bin/sh
# skript muj-ipf-up

iptables -P INPUT ACCEPT
iptables -P OUTPUT ACCEPT
iptables -P FORWARD ACCEPT

# ... a tady se bude připisovat

Přidáváme pravidla

editovat

Nová pravidla přidávám raději ručně z konzole, okouknu co dělají a teprve, jsem-li spokojen dopíšu je do "nahazovacího" skriptu. Tady se príma hodí, že máme v koukací konzoli i čísla řádků - pravidla můžeme zařazovat na místo, kde je přesně potřebujeme.

Sledování počtu paketů prošlých různými pravidly se může hodit kupř na to, že je-li tu nula (zvláště dlouhodobě), je otázka, zda ono pravidlo má vůbec smysl. Někdy zkrátka testujeme něco, co už se uplatnilo v řadě pravidel výše. Stává se to.

Taky je dobré dávat nahoru pravidla, která se uplatňují častěji. Například je běžné toto:

iptables -A INPUT -i eth0 -p tcp --dport 22 -j ACCEPT
iptables -A INPUT -i eth0 -p tcp --dport 25 -j ACCEPT
iptables -A INPUT -i eth0 -p tcp --dport 80 -j ACCEPT
iptables -A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT

První tři řádky říkají, že se má propustit vše co jde na daná čísla portů, čtvrtý řádek říká, že se má propustit vše, co se týká již dříve nastavených spojení.

Je asi zbytečné u již navázaných spojení znovu testovat číslo portu, a tak můžeme čtvrté pravidlo dát nahoru. Většina paketů se totiž týká již navázaných spojení.

Poznámka: Při této optimalizaci samozřejmě nesmíme narušit logiku pořadí testování. Prohazovat lze jen tam, kde na pořadí nesejde.

Logujeme co protéká

editovat

Když máme náš filtr tak nějak hotový, často nás začne dráždit otázka, co to je za pakety, které procházejí skrz naše pravidla nepovšimnuté? Tak si na konec všech pravidel přidáme řádek, který bude tyto pakety zapisovat do /var/log/syslog:

iptables -A INPUT -i eth0 -j LOG

Toto logování vypneme:

iptables -D INPUT č.pravidla

kde č.pravidla je číslo, které si zjistíme z výpisu pravidel.

Můžeme zjistit, že tu jsou kupř. pakety, které určitě chceme propouštět. Při závěrečné změně politiky z ACCEPT na DROP by nám tedy nějaké síťové služby přestaly fungovat. Musíme tedy pro ně přidat pravidla, která jim dovolí projít.

Taky můžeme zjistit, že jsou tu pakety, které opravdu zahodit zasluhují.

Ale tohle všechno už je záležitost vašeho ladění vašich IP filtrů a já vám teď můžu podržet palce při studiu a ladění.