==== iptables ==== {{page>konvence/pokročilý}} {{:locale.png}} Toto je překlad stránky [[https://help.ubuntu.com/community/IptablesHowTo|Iptables HowTo]] na oficiální [[https://help.ubuntu.com/community|komunitní dokumentaci]] Ubuntu ovšem v mnoha případech jsem se neubránil potřebě [[https://help.ubuntu.com/community/IptablesHowTo?action=info|původního autora]] doplnit o své vlastní zkušenosti a něco překladu z [[man]] stránky. {{ :documentation.png}} 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 [[http://netfilter.org/documentation/HOWTO/packet-filtering-HOWTO.html|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 [[bezpečnost/firewall|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 ([[http://cs.wikipedia.org/wiki/NAT|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ů. {{ :tux.png}} **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|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 [[Apache s MySQL a PHP|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 ==== {{:terminal.png}} Když napíšete do [[:terminál|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 [[http://cs.wikipedia.org/wiki/TCP|tcp]] portu 25 poslouchá poštovní server a na [[http://cs.wikipedia.org/wiki/TCP|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 [[http://cs.wikipedia.org/wiki/Spam|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ů **'[[http://cs.wikipedia.org/wiki/TCP|tcp]]**', **'[[http://cs.wikipedia.org/wiki/UDP|udp]]**', **'udplite**', **'[[http://cs.wikipedia.org/wiki/ICMP|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 [[http://cs.wikipedia.org/wiki/ICMP|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 [[Základní příkazy#"Man" a získávání pomoci|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 [[http://cs.wikipedia.org/wiki/ICMP|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á [[http://cs.wikipedia.org/wiki/ICMP|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 [[http://cs.wikipedia.org/wiki/ICMP|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 [[http://cs.wikipedia.org/wiki/File_Transfer_Protocol|FTP]] , nebo nějaká [[http://cs.wikipedia.org/wiki/ICMP|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 [[Iptables#Základní příkazy|Základní příkazy]]a 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 [[http://en.wikipedia.org/wiki/Virtual_private_server|VPS]] které používá [[http://en.wikipedia.org/wiki/OpenVZ|OpenVZ]] , nebo nemáte nainstalované nějaké jaderné moduly. Můžete vyzkoušet zapsat pravidlo takto: {{ :faq.png}} 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 [[iptables#Ukládání nastavení iptables|Ukládání nastavení iptables]] K povolení [[:SSH|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 {{.:info.png}} 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 [[http://cs.wikipedia.org/wiki/TCP|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 [[syslog|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 ==== {{.:important.png}} Pozor, zdá se že ''iptables'' a [[:Sdílení internetového připojení|NetworkManager]] mají jiste nesrovnalosti mezi sebou a jejich současné používání může způsobit potíže. Nicméně [[:Sdílení internetového připojení|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ší [[:Sdílení internetového připojení|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 [[:Sdílení internetového připojení|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 == {{ :ethernet.png}} Ú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]]) {{ :terminal.png}} bfu@ubuntu:~$ nano /etc/network/interfaces Pokud raději pracujete v grafickém prostředí Gnome zmáčkněte **Alt+F2** a napište: {{ :editor.png}} 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 ===