30.6. IPFW

IPFIREWALL (IPFW) is een firewall die binnen FreeBSD wordt ontwikkeld en onderhouden door vrijwillige leden van de staf. Het maakt gebruik van verouderde staatloze regels en een verouderde techniek om te realiseren wat eenvoudige stateful logica zou kunnen heten.

De verzameling voorbeeldregels van IPFW (die in /etc/rc.firewall en /etc/rc.firewall6 staan) uit de standaard FreeBSD-installatie is redelijk eenvoudig en niet voorbereid om zonder wijzigingen gebruikt te worden. Het voorbeeld maakt geen gebruik van stateful filteren, wat een voordeel is in de meeste situaties. Daarom worden deze regels niet als basis gebruikt in dit onderdeel.

De staatloze syntaxis van IPFW is krachtig door de technisch geavanceerde mogelijkheden van de regelsyntaxis die de kennis van de gemiddelde gebruiker van firewalls ver overstijgt. IPFW is gericht op de professionele gebruiker of de gevorderde thuisgebruiker die hoge eisen stelt aan de wijze waarop er met pakketten wordt omgegaan. Voordat de kracht van de IPFW regels echt ingezet kan worden, moet de gebruiker veel weten over de verschillende protocollen en de wijze waarop pakketten in elkaar zitten. Het tot op dat niveau behandelen van stof valt buiten de doelstellingen van dit Handboek.

IPFW bestaat uit zeven componenten: de verwerkingseenheid voor de firewallregels, verantwoording, loggen, regels met divert (omleiden) waarmee NAT gebruikt kan worden en de speciale gevorderde mogelijkheden voor bandbreedtebeheer met DUMMYNET, de fwd rule forward-mogelijkheid, de bridge-mogelijkheden en de ipstealth-mogelijkheden. IPFW ondersteunt zowel IPv4 als IPv6.

30.6.1. IPFW inschakelen

IPFW zit bij de basisinstallatie van FreeBSD als een losse tijdens runtime laadbare module. Het systeem laadt de kernelmodule dynamisch als in rc.conf de regel firewall_enable="YES" staat. IPFW hoeft niet in de FreeBSD kernel gecompileerd te worden.

Na het rebooten van een systeem met firewall_enable="YES" in rc.conf is het volgende bericht op het scherm te zien tijdens het booten:

ipfw2 initialized, divert disabled, rule-based forwarding disabled, default to deny, logging disabled

In de laadbare module zit de mogelijkheid om te loggen gecompileerd. Er is een knop in /etc/sysctl.conf om loggen aan te zetten en de uitgebreide loglimiet in te stellen. Door deze regels toe te voegen, staat loggen aan bij toekomstige herstarts:

net.inet.ip.fw.verbose=1
net.inet.ip.fw.verbose_limit=5

30.6.2. Kernelopties

Het is niet verplicht om IPFW in te schakelen door het mee te compileren in de FreeBSD kernel. Dit wordt alleen beschreven als achtergrondinformatie.

options    IPFIREWALL

Met IPFIREWALL wordt IPFW ingeschakeld als deel van de kernel.

options    IPFIREWALL_VERBOSE

Met IPFIREWALL_VERBOSE wordt het loggen van pakketten die worden verwerkt met IPFW mogelijk die het sleutelwoord log in een regel hebben staan.

options    IPFIREWALL_VERBOSE_LIMIT=5

Limiteert het aantal pakketten dat per regel wordt gelogd via syslogd(8). Deze optie kan gebruikt worden in vijandige omgevingen waar de activiteit van een firewall gelogd moet worden. Hierdoor kan een mogelijke ontzegging van dienst aanval door het vol laten lopen van syslog voorkomen worden.

options    IPFIREWALL_DEFAULT_TO_ACCEPT

Met IPFIREWALL_DEFAULT_TO_ACCEPT wordt standaard alles door de firewall doorgelaten. Dit wordt aangeraden als iemand voor het eerst een firewall opzet.

options    IPDIVERT

Met IPDIVERT wordt de NAT functionaliteit ingeschakeld.

Opmerking:

De firewall zal alle binnenkomende en uitgaande pakketten blokkeren als de kerneloptie IPFIREWALL_DEFAULT_TO_ACCEPT of een regel om deze verbindingen expliciet toe te staan ontbreekt.

30.6.3. /etc/rc.conf opties

Start de firewall:

firewall_enable="YES"

Om één van de standaard firewall types die geleverd wordt door FreeBSD te selecteren, lees /etc/rc.firewall, maak een selectie en plaats het in de volgende regel:

firewall_type="open"

Beschikbare waardes voor deze instelling zijn:

  • open — laat al het verkeer door.

  • client — beschermt alleen deze machine.

  • simple — beschermt het hele netwerk.

  • closed — blokkeert alle IP-verkeer, behalve voor lokaal verkeer.

  • UNKNOWN — voorkomt het laden de firewall-regels.

  • bestandsnaam — absoluut pad naar een bestand dat firewall-regels bevat.

Het is mogelijk om twee verschillende manieren te gebruiken voor speciaal gemaakte regels voor de ipfw firewall. één daarvan is door het zetten van de firewall_type variabele naar een absoluut pad van een bestand, welke firewall-regels bevat, zonder enige specifieke opties voor ipfw(8). Het volgende is een eenvoudig voorbeeld van een bestand met regelverzamelingen dat al het inkomend en uitgaand verkeer blokkeert:

add deny in
add deny out

Aan de andere kant is het mogelijk om de variabele firewall_script in te stellen op een absoluut pad van een uitvoerbaar script, welke inclusief ipfw commando's uitgevoerd wordt tijdens het opstarten van het systeem. Een geldig script met regels dat gelijkwaardig is aan het bestand met regels hierboven, zou het volgende zijn:

#!/bin/sh

ipfw -q flush

ipfw add deny in
ipfw add deny out

Opmerking:

Als firewall_type is gezet naar client of simple moeten de standaard regels die gevonden kunnen worden in /etc/rc.firewall gecontroleerd worden om te zien of deze configuratie voldoet voor de machine. Let ook op dat alle voorbeelden die gebruikt zijn in dit hoofdstuk ervan uitgaan dat de firewall_script variabele gezet is naar /etc/ipfw.rules.

Om loggen in te schakelen:

firewall_logging="YES"

Waarschuwing:

Het enige dat de variabele firewall_logging doet is de sysctl variabele net.inet.ip.fw.verbose op de waarde 1 zetten (zie Paragraaf 30.6.1, “IPFW inschakelen”). Er is geen variabele in rc.conf om logboeklimieten in te stellen, maar dat kan ingesteld worden via een sysctl variabele, handmatig of via /etc/sysctl.conf:

net.inet.ip.fw.verbose_limit=5

Als de machine in kwestie een gateway is, dus Network Address Translation (NAT) diensten levert via natd(8), dan staat in Paragraaf 31.10, “Network Address Translation” meer informatie over de benodigde instellingen voor /etc/rc.conf.

30.6.4. Het commando IPFW

Gewoonlijk wordt ipfw gebruikt om met de hand enkelvoudige regels toe te voegen of te verwijderen als IPFW actief is. Het probleem met deze methode is dat, als het systeem wordt uitgezet alle regels die gewijzigd of verwijderd zijn verloren gaan. Door alle regels in een bestand op te nemen dat bij het booten wordt geladen of door het bestand waarin de wijzigingen zijn gemaakt als een machine draait te laden bestaat die probleem niet.

Met ipfw kunnen de actieve regels van de firewall op het scherm getoond worden. De verantwoordingsmogelijkeden van ipfw(8) maken dynamisch tellers aan voor iedere regel en houden die bij voor alle pakketten die van toepassing zijn op die regel. Tijdens het testen van een regel is het afbeelden van de regel met zijn teller een van de manieren om te bepalen of de regel werkt.

Om alle regels in volgorde te tonen:

# ipfw list

Om alle regels te tonen met de tijd waarop deze voor het laatst van toepassing was:

# ipfw -t list

Het volgende commando kan gebruikt worden om de verantwoordingsinformatie, pakkettellers en de regel zelf te tonen. De eerste kolom is het regelnummer met daarachter het aantal keren dat de regel van toepassing was voor inkomend verkeer, gevolgd door het aantal keren dat de regel van toepassing was voor uitgaand verkeer. Als laatste wordt de regel zelf getoond:

# ipfw -a list

Ook kunnen onder de statische regels de dynamische regels getoond worden:

# ipfw -d list

En de dynamische regels die verlopen zijn:

# ipfw -d -e list

De tellers op nul gesteld worden:

# ipfw zero

Alleen de tellers voor regel met nummer NUM op nul stellen:

# ipfw zero NUM

30.6.5. Sets van IPFW regels

Een verzameling regels is een groep IPFW-regels die is gemaakt om pakketten toe te staan of te blokkeren op basis van de inhoud van dat pakket. De bi-directionele uitwisseling van pakketten tussen hosts bestaat uit een gesprek dat een sessie heet. De verzameling van firewallregels beoordeelt zowel de pakketten die aankomen van de host op het publieke Internet als de pakketten die op het systeem ontstaan als antwoord daarop. Iedere TCP/IP-dienst als telnet, www, mail, etc, heeft zijn eigen protocol en bevoorrechte (luister)poort. Pakketten bestemd voor een specifieke poort verlaten het bronadres via een onbevoorrechte (hogere) poort en doelen op de specifieke dienstpoort op het bestemmingsadres. Alle bovenstaande parameters (poorten en adressen) kunnen gebruikt worden als selectiecriteria om regels aan te maken die diensten doorlaten of blokkeren.

Als een pakket de firewall binnenkomt wordt het vergeleken met de eerste regel in de set regels en zo gaat dat voor iedere regel vanaf boven tot beneden. Als een regel van toepassing is op een pakket, dan wordt het actieveld van de regel uitgevoerd. Dit wordt de de eerst passende regel wint zoekmethode genoemd. Als een pakket bij geen enkele regel past, dan wordt de verplichte standaardregel 65535 van IPFW toegepast, die alle pakketten weigert zonder een antwoord terug te sturen naar de verzender.

Opmerking:

Het zoeken gaat door na regels met count, skipto en tee.

De instructies in dit onderdeel zijn gebaseerd op regels die gebruik maken van de stateful opties keep state, limit, in, out en via. Dit is het raamwerk waarmee een set van inclusieve firewallregels wordt samengesteld.

Waarschuwing:

Wees voorzichtig tijdens het werken met firewall-regels, het is gemakkelijk om uzelf uit te sluiten.

30.6.5.1. Regelsyntaxis

De regelsyntaxis zoals hier toegelicht is vereenvoudigd door alleen te tonen wat nodig is om een standaard inclusieve set met firewallregels te maken. De complete beschrijving van alle mogelijkheden staat in ipfw(8).

Regels bevatten sleutelwoorden die in een bepaalde volgorde van links naar rechts op een regel horen te staan. Sleutelwoorden worden vet weergegeven. Sommige sleutelwoorden hebben subopties die zelf ook weer sleutelwoorden hebben die ook weer subopties kunnen hebben.

Het karakter # wordt gebruikt om het begin van een opmerking te markeren en kan zowel op een eigen regel als achter een firewallregel staan. Lege regels worden genegeerd.

CMD REGEL_NUMMER ACTIE LOGGEN SELECTIE STATEFUL

30.6.5.1.1. CMD

Iedere regel moet beginnen met add om hem toe te voegen aan de tabel met regels.

30.6.5.1.2. REGEL_NUMMER

Elke regel is geassocieerd met een regel_nummer van 1 tot en met 65535.

30.6.5.1.3. ACTIE

Bij een regel kunnen één of meer acties horen die worden uitgevoerd als een regel geldt voor een pakket.

allow | accept | pass | permit

Deze opties betekenen allemaal hetzelfde: als de regel geldt voor een pakket, laat dat pakket dan door en stop met het zoeken naar geldende regels.

check-state

Vergelijkt het pakket met de tabel met dynamische regels. Als het erin staat, dan wordt de actie van de dynamisch door deze regel gemaakte regel uitgevoerd. Anders wordt er verder gezocht door de regels. Een regel met check-state heeft geen selectiecriteria. Als er geen regel met check-state in de set met regels staat, dan wordt de tabel met dynamische regels bij het eerste voorkomen van keep-state of limit gecontroleerd.

deny | drop

Deze opties betekenen hetzelfde: als de regel geldt voor een pakket, blokkeer dat pakket dan en stop met het zoeken naar geldende regels.

30.6.5.1.4. Loggen

log of logamount

Als een regel met het sleutelwoord log van toepassing is op een pakket, dan wordt er een bericht naar syslogd(8) geschreven met de faciliteitsnaam SECURITY. Er wordt alleen een bericht geschreven als het aantal voor die regel gelogde pakketten niet groter is dan de instelling van de parameter logamount. Als er geen logamount is ingesteld, dan wordt de limiet uit de sysctl(8) variabele net.inet.ip.fw.verbose_limit gehaald. In beide gevallen bestaat er in het geval de waarde nul is geen limiet. Als de limiet is bereikt, dan kan het loggen weer ingeschakeld worden door de teller voor het loggen weer op nul te zetten voor die regel met ipfw reset log.

Opmerking:

Er wordt gelogd als een pakket zeker past bij een regel, maar voordat de actie (bijvoorbeeld accept of deny) op een pakket wordt toegepast. Uiteindelijk bepaalt de gebruiker zelf voor welke regels loggen wordt ingeschakeld.

30.6.5.1.5. Selectie

De sleutelwoorden in deze paragraaf beschrijven de attributen van een pakket die gecontroleerd worden bij het bepalen of een regel wel of niet op een pakket van toepassing is. De attributen waarop gecontroleerd kan worden moeten in de beschreven volgorde gebruikt worden.

udp | tcp | icmp

Naast de hierboven aangegeven protocollen kunnen alle in /etc/protocols beschreven protocollen gebruikt worden. De waarde die wordt opgegeven is het protocol dat van toepassing moet zijn. Dit attribuut is verpicht.

from bron to best

De sleutelwoorden from en to worden gebruikt om te bekijken of een regel van toepassing is op IP-adressen. Een regel moet zowel bron- als bestemmingsadressen bevatten. any is een bijzonder sleutelwoord dat van toepassing is op alle IP-adressen. me is een bijzonder sleutelwoord dat van toepassing is op alle IP-adressen die ingesteld zijn op interfaces van een FreeBSD systeem om de PC waarop de firewall draait te vertegenwoordigen (deze machine). Zo kan dit onderdeel bijvoorbeeld de volgende vormen aannemen: from me to any, from any to me, from 0.0.0.0/0 to any, from any to 0.0.0.0/0, from 0.0.0.0 to any, from any to 0.0.0.0 of from me to 0.0.0.0. IP-adressen mogen ingevoerd worden in de vorm numeriek, door punten gescheiden adres/maskerlengte (CIDR-notatie) of als een enkelvoudig IP-adres in de vorm numeriek, door punten gescheiden. De port net-mgmt/ipcalc kan gebruikt worden om de berekeningen e vereenvoudigen. Aanvullende informatie is beschikbaar op de webpagina van het programma: http://jodies.de/ipcalc.

poortnummer

Wordt gebruikt voor protocollen die poortnummers ondersteunen (als TCP en UDP). Het gebruik van een poortnummer is verplicht. Er mogen ook dienstnamen uit /etc/services gebruikt worden in plaats van nummers.

in | out

Is op respectievelijk inkomende of uitgaande pakketten van toepassing. De sleutelwoorden in of out zijn verplicht in een regel.

via IF

Deze parameter geeft aan op welke interface de regel van toepassing is, waarbij IF de exacte naam van de bedoelde interface is.

setup

Dit is een verplicht sleutelwoord waarmee wordt aangegeven dat er gezocht wordt naar een pakket met het verzoek tot het opstarten van een TCP sessie.

keep-state

Dit is een verplicht sleutelwoord. Als er een pakket op een regel met keep-state van toepassing is, dan wordt er door de firewall een dynamische regel gemaakt die bi-directioneel verkeer zal toestaan tussen bron en bestemming en de bijbehorende poorten voor hetzelfde protocol.

limit {bron-adr | bron-poort | best-adr | best-poort}

De firewall staat maar N verbindingen toe met dezelfde groep parameters uit een regel. Er kunnen één of meer van de parameters bron- of bestemmingsadres en bron- en bestemmingspoort gebruikt worden. limit en keep-state kunnen niet in dezelfde regel gebruikt worden. De optie limit geeft dezelfde mogelijkheden als keep-state en voegt daar zijn eigen mogelijkheden aan toe.

30.6.5.2. Regeloptie stateful

Bij stateful filteren wordt verkeer bekeken als bi-directioneel verkeer dat samen een sessie vormt. Het heeft de mogelijkheid om te bepalen of de sessie tussen de zender en de ontvanger op de juiste wijze voortgaat. Alle pakketten die niet precies in de verwachting van een sessie passen worden automatisch als fout geblokkeerd.

De optie check-state wordt gebruikt om aan te geven waar IPFW-regels tegen de mogelijkheden voor dynamische regels gehouden moeten worden. Als er een passende regel bij een pakket wordt gevonden, dan kan dat pakket de firewall verlaten en wordt een nieuwe regel gemaakt voor het volgende pakket dat wordt verwacht in de sessie. Als er geen regel van toepassing is op het pakket, dan wordt de volgende regel in de groep regels getest.

De mogelijkheden voor dynamische regels zijn kwetsbaar voor een aanval die SYN-flood heet, waarmee wordt geprobeerd een zeer groot aantal regels aan te laten maken. Om deze aanval tegen te gaan, is de optie limit beschikbaar. Met deze optie kan het maximaal aantal simultane sessies geregeld worden op basis van bron en bestemmingsvelden. Als het aantal sessies gelijk aan het maximale aantal sessies is, wordt een pakket voor een nieuwe sessie geweigerd.

30.6.5.3. Firewallberichten loggen

De voordelen van loggen zijn duidelijk. Het biedt de mogelijkheid om na het feit informatie na te zien als: welke pakketten heeft de firewall laten vallen, waar kwamen ze vandaan en waar gingen ze heen. Dit zijn allemaal voordelen als het gaat om uitvinden waar een aanvaller vandaan komt en wat hij heeft geprobeerd.

Zelfs als logging is ingeschakeld logt IPFW nog niets uit zichzelf. De beheerder van de firewall beslist welke actieve regels iets weg moeten schrijven door het sleutelwoord log aan die regels toe te voegen. Gewoonlijk worden alleen deny-regels gelogd. Dit geldt bijvoorbeeld voor de deny-regel voor inkomende ICMP pings. Het is gebruikelijk om de standaardregel ipfw default deny everything te dupliceren, daar log in op te nemen, en deze als laatste in de verzameling met regels te plaatsen. Zo zijn alle pakketten te zien die niet voldeden aan ook maar één regel.

Loggen heeft ook mogelijke nadelen. Het is mogelijk om te veel te loggen en dan om te komen in logboekgegevens die uiteindelijk een schijf kunnen vullen. Een DoS aanval om een schijf met logs te vullen is een van de oudst bekende typen DoS aanvallen. Logberichten van de firewall worden niet alleen naar syslogd geschreven, maar ook op het root console getoond waar ze snel erg vervelend kunnen worden.

De kerneloptie IPFIREWALL_VERBOSE_LIMIT=5 beperkt het aantal opeenvolgende berichten dat naar syslogd(8) wordt geschreven voor één specifieke regel. Als deze optie is ingeschakeld, worden in dit geval maximaal vijf berichten voor dezelfde regel gemeld. Als er meer berichten op dezelfde regel zouden zijn, zou dat als volgt aan syslogd gemeld worden:

last message repeated 45 times

Standaard worden alle gelogde pakketten weggeschreven naar /var/log/security, wat is ingesteld in /etc/syslog.conf.

30.6.5.4. Regelscript bouwen

De meeste ervaren gebruikers van IPFW maken een bestand waarin de regels staan en stellen dat zo op dat het als script uitgevoerd kan worden. Het grootste voordeel van deze methode is dat de firewallregels allemaal vervangen kunnen worden zonder dat het systeem opnieuw gestart moet worden. Deze methode is ook erg geschikt voor het testen van regels omdat de procedure zo vaak als nodig uitgevoerd kan worden. Omdat het een script is, kan er gebruik gemaakt worden van substitutie zodat veel gebruikte waarden verduidelijkt en in meerdere regels toegepast kunnen worden. In het volgende voorbeeld wordt hier gebruik van gemaakt.

De syntaxis die in het script wordt gebruikt is compatibel met de shells sh(1), csh(1) en tcsh(1). Velden waarvoor substitutie van toepassing is worden vooraf gegaan door het dollarteken $. Definities worden niet vooraf gegaan door het voorvoegsel $. De waarden van een substitutie moet omsloten worden door "dubbele aanhalingstekens".

Een bestand met regels kan als volgt beginnen:

############### begin voorbeeldscript ipfw regels ##############
#
ipfw -q -f flush       # Verwijder alle bestaande regels.
# Stel standaarden in.
oif="tun0"             # uitgaande interface.
odns="192.0.2.11"      # IP adres DNS server ISP.
cmd="ipfw -q add "     # Voorvoegsel voor regel.
ks="keep-state"        # Te lui om iedere keer in te typen.
$cmd 00500 check-state
$cmd 00502 deny all from any to any frag
$cmd 00501 deny tcp from any to any established
$cmd 00600 allow tcp from any to any 80 out via $oif setup $ks
$cmd 00610 allow tcp from any to $odns 53 out via $oif setup $ks
$cmd 00611 allow udp from any to $odns 53 out via $oif $ks
################### einde voorbeeldscript ipfw regels ###########

Dat is alles. De feitelijke functie van de regels is in dit voorbeeld van ondergeschikt belang. Dit was slechts een voorbeeld om het gebruik van substitutie te illustreren.

Als het bovenstaande voorbeeld de inhoud van /etc/ipfw.rules was, dan kon het herladen worden met het volgende commando:

# sh /etc/ipfw.rules

/etc/ipfw.rules zou overal kunnen staan met iedere gewenste naam.

Wat in het bovenstaande voorbeeld met een bestand is gerealiseerd, kan ook met de hand:

# ipfw -q -f flush
# ipfw -q add 00500 check-state
# ipfw -q add 00502 deny all from any to any frag
# ipfw -q add 00501 deny tcp from any to any established
# ipfw -q add 00600 allow tcp from any to any 80 out via tun0 setup keep-state
# ipfw -q add 00610 allow tcp from any to 192.0.2.11 53 out via tun0 setup keep-state
# ipfw -q add 00611 allow udp from any to 192.0.2.11 53 out via tun0 keep-state

30.6.5.5. Verzameling van stateful regels

De volgende verzameling van regels, waarin geen gebruik gemaakt wordt van NAT, is een voorbeeld van hoe een erg veilige inclusieve firewall kan worden opgezet. Een inclusieve firewall laat alleen diensten toe waarvoor pass regels van toepassing zijn en blokkeert al het andere verkeer. Firewalls die ontworpen zijn om hele netwerksegmenten te beschermen hebben tenminste twee interfaces waarvoor regels moeten zijn die de firewall in staat stellen zijn werk te doen.

Alle UNIX® systemen en dus ook FreeBSD zijn zo ontworpen dat ze voor interne communicatie de interface lo0 en IP adres 127.0.0.1 gebruiken. De firewall moet dit interne verkeer gewoon doorgang laten vinden.

Voor de interface die is verbonden met het publieke Internet worden regels gemaakt waarmee sessies naar het Internet mogelijk gemaakt worden en toegang wordt gegeven voor pakketten die uit die sessies terug komen. Dit kan de gebruikers-PPP-interface tun0 zijn of de netwerkkaart die is verbonden met een xDSL of kabelmodem.

In gevallen dat er meer dan één netwerkkaart is aangesloten op het private netwerk achter de firewall, moeten er op de firewall-regels zijn om het verkeer tussen die interfaces vrije doorgang te geven.

De regels worden opgedeeld in drie onderdelen: alle interfaces met vrije doorgang, uitgaand op publieke interfaces en inkomend op publieke interfaces.

De volgorde van de regels in iedere sectie voor publieke interfaces moet zo zijn dat de regels die het meest gebruikt worden vóór de regels staan die minder vaak gebruikt worden. De laatste regel van een onderdeel geeft aan dat al het overige verkeer op die interface in die richting geblokkeerd en gelogd moet worden.

In het onderdeel Uitgaand van de volgende verzameling regels staan alleen regels met allow die parameters bevatten om individuele diensten beschikbaar te maken die publieke toegang tot Internet mogen hebben Al die regels moeten gebruik maken van de opties proto, port, in/out, via en keep-state. De regels met proto tcp maken ook gebruik van setup om te bekijken of het een pakket betreft voor het opzetten van een sessie om de stateful functionaliteit aan te sturen.

In het onderdeel Inkomend staan als eerste alle regels voor het blokkeren van ongewenste pakketten, om twee redenen. Als eerste kan het zo zijn dat kwaadaardige pakketten gedeeltelijk overeenkomen met legitiem verkeer. Deze regels moeten worden geblokkeerd in plaats van te worden binnengelaten, gebaseerd op hun gedeeltelijke overeenkomst met allow-regels. De tweede reden is dat nu ongewenste pakketten die vaak voorkomen en die bij voorkeur niet in de logboeken voorkomen niet meer van toepassing zijn op de laatste regel van het onderdeel waarin ze zouden worden gelogd. Met de laatste regel van dit onderdeel worden alle overige pakketten geblokkeerd en gelogd en ze kunnen bewijsmateriaal zijn in een zaak tegen iemand die heeft geprobeerd een systeem aan te vallen.

Iets waarop u ook moet letten is dat voor al het verkeer dat wordt geweigerd geen antwoord wordt gestuurd. Die pakketten verdwijnen gewoon. Zo weet een aanvaller niet of een pakket het doelsysteem wel heeft bereikt. Zo kan een aanvaller geen informatie verzamelen over een systeem: hoe minder informatie er over een systeem beschikbaar is, hoe veiliger het is. Als er pakketten gelogd worden met een onbekend poortnummer, dan is de functie van dat poortnummer na te zoeken in /etc/services of op http://en.wikipedia.org/wiki/List_of_TCP_and_UDP_port_numbers. Op de volgende link worden poortnummers van Trojans beschreven: http://www.sans.org/security-resources/idfaq/oddports.php.

30.6.5.6. Voorbeeld van een set inclusieve regels

Het volgende voorbeeld is een complete inclusieve verzameling van regels die geen gebruik maakt van NAT. Deze verzameling van regels is veilig om deze regels op uw eigen systemen te gebruiken. Dit kan door commentaar te maken van een pass-regel voor een dienst die niet gewenst is. Logberichten die niet gewenst zijn, zijn uit te sluiten door een deny-regel toe te voegen aan het onderdeel Inkomend. Voor de onderstaande regels dient de interfacenaam dc0 in iedere regel vervangen te worden door de interfacenaam van de netwerkkaart in het systeem die met het publieke Internet is verbonden. Voor gebruikers van PPP zou dat tun0 zijn.

Er zit een merkbare structuur in het gebruik van deze regels:

  • Alle regels die een verzoek zijn voor het opzetten van een sessie gebruiken keep-state.

  • Alle diensten die vanaf Internet bereikbaar zijn gebruiken de optie limit om flooding te voorkomen.

  • Alle regels gebruiken in of out om de richting aan te geven.

  • Alle regels gebruiken via interfacenaam om aan te geven op welke interface de regel van toepassing is.

De volgende regels zouden in /etc/ipfw.rules kunnen staan:

################ Begin bestand met IPFW regels ###############################
# Verwijder eerst de bestaande regels.
ipfw -q -f flush

# Stel commando voorvoegsel in.
cmd="ipfw -q add"
pif="dc0"     # Interfacenaam van NIC die verbinding
              # met het publieke Internet heeft.

#################################################################
# Geen beperkingen op de interface aan de LAN kant. Alleen nodig
# als er een LAN is. Wijzig xl0 naar de gebruikte interfacenaam.
#################################################################
#$cmd 00005 allow all from any to any via xl0

#################################################################
# Geen beperkingen op de loopback interface.
#################################################################
$cmd 00010 allow all from any to any via lo0

#################################################################
# Sta het pakket toe als het aan de tabel met dynamische regels
# was toegevoegd met een 'allow keep-state' commando.
#################################################################
$cmd 00015 check-state

#################################################################
# Interface aan het publieke Internet (onderdeel Uitgaand).
# Inspecteer verzoeken om een sessie te starten van achter de
# firewall op het private netwerk of vanaf de server zelf naar
# het publieke Internet.
#################################################################

# Geef toegang tot de DNS server van de ISP.
# x.x.x.x moet het IP adres van de DNS van de ISP zijn.
# Dupliceer deze regels als een ISP meerdere DNS servers heeft.
# Haal het IP adres evt. uit /etc/resolv.conf
$cmd 00110 allow tcp from any to x.x.x.x 53 out via $pif setup keep-state
$cmd 00111 allow udp from any to x.x.x.x 53 out via $pif keep-state

# Geef toegang tot de DHCP server van de ISP voor kabel- en
# xDSL-netwerken. Deze regel is niet nodig als gebruik gemaakt worden
# van PPP naar het publieke Internet. In dat geval kan de hele groep
# verwijderd worden. Gebruik de volgende regel en controleer het
# logboek voor het IP adres. Wijzig dan het IP adres in de regel
# commentaar hieronder en verwijder de eerste regel.
$cmd 00120 allow log udp from any to any 67 out via $pif keep-state
#$cmd 00120 allow udp from any to x.x.x.x 67 out via $pif keep-state

# Sta niet beveiligd www verkeer toe.
$cmd 00200 allow tcp from any to any 80 out via $pif setup keep-state

# Sta beveiligd www verkeer over TLS SSL toe.
$cmd 00220 allow tcp from any to any 443 out via $pif setup keep-state

# Sta het verzenden en ontvangen van e-mail toe.
$cmd 00230 allow tcp from any to any 25 out via $pif setup keep-state
$cmd 00231 allow tcp from any to any 110 out via $pif setup keep-state

# Sta de FreeBSD CVSUP functie toe voor uid root.
$cmd 00240 allow tcp from me to any out via $pif setup keep-state uid root

# Sta ping toe.
$cmd 00250 allow icmp from any to any out via $pif keep-state

# Sta Time toe naar buiten.
$cmd 00260 allow tcp from any to any 37 out via $pif setup keep-state

# Sta NNTP nieuws toe naar buiten.
$cmd 00270 allow tcp from any to any 119 out via $pif setup keep-state

# Sta beveiligde FTP, Telnet en SCP toe naar buiten.
# Deze functie maakt gebruik van SSH (secure shell).
$cmd 00280 allow tcp from any to any 22 out via $pif setup keep-state

# Sta whois toe naar buiten.
$cmd 00290 allow tcp from any to any 43 out via $pif setup keep-state

# Blokkeer en log al het andere dat probeert buiten te komen.
# Deze regel dwingt de 'block all' logica af.
$cmd 00299 deny log all from any to any out via $pif

#################################################################
# Interface aan het publieke Internet (onderdeel Inkomend).
# Inspecteert pakketten die van het publieke Internet komen
# met als bestemming de host zelf of het private netwerk.
#################################################################

# Blokkeer al het verkeer voor niet-routeerbare of gereserveerde
# adresreeksen.
$cmd 00300 deny all from 192.168.0.0/16 to any in via $pif   #RFC 1918 privaat IP
$cmd 00301 deny all from 172.16.0.0/12 to any in via $pif     #RFC 1918 privaat IP
$cmd 00302 deny all from 10.0.0.0/8 to any in via $pif        #RFC 1918 privaat IP
$cmd 00303 deny all from 127.0.0.0/8 to any in via $pif       #loopback
$cmd 00304 deny all from 0.0.0.0/8 to any in via $pif         #loopback
$cmd 00305 deny all from 169.254.0.0/16 to any in via $pif    #DHCP auto-config
$cmd 00306 deny all from 192.0.2.0/24 to any in via $pif      #gereserveerd voor documentatie
$cmd 00307 deny all from 204.152.64.0/23 to any in via $pif   #Sun cluster interconnect
$cmd 00308 deny all from 224.0.0.0/3 to any in via $pif       #Klasse D & E multicast

# Blokkeer publieke pings.
$cmd 00310 deny icmp from any to any in via $pif

# Blokkeer ident.
$cmd 00315 deny tcp from any to any 113 in via $pif

# Blokkeer alle Netbios diensten. 137=naam, 138=datagram, 139=sessie.
# Netbios is de Windows® bestandsdeeldienst.
# Blokkeer Windows hosts2 name server verzoeken 81.
$cmd 00320 deny tcp from any to any 137 in via $pif
$cmd 00321 deny tcp from any to any 138 in via $pif
$cmd 00322 deny tcp from any to any 139 in via $pif
$cmd 00323 deny tcp from any to any 81 in via $pif

# Blokkeer gefragmenteerde pakketten.
$cmd 00330 deny all from any to any frag in via $pif

# Blokkeer ACK pakketten die niet in de tabel met dynamische regels
# staan.
$cmd 00332 deny tcp from any to any established in via $pif

# Geef toegang tot de DHCP server van de ISP voor kabel- en
# xDSL-netwerken. Deze regel is niet nodig als gebruik gemaakt worden
# van PPP naar het publieke Internet. In dat geval kan de hele groep
# verwijderd worden. Hier wordt hetzelfde IP adres gebruikt als in de
# sectie voor Uitgaand verkeer.
#$cmd 00360 allow udp from any to x.x.x.x 67 in via $pif keep-state

# Sta inkomend webverkeer toe omdat er een Apache server draait.
$cmd 00400 allow tcp from any to me 80 in via $pif setup limit src-addr 2

# Sta beveiligde FTP, telnet en SCP toe vanaf Internet.
$cmd 00410 allow tcp from any to me 22 in via $pif setup limit src-addr 2

# Sta niet beveiligde telnet sessie toe vanaf het publieke Internet.
# Dit heeft het label ``niet veilig'' omdat gebruikersnaam en
# wachtwoord als platte tekst over Internet gaan. Als er geen telnet
# server draait, hoeft deze regel niet actief te zijn.
$cmd 00420 allow tcp from any to me 23 in via $pif setup limit src-addr 2

# Weiger en log alle niet toegestane inkomende verbindingen van buiten.
$cmd 00499 deny log all from any to any in via $pif

# Al het andere verkeer wordt standaard geblokkeerd. Weiger en log alle
# pakketten die tot hier zijn gekomen om te bekijken welke het waren.
$cmd 00999 deny log all from any to any
################ Einde bestand met IPFW regels ########################

30.6.5.7. Voorbeeld NAT en stateful regels

Om NAT met IPFW te gebruiken moeten een extra aantal instellingen gemaakt worden. In het instellingenbestand voor de kernel moet option IPDIVERT toegevoegd worden aan de andere opties van IPFIREWALL.

Naast de normale IPFW opties in /etc/rc.conf zijn de volgende nodig:

natd_enable="YES"                   # Schakel NATD in
natd_interface="rl0"                # interfacenaam voor de publieke Internet NIC
natd_flags="-dynamic -m"            # -m = behoud poortnummers als mogelijk

Stateful regels samen met de regel divert natd (Network Address Translation) gebruiken maakt het schrijven van regels veel gecompliceerder. De plaats van de regels met check-state en divert natd zijn van kritiek belang. De logica bestaat niet langer uit het eenvoudigweg van boven naar beneden doorwerken van de regels. Er wordt dan ook een nieuw type actie gebruik: skipto. Bij het gebruik van skipto is het verplicht iedere regel te nummeren zodat duidelijk is waar een skipto precies heen springt.

Hieronder staat een groep regels zonder commentaar waarin een manier om pakketten door de groep regels te leiden wordt aangegeven.

De verwerking begint met de eerste regel en er wordt steeds een volgende regel gecontroleerd tot het einde wordt bereikt of totdat een regel op het gecontroleerde pakket van toepassing is, en het pakket uit de firewall wordt vrijgelaten. In het voorbeeld zijn de regels 100, 101, 450, 500, en 510 van belang. Die regels regelen de vertaling van inkomende en uitgaande pakketten zodat er in de tabel met de dynamische keep-state-regels altijd het private IP-adres staat. Daarnaast is het van belang op te merken dat er in alle allow- en deny-regels de richting van het pakket wordt gecontroleerd (inkomend of uitgaand) en over welke interface het pakket gaat. Merk ook op dat alle uitgaande verzoeken voor het starten van een sessie met een skipto naar regel 500 gaan voor NAT.

Stel dat een gebruiker zijn webbrowser gebruikt om een webpagina op te halen. Webpagina's worden over poort 80 verzonden. Er komt een pakket de firewall binnen dat niet past bij regel 100 omdat het naar buiten gaat en niet naar binnen. Het komt voorbij regel 101 omdat dit het eerste pakket is en er dus nog niets over in de dynamische keep-state tabel staat. Als het pakket bij 125 aankomt blijkt het te passen bij die regel. Het gaat naar buiten door de interface aan het publieke Internet. Het pakket heeft dan nog steeds het bron-IP-adres van het private LAN. Als blijkt dat deze regel geldt, dan gebeuren er twee dingen: door keep-state wordt er een regel in de dynamische keep-state tabel gezet en wordt de aangegeven actie uitgevoerd. De actie is onderdeel van de informatie uit de dynamische tabel. In dit geval is het skipto rule 500. In regel 500 wordt NAT op het IP-adres van het pakket toegepast en dan kan het weg. Dit is van groot belang. Dit pakket komt aan op zijn bestemming en als er een pakket als antwoord terug komt, dan begint de verwerking van het antwoordpakket weer van voor af aan. Nu voldoet het aan regel 100 en dus wordt het bestemmingsadres vertaald naar het bijbehorende IP-adres op het LAN. Daarna past het bij de check-state-regel en wordt een vermelding in de tabel gevonden wat betekent dat er een bestaande sessie is en wordt het doorgelaten naar het LAN. Het gaat dan naar de PC op het LAN die als eerste een pakket heeft verzonden en die verstuurt een nieuw pakket met de vraag om een volgend segment met gegevens naar de server. Nu blijkt bij controle van de check-state-regel dat die op het pakket van toepassing moet zijn en er staat een vermelding in de tabel voor uitgaand verkeer. Daarom wordt de bijbehorende actie skipto rule 500 uitgevoerd. Het pakket springt naar regel 500, er wordt NAT op toegepast en het kan zijn weg vervolgen.

Wat betreft binnenkomende pakketten wordt alles dat onderdeel is van een bestaande sessie automatisch afgehandeld door de check-state-regel en de correct geplaatste divert natd-regels. Nu hoeven alleen de foute pakketten nog geweigerd te worden en moeten de inkomende geauthoriseerde diensten doorgelaten worden. In dit geval draait er een Apache server op de firewall-machine die vanaf Internet bereikbaar moet zijn. Het nieuwe inkomende pakket past bij regel 100 en het IP-adres wordt aangepast aan het interne IP-adres van de firewall-machine. Dat pakket wordt dan gecontroleerd op alle ongewenste eigenschappen en komt uiteindelijk aan bij regel 425 die van toepassing blijkt te zijn. In dat geval kunnen er twee dingen gebeuren: de pakketregel wordt in de dynamische keep-state tabel gezet, maar nu wordt het aantal nieuwe sessies dat van het bron IP-adres komt gelimiteerd tot twee. Dit is een bescherming tegen DoS-aanvallen op de dienst die op dat poortnummer wordt aangeboden. De actie is allow, dus het pakket wordt tot het LAN toegelaten. Voor het pakket dat als antwoord wordt verstuurd herkent de check-state regel dat het pakket bij een bestaande sessie hoort. Het stuurt het naar regel 500 voor NAT en stuurt het via de uitgaande interface weg.

Voorbeeld Set Regels #1:

#!/bin/sh
cmd="ipfw -q add"
skip="skipto 500"
pif=rl0
ks="keep-state"
good_tcpo="22,25,37,43,53,80,443,110,119"

ipfw -q -f flush

$cmd 002 allow all from any to any via xl0  # exclude LAN traffic
$cmd 003 allow all from any to any via lo0  # exclude loopback traffic

$cmd 100 divert natd ip from any to any in via $pif
$cmd 101 check-state

# Toegestaan uitgaand verkeer.
$cmd 120 $skip udp from any to xx.168.240.2 53 out via $pif $ks
$cmd 121 $skip udp from any to xx.168.240.5 53 out via $pif $ks
$cmd 125 $skip tcp from any to any $good_tcpo out via $pif setup $ks
$cmd 130 $skip icmp from any to any out via $pif $ks
$cmd 135 $skip udp from any to any 123 out via $pif $ks

# Blokkeer al het verkeer voor niet-routeerbare of gereserveerde
# adresreeksen.
$cmd 300 deny all from 192.168.0.0/16  to any in via $pif  #RFC 1918 privaat IP
$cmd 301 deny all from 172.16.0.0/12   to any in via $pif  #RFC 1918 privaat IP
$cmd 302 deny all from 10.0.0.0/8      to any in via $pif  #RFC 1918 privaat IP
$cmd 303 deny all from 127.0.0.0/8     to any in via $pif  #loopback
$cmd 304 deny all from 0.0.0.0/8       to any in via $pif  #loopback
$cmd 305 deny all from 169.254.0.0/16  to any in via $pif  #DHCP auto-config
$cmd 306 deny all from 192.0.2.0/24    to any in via $pif  #gereserveerd voor documentatie
$cmd 307 deny all from 204.152.64.0/23 to any in via $pif  #Sun cluster
$cmd 308 deny all from 224.0.0.0/3     to any in via $pif  #Klasse D & E multicast

# Toegestaan inkomend verkeer.
$cmd 400 allow udp from xx.70.207.54 to any 68 in $ks
$cmd 420 allow tcp from any to me 80 in via $pif setup limit src-addr 1

$cmd 450 deny log ip from any to any

# Dit is de 'skipto' locatie voor de uitgaande stateful regels.
$cmd 500 divert natd ip from any to any out via $pif
$cmd 510 allow ip from any to any

######################## Einde regels  ##################

Het volgende voorbeeld doet vrijwel hetzelfde als het bovenstaande, maar volgt een zelfdocumenterende stijl voor het opstellen van regels en commentaar waardoor minder ervaren gebruikers beter kunnen begrijpen wat de regels doen.

Voorbeeld Set Regels #2:

#!/bin/sh
################ Begin bestand met IPFW regels ###############################
# Verwijder eerst de bestaande regels.
ipfw -q -f flush

# Stel commando voorvoegsel in.
cmd="ipfw -q add"
skip="skipto 800"
pif="rl0"     # Interfacenaam van NIC die verbinding
              # met het publieke Internet heeft.

#################################################################
# Geen beperkingen op de interface aan de LAN kant.
# Wijzig xl0 naar de gebruikte interfacenaam.
#################################################################
$cmd 005 allow all from any to any via xl0

#################################################################
# Geen beperkingen op de loopback interface.
#################################################################
$cmd 010 allow all from any to any via lo0

#################################################################
# Controleer of pakket inkomend is. NAT in dat geval.
#################################################################
$cmd 014 divert natd ip from any to any in via $pif

#################################################################
# Sta het pakket toe als het aan de tabel met dynamische regels
# was toegevoegd met een 'allow keep-state' commando.
#################################################################
$cmd 015 check-state

#################################################################
# Interface aan het publieke Internet (onderdeel Uitgaand).
# Inspecteer verzoeken om een sessie te starten van achter de
# firewall op het private netwerk of vanaf de server zelf naar
# het publieke Internet.
#################################################################

# Geef toegang tot de DNS server van de ISP.
# x.x.x.x moet het IP adres van de DNS van de ISP zijn.
# Dupliceer deze regels als een ISP meerdere DNS servers heeft.
# Haal het IP adres evt. uit /etc/resolv.conf
$cmd 020 $skip tcp from any to x.x.x.x 53 out via $pif setup keep-state

# Geef toegang tot de DHCP server van de ISP voor kabel en xDSL.
$cmd 030 $skip udp from any to x.x.x.x 67 out via $pif keep-state

# Sta niet beveiligd www verkeer toe.
$cmd 040 $skip tcp from any to any 80 out via $pif setup keep-state

# Sta beveiligd www verkeer over TLS SSL toe.
$cmd 050 $skip tcp from any to any 443 out via $pif setup keep-state

# Sta het verzenden en ontvangen van e-mail toe.
$cmd 060 $skip tcp from any to any 25 out via $pif setup keep-state
$cmd 061 $skip tcp from any to any 110 out via $pif setup keep-state

# Sta de FreeBSD CVSUP functie toe voor uid root.
$cmd 070 $skip tcp from me to any out via $pif setup keep-state uid root

# Sta ping toe naar het publieke Internet.
$cmd 080 $skip icmp from any to any out via $pif keep-state

# Sta Time toe.
$cmd 090 $skip tcp from any to any 37 out via $pif setup keep-state

# Sta NNTP nieuws toe.
$cmd 100 $skip tcp from any to any 119 out via $pif setup keep-state

# Sta beveiligde FTP, Telnet en SCP toe.
# Deze functie maakt gebruik van SSH (secure shell).
$cmd 110 $skip tcp from any to any 22 out via $pif setup keep-state

# Sta whois toe.
$cmd 120 $skip tcp from any to any 43 out via $pif setup keep-state

# Sta NPT tijdserver toe.
$cmd 130 $skip udp from any to any 123 out via $pif keep-state

#################################################################
# Interface aan het publieke Internet (onderdeel Inkomend).
# Inspecteert pakketten die van het publieke Internet komen met
# als bestemming deze gateway-server zelf of het private netwerk.
#################################################################

# Blokkeer al het verkeer voor niet-routeerbare of gereserveerde
# adresreeksen.
$cmd 300 deny all from 192.168.0.0/16  to any in via $pif  #RFC 1918 privaat IP
$cmd 301 deny all from 172.16.0.0/12   to any in via $pif  #RFC 1918 privaat IP
$cmd 302 deny all from 10.0.0.0/8      to any in via $pif  #RFC 1918 privaat IP
$cmd 303 deny all from 127.0.0.0/8     to any in via $pif  #loopback
$cmd 304 deny all from 0.0.0.0/8       to any in via $pif  #loopback
$cmd 305 deny all from 169.254.0.0/16  to any in via $pif  #DHCP auto-config
$cmd 306 deny all from 192.0.2.0/24    to any in via $pif  #gereserveerd voor documentatie
$cmd 307 deny all from 204.152.64.0/23 to any in via $pif  #Sun cluster
$cmd 308 deny all from 224.0.0.0/3     to any in via $pif  #Klasse D & E multicast

# Blokkeer ident.
$cmd 315 deny tcp from any to any 113 in via $pif

# Blokkeer alle Netbios diensten. 137=naam, 138=datagram, 139=sessie.
# Netbios is de Windows® bestandsdeeldienst.
# Blokkeer Windows hosts2 name server verzoeken 81.
$cmd 320 deny tcp from any to any 137 in via $pif
$cmd 321 deny tcp from any to any 138 in via $pif
$cmd 322 deny tcp from any to any 139 in via $pif
$cmd 323 deny tcp from any to any 81  in via $pif

# Blokkeer gefragmenteerde pakketten.
$cmd 330 deny all from any to any frag in via $pif

# Blokkeer ACK pakketten die niet in de tabel met dynamische regels
# staan.
$cmd 332 deny tcp from any to any established in via $pif

# Geef toegang tot de DHCP server van de ISP voor kabel- en
# xDSL-netwerken. Deze regel is niet nodig als gebruik gemaakt worden
# van PPP naar het publieke Internet. In dat geval kan de hele groep
# verwijderd worden. Hier wordt hetzelfde IP adres gebruikt als in de
# sectie voor Uitgaand verkeer.
$cmd 360 allow udp from x.x.x.x to any 68 in via $pif keep-state

# Sta inkomend webverkeer toe omdat er een Apache server draait.
$cmd 370 allow tcp from any to me 80 in via $pif setup limit src-addr 2

# Sta beveiligde FTP, telnet en SCP toe vanaf Internet.
$cmd 380 allow tcp from any to me 22 in via $pif setup limit src-addr 2

# Sta niet beveiligde telnet sessie toe vanaf het publieke Internet.
# Dit heeft het label ``niet veilig'' omdat gebruikersnaam en
# wachtwoord als platte tekst over Internet gaan. Als er geen telnet
# server draait, hoeft deze regel niet actief te zijn.
#$cmd 390 allow tcp from any to me 23 in via $pif setup limit src-addr 2

# Weiger en log alle niet toegestane inkomende verbindingen vanaf het
# publieke Internet.
$cmd 400 deny log all from any to any in via $pif

# Weiger en log alle niet toegestane uitgaande verbindingen naar
# Internet.
$cmd 450 deny log all from any to any out via $pif

# Dit is de 'skipto' locatie voor de uitgaande stateful regels
$cmd 800 divert natd ip from any to any out via $pif
$cmd 801 allow ip from any to any

# Al het andere verkeer wordt standaard geblokkeerd. Weiger en log alle
# pakketten die tot hier zijn gekomen om te bekijken welke het waren.
$cmd 999 deny log all from any to any
################ Einde bestand met IPFW regels ########################

All FreeBSD documents are available for download at http://ftp.FreeBSD.org/pub/FreeBSD/doc/

Questions that are not answered by the documentation may be sent to <freebsd-questions@FreeBSD.org>.
Send questions about this document to <freebsd-doc@FreeBSD.org>.