Firewall configuratie voor iptables
- Inleiding in de iptables firewall
- Functionaliteit van de firewall in woorden
- Firewall performance in Linux
- Negeren of weigeren van pakketten?
- Laden van de iptables configuratie
- Toevoegen en verwijderen van vijanden in de firewall
Inleiding in de iptables firewall
Een firewall in computerterminologie is een software of hardware oplossing die probeert zoveel mogelijk kwaardaardig networkverkeer te stoppen, terwijl nuttig verkeer wordt doorgelaten. Firewalls kunnen ofwel worden geïntegreerd in bestaande netwerkapparatuur zoals routers, als aparte apparaten met als enige functie om een netwerk te beschermen of in de eerste lagen van de netwerk stack op een van netwerk voorziene computer.
Belangrijk
Firewalls kunnen zeer effectief zijn in het blokkeren van ongewenst verkeer naar een computer of netwerk. Deze pagina beschrijft een methode om een dergelijke firewall te implementeren in de kernel van uw computer. U moet begrijpen dat het net zo gemakkelijk is om vijanden te blokkeren, als om uw eigen toegang te onmogelijk te maken. Tijdens het testen moet er daarom ook altijd een achterdeur geopend blijven, bijvoorbeeld door de firewall zo in te stellen dat die bij herstarten van de computer niet automatisch opstart. In het geval u tijdens het testen uzelf buitensluit is dan een herstart genoeg om opnieuw toegang te krijgen. Denk niet dat dit u niet zal overkomen. Het gebeurde mij in het verleden, zelfs met meer dan 10 jaren ervaring in Unix/Linux beveiliging en firewall configuraties.
Iptables is een software oplossing die beschikbaar is op de meeste Linux computer met een kernel versie 2.4 of nieuwer. Om heel eerlijk te zijn moet ik zeggen dat iptables niet de firewall zelf is. Het iptables programma is een gebruikers interface die vanaf de commandoregel kan worden aangeroepen om filtertabellen in de kernel aan te passen. De echte firewall bevindt zich in de kernel. Omdat de meeste mensen alleen het iptables programma zullen gebruiken wordt het vaak benoemd als de Linux firewall, en dat zullen we uit gemakzucht hier dan ook maar doen.
Netwerkpakketten die een in een netwerk aangesloten Linux computer binnenkomen of uitgaan passeren een aantal tabellen in de kernel. Elke tabel bevat nul of meer eenvoudige regels waar het IP adres of specifieke eigenschappen van een pakket worden gecontroleerd. Wanneer een regel overeenkomt kunnen een aantal acties in gang worden gezet. Een netwerkpakket kan eenvoudigweg worden genegeerd, geweigerd, geaccepteerd, of doorgestuurd naar een andere tabel met regels. Hoewel het principe van dit firewall systeem eenvoudig is, is het vaak heel moeilijk een degelijke firewall te configureren die in een specifieke behoefte voorziet. Dit komt deels omdat er kennis nodig is van de onderliggende structuren, en deels omdat er geen goede documentatie is die de werking op zo’n manier uitlegt dat het ook kan worden begrepen door mensen die niet werken als netwerkbeheerder. Er is bovendien het probleem dat je een firewall probleem op vele manieren kunt oplossen met iptables, waarbij veel oplossingen niet optimaal zijn omdat ze niet schaalbaar zijn, flexibel of beide. Ik zal hier het raamwerk uitleggen van de firewall instellingen die ik gebruik op een aantal van mijn Linux computers. Deze computers werken allemaal met de Linux distributie CentOS 5.4. Wanneer u een andere distributie gebruikt zullen de lokaties van de bestanden waarschijnlijk anders zijn, maar het algemene concept blijft hetzelfde.
Functionaliteit van de firewall in woorden
De meeste beschikbare firewall implementaties voor iptables missen een duidelijke beschrijving in woorden van de ontwerpachtergronden. Ze worden slechts gepresenteerd als een aantal regels. Dit maakt het moeilijk voor mensen om de functionaliteit te begrijpen en te beslissen of het past in hun specifieke situatie. Het maakt het ook moeilijk om wijzigingen aan te brengen in de firewall instellingen zonder de functionaliteit teniet te doen. Zonder verdere configuratie zijn vijf tabellen van regels voorgedefiniëerd in de kernel. De PREROUTING is de eerste tabel voor binnenkomende pakketten. Vanaf de PREROUTING tabel kunnen pakketten ofwel doorgestuurd worden naar de INPUT tabel, of naar de FORWARD tabel. De INPUT tabel is voor pakketten die lokaal afgeleverd moeten worden. De FORWARD tabel wordt uitsluitend gebruikt op computers waarop routing is geactiveerd. Het zorgt ervoor dat pakketten doorgestuurd worden naar andere bestemmingen dan de lokale computer. De OUTPUT tabel wordt gebruikt om pakketten na te bewerken die afkomstig zijn van de lokale computer en de POSTROUTING tabel brengt de pakketten naar de netwerkadapter voor aflevering in den
vreemde.
In onze iptables firewall configuratie zullen we ons alleen concentreren op binnenkomend verkeer. Het controleren van uitgaand verkeer kan mogelijk ook nodig zijn, bijvoorbeeld om bepaalde applicaties ervan te weerhouden om verbinding te maken met externe computers, maar in dit configuratievoorbeeld zien we te buitenwereld als het grootste gevaar. We zullen daarom firewall regels definiëren die zowel op de INPUT, als de FORWARD tabellen betrekking hebben en laten de OUTPUT tabel ongemoeid.
Als eerste zullen we de pakketten in verschillende groepen indelen. Elke groep van pakketten verdient zijn eigen behandeling.
- Vijanden
-
De vijanden zijn pakketten die afkomstig zijn van bronnen, of bedoeld zijn voor bestemmingen die niet toegestaan zijn. Eén manier om een vijandig pakket te herkennen is door de kijken naar het bron IP adres. Misschien weet u IP adressen die gebruikt worden door spammers die uw forums vervuilen. Vijanden kunnen ook pakketten zijn die bestemd zijn voor verdachte poorten, bijvoorbeeld om de computer te scannen voor onbeveiligde poorten waarop een MySQL server draait.
- Vrienden
-
Vrienden zijn pakketten die afkomstig zijn van een vertrouwde bron. Vrienden hebben meer privileges dan andere pakketten. Het is bijvoorbeeld mogelijk om netwerk verkeer naar de SSH poort toe te staan voor vrienden, maar de blokkeren vanaf andere bronnen.
- Foutieve pakketten
-
Eén methode die hackers gebruiken om computers in een netwerk aan te vallen is door ze pakketten de sturen die ongeldig zijn, in de hoop dat dit ofwel de computer laat crashen, of dat hiermee lokaal verkeer kan worden onderschept. Ongeldige pakketten kunnen een ongeldige combinatie van TCP/IP vlaggen bevatten. Maar het is ook mogelijk dat hackers pakketten verzenden naar een computer die afkomstig zijn van één van de private IP adres bereiken in de hoop dat ze hier mee een deel van het verkeer kunnen onderscheppen of ontregelen. Zoals mogelijk bekend zijn adresbereiken zoals 192.168.0.0/16 en 10.0.0.0/8 gereserveerd voor het gebruik op privé netwerken. Veel standaard firewall implementaties hebben uitzonderingen die meer rechten geven aan netwerkverkeer van deze bronnen. Maar wanneer je een een computer in een netwerk hebt—speciaal in een datacentrum—zou er geen verkeer van deze IP bereiken moeten komen. In dat geval moeten deze pakketten worden gemarkeerd als ongeldig en op gepaste wijze worden behandeld.
- Altijd toegestane pakketten
-
Toegestane pakketten zijn pakketten waarvan het absoluut zeker is dat geen enkele blokkerende firewall regel op hen van toepassing is. Dit kunnen pakketten zijn voor specifieke poorten waarop geen firewall filtering van toepassing is, pakketen die komen vanaf de lokale loopback interface of pakketten die onderdeel zijn van een stroom van pakketten die eerder al gecontroleerd en geaccepteerd zijn. Het mag vreemd lijken om een aparte groep te maken voor altijd toegestane pakketten, maar het heeft voordelen wat betreft de performance van de firewall.
Firewall performance in Linux
Heb ik al verteld dat de firewall implementatie van Linux bestaat uit een aantal tabellen met regels die in volgorde worden doorlopen? Wanneer u dit concept begrijpt zult u ook begrijpen dat de tijd die nodig is om een pakket te vergelijken met alle regels evenredig toe zal nemen met het aantal regels. Dit kan performance problemen geven op zwaar belaste computers waar een groot aantal pakketten per seconde moet worden gecontroleerd.
Er zijn een aantal mogelijkheden om potentiële performance problemen op te lossen in de firewall. Het eerste dat moet worden gedaan is de regels op zodanige wijze te sorteren dat regels die de hoogste kans hebben op een match in het begin van de tabellen komen te staan. Bovendien zouden we moeten proberen om de tabellen zodanig te organiseren voor de verschillende pakketten dat die zodanig worden verwerkt dat bij pakketten die geaccepteerd moeten worden dat in een vroeg stadium gebeurt, terwijl alleen pakketten die waarschijnlijk toch geblokkeerd worden de hele lijst met tabellen en regels doorlopen. Om dit uit te voeren stel ik de volgende stroom van pakketten door de firewall voor.
Negeren of weigeren van pakketten?
Wanneer een inkomend pakket geen toestemming krijgt om de server binnen te komen dan zijn er twee manieren om daarmee om te gaan. Allereerst kan er een antwoord aan de zendende computer worden gestuurd dat het pakket is geweigerd, of het pakket kan worden genegeerd zonder reactie. In veel firewalls is het versturen van een weigering geïmplementeerd omdat het netter is wat betreft volgen van internet standaarden, maar zouden we dat alleen om die reden doen? Wanneer de beslissing gekomen is om een pakket niet te accepteren, dan is daar iets mee aan de hand. Ofwel het is een ongeldig pakket, of het is van een bron die u niet vertrouwt. Laten we dat nu eens in een ander perspectief zien. Vergelijk de computer met uw huis. Wanneer u weet dat uw huis zeer goed beveiligd is en een inbreker loopt rond het huis op zoek naar een manier om binnen te komen, zou u dan “Het huis is beveiligd” schreeuwen, elke keer als hij op de deur klopt, of zou u niks zeggen en misschien de politie bellen. Waarschijnlijk het laatste. In computers kunnen we een vergelijkbare actie doen als de politie bellen, namelijk een logfile vijhouden of een email zenden naar het adres van een beheerder. Maar wanneer u weet dat de beveiliging in orde is zou u waarschijnlijk slechts uw mond dichthouden. Het niet antwoorden op verdachte pakketten heeft twee andere voordelen. Een inbreker weet dat het huis bestaat omdat het een tastbaar object is, maar een computer op het internet is alleen herkenbaar bij het anonieme IP adres. Wanneer je alle verdachte pakketten eenvoudigweg negeert zal de zender niet weten of de computer bestaat, of dat het IP adres niet toegewezen is. De aanvaller zal daardoor waarschijnlijk na een paar pogingen stoppen om een gemakkelijker te identificeren slachtoffer te zoeken. Bij het negeren van pakketten is er bovendien het voordeel dat dit niet veel processortijd vergt op de eigen computer, maar door de manier waarop IP protocollen werken moet het proces op de zendende computer wachten tot een timeout is opgetreden die uiteindelijk aangeeft dat de verbinding is mislukt.
Daarom zullen we in onze configuratie alleen pakketten negeren, niet weigeren.
Laden van de iptables configuratie
Op de RedHat familie van Linux distributies wordt de configuratie van het systeem die moet worden geladen bij opstarten opgeslagen in de /etc/sysconfig directory. Het bestand iptables bevat een lijst met regels voor de firewall. Het raamwerk van onze firewall lijkt op het onderstaande
#
# Example fast and scalable firewall configuration with iptables
# Please only implement if you fully understand the functionality
# because is very easy to lockout yourself from your computer if
# the script isn't adapted to your specific situation.
#
*filter
:INPUT ACCEPT [0:0]
:FORWARD ACCEPT [0:0]
:OUTPUT ACCEPT [0:0]
:Always - [0:0]
:Allow - [0:0]
:Bogus - [0:0]
:Enemies - [0:0]
:Friends - [0:0]
-A INPUT -j Bogus
-A INPUT -j Always
-A INPUT -j Enemies
-A INPUT -j Allow
-A FORWARD -j Bogus
-A FORWARD -j Always
-A FORWARD -j Enemies
-A FORWARD -j Allow
-A Bogus -p tcp -m tcp --tcp-flags SYN,FIN SYN,FIN -j DROP
-A Bogus -p tcp -m tcp --tcp-flags SYN,RST SYN,RST -j DROP
-A Bogus -s 169.254.0.0/16 -j DROP
-A Bogus -s 172.16.0.0/12 -j DROP
-A Bogus -s 192.0.2.0/24 -j DROP
-A Bogus -s 192.168.0.0/16 -j DROP
-A Bogus -s 10.0.0.0/8 -j DROP
-A Bogus -s 127.0.0.0/8 -i ! lo -j DROP
-A Always -p udp --dport 123 -j ACCEPT
-A Always -m state --state ESTABLISHED,RELATED -j ACCEPT
-A Always -i lo -j ACCEPT
-A Friends -s 123.123.123.123 -j ACCEPT
-A Friends -s 111.111.111.0/24 -j ACCEPT
-A Friends -j DROP
-A Enemies -m recent --name psc --update --seconds 60 -j DROP
-A Enemies -i ! lo -m tcp -p tcp --dport 1433 -m recent --name psc --set -j DROP
-A Enemies -i ! lo -m tcp -p tcp --dport 3306 -m recent --name psc --set -j DROP
-A Enemies -i ! lo -m tcp -p tcp --dport 8086 -m recent --name psc --set -j DROP
-A Enemies -i ! lo -m tcp -p tcp --dport 10000 -m recent --name psc --set -j DROP
-A Enemies -s 99.99.99.99 -j DROP
-A Allow -p icmp --icmp-type echo-request -j Friends
-A Allow -p icmp --icmp-type any -m limit --limit 1/second -j ACCEPT
-A Allow -p icmp --icmp-type any -j DROP
-A Allow -p tcp -m state --state NEW -m tcp --dport 22 -j Friends
-A Allow -p tcp -m state --state NEW -m tcp --dport 25 -j ACCEPT
-A Allow -p tcp -m state --state NEW -m tcp --dport 80 -j ACCEPT
-A Allow -p tcp -m state --state NEW -m tcp --dport 443 -j ACCEPT
-A Allow -j DROP
COMMIT
Ik heb een paar lege regels toegevoegd om het bestand gemakkelijker leesbaar te maken. Het eerste blok geeft ons de namen van de tabellen die we zullen gebruiken, en de initiële waarden van de pakket en byte tellers. Met deze instellingen resetten we de tellers elke keer als de firewall configuratie opnieuw geladen wordt. De standaard actie voor de drie interne tabellen INPUT, FORWARD en OUTPUT wordt ingesteld op ACCEPT. Dit betekent dat een pakket geaccepteerd wordt door elk van deze tabellen, tenzij een regel in de tabel anders aanwijst. De vijf door onszelf gedefiniëerde tabellen hebben geen standaard actie. De logica van de firewall zal daardoor doorgaan met het verwerken van andere regels wanneer de regels in die tabellen niet tot een definitief antwoord leiden wat te doen met een pakket.
De volgende twee blokken voegen vier filterregels toe aan de INPUT en FORWARD tabel. Elke regel voert een sprong uit naar een door ons gedefiniëerde tabel. De volgorde waarin deze commando’s voorkomen in het iptables bestand is belangrijk omdat dit ook de volgorde zal zijn waarin de regels door de kernel zullen worden verwerkt.
Ongeldige netwerkpakketten
De Bogus groep bevat een handvol regels die ongeldig pakketten definiëren. Dit zijn ondermeer pakketten waarbij zowel de SYN als de FIN vlaggen zijn gezet of de SYN en RST vlaggen, pakketten van specifieke bereiken van ongeldige IP adressen en pakketten met IP adressen die behoren bij de virtuele loopback adapter (127.x.x.x), maar die niet afkomstig zijn van een lokale bron. Dit zijn allemaal pakketten die inelkaar geknutseld worden door hackers of aanvallers om het systeem in verwarring te brengen of binnen te dringen.
Hoge-prioriteit netwerkpakketten
De tweede groep Always bevat hoge-prioriteit pakketten die altijd zouden moeten worden geaccepteerd zonder veel vertraging. In mijn specifieke situatie functioneren de meeste servers die ik beheer ook als NTP tijdservers. Om accurate tijd te verzorgen is het belangrijk om een lage vertraging te hebben bij het verwerken van netwerk pakketten van het Network Time Protocol. Deze pakketten worden verzonden als UDP pakketten naar poort 123. Om die reden worden deze pakketten direct geaccepteerd, zonder verder nog regels te checken. eze pakketten zouden kunnen komen van een aanvaller en zelfs onderdeel kunnen zijn van een DDOS aanval, maar we accepteren die situatie. Het verwerken van NTP pakketten heeft een dusdanig lage overhead dat zelfs wanneer pakketten op zeer hoge snelheid binnenkomen het slechts weinig CPU bronnen zal kosten. Er worden ook geen statussen bewaard zoals met het TCP protocol wel het geval is die buffer overflows zouden kunnen veroorzaken. Het enige wat zou kunnen gebeuren is verzadiging van het netwerk, maar dat gebeurt met een DDOS aanval onafhankelijk of we de pakketten nu accepteren of negeren.
De volgende regel is net zo belangrijk. Het vertelt ons om alle pakketten te accepteren van een verbinding die we daarvoor hebben geaccepteerd als zijnde OK. Veel firewall configuraties missen deze specifieke regel, maar vanuit het oogpunt van performance is het een hele belangrijke. De meeste TCP/IP protocollen wisselen veel pakketten uit over een enkele verbinding. Wanneer we praktisch gesproken alleen het eerste pakket van die strom testen en dan vervolgens de hele stroom als geaccepteerd of geweigerd markeren is er slechts weinig overhead nodig bij het verwerken van geaccepteerde netwerk verbindingen.
De derde regel accepteert al het verkeer van de loop-back adapter. Wat veel firewall regels lijken te vergeten is dat ook het verkeer van en naar de loopback adapter door de firewall gecontroleerd wordt. Dit kan aanzienlijke performance problemen geven wanneer de loopback adapter bijvoorbeeld wordt gebruikt voor verbindingen tussen een Apache webserver en een SQL database.
Vrienden
In het volgende blok definiëren we onze vrienden. Zoals je mogelijk hebt gezien wordt de Friends chain niet direct aangeroepen vanuit de INPUT of OUTPUT chain. Het wordt aangeroepen vanuit andere chains die we later zullen definiëren om toegang te accepteren tot specifieke poorten voor bepaalde IP adressen maar niet voor anderen. De Friends chain wordt aangeroepen om het bron IP adres te vergelijken met een lijst van toegestane adressen. De eerste regel controleert if het IP adres gelijk is aan 123.123.123.123. Als dat het geval is wordt het pakket geaccepteerd zonder verdere uitvoering van firewall regels. Vervolgens wordt het IP adres gecontroleerd ten opzichte van een IP adres range van 111.111.111.0 tot 111.111.111.255. Als het IP address in deze range ligt wordt het pakket ook geaccepteerd. De derde regel negeert alle pakketten die niet door één van de vorige regels geaccepteerd is.
Het moge duidelijk zijn dat de IP adressen die hier genoemd worden slechts voorbeelden zijn. Ze moeten in de eigen situatie vervangen worden door adressen waar vriendschappelijk verkeer normaliter vandaan komt, bijvoorbeeld het IP adres van de eigen ADSL verbinding of IP adressen van andere servers in het eigen netwerk. Het is toegestaan extra regels toe te voegen voor de –A Friends -j DROP regel.
Vijanden
Vijanden kunnen we op twee manieren herkennen. Ofwel bij het bron IP adres, ofwel door hun gedrag. Helaas werkt de firewall in de kernel op een laag niveau in de netwerk hierarchie en veel gedragskenmerken zijn alleen zichtbaar op het applicatie niveau, bijvoorbeeld woordenboek aanvallen om wachtwoorden te achterhalen op SSH servers of spam emails. Maar sommig gedrag kan worden gedetecteerd op het laagste netwerk niveau en één daarvan is het scannen van poorten. Het scannen van poorten is een methode waarbij met een aantal TCP/IP poorten op de aangevallen computer verbinding wordt gelegd om te zoeken naar open verbindingen met SQL servers, controlepanelen en andere applicaties met netwerk faciliteiten. Mijn ervaring heeft me geleerd dat veel poortscanners zoeken voor onbeveiligde verbindingen met MySQL en MSSQL servers. Omdat mijn servers alleen SQL verzoeken van lokale applicaties accepteren is elk verzoek van de buitenwereld per definitie van een vijand. In de IP firewall heb ik regels geplaatst die worden geactiveerdwanneer verzoeken binnenkomen voor poort 1433, poort 3306 en enkele andere bekende poorten. Elk IP adres van waaraf zo’n verzoek wordt gegenereerd gaat in quarantaine voor een periode van 60 seconden. Dit wordt gedaan door de –name psc –set actie en er wordt gecontroleerd bij elk volgend pakket of die periode van 60 seconden nog niet verstreken is. De Linux kernel houdt een lijst bij van poortscan IPs die kan worden bekeken op de lokatie /proc/net/ipt_recent/psc. Ik heb een timeout van 60 seconden genomen omdat ik sommige gevallen bij het testen ikzelf mogelijk als een poortscanner word geidentificeerd door de firewall. In dat geval sluit ik mijzelf slechts voor een periode van één minuut buiten. Maar het is uiteraard ook mogelijk die periode te verhogen naar bijvoorbeeld 15 minuten of een uur.
Andere vijanden zijn vijanden die we kennen door het IP adres of een IP adresbereik. Ik heb hier het adres 99.99.99.99 toegevoegd als een voorbeeld, maar dit kunnen ook bereiken zijn zoals 111.111.111.0/24.
Toevoegen en verwijderen van vijanden in de firewall
Friends come and go, but enemies accumulate is wat Jones’ motto ons leert. In de IT wereld ligt dat een klein beetje anders. Veel vijanden zijn dat slechts tijdelijk. Het zijn computers die geinfecteerd zijn, of servers met configurateproblemen zoals open mail of web proxies. Wanneer deze problemen opgelost zijn kan een vijand weer in een vriend veranderen.
Hierom zoeken we naar een gemakkelijke methode om IP adressen of IP bereiken aan de iptables firewall die we hebben gemaakt toe te voegen of te verwijderen. In veel iptables firewall implementaties die u op het internet vindt is dit zeer moeilijk. Er is een diepgaande kennis nodig van de werking van de firewall voordat het mogelijk is wijzigingen erin te maken. Dat is raar, want wanneer de computer onder vuur ligt zijn er wel andere dingen te doen dan handleidingen te lezen, scripts te ontcijferen en dergelijke. Er was al te zien dat we de vijanden afgescheiden hebben in onze firewall door alle vijand gerelateerde firewall regels in een apparte tabel te plaatsen. Met twee shell scripts kunnen we regels toevoegen of verwijderen uit deze tabel.
/usr/local/bin/addenemy
#!/bin/sh
iptables -L -n -v | grep -q $1
RETVAL=$?
if [ $RETVAL -eq 0 ]; then
echo "IP address already in blocklist: $1"
exit 0
fi
echo "Adding enemy $1"
iptables -A Enemies -s $1 -j DROP
Dit script maakt eerst een dump van de huidige firewall regels and controleert of het IP adres of de IP range overeenkomt met een bestaande regel. Als dat het geval is wordt een waarschuwing getoond en stopt het script zonder verdere actie te ondernemen. Wanneer geen overeenkomende regel kan worden gevonden wordt het IP adres of IP range toegevoegd aan de lijst met vijanden. Door de hele lijst met regels te controleren op het nieuwe IP adres hebben een soort beveiliging gecreëerd waarmee het moeilijker wordt één van onze eigen IPs toe te voegen aan de firewall, omdat dit script ook voortijdig zal stoppen als ze het IP adres of bereik vindt in de tabel met vrienden. Maar er geen test op individuele IPs ten opzichte van IP bereiken dus is nog steeds aandacht vereist bij het gebruik.
/usr/local/bin/delenemy
#!/bin/sh
echo "Deleting enemy $1"
iptables -D Enemies -s $1 -j DROP
Dit script verwijdert een regel van de Enemies tabel die overeen komt met het opgegeven IP adres of IP bereik.
In any organization there will always be
one person who knows what is going on.
This person must be fired.
CONWAY'S LAW
|