iptables
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ů.
- 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…
- 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.
- 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