Om het zin van connection tracking te verduidelijken zullen we eerst de
beperkingen van traditionele packetfilters (zoals ook ipfwadm en ipchains)
toelichten. Hierbij wordt enige achtergrond kennis van
TCP/IP verondersteld.
application layer firewall's, of proxy based firewall's
Packet filtering firewall's, kortweg packet filters, zijn feitelijk routers
met een additionele filter voorziening. Alleen de netwerkpakketjes die
aan bepaalde kenmerken voldoen worden gerouteerd. Een bekend voorbeeld
is de ACL's op Cisco routers. Maar ook Linux ipfwadm en ipchains zijn
packet filters.
Bij een proxy based firewall is er geen verkeer door de firewall
mogelijk. Client applicaties maken contact met een proxy server op de
firewall en deze proxy server maakt vervolgens namens de client applicatie
contact met de uiteindelijke server. Een bekend voorbeeld van een proxy
server is de Squid proxy, maar ook Sendmail kan als een proxy beschouwd
worden. Een typische application layer firewall is de Gauntlet van TIS
De algemene opvatting is dat een proxy based firewall een betere
bescherming kan bieden aan het achterliggende netwerk dan een
packetfilter. De proxy based firewall zelf is echter kwetsbaarder
doordat vanaf de buitenwereld direct contact gemaakt kan worden met
processen op de firewall. Om deze reden wordt een proxy based firewall
zelf dikwijls beschermd door packetfilters.
Packet filtering firewall's zijn transparant en vergen weinig resources.
Ze worden echter vaak weer uitgebreid met enkele proxy servers om extra
beveiliging en/of extra functionaliteit te bieden.
De techniek van statefull inspection, of connection tracking, is bedoeld
om de kloof tussen packetfilters en proxy servers te verkleinen.
Strikt genomen is een statefull filter een verbeterd packetfilter.
De bedoeling is het beveiligingsniveau van proxyservers te combineren
met de transparantie en performance van packetfilters.
Wat is er mis met traditionele packetfilters
In de meeste situaties willen we dat een firewall toestaat dan connecties
worden aangegaan vanaf het beveiligde netwerk naar buiten, maar niet
andersom. We moeten dus de `richting' van een connectie weten en alleen
verkeer toestaan dat behoort tot een connectie die van `binnen' naar
`buiten' is opgebouwd.
Bij
TCP-verkeer kunnen wij dat realiseren door onderscheid te maken tussen
het eerste packet van een connectie en alle vervolg pakketten. Het
eerste pakket is herkenbaar doordat de SYN-vlag gezet is maar de
ACK-vlag niet. Daarnaast kunnen we gebruik maken van de eigenschap dat
het clientproces in de regel een poortnummer groter dan 1023 gebruikt,
terwijl het serverproces luistert naar een bekend laag poortnummer.
Voor het gebruik van HTTP moet de firewall toestaan dat er verkeer
plaatsvindt van hoge poortnummers op ons eigen netwerk naar poort 80 op
ieder willekeurig adres in het Internet. Tevens is verkeer toegestaan
van poort 80 van ieder willekeurig adres naar hoge poortnummers op
ons eigen netwerk, mits dit verkeer is dat de kenmerken heeft van een
bestaande connectie. Dit laatste aspect wordt beoordeeld aan de hand
van het aanwezig zijn van een SYN-vlag.
Bij
UDP zijn er geen SYN- en ACK-vlaggen en kunnen we alleen de
poortnummers gebruiken om te beoordelen wat de richting is van de
connectie (voor zover je bij UDP van een connectie kunt spreken). In de
praktijk beperkt het gebruik van UDP op het Internet zich tot DNS.
Het probleem bij deze vorm van filteren is dat er alleen gekeken wordt naar de uiterlijke kenmerken
van de netwerkpakketjes. De pakketjes worden in feite vertrouwd op
hun `mooie blauwe ogen'. Het zal geen verbazing wekken dat er veel trucks
bedacht zijn om pakketjes te genereren die de
kenmerken hebben van een bestaande connectie. Deze pakketjes worden zonder
meer doorgelaten door het packetfilter. Een buitenstaander kan zo met
behulp van
een scanningtool als inmap een aardig beeld van ons interne netwerk krijgen.
Ook zijn DoS aanvallen mogelijk, of kan geprobeerd worden UDP
connecties aan te gaan door gebruik te maken van poort 53 (DNS).
Met FTP wordt het nog wat gevaarlijker. Hier speelt het probleem dat de
dataconnectie van `buiten' naar `binnen' wordt opgebouwd. Dit betekent
dat de firewall moet toestaan dat er connecties vanaf het Internet worden
opgebouwd, mits dit vanaf poort 20 gebeurt. Het ligt dus voor de hand
dat er tools in omloop zijn die juist poort 20 gebruiken om het netwerk
af te tasten op zoek naar services die toevallig op een hoog poortnummer
draaien. Bij een slecht geconfigureerd packetfilter zijn ook services op
de lage poortnummers toegankelijk voor deze tools. We kunnen dit manco
ondervangen door alleen passive FTP toe te staan, maar niet iedere
FTP-server ondersteunt dit.
De voordelen van connection tracking
Bij connection tracking wordt niet alleen naar de uiterlijke kenmerken
van pakketjes gekeken, maar wordt bij ieder pakketje daadwerkelijk
gecontroleerd of het behoort tot een geregistreerde connectie. Hiertoe
wordt van iedere connectie, mits deze is toegestaan, de status bijgehouden
in een zogenaamde connection table. De connections table is terug te
vinden in /proc/net/ip_conntrack
Van pakketjes die deel lijken uit te maken van een bestaande connectie
maar waarvan geen bijbehorende connectie in de connections
table kan worden gevonden, mag worden aangenomen dat deze met kwade
bedoelingen ons netwerk wil bereiken. Het verdient aanbeveling dit te loggen.
Met connection tracking kan niet alleen gecontroleerd worden of verkeer
deel uitmaakt van een bestaande connectie, maar ook of verkeer verband
houdt met een andere bestaande connectie. Op deze wijze kan
gecontroleerd worden of een aangevraagde FTP dataconnectie hoort bij een
geldige FTP controll connectie en, indien dit het geval is, toestaan.
Zo kan ook gecontroleerd worden of bepaalde ICMP messages verband houden met
bestaande of aangevraagde TCP of UDP connecties.
Toepassing van connection tracking
De filterchains worden onderhouden met het commando iptables. Voor het
filteren zijn drie chains van belang, INPUT, OUTPUT en FORWARD. INPUT
en OUTPUT worden gebruikt voor verkeer van en naar het locale systeem,
de FORWARD chain wordt gebruikt voor verkeer dat gerouteerd wordt. Dit
verkeer gaat, in tegenstelling tot bij ipchains, niet door de INPUT of
OUTPUT chain.
Het -state statement wordt gebruikt om aan te geven
dat de status gecontroleerd moet worden. De opties NEW en ESTABLISHED
duiden hierbij op nieuwe en bestaande connecties. Met RELATED worden
connecties aangeduid die verband houden met, maar geen deel uitmaken
van, bestaande connecties. Hiermee kunnen FTP data connecties en ICMP
error messages aangeduid worden. INVALID geeft aan dat er geen geldige
bijbehorende connectie gevonden kan worden.
We geven hieronder enkele configuratie voorbeelden. Opgemerkt moet worden
dat de gebruikte iptables statements te algemeen zijn om zonder meer in
een echte firewall toe te passen.
TCP
Stel we hebben een firewall met eth0 als externe interface. We gebruiken
de volgende statements:
iptables -A FORWARD -p tcp -m state --state ESTABLISHED -j ACCEPT
iptables -A FORWARD -p tcp -m state --state NEW -i ! eth0 -j ACCEPT
Wanneer een connectie wordt opgebouwd zal een match plaatsvinden op
de tweede regel met het NEW statement. Er wordt nu een regel in de
connections table aangemaakt. De status van de connectie is SYN_SENT
met het kenmerk UNREPLIED. Wanneer de andere partij antwoordt met
een SYN en een ACK zal het kenmerk UNREPLIED vervallen en krijgt
de connectie de status SYN_RECV. Wanneer de client het antwoord van de
server bevestigt met een ACK zal de status van de connectie wijzigen
in ESTABLISHED, met als kenmerk ASSURED.
Strikt genomen heeft de status van de connectie geen invloed op
het al dan niet doorlaten van pakketjes. We filteren immers op NEW,
ESTABLISHED, RELATED of INVALID. ESTABLISHED betekent in dit niets anders
dan geval "er is een corresponderende entry in de connections table".
De geregistreerde status heeft alleen betrekking op de time-out. Deze is
standaard twee minuten voor SYN_SENT, één minuut voor SUN_RECV en vijf
dagen voor ESTABLISHED.
UDP
Omdat het UDP protocol zelf geen status kent zal moeten worden uitgegaan
van een veronderstelde status.
We gebruiken vergelijkbare statements als hierboven bij het TCP voorbeeld:
iptables -A FORWARD -p udp -m state --state ESTABLISHED -j ACCEPT
iptables -A FORWARD -p udp -m state --state NEW -i ! eth0 -j ACCEPT
Na een eerste pakket wordt een entry aangemaakt met als kenmerk
UNREPLIED. Deze entry heeft een time-out van 30 seconden. Wanneer binnen
30 seconden een antwoord komt verdwijnt het kenmerk UNREPLIED en wordt
de time-out weer teruggezet op 30 seconden. Wordt het verkeer gecontinueerd
dan krijgt de entry het kenmerk ASSURED en gaat de time-out naar 180
seconden. Wanneer er enige tijd geen verkeer meer plaatsvindt wordt er
van uitgegaan dat de bovenliggende applicatie klaar is en zal de entry
geruisloos verdwijnen.
FTP
Voor active FTP kunnen we gebruik maken van de RELATED optie. Hiervoor moet
de ip_conntrack_ftp module geladen worden, of in de kernel worden
mee gecompileerd. We dienen hiertoe de We gebruiken de statements uit
het eerste voorbeeld en voegen er een derde statement aan toe:
iptables -A FORWARD -p tcp -m state --state ESTABLISHED -j ACCEPT
iptables -A FORWARD -p tcp -m state --state NEW -i ! eth0 -j ACCEPT
iptables -A FORWARD -p tcp --sport 20 -m state --state RELATED -j ACCEPT
De optie RELATED in de derde regel heeft een vergelijkbare rol als de
optie NEW in de tweede regel. De ip_conntrack_ftp module kijkt mee met
de controll connectie op poort 21. Wanneer er een PORT statement passeert
worden de meegegeven parameters gebruikt om een speciale entry op te nemen in
de connections table met als kenmerk EXPECTED. Zodra de dataconnectie
wordt geopend wordt deze entry vervangen door een normale tcp entry.
ICMP
Een aantal ICMP typen kunnen beschouwd worden als een vraag-antwoord
combinatie zodat de ESTABLISHED optie gebruikt kan worden. Een voorbeeld
is ping. Wanneer we een systeem willen pingen wordt er een ICMP echo
request (ICMP type 8) verstuurt en kunnen nu een echo reply (type 0)
terug verwachten.
Andere typen ICMP houden verband met bestaande of op te bouwen TCP of UDP
connecties. Een voorbeeld daarvan is destination unrechable (type 3) of
time exceeded (type 11). Wanneer we deze messages willen kunnen ontvangen
moeten we gebruik maken van RELATED kwalificatie.
iptables -A FORWARD -p icmp -m state --state ESTABLISHED,RELATED -j ACCEPT
iptables -A FORWARD -p icmp -m state --state NEW -i ! eth0 -j ACCEPT
Wanneer we een echo request versturen wordt er een entry in de connections
table gemaakt met als kenmerk UNREPLIED. Wanneer de verwachte echo
reply passeert wordt de entry direct verwijderd. We verwachten namelijk
maar één reply per request. Wanneer geen reply komt wordt na 30 seconden
de entry verwijderd.
Een nieuwe TCP of UDP connectie zal deze in eerste
instantie met het kenmerk UNREPLIED in de connections table opgenomen
worden. Wanneer we nu in plaats van het verwachte TCP of UDP pakket
een ICMP destination unrechable of ICMP time exceeded ontvangen zal deze
worden doorgelaten en zal vervolgens de entry uit de connections table
worden verwijderd.
Configuratie
Netfilter en iptables voorzien in een kernel faciliteit en een
command interface. Wanneer we netfilter willen toepassen zullen we de
gewenste configuratie moeten vastleggen in één of meerdere scripts
waarin veelvuldig het iptables commando wordt aangeroepen. Het schrijven
van een dergelijk script is geen sinecure en vereist diepgaande kennis
van de TCP/IP protocol suite, alsmede kennis van firewall principes. Om
dit werk te vereenvoudigen is een userinterface waarin we onze wensen
op een hoger abstractieniveau kunnen invoeren erg plezierig. Een korte
zoektocht op freshmeat leert dat er vele scripts in omloop zijn, in
Bash of in Perl, die het configureren vereenvoudigen. Het is moeilijk
de kwaliteit van al deze scripts te beoordelen.
Voor een eenvoudige configuratie is bijvoorbeeld gShield bruikbaar.
Een opmerkelijke tool is fwbuilder. Dit is een grafische interface die
grote overeenkomsten toont met de interface van FireWall-1. Zo kunnen
hosts, netwerken gegroepeerd worden in objects en als als zodanig in
een rulebase worden opgenomen. fwbuilder kan behalve voor met iptables
ook met ipchains of ipfilter gebruikt worden. fwbuilder is helaas nog in
Bèta status.
Verbeteringen
Wanneer we connection tracking in onze Linux firewall implementeren
hebben we de mogelijkheid om de tcp-window-tracking patch aan te brengen.
Deze patch implementeert TCP window tracking zoals door Guido van
Rooij is beschreven in zijn artikel
'Real Stateful TCP Packet Filtering
in IP Filter' Hierbij worden bij de TCP pakketjes niet alleen ip-adressen
en portnummers maar ook de serienummers gecontroleerd. Dit gebeurt aan de
hand van de window-size declaraties die over en weer gestuurd worden. In
feite wordt nu daadwerkelijk de status van de connectie gecontroleerd, waar
voorheen alleen de aanwezigheid van de connectie gecontroleerd werd.
Deze vorm van statefull filtering is reeds geïmplementeerd in
ipfilter, de firewall software die wordt gebruikt in
FreeBSD en OpenBSD.
De tcp-window-tracking code bevindt zich formeel nog in een
experimenteel stadium en is daarom nog niet in de stabiele kernel is
opgenomen. Implementatie ervan zal er toe leiden dat de mogelijkheden
om malafide TCP pakketjes door de firewall te loodsen nog kleiner wordt
en de kwaliteit van de beveiliging nog verder verbetert.
Vergelijking
Wanneer we het hebben over connection tracking en statefull inspection
dringt de behoefte aan een vergelijking met FireWall-1 zich op. Men moet
echter erg voorzichtig zijn met het vergelijken van een commercieel
product met een OpenSource product. FireWall-1 is een compleet pakket
met diverse proxy's, een VPN module, een programmeertaal, een logparser
en natuurlijk een grafische userinterface. Netfilter is slechts een
filter structuur met iptables als commando-interface. Het combineren met
met proxy's, VPN software of grafische userinterface ligt buiten het
aandachtsgebied van de ontwikkelaars, maar behoort wel tot de mogelijkheden.
Bij beide firewall's vindt de feitelijke filtering plaats in de kernel,
en wordt in de kernel een tabel bijgehouden met de bestaande connecties.
Een belangrijk verschil is dat FireWall-1 één grote filtertabel
heeft die alleen inkomend verkeer filtert, terwijl netfilter gebruik
maakt van afzonderlijke chains. In complexere architecturen kunnen
de afzonderlijke chains de configuratie vereenvoudigen doordat aan
de diverse verkeersstromen specifieke chains kunnen worden toegewezen.
Opvallend is dat FireWall-1 standaard (nog) geen mogelijkheid heeft voor
statefull filtering van ICMP messages. Met name voor echo request/replay
is dit een gemis. Netfilter biedt, zij het experimenteel, TCP window
tracking. Het is niet bekend of er plannen zijn om TCP window tracking
in FireWall-1 toe te gaan passen. De grafische userinterface van
FireWall-1 maakt het makkelijk snel een deugdelijke
configuratie op te zetten. De interface tool
fwbuilder
biedt een vergelijkbare
functionaliteit aan iptables. De waarde van een grafische userinterface
moet echter echter niet overschat worden. Goede kennis van de TCP/IP
protocollen en filtertechnieken is nog steeds geboden. Van een goede
firewall deskundige mag echter verwacht worden dat deze ook met iptables
commando's uit de voeten kan.
Conclusies
Netfilter heeft een open structuur die veel ruimte biedt aan toekomstige
ontwikkelingen. Door toepassing van connection tracking is het mogelijk
kwalitatief hoogwaardige firewall's te bouwen. Toepassing van TCP window
tracking zal de kwaliteit van de beveiliging verder doen toenemen.
Goede kennis van de TCP/IP protocol suite en van de filter technieken is echter
onontbeerlijk om tot een goed resultaat te komen.
De structuur van netfilter vormt een solide basis voor verdere
uitbreidingen en verfijningen in de filtertechniek.
Links