[[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.