< iptables

iptables bevezetés

Szerző: Sallai András

Copyright © Sallai András, 2020

Licenc: 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

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:

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.