Free of Open?

Van een FreeBSD firewall naar een OpenBSD firewall met flashrd.

 

“FreeBSD firewalls hebben een goede reputatie. FreeBSD heeft de keuze gemaakt om de bestaande code te verbeteren zodat deze beter performt op multi processor systemen (SMP). Hierdoor is de hoeveelheid nieuwe features beperkt. Hier liep ik tegen aan toen ik een aantal nieuwe features moest implementeren in een kritische produktie-omgeving. OpenBSD bevatte wel de gewenste features, een simpelere manier van regels beschrijven, en door de verbeterde manier om NAT regels te beschrijven werd het ineens wel mogelijk om een VPN verbinding werkend te krijgen. Omdat er snel en veilig upgrades gedaan moesten worden is ervoor gekozen om flashrd te gaan gebruiken.”

 

FreeBSD's PF stamt nog uit de tijd van OpenBSD 4.5 (mei 2009) en is daarna niet meer gesynchroniseerd met OpenBSD's nieuwere features. Er is wel aan de FreeBSD implementatie gewerkt, maar zoals eerder beschreven met name gericht op performance verbeteringen bij multiprocessor systemen (SMP). Naast de nieuwere features zijn hierdoor ook semantiek versimpelingen niet meegenomen.

 

OpenBSD's ontwikkelingen zijn onder andere het verbeteren van de regel semantiek. Had je eerst 3 regels nodig om een aantal redirect en/of nat rules te maken, nu is dat er 1. Hierdoor is het dus mogelijk om deze combinatie aan regels te reduceren. In de firewall configuratie die ik onder handen moest nemen moet je hierbij denken aan 300 firewall regels voor de migratie naar 200 firewall regels na de migratie.

 

Doordat regels nu slimmer te combineren zijn wordt de hoeveelheid regels drastisch beperkt. Minder regels betekent over het algemeen dat deze beter te lezen zijn, de rulebase wordt overzichtelijker. Een overzichtelijke rulebase zorgt vervolgens ervoor dat deze beter begrepen wordt waarna de beheerders minder fouten zullen maken bij het aanpassen van de rulebase.

 

De oude opstelling was niet gebouwd om snel en flexibel te kunnen updaten.  Omdat het vandaag de dag wenselijk is om snel nieuwe features, en configuratie wijzigingen te doen ,is er bij het bekijken van een nieuw firewall platform gekeken of dit ook meegenomen kon worden. De beoogde machines waarop dit firewall platform komt te draaien is een aantal Soekris appliances. Soekrissen bieden de mogelijkheid om een interne SSD (mini PCIe) te gebruiken en/of op te starten via USB-stick. Het gebruik van SSD betekent wel dat de kast open gemaakt moet worden als er een nieuwe image of configuratie geplaatst moet worden. De USB-stick is hier de oplossing. Deze kan zonder het openen van de kast geplaatst en verwijderd worden wat de benodigde flexibiliteit levert.

 

Gezien bovenstaande wensen en de mogelijkheden die OpenBSD biedt, en de eis om USB-sticks te kunnen gebruiken is ervoor gekozen om flashrd te gebruiken. Flashrd is een applicatie die OpenBSD 5.4 STABLE gebruikt. Flashrd combineert daarnaast een voorbereide configuratie met het besturingssysteem en maakt hiervan een heel kleine USB image (kleiner dan 1GB). Dit maakt het mogelijk om zowel OpenBSD als USB sticks te gebruiken. Deze keuze werd hierdoor eenvoudig; dit was het platform en de applicatie die nodig is om de nieuwe firewalls op te baseren.

 

Nu  de inventarisatie, onderzoeken en overwegingen gedaan zijn, en de keuze gemaakt is, is het tijd om de werkomgeving op te gaan bouwen. Vandaag de dag leveren hardware leveranciers goed uitgeruste apparaten. Deze zijn vaak voorzien van een grote hoeveelheid opslag en geheugen. Dit gaf mij de mogelijkheid om de werkomgeving geheel virtueel te maken. Ik ben dan ook begonnen met het opzetten van een aantal Virtual Machines (VM's) op mijn werklaptop, en had ik de beschikking over de Soekris en een USB-stick.

 

Virtuele Machines opzetten

Voor het VM gedeelte heb ik gebruik gemaakt van 3 VM's, een bouwVM (1 CPU, 10GB disk); een testVM (1 CPU, 10GB diskruimte); en een kale VM (1 CPU, 10GB diskruimte en voldoende netwerkkaarten).

 

De bouwVM is met name bedoeld om door middel van flashrd een aantal images te kunnen produceren en te kunnen testen of dat proces goed werkt.

De testVM is om te configuraties te kunnen testen los van een installatie eromheen, een standaard OpenBSD installatie vormde de ondergrond (deze VM is optioneel).

De laatst gebruikte VM is een kale VM; deze VM heeft dezelfde hoeveelheid netwerkkaarten als de beoogde machines hebben, hierop is vooraf geen installatie opgezet. Dat geeft namelijk een uitgelezen mogelijkheid om met wat trucjes een image te kunnen wegschrijven en daarmee het USB gedeelte te kunnen nabootsen. VMware in de door mij gebruikte setup ondersteunt geen bootable USB-sticks.

 

Flashrd gaat ervanuit dat je voldoende ruimte hebt om in de /tmp partitie bestanden te kunnen plaatsen.  De volgende df output geeft een beeld van hoe dat er dan uit kan zien:

 

# df -h

Filesystem     Size    Used   Avail Capacity  Mounted on

/dev/wd0a      480M   52.6M    403M    12%    /

/dev/wd0k      4.5G    1.1G    3.2G    25%    /home

/dev/wd0d      763M   20.0M    705M     3%    /tmp

/dev/wd0f      1.3G    429M    794M    35%    /usr

/dev/wd0g      743M    192M    514M    27%    /usr/X11R6

/dev/wd0h      2.8G    214K    2.6G     0%    /usr/local

/dev/wd0j      1.6G    2.0K    1.5G     0%    /usr/obj

/dev/wd0i      1.1G    949M    161M    85%    /usr/src

/dev/wd0e      1.1G    8.5M    1.0G     1%    /var

Dit geeft aan dat er maar 705MB beschikbaar is op de /tmp partitie. Ter illustratie, een standaard image is ca 1GB groot. Ik heb ervoor gekozen om gebruik te maken van de  /home partitie.

 

Wat is flashrd?

 

Zoals eerder al kort beschreven is flashrd een applicatie die met name geschreven is voor het produceren van images voor embedded systemen. Er is minstens 64 mb aan intern geheugen nodig en voor een image ca 1GB diskruimte. Aangeraden wordt om minstens 128mb ram beschikbaar te hebben, en als er meerdere images geplaatst moeten worden voor upgrades wordt een 4GB USB-stick aangeraden. De kleine images worden op USB-stick geschreven en vanaf daar deels via een memory filesystem (mfs) aan het systeem beschikbaar gemaakt. Deze filesystems zijn read-only, zodat het systeem elke keer op dezelfde manier opstart. Mocht het iemand lukken om in te breken op het systeem zal deze niet per definitie wijzigingen kunnen maken. Deze kleine images, tezamen met een voorbereide configuratie maken het mogelijk om snel geschikte images te maken waarmee apparaten zoals een Soekris gestart kunnen worden.

 

Flashrd installeren

 

Als de handleiding van flashrd gevolgd wordt, is te lezen dat men een aantal directories verwacht c.q. aanraadt. In de /home partitie heb ik een tmp/ directory aangemaakt. Hieronder zijn vervolgens de beoogde directories aangemaakt. Hierdoor heb je enerzijds de OpenBSD bestanden beschikbaar en anderzijds de flashrd bestanden om de 'build' te kunnen doen:

 

mkdir /home/tmp

mkdir /home/tmp/openbsd
mkdir /home/tmp/flashrd

Download de flashrd software van de website (http://www.nmedia.net/flashrd/flashrd-1.4.tar.gz) en pak deze uit in de flashrd directory:

tar xzpf /home/tmp/flashrd/flashrd-1.4.tar.gz -C /home/tmp/flashrd/

Download daarna een aantal bestanden van een OpenBSD mirror (http://ftp.nluug.nl/pub/OpenBSD/5.4/amd64/) zodat er een goede volledige image gebouwd kan worden. Deze worden geplaatst in de /home/tmp/openbsd directory: etc54.tgz, base54.tgz. Optioneel kunnen de volgende bestanden ook gedownload worden, maar deze zijn zeker niet verplicht: man54.tgz, comp54.tgz.

Flashrd maakt naast de gedownloade bestanden ook gebruik van de 'sourcetree' van OpenBSD. Dat is de broncode lijst zoals deze gebruikt wordt door de ontwikkelaars. Deze sourcetree kan direct worden gedownload vanaf een OpenBSD Mirror:

cd /usr/src && cvs -d anoncvs@openbsd.cs.fau.de:/cvs -q get -rOPENBSD_5_4 src

SSH fingerprints:

(RSA) 2048 d0:f2:0c:a3:bf:28:ba:18:50:5f:04:dc:13:ed:63:42
 (DSA) 1024 9f:a1:78:0b:d4:76:68:bf:3e:83:d0:41:c8:1e:33:8b
 (ECDSA) 256 f0:d1:64:e6:6b:2f:9e:1e:85:aa:75:e3:a0:52:d3:5a

Vergeet niet om de fingerprints te valideren voor je er gebruik van maakt, als ze overeenkomen geeft dat een betrouwbaarder beeld van de mirror. Als de fingerprints niet overeenkomen zoek dan een andere mirror met gepubliceerde bekende fingerprints die wel kloppen.

We kunnen nu met flashrd aan de slag, we maken zoveel mogelijk gebruik van de standaard instellingen. Dat betekent dat er straks een image beschikbaar is die ca 1GB groot zal zijn. Dat past dus ruim op de hedendaagse (commerciële) USB-sticks.

Flashrd gebruiken

De syntax om een image te maken via flashrd is heel simpel. Vanuit de directory waar de uitgepakte flashrd bestanden staan doen we het volgende:

./flashrd /home/tmp/openbsd

Flashrd pakt nu de directory waar  de openbsd installatie geplaatst is, onder water wordt /usr/src gebruikt voor de kernel. De bestanden die worden gegenereerd, is in mijn geval amd64-<datum> en flashimg.amd64-<datum>.  Het laatste bestand is het bestand welke gebruikt wordt om te schrijven naar USB-stick. Let wel dat als je meerdere images op dezelfde dag maakt, deze de voorgaande overschrijft. Maak van elke goede image die je wilt bewaren een reserve kopie om te voorkomen dat je deze kwijt raakt!

Flashrd console instellen

De standaard configuratie is ingesteld op een PC. Dat wil zeggen dat er een grafische omgeving wordt gebruikt om het scherm aan te sturen en er een keyboard beschikbaar is. Op de test soekris is dat niet het geval. Er moest een aanpassing komen om dit standaard gedrag om te zetten. Naast deze aanpassing moest ik ook de serial-speed aanpassen zodat deze overeenkwam met de gekozen waardes. Om dat te doen kun je het volgende intypen:

./cfgflashrd -c “38400” -i flashimg.amd64-<datum>

Het cfgflashrd bestand is een bestand wat een bestaande image aanpast met de waarden die jij opgeeft. De optie -c <getal> betekend het inschakelen van de console op een bepaalde baud snelheid. De optie -i <naam> geeft aan welke image bewerkt moet worden. Indien gewenst is het mogelijk om direct een apparaat te beschrijven. In het geval dat er een VM gebruikt wordt raad ik dat sterk af in verband met de schrijftijd naar een USB stick.

Omdat het werken in een VM en het schrijven naar een USB-stick potentieel lang duurt heb ik ervoor gekozen om de image naar mijn Apple laptop zelf te kopieren, en vanaf daar schrijf ik de usb image naar een rdisk (raw disk) omdat dat veruit de snelste manier is om een image weg te schrijven. In mijn geval is dat op de volgende manier:

sudo dd if=flashimg.amd64-<datum> of=/dev/rdisk2 bs=1m

Omdat er geen standaard root-user is op een Apple, wordt sudo gebruikt om commando's met verhoogde privileges aan te spreken. Dat is in dit geval nodig omdat we direct naar een apparaat gaan schrijven. Dat wordt gedaan door middel van dd, dd is in staat om 'images' te schrijven naar apparaten. Zo kan bijvoorbeeld een ISO bestand worden weggeschreven naar een USB-stick, of een firmware image voor een Soekris. De optie if=<naam> is de input naam welke gelezen en geconverteerd moet worden naar de optie of=<naam>. Deze of=<naam> wordt gebruikt om het geconverteerde bestand uiteindelijk weg te schrijven. De optie bs=<naam> staat voor de grootte van de blocks die geschreven worden. Veelal ligt die waarde tussen de 512 en 1024(1M) waarmee het snelst een bestand kan worden weggeschreven. De actie duurt ongeveer 2 minuten.

Na het beschrijven van de USB-stick kun je proberen om deze in een Soekris of welke machine dan ook te plaatsen en te booten vanaf USB. Als alles goed gewerkt heeft, heb je een standaard installatie op USB staan. Let wel, deze standaard configuratie en installatie is waarschijnlijk niet wat je wilt, er missen specifieke configuraties.

Specifieke configuraties

Standaard worden er twee bestanden uit de etc/ directory gekopieerd. De gebruikte etc/ directory is afkomstig uit de OpenBSD directory waar ik eerder naar verwees hebben : /home/tmp/openbsd (ofwel volledig: /home/tmp/openbsd/etc). Deze bestanden zijn pwd.db en login.conf.

In mijn geval wilden we hier een DHCP configuratie, een Firewall configuratie, een rc.conf.local configuratie om lokale diensten te kunnen starten, etc. in meenemen. Allereerst moet ervoor gezorgd worden dat de gewenste configuratie in de etc/ map komt te staan.

In de opstelling die ik moest bouwen, heb ik ook een aantal directories die naast de configuratie bestanden meegekopieërd moesten worden. Standaard is het niet mogelijk om directories (recursieve bestanden) te kopiëren, hiervoor moet een extra wijziging gemaakt worden in het script wat hiervoor zorgt.

De lijst van de te kopiëren bestanden vinden zich in het bestand mkrdroot welke zich in de directory bevind waar flashrd is uitgepakt.

Ik maak zelf gebruik van vi, maar elke willekeurige editor is goed genoeg om de volgende wijzigingen te maken:

vi mkrdroot

Zoek naar de volgende regel:

[ -z "$etccopy" ] && etccopy="etc/login.conf etc/pwd.db”

En pas deze aan naar

[ -z "$etccopy" ] && etccopy="etc/login.conf etc/pwd.db [vul hier de bestanden en eventueel directories aan die gekopieerd moeten worden]”

Na deze aanpassing moet er nog een klein stukje worden aangepast:

for i in $etccopy; do

 echo -n " $i"

 c 2 cp -r $distloc/$i $tmpmntdir/etc
done
echo

De gemarkeerde -r zorgt ervoor dat de directories wel naar wens worden meegekopieërd.

Valkuilen

Tijdens het aanpassen van de configuratie om mijn eigen wijzigingen mee te geven liep ik tegen een aantal beperkingen aan. De /etc schijf die virtueel wordt meegegeven op de USB-stick is relatief klein. Hierdoor is in de standaard installatie net voldoende ruimte voor de standaard configuratie. Een kleine afwijking kan er al voor zorgen dat deze niet meer past. Als je dan net als ik denk om de /etc directory dan maar te vergroten, kan dit weer op andere fronten tot problemen leiden. Houd je in dit geval dus zoveel als mogelijk aan de defaults. Is het echt nodig om deze aan te passen zorg er dan voor dat je volledig op de hoogte bent van de wijzigingen.

Een voorbeeld van hoe /etc gewijzigd kan worden:

export vnddirs="root bin etc sbin usr home"  # must match vnddirs= in stand/rc and fstab

export vndsize="50 auto 50 auto auto 512"   # min partition sizes (or auto) (in MBytes)

Overigens zijn de veroorzakers van een goed gevulde /etc met name de externe firmwares die meegeleverd worden. Omdat ik deze niet nodig had heb ik die eruitgehaald door het uitcommentariëren van de bestanden in firmware.list, te vinden in de directory waarin flashrd is uitgepakt. Mocht je toch een firmware nodig hebben kun je deze eenvoudig weg weer inschakelen door het commentaar teken te verwijderen.

Let ook op als je configuraties aangeleverd krijgt. Flashrd start alleen als er in rc.conf.local als eerste /etc/rc.flashrd.conf wordt aangeroepen, zodat het flashrd subsysteem geladen wordt. Zonder deze regel zal flashrd niet starten.

Naast het niet vergeten van deze stap, is het ook verstandig om te bepalen of je de /var partitie wilt backuppen, hierin staan onder andere leases en andere potentieel nuttige informatie die een reboot moeten overleven. In het geleverde bestand /etc/rc.flashrd.sub (tip: pas deze aan op de bouw machine) kun je instellen welke directories met tar moeten worden ingepakt en op de image geplaatst worden. Na het herstarten worden deze directories vervolgens teruggezet.

Haal het commentaar teken in het genoemde bestand weg van de volgende regel:

#savetardirs="$tardirs"

Mocht het nodig zijn om andere directories te backuppen dan /var, zorg dan dat deze opgenomen is in de tardirs= variabele in /etc/rc.flashrd.sub. Lees goed het commentaar wat eromheen staat voor hier wijzigingen gemaakt worden.

Testen met de Virtuele Machines

Omdat we de installatie willen testen maar het mogelijk een heel gedoe is om dit met de USB stick te doen, kan dat ook via een testVM.

Deze heeft als lastigheid dat deze niet kan starten vanaf een USB-stick. Er moet dus omheen gewerkt worden. Ik heb hiervoor een liveCD van OpenBSD gedownload (http://livecd-openbsd.sourceforge.net) en hiermee de kale VM opgestart. Standaard wordt hierop ingelogd met de gebruiker root en het wachtwoord openbsd1729. Zorg ervoor dat je een custom liveCD maakt als je deze op onveilige plekken gaat gebruiken!

Zodra je ingelogd bent op de machine, kun je zien dat wd0 de VMWare disk is. Omdat een liveCD beperkt is qua geheugen en opslag, moeten we een workaround hiervoor toepassen. We gaan gebruik maken van het programma netcat (nc). Op mijn laptop start ik deze in de directory waarin ik al eerder de image heb geplaatst om naar USB-stick te schrijven:

nc -p 2222 < flashimg.amd64-<datum>

Met het bovenstaande commando zorgen we ervoor dat een netcat server actief is op poort 2222 en dat, als deze wordt aangesproken, hij de inhoud van de genoemde flashimg ophoest.

Op de liveCD staat ook het bestand netcat, deze gebruiken we om aan te geven dat we een netcat client sessie willen starten en daar moet iets specifieks mee gebeuren:


nc <hostname/ip> 2222 dd of=/dev/wd0 bs=512k

Hierboven staat aangegeven wat netcat moet doen, allereerst geven we het remote IP adres op waar we netcat actief hebben, tezamen met de gebruikte poort. Daarachter staat het commando die uitgevoerd moet worden met de informatie die via netcat wordt aangeleverd. Omdat de netcat server meteen begint met 'spugen' van informatie, hebben we een alternatieve dd gebruikt met alleen een output en een blocksize, de input komt via de 'standaardinput' en hoeft dus niet te worden opgegeven.

Zodra dit gedaan is, en de machine wordt herstart, heb je een exacte kopie van de USB-stick op een VMware harddisk staan. Je zult zien dat je hiermee dan ook een 'echte' OpenBSD installatie hebt die hetzelfde werkt als vanaf de stick.

Resultaat

Nu de specifieke configuratie is meegegeven, we een geprepareerde image hebben, is het zaak om deze te testen. Ik heb de stick in de Soekris gestopt en door middel van de console koppeling bekeken wat er gebeurde. Na een aantal dagen testen en spelen met de diverse opties zag ik op dat moment voor het eerste een succesvolle boot. Het systeem was hiermee ready to go!

Het opnieuw maken van een image, welke naar USB-stick geschreven wordt, is hiermee erg makkelijk. Enkele dagen achter elkaar heb ik nieuwe images gemaakt. Deze images vervolgens weggeschreven naar USB-stick en elke dag een herstart gedaan van de 'nieuwe' image. Met en zonder configuratie wijzigingen. Dat werkte perfect en naar wens.

Dit betekent dat ik hiermee een aantal OpenBSD firewalls kan prepareren, voorbereiden en offline alvast kan testen voor ik deze naar de productie firewalls breng. Om eventuele problemen voor te zijn, zijn er meerdere USB-sticks in omloop op kantoor. Mocht er een onverwachte outage zijn ben ik in staat om binnen een paar minuten een nieuwe USB-stick te maken, naar de firewalls te lopen en een nieuwe stick te plaatsen. Na de herstart is de machine volledig zoals voorheen.

Moet er een upgrade plaats vinden? Dan kan hetzelfde proces worden gehanteerd. Sterker nog, ik ben in staat om een nieuwe upgrade klaar te zetten, offline te testen. Mocht deze in de praktijk toch niet leveren wat er geleverd moet worden? Dan haal ik de oude stick terug en plaats ik die. De machine wordt vervolgens herstart en binnen een paar minuten is de configuratie weer in de oude bekende werkende staat.

Zijn mijn doelstellingen gehaald? Jazeker! De opdrachtgever is tevreden met de nieuwe functionaliteit. De images leveren nu de gewenste flexibiliteit. Er is uitgebreide documentatie geschreven. Mission Accomplished!

Links

http://www.nmedia.net/flashrd/

http://www.openbsd.org

http://www.freebsd.org

http://www.pfsense.org

http://livecd-openbsd.sourceforge.net
http://ftp.nluug.nl/pub/OpenBSD/5.4/amd64/
http://www.soekris.com

Over de besturingssystemen:

BSD is -het- besturingssysteem dat ontwikkeld werd door de universiteit van Berkeley, afgeleid van het AT&T Unix systeem. FreeBSD en OpenBSD zijn beiden afgeleiden van BSD.

FreeBSD is een besturingssysteem ontwikkeld met een open licentie, veel gebruikt door leveranciers als Cisco, Juniper maar ook Apple (OS X). FreeBSD is de meest gebruikte BSD variant van allemaal, en combineert het beste van alle werelden met daarnaast zijn eigen inbreng. Een aantal ontwikkelaars uit het BSD project zelf, zijn nog steeds actief voor FreeBSD, zoals bijvoorbeeld Kirk McKusick.

OpenBSD is een besturingssysteem oorspronkelijk afkomstig uit een splitsing van NetBSD. NetBSD is een directe afgeleide van BSD. OpenBSD is opgericht door Theo de Raadt, berucht en beroemd binnen de Open Source community door zijn ongenuanceerde uitspraken, en visie op wat hij perse wilt bereiken. Het OpenBSD project richt zich met name op beveiliging, code auditing en het afdwingen van open licenties.

Over de schrijver:

Remko Lodder is een 30 jarige BSD-Unix fanaat, is committer en teamlid van het FreeBSD team, lid van het Security Team en diverse andere groepen. In zijn professionele leven werkt Remko voor Snow B.V. als Network en Security Engineer. In zijn vrije tijd woont hij samen met zijn vrouw Denise en kinderen Luca en Bram in Barendrecht.