[[oktatas:linux:tuzfal:netfilter:iptables|< iptables]] ====== iptables bevezetés ====== * **Szerző:** Sallai András * Copyright (c) Sallai András, 2020 * Licenc: [[https://creativecommons.org/licenses/by-sa/4.0/|CC Attribution-Share Alike 4.0 International]] * Web: https://szit.hu ===== Az iptables keretrendszer ===== Az iptables egy keretrendszer, amivel szabályokat vehetünk fel a Netfilter számára. ===== Az iptables láncai ===== Az iptables 5 beépített lánccal rendelkezik. Az 5 lánc a netfilter 5 kampójához kapcsolódik. ^ Beépített lánc neve ^ Kampó a kernelben ^ | PREROUTING | NF_IP_PRE_ROUTING | | INPUT | NF_IP_LOCAL_IN | | FORWARD | NF_IP_FORWARD | | OUTPUT | NF_IP_LOCAL_OUT | | POSTROUTING | NF_IP_POST_ROUTING | {{:oktatas:linux:tuzfal:netfilter:iptables:iptables_netfilter.png|}} ===== Az iptables parancs ===== Az iptables parancsot használjuk az iptables keretrendszer számára. A következő táblázat bemutatja, milyen parancsok állnak rendelkezésre, az iptables paranccsal együtt. | iptables | IPv4-s szabályok | | ip6tables | IPv6-s szabályok | | ebtables | | | arptables | | Az iptables kapcsolókkal dolgozik. Kapcsolókkal mondjuk meg: * melyik láncon szeretnék beállítást végezni * mi lesz a csomag célja Ezekkel együtt szükség van olyan kapcsolókra, amelyek megmondják milyen csomagokra illeszkedjen a szabály. * Milyen protokollra illeszkedjen a csomag (TCP, UDP, ICMP, ALL). * Milyen forrásportra illeszkedjen a csomag. * Milyen célportra illeszkedjen a csomag. * Milyen forrás IP címre illeszkedjen a csomag. * Milyen cél IP címre illeszkedjen a csomag. Valójában létezik egy tcp, udp icmp modul, amiket alapértelmezetten használhatunk. Ezeket a modulokat nem is kell megadnunk, hogy töltődjenek be, csak használjuk. Speciális illeszkedés állítható be még több modul használatával. * Megmondjuk milyen milyen modult akarunk használni. * Megmondjuk milyen plusz információkat tegyen a modul. ===== Láncok alapértelmezett irányelve ===== A láncok rendelkeznek egy alapértelmezett irányelvvel. Azok a csomagok, amelyek nem illeszkednek egyetlen szabályra sem, az alapértelmezett irány lesz érvényes. Az irányelv kétféle lehet: * ACCEPT * DROP Az alapértelmezetten irányelv, minden láncon ACCEPT. Ezt is az iptables paranccsal állíthatjuk. Tiltás beállítása az INPUT láncon: iptables -P INPUT DROP vagy: iptables --policy INPUT DROP Engedélyezés: iptables -P INPUT ACCEPT vagy: iptables --policy ACCEPT ===== Szabályok listája ===== A szabályok a láncokon listát alkotnak, és számozottak. A szabályok sorrendje nem mindegy, mivel a Netfilter a szabályokon sorban halad, és ha a csomag illeszkedik egy szabályra, akkor a további szabályok már mellőzve lesznek. Az alábbiakban egy szabálylista példát láthatunk: 1 ACCEPT all lo 2 ACCEPT tcp dpt:ssh 3 ACCEPT tcp dpt:smtp 4 ACCEPT udp spt:domain state ESTABLISHED 5 ACCEPT tcp spts:1024:65535 state ESTABLISHED 6 DROP all A szabályok listáját két módon állíthatjuk fel: Megengedő: * alapból mindent lehet, amit nem tiltunk Szigorú: * alapból minden tiltva, ami nincs engedve A biztonság érdekében, általában ez az utóbbi a kívánatos. ===== Szabályok beállítása ===== A szabályokat felvehetjük parancssorból, vagy írhatjuk scriptbe, esetleg rábízhatjuk a rendszerre a betöltést. A szabályokat mindig egy láncra állítjuk be. A szabályok vége engedés, tiltás, egyéb. Az elsőnek felvett szabály az 1-s helyre kerül. A másodiknak felvett szabáls a 2-s helyre, stb. Minden bejövő csomag tiltása: iptables -A INPUT -j DROP Ilyen beállítást nem szokás első helyre tenni, de kezdhetünk ezzel ismerkedni. Szigorúbb szabályozás esetén, a mindent tiltó szabály mehet a lista végére, az alapértelmezett irányelv helyett. Kísérletezzünk. Készítsünk két virtuális gépet. Legyen kliens és egy szerver gép. Állítsunk be mindkét gép számára IP címet a 192.168.10.0/24 tartományból. Például: {{:oktatas:linux:tuzfal:netfilter:ketgep.png|}} A kliensről vizsgáljuk meg a kapcsolatot a szerver irányába. Használjuk a ping parancsot: ping 192.168.10.2 Most a szerveren adjuk ki az alábbi parancsot: iptables -A INPUT -j DROP Most végezzük el újra a kliensről a kapcsolat vizsgálatát. ping 192.168.10.2 Az ECHO REPLY csomagok nem érkeznek vissza. Végül töröljük szabályt: iptables -D INPUT -j DROP Teszteljünk újra: ping 192.168.10.2 ===== SSH engedélyezése ===== Töröljük a szabályokat, ha még vannak, ehhez használhatjuk a -F kapcsolót: iptables -F Ez törli a filter táblához kapcsolódó láncok összes szabályát. A további vizsgálatok érdekében, telepítsünk egy SSH szolgáltatást a szervergépre: apt install ssh A kliens gépre telepítsünk telnet klienst: apt install telnet Természetesen, használhatunk SSH klienst is. A telnet kliens, most azért elég nekünk, mert csak azt szeretnénk megnézni, kapcsolódik-e a szolgáltatáshoz. Teszteljük a kapcsolatot a kliensen a telnet paranccsal: telnet 192.168.10.2 22 A kapcsolat kiépül, a kimenet ehhez hasonló lehet: $ telnet 192.168.5.102 22 Trying 192.168.5.102... Connected to 192.168.5.102. Escape character is '^]'. SSH-2.0-OpenSSH_7.9p1 Debian-10+deb10u2 Láthatjuk az SSH szerver beengedte a telnet klienst és vár a kommunikáció folytatására. A kapcsolatot a quit paranccsal, vagy a ^] karakterpáros beírásával szakíthatjuk meg. Állítsuk vissza a tiltást, majd próbálkozzunk újra: iptables -A INPUT -j DROP Ha sikeresen beállítottuk a teljes tiltás, akkor ehhez hasonlót látunk kliensoldalon teszteléskor: $ telnet 192.168.5.102 22 Trying 192.168.5.102... telnet: Unable to connect to remote host: Connection refused A kapcsolódás sikertelen. Most engedélyezzük a befelé jövő SSH protokollt a szerveren. Használjuk az iptables parancsot. A -A kapcsoló a szabályokat mindig a szabálylista végére fűzi. Nekünk viszont a mindent tiltó utasítás előtt kell beszúrni a megengedő parancsot. Ehhez használjuk a -I kapcsolót. A kapcsoló segítségével beszúrhatunk egy utasítást az első helyre: iptables -I INPUT 1 -p tcp --dport 22 -j ACCEPT A beszúrás helyett, azt is megtehetjük, hogy törölünk mindent tiltó szabályt, majd újra kezdjük. Előbb kiadjuk a -A kapcsolóval a 22 portot beengedő szabályt, ás utána vissza tesszük a végén a mindent tiltó szabályt. Ellenőrizzük az INPUT láncot: iptables -L INPUT Kiíratható a szabályok sorszáma is: iptables -L INPUT --line-numbers A -p tcp --dport22 összetartozó kapcsolók, valójában a tcp modul részei. A tcp modult, azonban nem kell betölteni, mert alapból be van töltve az udp és icmp csomagokhoz hasonlóan. Modul betöltése így is megadható, csak szükségtelen: iptables -I INPUT 1 -m tcp -p tcp --dport 22 -j ACCEPT Ebből következik, portot úgy adhatunk meg, ha megadjuk milyen szállítási protokollhoz tartozik. ===== Levelezőszerver ===== Ha vannak beállítva tűzfal szabályok, ürítsük ki a láncokat: iptables -F Telepítsünk levelezőszervert: apt install postfix A feltett kérdésekre csak nyomjunk Entert-t. Állítsuk vissza az előző részekben, már tanult két szabályt: iptables -A INPUT -p tcp --dport 22 -j ACCEPT iptables -A INPUT -j DROP Listázzuk az INPUT lánc számára beállított szabályokat. iptables -L INPUT --line-numbers Ehhez hasonlót láthatunk: # iptables -L INPUT --line-numbers Chain INPUT (policy ACCEPT) num target prot opt source destination 1 ACCEPT tcp -- anywhere anywhere tcp dpt:ssh 2 DROP all -- anywhere anywhere Most szúrjuk be a második helyre a levelezőszerver engedélyezését: iptables -I INPUT 2 -p tcp --dport 25 -j ACCEPT Nézzük meg az INPUT lánc szabálylistáit: # iptables -L INPUT --line-numbers Chain INPUT (policy ACCEPT) num target prot opt source destination 1 ACCEPT tcp -- anywhere anywhere tcp dpt:ssh 2 ACCEPT tcp -- anywhere anywhere tcp dpt:smtp 3 DROP all -- anywhere anywhere A kliens oldalon ellenőrizzük elérhető-e a levelezőszerver: telnet 192.168.10.2 25 ===== Visszatérő csomagok ===== Az eddigi részekben a kliensről indított kapcsolatokat szabályoztuk. Most foglalkozzunk azokkal a csomagokkal, amelyek befele jönnek, de a szerverről kezdeményezett kapcsolatok. Ilyen lehet ha telepíteni szeretnénk a szerverre, ez általában HTTP protokollon keresztül történik. Ha nincs beállítva, vegyük fel az INPUT láncra a következő szabályokat: iptables -A INPUT -p tcp --dport 22 -j ACCEPT iptables -A INPUT -p tcp --dport 25 -j ACCEPT iptables -A INPUT -j DROP Ellenőrizzük: iptables -L INPUT Ha most szeretnénk telepíteni két okból sem megy. A DNS kérések nem képesek visszatérni a DNS szerverektől, és maga a HTTP forgalom sem képes visszatérni. Engedélyezzük a visszatérő DNS forgalmat és a HTTP forgalmat: iptables -I INPUT 3 -p udp --sport 53 -j ACCEPT iptables -I INPUT 4 -p tcp --sport 80 -j ACCEPT Ellenőrizzük: iptables -L INPUT --line-numbers Most próbáljuk ki a telepítést: apt install telnet ===== Szabályok törlése ===== Egy szabály törölhető a -D kapcsolóval. Mellette adjuk meg az összes többi kapcsolót. iptables -D INPUT -j DROP A -D kapcsoló mellett megadható a szabály száma is. Töröljük, például a 2-s szabályt: iptables -D INPUT 2 Ekkor a többi kapcsoló megadása szükségtelen. Az összes szabályt törölhetjük egyetlen utasítással: iptables -F INPUT Ellenőrizzük: iptables -L INPUT Ha nem adunk meg láncot, az összes filter láncra vonatkozik a beállítás: iptables -F ===== Lokális csomagok ===== A szerveren lehetnek olyan folyamatok, amelyek más folyamatokkal localhoston kommunikálnak. Ezeket indokolatlan tiltani, így engedjük korlátozás nélkül. Tehetjük az első helyre: iptables -I INPUT 1 -i lo -j ACCEPT A -i kapcsolóval a hálózati eszközre hivatkozunk, azon belül a befelé tartó forgalomra. A szabálylista elején jó helyen van, ezért az 1-s helyre szúrtuk be. ===== Script írása ===== A scripbe az alábbi sorrendben írhatjuk a szabályokat: * minden meglévő szabályt törlünk * minden irányelvet elfogadásra állítunk * helyi (locahost) forgalom engedélyezése * bejövő forgalom engedése * visszatérő forgalom engedése * minden más tiltása #!/bin/bash # Töröljük az összes szabályt: iptables -F # Alapértelmezett irányelve az elfogadás: iptables -P INPUT ACCEPT # Lokálisan minden mehet: iptables -A INPUT -s 127.0.0.1 -d 127.0.0.1 -j ACCEPT # Befelé jöhet az SSH kapcsolat: iptables -A INPUT -t tcp --dport 22 -j ACCEPT # Befelé jöhet az SMTP kapcsolat: iptables -A INPUT -t tcp --dport 25 -j ACCEPT # Jöhetnek a visszatérő DNS válaszok: iptables -A INPUT -t udp --sport 53 -j ACCEPT # Jöhetnek a visszatérő HTTP válaszok: iptables -A INPUT -t tcp --sport 80 -j ACCEPT # Ami eddig nem jutott át, azt eldobjuk: iptables -A INPUT -j DROP A tűzfalat kikapcsoló script: #!/bin/bash iptables -F iptables -P INPUT ACCEPT ===== Állapotfigyelés ===== A visszatérő csomagok felfedezhetők a state modullal. A state modul a -m kapcsolóval tölthető be. A --state kapcsolóval megadhatjuk milyen állapotú csomagokat szeretnénk figyelni. Lehetséges állapotok: * NEW - kapcsolatteremtő csomag * ESTABLISHED - létező kapcsolathoz tartozik * RELATED - létező kapcsolathoz tartozik, de nem része * INVALID - nem azonosítható csomag; általában eldobandó iptables -A INPUT -m state --state ESTABLISHED -p tcp --dport 80 -j ACCEPT DNS engedése: iptables -A INPUT -m state --state ESTABLISHED -p udp --dport 53 -j ACCEPT Ezt követően, írjuk át a firewall.sh visszatérő csomagjaira vonatkozó részt. #!/bin/bash echo "Szabályok betöltése..." # Töröljük az összes szabályt: iptables -F # Alapértelmezett irányelve az elfogadás: iptables -P INPUT ACCEPT # Lokálisan minden mehet: iptables -A INPUT -s 127.0.0.1 -d 127.0.0.1 -j ACCEPT # Befelé jöhet az SSH kapcsolat: iptables -A INPUT -p tcp --dport 22 -j ACCEPT # Befelé jöhet az SMTP kapcsolat: iptables -A INPUT -p tcp --dport 25 -j ACCEPT # Jöhetnek a visszatérő DNS válaszok: iptables -A INPUT -m state --state ESTABLISHED -p udp --sport 53 -j ACCEPT # Jöhetnek a visszatérő HTTP válaszok: iptables -A INPUT -m state --state ESTABLISHED -p tcp --sport 80 -j ACCEPT # Ami eddig nem jutott át, azt eldobjuk: iptables -A INPUT -j DROP echo "A szabályok betöltve" ===== Tartós tárolás ===== A csomagszűrő szabályok az iptables parancs kiadásakor a memóriában vannak. Ha parancsfájlba írtuk a parancsokat az rendszerindításkor nem fut le, vagyis a tűzfalunk nem indul el. Rendszerindításkor a betöltésről gondoskodni kell. Szükségünk van az iptables-persistent, és a netfilter-persistent csomagokra. Elég, ha telepítjük az elsőt, az függőségként felteszi a netfilter-persistent csomagot. Telepítés: apt install iptables-persistent A telepítő rákérdez, hogy mentsük-e a memóriában lévő szabályokat. Ha be vannak töltve menthetjük, de ez a művelet később bármikor elvégezhető. Az iptables-persistent a szabályokat a következő két fájlba menti: * /etc/iptables/rules.v4 * /etc/iptables/rules.v6 A netfilter-persistent, ami szintén telepítésre kerül, feltesz egy systemd szolgáltatást, amelyet így kezelhetünk: systectl status netfilter-persistent systectl stop netfilter-persistent systectl start netfilter-persistent systectl enable netfilter-persistent systectl disable netfilter-persistent Ha egyszer mentettük a beállításainkat a rendszerindításkor a netfilter-persistent automatikusan betölti. ==== Mentés ==== Ha változtattunk a szabályokon, akkor mentsük el: iptables-save > /etc/iptables/rules.v4 ip6tables-save > /etc/iptables/rules.v6 Az IPv6-s címeket külön kell mentenünk. A szabályok szerkeszthetők a rules.v4 és rules.v6 fájlban is.