iptables

Tento návod je určen pro pokročilé uživatele

Toto je překlad stránky Iptables HowTo na oficiální komunitní dokumentaci Ubuntu ovšem v mnoha případech jsem se neubránil potřebě původního autora doplnit o své vlastní zkušenosti a něco překladu z man stránky.

Linuxové jádro obsahuje subsystém Netfilter, který má na svědomí síťový provoz na vašem systému. Všechny moderní linuxové firewally využívají tento Netfilter. V dokumentu Linux 2.4 Packet Filtering HOWTO od Rusty Russella, který najdete pravděpodobně ve svém systému na /usr/share/doc/iptables/html/packet-filtering-HOWTO.html se dočtete, že Linux dokázal filtorvat síťové pakety již od verze 1.1 v roce 1994. Tento systém byl založen na ipfw z BSD a má ho a svědomí Alan Cox. V jádře 2.0 se objevil nástroj ipfwadm od Jose Vose a v roce 1998 již zmíněný Rusty Rusella a Michaela Neulinga značně přepracovali jádro 2.2 a přidaly nástroj pojmenovaný ipchains. Teprve v roce 1999 se do jádra 2.4 dostala další značná úprava systému filtrování paketů a nový nástroj na jeho správu pojmenovaný iptables.

Takže už víme, že iptables jsou v našem systému přítomné vždycky. Kromě iptables můžete používat mnoho jiných nástrojů na spravování a nastavování pravidle síťového provozu jako jsou UFW (výchozí nástroj pro Ubuntu od verze 8.04, Firestarter,Lokkit, Firehol nebo Guarddog. Více se můžete dočíst na obecné stránce o firewallech a možná pokračovat ve čtení tam, protože práce například s UFW je mnohem lepší, snazší, přátelštější a v tomto návodu jen ztratíte čas.

Stručně o struktuře iptables a jak to zhruba funguje

Iptables jsou rozděleny do čtyř nezávislých tabulek filter, nat, mangle a raw. Jaké jsou v iptables konkrétně přítomné záleží na konfiguraci jádra a na nastavení jadrných modulů. Se kterou tabulkou hodláme pracovat musíme specifikovat přepínačem -t, –table jméno-tabulky. Pokud tabulku nespecifikujeme použije se výchozí tabulka filter.

Tabulky jsou následující: filter Výchozí tabulka vhodná pro základní filtrování, logování, počítání… Obsahuje tři vestavěné řetězy pravidel INPUT (pro pakety přicházejících do systému), OUTPUT (pro pakety odcházející ze systému), FORWARD (pro routrované pakety).

nat Používá se pro pro překlad adres (NAT), maškarády, port forwarding… Používá se jen pro první paket spojení. Má vestavěné také tři řetězy pravidel PREROUTING pro alternování příchozích paketů. POSTROUTING pro alternování odchozích paketu. A OUTPUT pro alternování lokálně generovaných paketů.

mangle Vhodná pro vychytávky související a alternováním paketů a zatím přesahuje rámec tohoto návodu.

raw Slouží k jakémusi nastavování výjimek a taky se jí nebudeme zabývat.

Jak jste si jistě všimli, v tabulkách jsou nějaké řetězy. Ptáte se co to je takový řetěz a proč řetěz? Jedná se o jakési sady pravidel dělených ( v případě tabulky filter) na příchozí, odchozí a přeposílanou komunikaci. Řetězy se nazývají kvůli způsobu jakým se zpracovávají. Když se podíváme jak se bude chovat filtrovaný paket poštovního protokolu smtp směřující na port 25 při průchodu řetěze INPUT z tabulky filter. Bude to vypadat zhruba následovně:

bfu@ubuntu:~$ iptables -L INPUT

Chain INPUT (policy ACCEPT)
target     prot opt source               destination
ACCEPT     all  --  anywhere             anywhere            state RELATED,ESTABLISHED
ACCEPT     tcp  --  anywhere             anywhere            tcp dpt:ssh
ACCEPT     tcp  --  anywhere             anywhere            tcp dpt:www
DROP       all  --  anywhere             anywhere

Výchozí politika je nastavená na ACCEPT, ale ta se bude uplatňovat až jako poslední, takže paket směřující na smtp port 25 projde nejprve prvním pravidlem, kde se testuje jestli je paket ze založeného spojení, nebo ze spojení odvozeného. Dále se testuje zda-li paket nesměřuje na ssh port 22. Protože nikoliv, z drhého pravidla se přesouvá na třetí, kde se testuje zda-li se nejedná o paket směřující na www port 80. Protože nikoliv, je náš nebohý paket předán k dalšímu testování čtvrtým pravidlem, které nedělá nic jiného, než že všechny pakety zahazuje (DROP). Výsledek je, že náš paket neprošel testování v poslední pravidlu a ztratí se v nicotě.

Když pravidla přeházíme tímto způsobem:

bfu@ubuntu:~$ iptables --insert INPUT 3 -j DROP
bfu@ubuntu:~$ iptables --delete INPUT 5

Potom nový výpis bude vypadat takto:

bfu@ubuntu:~$ iptables -L INPUT

Chain INPUT (policy ACCEPT)
target     prot opt source               destination
ACCEPT     all  --  anywhere             anywhere            state RELATED,ESTABLISHED
ACCEPT     tcp  --  anywhere             anywhere            tcp dpt:ssh
DROP       all  --  anywhere             anywhere
ACCEPT     tcp  --  anywhere             anywhere            tcp dpt:www

Výsledek bude takový, že náš smtp paket proleze, ale další www pakety směřující na port 80 budou nemilosrdně zahozeny, protože než dojde na pravidlo testující pakety směřující na port 80, uplatní se pravidlo, které zahodí vše.

Řetězů ale může být víc a můžete si taky nastavit vlastní „uživatelské“. Pomocí uživatelem definovaných řetězů se dají vytvářet komplikovanější filtry…

Z výše uvedeného příkladu je patrné , že pravidla se většinou ukončují přepínačem -j nebo –jump ACCEPT nebo DROP. Tedy něco jako : Pokud paket pravidlu vyhoví dostane za úkol „skočit“ na nějaký „cíl“ . Cíl tedy určuje osud paketu. Existuji čtyři základní cíle a celá řada rozšíření. Kromě vestavěných cílů je také možné posílat pakety na uživatelem definované řetězy.

'ACCEPT'

Dovolí paketu projít.

'DROP'

Upustí paket na zem. Zahodí ho a více se o něj nestará.

'QUEUE'

Podstoupí paket do uživatelského prostoru.

'RETURN'

Vrátí paket do předchozího řetězu , ze kterého se dostal do tohoto řetězu. Pakte se nevrátí na začátek řetězu, ale pokračuje od pravidla, kde přestal. Pokud tímto způsobem dorazí paket na konce vestavěného řetězu a nebo paket vyhoví pravidlu zakončeném na RETURN ve vestavěném řetězu, potom výchozí politika řetězu rozhodne o osudu paketu.

Základní příkazy

Když napíšete do terminálu jako superuživatel, tedy nejspíš zadáním sudo

bfu@ubuntu:~$  iptables -L

tak se vám vypíší všechny aktuálně nastavené pravidla pro síťový provoz v iptables. Protože předpokládám, že jste váš systém právě začali nastavovat, bude to vypadat zhruba takto :

Chain INPUT (policy ACCEPT)
target     prot opt source               destination

Chain FORWARD (policy ACCEPT)
target     prot opt source               destination

Chain OUTPUT (policy ACCEPT)
target     prot opt source               destination

Všimněte si , že v závorkách , je u každého řetězu (chain) uvedená výchozí politika na ACCEPT. To znamená, že váš systém, je otevřený všem požadavkům. Zejména je důležitý řetěz INPUT, protože ten představuje způsob zpracování paketů přicházejících a váš server.

Pokusíte-li se skenovat porty vašeho stroje příkazem nmap (ip adresu 62.245.78.194 si nahraďte za adresu vlastního stroje)

bfu@ubuntu:~$ nmap 62.245.78.194

Starting Nmap 5.00 ( http://nmap.org ) at 2010-08-08 6:18 CEST
Interesting ports on ip-62-245-78-194.net.upcbroadband.cz (62.245.78.194):
Not shown: 996 closed ports
PORT    STATE SERVICE
25/tcp  open  smtp
80/tcp  open  http
139/tcp open  netbios-ssn
445/tcp open  microsoft-ds

Nmap done: 1 IP address (1 host up) scanned in 0.24 seconds

zjistíte, že na tcp portu 25 poslouchá poštovní server a na tcp portu 80 poslouchá webový server. Pokud váš systém nemá sloužit jako poštovní nebo webový server, tak toto nastavení je velmi nevhodné, protože například kdokoliv může přes váš server odesílat spam do internetu.

Dříve než si předvedeme jak pravidla nastavit, ukážeme si zjednodušeně, jak se pravidla zapisují.

Zjednodušená syntaxe zápisu pravidel pro iptables

Zjednodušeně se dá příkaz na definování pravidla popsat takto :

iptables	< -t tabulka >	< příkaz >	< řetězec >	< specifikace pravidla >	< cíl >

Syntaxe je mnohem komplexnější, ale tohle nám zatím stačí.

Příkazy:

-A, –append řetěz specifikace-příkazu

Připojí jedno nebo více pravidel na konec vybraného řetězce. Jestliže zdrojové a/nebo cílové jméno odpovídá více adresám , pravidlo bude přidáno na všechny vyhovující kombinace.

-D, –delete řetěz specifikace-příkazu

-D, –delete řetěz číslo-pravidla

Z vybraného řetězu smaže jedno nebo více pravidel. Jsou dvě možné varianty tohoto příkazu: Buď smažete pravidlo podle jeho čísla (začínají se číslovat od 1), nebo pravidlo , které chcete smazat popíšete stejně, jako v specifikace-příkazu příkazu –append.

-I, –insert řetěz [číslo-příkazu] specifikace-příkazu

Vloží jedno nebo více pravidel do zvoleného řetězu. Podle čísla se určí pořadí pravidla. Uvedete-li 1, zařadí se pravidlo na začátek. Neuvedete-li číslo pravidla vůbec, použije se implicitně 1.

-R, –replace řetěz číslo-příkazu specifikace-příkazu

Nahradí pravidlo ve zvoleném řetězu. Jestliže zdrojové a/nebo cílové jméno odpovídá více adresám, příkaz selže. Pravidla jsou číslována od 1.

-L, –list [řetěz]

Vypíše seznam všech pravidel ve zvoleném řetězu. Pokud není řetěz uveden, vypíše všechny. Stejně jako všechny ostatní příkazy pro iptables se i tento vztahuje k specifikované tabulce . Pokud tabulku nespecifikujete, použije se tabulka Filter. Výpis pravidle pro tabulku NAT získáte zadáním iptables -t nat -n -L. Všiměte si prosím, že parametru -n kterým se zamezuje zpětnému vyhledávání jmen v DNS. Je také možné příkaz použít spolu s volbou -Z –zero, která způsobí, že řetěz(y) bude nejprve vypsán a bezprostředně potom bude počítadlo paketů vynulováno.

-S, –list-rules [řetěz]

Vypíše všechny pravidla ve zvoleném řetězu. Jestliže není žádný řetěz určen, vypíší se všechny řetězy po způsobu iptaples-save. Jako všechny ostatní příkazy pro iptables se vztahují k jedné tabulce. Pokud žádnou neuvedete, použije se tabulka Filter.

-F, –flush [řetěz]

Spláchne (smaže) všechny pravidla z uvedeného řetězu. Spláchne všechny pravidla ze všech řetězů, pokud žádný řetěz není vybrán. Alternativně je možné mazat všechny pravidla jedno po druhém pomocí –delete, cože je nesrovnatelně pracnější.

-Z, –zero [řetěz]

Vynuluje počítadla paketů u všech řetězů. Je povolené použít tuto volbu spolu s -L –list , aby se vypsal seznam řetězů přesně před vynulováním.

-N, –new-chain [řetěz]

Vytvoří nový , uživatelem definovaný, řetěz zvoleného jména. Jméno uživatelem definovaného řetězu musí být jedinečné.

-X, –delete-chain [řetěz]

Smaže uživatelem definovaný řetěz. Na řetěz nesmí existovat žádné odkazy. Pokud nějaké existují musíte je nejprve smazat nebo přejmenovat. Například řetěz nesmí obsahovat žádná pravidla. POkud neuvedete řetěz v příkazu, budou smazány všechny nezabudované řetězy.

-P, –policy řetěz cíl

Nastaví výchozí politiku pro řetěz a daný cíl. Povolené hodnoty pro cíle najdete v sekci CÍLE. Jen vestavěné řetězy mohou mít definovanou výchozí politiku. Vestavěné řetězy ani uživatelem definované řetězy nesmí být cílem pro jakoukoliv výchozí politiku.

-E, –rename starý-řetěz nový-řetěz

Přejmenuje uživatelem definovaný řetěz . Jedná se jen o kosmetickou úpravu, která nemá vliv na na strukturu tabulky.

-h, –help

Nápověda. Vypíše velmi stručnou nápovědu k syntaxi příkazů.

Parametry:

Tyto parametry se používají při definování pravidel síťového provozu a následují za výše uvedenými příkazy add, delete, insert, replace a append. Před některými může bát uvedený !, který značí negaci.

[!] -p –protocol protokol

Protokol pravidla a nebo kontrolovaného paketu. Můžete určit jeden z následujících protokolů 'tcp', 'udp', 'udplite', 'ICMP', 'esp', 'ah', 'sctp' or 'all'. Můžete také použít číselnou reprezentaci protokolu. Jméno protokolu z /etc/protocols je také použitelné. Argument „!“ před protokolem invertuje test. Číslo nula je ekvivalentní pro all. Protokol all zastupuje všechny protokoly a bude použit jako výchozí pokud tuto volbu vynecháte.

[!] -s –source adresa[/maska]

Specifikuje zdroj. Adresa může být síťové jméno, jméno hostitele, nebo prostá IP adresa. Maska může být buď síťová maska nebo prosté číslo vyjadřující počet jedniček na levé straně masky . Takže IP maska 24 je ekvivalentní zápisu 255.255.255.0. Volitelně je možné výběr adres obrátit pomocí „!“. Přepínač –src je ekvivalentem pro –source.

[!] -d –destination protokol

Specifikuje cíl. Podívejte se na specifikaci -s (source) pro detailní popis. Přepínač –dst je možné použít jako alias.

-j –jump cíl

Specifikuje cíl pravidla . To jest cíl kam je paket poslán, když vyhoví pravidlu. Cílem může být uživatelem definovaný řetěz , ale musí to být jiný řetěz , než ve kterém je toto pravidlo definované. Dále může být cílem jeden ze zabudovaných cílů, která určí osou paketu. Cílem také může být rozšíření (extension) o který se můžete dočíst v sekci o rozšířeních. Pokud je cíl z definice pravidla vynechán (a nepoužijete přepínač -g) potom pravidlo nebude mít na osud paketu žádný vliv, ale počítadlo pravidla se bude navyšovat.

-g –goto řetěz

Toto určuje, že zpracování by mělo pokračovat v uživatelem definovaném řetězu. Na rozdíl od volby –jump nebude zpracovávání pokračovat v původním pravidle, ale přesune se do odkázaného řetězu.

[!] -i –in-interface jméno

Jméno rozhraní na které paket dorazil (lze použít jen na pakety testované v řetězech INPUT, FORWARD a PREROUTING). Argument „!“ použitý před jménem rozhraní obrátí význam. Jestliže jméno interfejsu zakončíte na „+„ tak se použijí všechny interfejsy, které začínají na toto jméno. Pokud volbu -i vynecháte, použije se jakýkoliv interfejs.

[!] -o –out-interface jméno

Jméno rozhraní ze kterého bude paket odeslán (lze použít jen pro pakety testované v řetězech FORWARD, OUTPUT a POSTROUTING). Argument “!“ použitý před jménem rozhraní obrátí význam. Jestliže jméno interfejsu zakončíte na na „+„ tak se použijí všechny interfejsy, které začínají na toto jméno. Pokud volbu –out-interface vynecháte, použije se jakýkoliv interfejs.

[!] -f –fragment

Toto znamená, že pravidlo se vztahuje jen na druhý a další fragment fragmentovaného paketu. Protože neexistuje žádný způsob jak určit zdrojový nebo cílová port paketu (nebo ICMP paketu), takový paket nevyhoví žádnému pravidlu, které by ho pospalo. Jestliže použijete “!“ před přepínačem –fragment pravidlo se bude týkat pouze prvního fragmentu (hlavičky) paketu, nebo nefragmentovaných paketů.

-c –set-counters pakety bajty

Toto umožňuje administrátorovi nastavit počítadla paketů a bajtů u pravidla. Možno použít jen během INSERT, APPEND, REPLACE operací.

Další možnosti lze určit tímto způsobem.

-v –verbose

Upovídaný výstup. Toto umožní příkazu –list navíc vypsat ještě jméno interfejsu, možnosti pravidla (pokud nějaké jsou), TOS masku. Také se zobrazí počítadla bajtů a paketů s příponami „K“, „M“ nebo „G“ pro násobky 1000, 1 000 000 a 1 000 000 000 (podívejte se na volbu -x, která toto přenastavuje ). U příkazů APPEND, INSERT, DELETE, REPLACE se vypíší detailní informace .

-n –numeric

Číselný výstup. IP adresy a čísla portů budou vypsána v číselném formátu

—list-numbers

V seznamu pravidel přidá na začátek řádku číslo pravidla, podle jeho pozice v řetězu. Nejprve se program pokusí zobrazit jména hostitele, jména sítí nebo služeb.

-x –exact

Rozšiřuje čísla. Zobrazí přesné číslo u počítadel paketů a bajtů, nikoliv pouze zaokrouhlené číslo na násobky 1000, 1 000 000 a 1 000 000 000. Tato možnost je pouze použitelná u příkazu –list (-l).

MATCH EXTENSIONS

Iptables můžou flirtovat pakety pomocí rozšíření. Zapisují se za přepínač -m nebo –match. Za tímto přepínačem následuje jméno modulu a pak parametry. Modulů i jejich možností je opravdu velké množství a všechny je najdete v man stránkách . Pro potřeby tohoto dokumentu zde popíšu jen ty , se kterými budeme pracovat.

conntrack

Tento modul v kombinaci s modulem na stopování spojení umožňuje přístup ke stavu stopování spojení pro pro zkoumané pakety/spojení. [!] –ctstate seznam stavů INVALID znamená, že paket nemůže být z nějakého důvodu identifikován. Může to být například docházející paměť, a nebo ICMP chyba , která se nevztahuje k žádnému známému spojené.

ESTABLISHED je stav paketu vztahujícího se ke spojení, které posílá pakety oběma směry.

NEW znamená, že paket začal nové spojené , nebo patří do spojené které ještě neposílalo pakety oběma směry.

RELATED znamená, že paket začíná nové spojené , ale jedná se o spojení, které má vztah k již existujícímu spojení. Jedná se například o přenos dat po FTP , nebo nějaká ICMP chyba.

state

Tento modul v kombinaci se stopováním spojení umožňuje přístup ke stavu stopovaného spojení. [!] –state seznam stavů Za přepínač uveďte čárkou oddělený seznam stavů spojen, které se mají vyhledávat. Seznam možných stavů je následující: INVALID znamená, že paket nemůže být z nějakého důvodu identifikován. Může to být například docházející paměť, a nebo ICMP chyba, která se nevztahuje k žádnému známému spojené.

ESTABLISHED je stav paketu vztahujícího se ke spojení, které posílá pakety oběma směry.

NEW znamená, že paket začal nové spojené , nebo patří do spojené které ještě neposílalo pakety oběma směry.

RELATED znamená, že paket začíná nové spojené , ale jedná se o spojení, které má vztah k již existujícímu spojení. Jedná se například o přenos dat po FTP , nebo nějaká ICMP chyba.

Povolení "založeného" spojení

Opět připomenu, že s iptables můžete pracovat jen jako superuživatel (root).

Vraťme se nyní zpět k příkladu z kapitoly Základní příkazya ukažme si jak nastavovat dále iptables.

bfu@ubuntu:~$ iptables -L

Chain INPUT (policy ACCEPT)
target     prot opt source               destination

Chain FORWARD (policy ACCEPT)
target     prot opt source               destination

Chain OUTPUT (policy ACCEPT)
target     prot opt source               destination

Takže vidíme, že máme úplně vše otevřené. Aby to vůbec mohlo začít fungovat, tak musíme nejprve povolit již založená spojení a spojení, která se k nim vztahují.

bfu@ubuntu:~$ iptables -A INPUT -m conntrack --ctstate ESTABLISHED,RELATED -j ACCEPT

Všimněte si, že stavy spojení ESTABLISHED,RELATED jsou oddělení čárkou, ale není mezi nimi mezera.

Pokud nebude výše uvedený příkaz fungovat, tak je možné, že váš stroj je virtuální, umístěný na VPS které používá OpenVZ , nebo nemáte nainstalované nějaké jaderné moduly. Můžete vyzkoušet zapsat pravidlo takto:

bfu@ubuntu:~$ iptables -A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT

Povolení příchozích spojení na určité porty

Nejprve by jste měli začít tím, že zablokujete veškeré příchozí spojení. Je ALE možné, že pracujete s vaším strojem přes SSH a tudíž je velmi žádoucí nejprve ssh povolit. V opačném případě se vám může stát, že si přístup na server úplně zablokujete a budete k němu muset jít například do serverovny a restartovat ho. Restart počítač bude mít za následek, že se iptables vrátí do původního stavu. O definitivním uložení iptables si přečtěte v kapitole Ukládání nastavení iptables

K povolení ssh přístupu na server potřebujete otevřít tcp port číslo 22 pro příchozí spojení, tedy pro tabulku FILTER a řetěz INPUT.

bfu@ubuntu:~$ iptables -t filter -A INPUT -p tcp --dport ssh -j ACCEPT

Všimněte si, že jsem volbou -t řekl, že chci pravidlo uložit do řetězu INPUT v tabulce filter. Při práci s tabulkou filter je zbytečné tabulku specifikovat, protože, pokud tabulku neurčíme, použije se výchozí filter. Takže alternativně můžeme použít kratší zápis.

bfu@ubuntu:~$ iptables -A INPUT -p tcp --dport ssh -j ACCEPT
  • Přepínač -A přidává do řetězu INPUT nové pravidlo
  • Za jménem řetězu (v našem případě to je INPUT) následuje definice pravidla.
  • Přepínač -p určuje protokol tcp
  • Přepínač –dport je cílový port, kam paket směřuje na našem sytému. Port je možné zapsat i číslem 22 , na kterém serve ssh obvykle poslouchá.
  • Za přepínačem -j je cíl na který má paket „skočit“ v případě, že bude pravidlu vyhovovat. ACCEPT = paket přijat.

Necháme si opět vypsat pravidla v řetězu INPUT v tabulce filter. Tentokrát si necháme vypsat „upovídaný“ seznam.

bfu@ubuntu:~$ sudo iptables --verbose --list INPUT

Chain INPUT (policy ACCEPT 321K packets, 427M bytes)
pkts bytes  target  prot  opt   in  out  source    destination
3859 1050K  ACCEPT   all   --   any any  anywhere  anywhere   ctstate RELATED,ESTABLISHED
   1    48  ACCEPT   tcp   --   any any  anywhere  anywhere   tcp dpt:ssh

Můžeme vidět na začátku pkts jako počítadlo přijatých paketů, bytes jako počítadlo bajtů, target jako cíl, proto jako protokol, opt jako možnosti pravidla, in jako příchozí síťový interfejs, out jako odchozí síťový interfejns, source jako zdrojová adresa, destination jako cílová adresa. Dále je pak už jen zvolený matchig –match nebo filtrovaný port.

Teď si ještě zkusíme povolit port 80 , na kterém poslouchá webový server.

bfu@ubuntu:~$ iptables -A INPUT -p tcp --dport 80 -j ACCEPT

A opět zkontrolujeme naše pravidla.

bfu@ubuntu:~$ iptables -L INPUT

Chain INPUT (policy ACCEPT)
target     prot opt source               destination
ACCEPT     all  --  anywhere             anywhere            ctstate RELATED,ESTABLISHED
ACCEPT     tcp  --  anywhere             anywhere            tcp dpt:ssh
ACCEPT     tcp  --  anywhere             anywhere            tcp dpt:www

Teď máme výslovně povolené porty 22 a 80. Mimo tyto máme povolené i všechny ostatní protože u řetězu INPUT máme policy ACCEPT, tedy výchozí politiku zpracování paketu.

Blokování spojení

Pravidla se vykonávají postupně jedno po druhé. Jakmile paket jednou vyhoví, již se následujícím pravidlem nezpracovává. Jestliže chceme veškerou další komunikaci zablokovat stačí nám na konec přidat jednoduché pravidlo s prázdnou definicí:

bfu@ubuntu:~$ iptables -A INPUT -j DROP

Výpis pravidel potom bude vypadat takto:

bfu@ubuntu:~$ sudo iptables -L INPUT

Chain INPUT (policy ACCEPT)
target     prot opt source               destination
ACCEPT     all  --  anywhere             anywhere            ctstate RELATED,ESTABLISHED
ACCEPT     tcp  --  anywhere             anywhere            tcp dpt:ssh
ACCEPT     tcp  --  anywhere             anywhere            tcp dpt:www
DROP       all  --  anywhere             anywhere

Editování pravidel

Toto nastavení iptables vypadá docela dobře a pochopitelně, ale má několik nedostatků.

  1. Při definování pravidle jsem si nedali pozor na síťové rozhraní , pro které chceme pravidlo uplatnit. Protože jsem žádné neurčili, použilo se výchozí all, takže v současném stavu máme zablokované i síťové rozhraní lo pro loopback. To může některým programům znepříjemnit život a dokonce, můžou přestat úplně fungovat. Když bychom do řetězu INPUT nyní pouze příkazem –append přidali další pravidlo, tak již bude 5. v pořadí, a protože 4. pravidlo všechno vyhazuje , na 5. už se nikdy nedostane. Proto musíme nové pravidlo do řetězu vložit příkazem –insert.
 bfu@ubuntu:~$ iptables -I INPUT 1 -i lo -j ACCEPT

Číslo 1 ze slovem INPUT určuje pozici, kam se má pravidlo vložit, tedy na první pozici.

Abychom si mohli v seznamu pravidel prohlédnout, které síťová rozhraní ovlivňují, musíme si zažádat o „upovídaný“ výpis.

 bfu@ubuntu:~$ sudo iptables -v -L INPUT

 Chain INPUT (policy ACCEPT 260 packets, 67806 bytes)
 pkts bytes target prot opt in  out source   destination
 718 69470  ACCEPT all  --  lo  any anywhere anywhere
 680K  800M ACCEPT all  --  any any anywhere anywhere  ctstate RELATED,ESTABLISHED
    1    48 ACCEPT tcp  --  any any anywhere anywhere  tcp dpt:ssh
    0     0 ACCEPT tcp  --  any any anywhere anywhere  tcp dpt:www
    2   656 DROP   all  --  any any anywhere anywhere

Nyní všechny pakety, které jdou na interfejs lo jsou akceptovány a ty ostatní jsou podstoupeny druhému pravidlu…

  1. Další úpravu bychom mohli udělat tak, že jedno nadbytečné pravidlo odstraníme - tedy to poslední.
 bfu@ubuntu:~$ iptables -D INPUT 5

Dále pak přenastavíme výchozí politiku z ACCEPT na DROP.

 bfu@ubuntu:~$ iptables -P INPUT DROP

Nyní, když se podíváme na výpis pravidel, máme tam o jedno méně a celý řetěz funguje stejně, ale rychleji.

  1. V optimalizování se dá pokračovat. Můžeme totiž předpokládat, že požadavků na webový server bude poměrně víc, než požadavků na ssh server (to samozřejmě není obecně platné pravidlo - můžou existovat stroje, které to mají obráceně). Proto by bylo optimálnější, kdyby se nejprve testoval paket směrovaný na port 80. Jakmile paket projde 3. pravidlem (www) , už nebude pokračovat na 4. pravidlo (ssh).
 bfu@ubuntu:~$ iptables -D INPUT 4
 bfu@ubuntu:~$ iptables -I INPUT 3 -p tcp --dport 80 -j ACCEPT

Nakonec to tedy vypadá takto:

 bfu@ubuntu:~$ sudo iptables -L INPUT

 Chain INPUT (policy DROP)
 target     prot opt source               destination
 ACCEPT     all  --  anywhere             anywhere
 ACCEPT     all  --  anywhere             anywhere            ctstate RELATED,ESTABLISHED
 ACCEPT     tcp  --  anywhere             anywhere            tcp dpt:www
 ACCEPT     tcp  --  anywhere             anywhere            tcp dpt:ssh

Logování

V našem případě nastavení iptables, který tady probíráme, se síťový provoz neloguje. Pokud máte zájem o logování síťového provozu, tak toto je nejrychlejší cesta:

bfu@ubuntu:~$ iptables -I INPUT 5 -m limit --limit 5/minute -j LOG --log-prefix "iptables denied: " --log-level 7

Všechno se pak loguje do syslogu.

Ukládání nastavení iptables

Když nyní restartujete svůj systém, veškeré změny v iptables , které jste provedli se ztratí a nastaví se původní. K ukládání konfigurace máme šikovný nástroj iptables-save.

bfu@ubuntu:~$ iptables-save

který nám na standardní výstup vypíše definici všech pravidel pro iptables.

# Generated by iptables-save v1.4.4 on Thu Sep  9 23:45:38 2010
*filter
:INPUT DROP [1038:265543]
:FORWARD ACCEPT [0:0]
:OUTPUT ACCEPT [3370244:1009997559]
-A INPUT -i lo -j ACCEPT
-A INPUT -m conntrack --ctstate RELATED,ESTABLISHED -j ACCEPT
-A INPUT -p tcp -m tcp --dport 80 -j ACCEPT
-A INPUT -p tcp -m tcp --dport 22 -j ACCEPT
COMMIT
# Completed on Thu Sep  9 23:45:39 2010

Daleko praktičtější než výpis konfigurace na standardní výstup (na obrazovku) je lepší výstup do souboru.

bfu@ubuntu:~$ iptables-save > /etc/iptables.rules

Obrácenou službu nám udělá program iptables-restore, který umí konfiguraci ze souboru načíst a nastavit iptables.

bfu@ubuntu:~$ iptables-restore < /etc/iptables.rules

Zajímavým pomocníkem při nastavování iptables může být i program iptables-apply, který se vám hodí ve chvílích, kdy nevíte přesně, co děláte a jste ke server připojeni vzdáleně. V takových situacích se vám může snadno stát, že si zakážete na server přístup a potom vám nezbude nic jiného, než se zvednout ze židle a dojít si server restartovat. Použití má snadné:

bfu@ubuntu:~$ sudo iptables-apply --timeout 30 /etc/iptables.rules

Applying new ruleset... done.
Can you establish NEW connections to the machine? (y/N) apparently not...
Timeout. Something happened (or did not). Better play it safe...
Reverting to old ruleset... done.

iptables-apply neudělá nic jiného, než že na dobu třiceti sekund nastaví pravidla uložená v souboru /etc/iptables.rules a po uplynutí stanovené doby vrátí původní konfiguraci.

Automatické nastavení iptables při startu systému

Pozor, zdá se že iptables a NetworkManager mají jiste nesrovnalosti mezi sebou a jejich současné používání může způsobit potíže. Nicméně NetworkManager je stále v beta verzi, takže se dá očekávat zlepšení. Pokud jste velmi zatížení na bezpečnost a potřebujete mít firawall na 100% zapnutý od okamžiku, kdy zapnete počítač, je lepší NetworkManager nepoužívat. Mějte taky na paměti, že iptables a NetworkManager mají opačný účel - iptables síťovou komunikaci omezují, zatímco NetworkManager se jí snaží za každou senu udržet.

Máte tedy dvě řešení : Buď použijete /etc/network/interfaces a nebo se svěříte do rukou NetworkManager.

Automatické nastavení při startu pomocí /etc/network/

Máte na výběr opět dvě možnosti: Buď můžete začít provádět změny do /etc/network/interfaces, anebo přidat skript do /etc/network/if-pre-up.d/ a /etc/network/if-post-down.d/

Řešení #1 - /etc/network/interfaces

Úpravou konfiguračního souboru /etc/network/interfaces docílíte toho, že se nastavení iptables automaticky načte při startu systému. Budete potřebovat znát jméno síťového rozhraní, které používáte, aby jste k němu mohli napsat pravidla. Pokud jméno interfejsu neznáte, tak je to pravděpodobně eth0. Mžete si zkusit vylistovat vaše síťové interfejsy zadáním příkazu:

bfu@ubuntu:~$ iwconfig

Pokud dostanete výstup podobný tomuto:

lo        no wireless extensions.

eth0      no wireless extensions.

potom v systému nemáte žádnou bezdrátovou síťovou kartu, aproto bude nejlepší použít interfejs eth0.

Jelikož nyní již víte jaký interfejs použít, můžete otevřít soubor /etc/network/interfaces. Vyberte si svůj oblíbený editor. Musíte být přihlášený jako správce (root)

bfu@ubuntu:~$ nano /etc/network/interfaces

Pokud raději pracujete v grafickém prostředí Gnome zmáčkněte Alt+F2 a napište:

gksudo gedit /etc/network/interfaces

a zmáčkněte klávesu enter .

Pro práci v grafickém prostředí KDE zmáčkněte Alt+F2 a napište

kdesu kate /etc/network/interfaces

a zmáčkněte klávesu enter.

Na konec řádku, který se vztahuje k vašemu síťovému rozhraní napište :

pre-up iptables-restore < /etc/iptables.rules

Můžete mít také připravenou sadu pravidel, která se použije při vypínání iptables. Pravidla uložte do souboru /etc/iptables.downrules a na další řádek v souboru /etc/network/interfaces napište toto:

post-down iptables-restore < /etc/iptables.downrules

Nakonec bude vypadat soubor /etc/network/interfaces takto:

auto eth0
iface eth0 inet dhcp
  pre-up iptables-restore < /etc/iptables.rules
  post-down iptables-restore < /etc/iptables.downrules
Řečení #2 /etc/network/if-pre-up.d a /etc/network/if-post-down.d

Druhou možností je přidat iptables-restore a iptables-save do /etc/network/if-pre-up.d a /etc/network/if-post-down.d .

Do souboru /etc/network/if-pre-up.d/iptablesload napište následující řádky:

iptables-restore < /etc/iptables.rules
exit 0

A do souboru /etc/network/if-post-down.d/iptablessave napište :

iptables-save -c > /etc/iptables.rules
if [ -f /etc/iptables.downrules ]; then
   iptables-restore < /etc/iptables.downrules
fi
exit

Nakonec se ujistěte, že oba soubory mají povolenou spouštění:

bfu@ubuntu:~$ chmod +x /etc/network/if-post-down.d/iptablessave
bfu@ubuntu:~$ chmod +x /etc/network/if-pre-up.d/iptablesload

Pokun chcete navíc mezi restarty počítače zachovávat počítadla paketů, tak použijte pro uložení nastavení iptables program iptables-save s parametrem -c

iptables-save -c > /etc/iptables.rules

Automatické nastavení při startu pomocí NetworkManagera

NetworkManager ma v sobě zabudovanou schopnost spouštět skripty, když se zapíná i když se vypíná. K uložení a obnovení pravidle iptables při startu NetworkManagera vytvoříme právě takový skript. Otevřete si svůj oblíbený editor, třeba nano

bfu@ubuntu:~$ nano /etc/NetworkManager/dispatcher.d/01firewall

nebo v grafickém prostředí Gnome zmáčkněte Alt+F2 a napište:

gksudo gedit /etc/NetworkManager/dispatcher.d/01firewall

V KDE zmáčkněte Alt+F2 anapište:

kdesu kate /etc/NetworkManager/dispatcher.d/01firewall

Potom do souboru vložte následující:

if [ -x /usr/bin/logger ]; then
        LOGGER="/usr/bin/logger -s -p daemon.info -t FirewallHandler"
else
        LOGGER=echo
fi

case "$2" in
        up)
                if [ ! -r /etc/iptables.rules ]; then
                        ${LOGGER} "No iptables rules exist to restore."
                        return
                fi
                if [ ! -x /sbin/iptables-restore ]; then
                        ${LOGGER} "No program exists to restore iptables rules."
                        return
                fi
                ${LOGGER} "Restoring iptables rules"
                /sbin/iptables-restore -c < /etc/iptables.rules
                ;;
        down)
                if [ ! -x /sbin/iptables-save ]; then
                        ${LOGGER} "No program exists to save iptables rules."
                        return
                fi
                ${LOGGER} "Saving iptables rules."
                /sbin/iptables-save -c > /etc/iptables.rules
                ;;
        *)
                ;;
esac

Nakonec se musíme ujistit, že NeteorkManager je schopen náš skript spouštět. Toho docílíte zapsáním následujícího do terminálu.

bfu@ubuntu:~$ chmod +x /etc/NetworkManager/dispatcher.d/01firewall

Iptables pro pokročilé

Nastavení routrování

Jak nastavit NAT

Jak bezpečně nastavit firewall

Matching extensions