Csomagszűrés
Célom az ebben a fejezetben bemutatott beállításokkal, hogy a belső hálózatból csak a meghatározott forgalom juthasson ki az Internetre. De nem csak a forgalom ,,milyensége'' legyen korlátozva, hanem az is, hogy mely gépek érhetik el egyáltalán a belső hálózaton kívüli gépeket. Valamint az, hogy a VPN-en kapcsolódó felhasználók csak a számukra engedélyezett szolgáltatásokat tudják használni. Nagyon hasznos, alapos és jó (bár angol nyelvű) olvasmány a csomagszűrés témában: [4], amely többféle formátumban is letölthető az oldalról.
Egy szkriptben készítettem el a csomagszűrőnk beállításait, hogy
egyszerűen használhassak változóneveket is. Viszont semmi sem
akadályoz meg bennünket abban, hogy ha egyszer betöltöttük a
szabályainkat, akkor az iptables-save parancs segítségével
kimentsük azokat egy fájlba, és a rendszer indulásakor az
iptables-restore parancs segítségével abból a fájlból
töltsük őket vissza.
Önkényesen választott elnevezéseket használok a saját láncok
neveként, illetve a változók neveiként, de bízom benne, hogy
érthető. A feltételezés az, hogy a tűzfal egy dhcp szervertől
kapja az IP címét, amely dinamikusan változik, tehát nem fix a
cím.15.3 Ha ftp elérést is szeretnénk a
tűzfalon keresztül engedélyezni, akkor javasolt a megfelelő
kernelmodulok betöltése (a 2.6-os sorozatnál az
ip_conntrack_ftp és az ip_nat_ftp modulok). Az
alábbi szkriptet a magyarázatok feldarabolták, de egyetlen fájlba
kell beírnunk!
A később használt változókat definiáltam a szkript elején.
#!/bin/sh BelsoInterface=eth1 KulsoInterface=eth0 KulsoIPCim=a.tuzfal.kulso.cime BELSO_PROXY=192.168.10.251 BELSO_MAIL=192.168.10.252 BELSO_SLAVEDNS=192.168.10.252 BELSO_DNS=192.168.10.253 BELSO_NTP=192.168.10.253 BELSO_WEB=192.168.10.247 ADMIN=192.168.10.10 VPN1NET=10.10.1.0
Itt az látható, hogy először kitöröljük a jelenlegi szabályokat a filter és nat táblákat, majd töröljük az általunk létrehozott láncokat. Ezekre a sorokra azért van szükség, hogy ha újra lefuttatjuk ezt a szkriptet, akkor nulláról jöjjenek létre a szabályaink, ne maradhasson bent régi szabály. A szkript első futtatásakor emiatt hibaüzenet fogunk kapni, mely szerint nem léteznek a törölni kívánt láncok, de ez természetes, hiszen valóban nem léteznek, a törlés után fogjuk őket létrehozni.
iptables -t nat -F iptables -t filter -F iptables -X icmpk iptables -X belso iptables -X kulso iptables -X DROPINVALID
Ezen sorok segítségével beállítjuk a filter és nat táblák alapértelmezett szabályait.
iptables -t filter -P INPUT DROP iptables -t filter -P FORWARD DROP iptables -t filter -P OUTPUT ACCEPT iptables -t nat -P PREROUTING ACCEPT iptables -t nat -P POSTROUTING ACCEPT iptables -t nat -P OUTPUT ACCEPT
Annak biztosítása, hogy a belső hálózat proxy-jától érkező csomagok úgy jussanak ki az Internetre, hogy a tűzfal címével látszódjanak. Megtehetjük, hogy ezt a szabályt úgy írjuk meg, hogy csak megadott portokra menő csomagokra legyen érvényes, de a FORWARD láncban is szabályozhatjuk, hogy mit engedünk át magunkon. Most ez utóbbit mutatom be.15.3
iptables -t nat -A POSTROUTING -s $BELSO_PROXY -o eth0 -j MASQUERADE #iptables -t nat -A POSTROUTING -s $BELSO_PROXY -o eth0 -j SNAT --to-source $KulsoIPCim
Az alábbi két szabály a tűzfal két megadott külső portjára érkező kapcsolatokat berakja a belső hálózat megadott gépeire. Ne felejtsük, hogy a FORWARD lánc erre vonatkozó szabályai is szükségesek ahhoz, hogy a belső gépeink a megadott portokon valóban elérhetőek legyenek a külvilág számára!
iptables -t nat -A PREROUTING -i $KulsoInterface -p tcp --dport 80 -j DNAT --to-destination $BELSO_WEB:80 iptables -t nat -A PREROUTING -i $KulsoInterface -p tcp --dport 993 -j DNAT --to-destination $BELSO_MAIL:993
A saját láncaink létrehozása.
iptables -N icmpk iptables -N belso iptables -N kulso iptables -N DROPINVALID
Az első szabály azt biztosítja, hogy a loopback interfészen
minden forgalom lehetséges legyen. A második szabály a tűzfalra
érkező ICMP csomagok sorsáról rendelkezik (betereli őket
az icmpk néven létrehozott saját láncunkba). A harmadik
szabály az iptables állapottartó lehetőségét használja ki.
Ily módon arról ,,értesítettük'' a kernelünket, hogy a már
kiépült kapcsolatokhoz tartozó csomagokat engedélyezze. A
negyedik szabály a DROPINVALID nevű saját láncunkba tereli
a kernel által INVALID állapotúnak érzékelt csomagokat. Az
utolsó sor szintén a DROPINVALID láncba küldi a
csomagokat, de csak azokat, amelyek NEW állapotúak ugyan, de
nincs bekapcsolva bennük a SYN bit.
iptables -A INPUT -i lo -j ACCEPT iptables -A INPUT -p icmp -j icmpk iptables -A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT iptables -A INPUT -m state --state INVALID -j DROPINVALID iptables -A INPUT -p tcp -m state --state NEW ! --syn -j DROPINVALID
A forgalom átirányítása a saját láncainkra attól függően, hogy a tűzfal melyik hálózati kártyáján érkezik.
iptables -A INPUT -i $BelsoInterface -j belso iptables -A INPUT -i $KulsoInterface -j kulso
Azt a forgalmat, amely a szabályainkon kívül esik, azt logoljuk, majd eldobjuk.
iptables -A INPUT -j LOG --log-prefix "INPUT DROP: " iptables -A INPUT -j DROP
Az első szabály ismerős lehet, hiszen az INPUT láncban már kiadtunk egy hasonlót. Itt is ugyanaz a feladata, mint ott. A második, harmadik és negyedik szabállyal azt állítjuk be, hogy a belső hálózaton lévő proxyszerverünk az általában használatos portokra (ftp - 21, http - 80, https - 443) kimehessen (és persze rajta keresztül a proxy-n engedélyezett egyéb belső gépek is). Az utolsó két sor a külvilág számára teszi lehetővé a két megadott belső gépünk megfelelő portjának az elérését. Ne felejtsük, hogy ezek a szabályok összefüggésben állnak a PREROUTING láncban meghatározott DNAT szabályokkal!
iptables -A FORWARD -p tcp -m state --state ESTABLISHED,RELATED -j ACCEPT iptables -A FORWARD -p tcp -m state --state NEW --syn -s $BELSO_PROXY --dport 21 -j ACCEPT iptables -A FORWARD -p tcp -m state --state NEW --syn -s $BELSO_PROXY --dport 80 -j ACCEPT iptables -A FORWARD -p tcp -m state --state NEW --syn -s $BELSO_PROXY --dport 443 -j ACCEPT iptables -A FORWARD -p tcp -m state --state NEW --syn -d $BELSO_WEB --dport 80 -j ACCEPT iptables -A FORWARD -p tcp -m state --state NEW --syn -d $BELSO_MAIL --dport 993 -j ACCEPT
Itt szabályozzuk a 10.10.1.0/24-es VPN hálózatunkból érkező kapcsolatokat. Az első szabály a névfeloldást végző belső szerverünk elérését engedélyezi UDP protokollon, a második szabály pedig minden belső hálózaton lévő gép elérését lehetővé teszi TCP protokollon keresztül.
iptables -A FORWARD -p udp -m state --state NEW --syn -s VPN1NET -d $BELSO_DNS --dport 53 -j ACCEPT iptables -A FORWARD -p tcp -m state --state NEW --syn -s VPN1NET -j ACCEPT
Azt a forgalmat, amely a szabályainkon kívül esik, azt logoljuk, majd eldobjuk.
iptables -A FORWARD -j LOG --log-prefix "FORWARD DROP: " iptables -A FORWARD -j DROP
Azokat az ICMP típusokat soroltam fel itt, amelyek eljuthatnak a tűzfalhoz. Ezeket általában érdemes engedélyezni, bár a ping-ről megoszlanak a vélemények.
iptables -A icmpk -p icmp --icmp-type destination-unreachable -j ACCEPT iptables -A icmpk -p icmp --icmp-type time-exceeded -j ACCEPT iptables -A icmpk -p icmp --icmp-type parameter-problem -j ACCEPT iptables -A icmpk -p icmp --icmp-type source-quench -j ACCEPT iptables -A icmpk -p icmp --icmp-type echo-request -j ACCEPT iptables -A icmpk -p icmp --icmp-type echo-reply -j ACCEPT
Azt a forgalmat, amely a szabályainkon kívül esik, azt logoljuk, majd eldobjuk.
iptables -A icmpk -j LOG --log-prefix "Icmpk DROP: " iptables -A icmpk -j DROP
Korlátozzuk, hogy a belső hálózatból mely gépek a tűzfal melyik
portját érhetik el. Így érvényesítjük azt az
elvet15.4, hogy a tűzfallal a
munkaállomások nem léphetnek közvetlen kapcsolatba, csak
valamelyik belső szerveren keresztül csinálhatnak bármit is
(levelet csak a belső mailszerver küldhet a tűzfalnak,
névfeloldásért csak a két dns szerver fordulhat a tűzfalhoz, a
tűzfal időszolgáltatását csak a belső ntp szerver veheti igénybe,
és csak az adminisztrátor gépéről lehet elérni a tűzfalat
ssh-val).
iptables -A belso -p tcp -s $BELSO_MAIL --dport 25 -j ACCEPT iptables -A belso -p udp -s $BELSO_DNS --dport 53 -j ACCEPT iptables -A belso -p tcp -s $BELSO_DNS --dport 53 -j ACCEPT iptables -A belso -p udp -s $BELSO_SLAVEDNS --dport 53 -j ACCEPT iptables -A belso -p tcp -s $BELSO_SLAVEDNS --dport 53 -j ACCEPT iptables -A belso -p udp -s $BELSO_NTP --dport 123 -j ACCEPT iptables -A belso -p tcp -s $ADMIN --dport 22 -j ACCEPT
Azt a forgalmat, amely a szabályainkon kívül esik, azt logoljuk, majd eldobjuk.
iptables -A belso -j LOG --log-prefix "belso DROP: " iptables -A belso -j DROP
A külső portjaink elérésére vonatkozó szabályok. Az első a
dinamikus IP cím miatt van, a második azért, hogy tudjanak nekünk
levelet küldeni. A harmadik pedig azért, mert egyes
levelezőszerverek megpróbálják elérni az identd démont,
hogy információhoz jussanak a levelet küldőről, és amíg ez nem
sikerül nekik (vagy az erre szánt idő le nem jár), addig nem
veszik el tőlünk a levelet. A REJECT szabálynak
köszönhetően azonnal elutasító választ kap a kérdező, így nem
kell az időtúllépést megvárnunk, gyorsabb lesz a levél elküldése.
iptables -A kulso -p udp --sport 67 --dport 68 -j ACCEPT iptables -A kulso -p tcp --dport 25 -j ACCEPT iptables -A kulso -p tcp --dport 113 -j REJECT
Azt a forgalmat, amely a szabályainkon kívül esik, azt logoljuk, majd eldobjuk.
iptables -A kulso -j LOG --log-prefix "kulso DROP: " iptables -A kulso -j DROP
Az összes érvénytelen csomagot logoljuk, majd eldobjuk.
iptables -A DROPINVALID -j LOG --log-prefix "INVALID packet: " iptables -A DROPINVALID -j DROP
Kosa Attila
2009-03-23