Hackskydd i OpenBSD 3.3

Introduktion och historik
OpenBSDs skydd
Andra metoder

OpenBSD 3.3 - This you can trust



16/06-03 | IcePic | icepic@64bits.se


Introduktion och historik

För att kunna uppskatta denna artikel krävs det att man har lite koll på allmänt programmerande, virtuellt minne och hur buffer overflows någorlunda fungerar.

En ganska bra beskrivning av 'buffer overflows' finns här:
LinuxJournal

..men i korthet går det iallafall ut på att när man gör ett anrop eller hoppar till en subrutin så sparas en massa data på stacken tillsammans med anropets inparametrar och returaddressen dit man avser att återgå till när anropet är färdigt.

Om man då, via en bugg eller genom att göra något "oväntat" (som att mata in en 8000 tecken lång URL eller liknade), kan få en sträng eller en buffer att "flöda över" så kommer det extra datat att läcka in i omgivande data och allra helst (ur attackerarens perspektiv) skriva över returaddressen. Kan man skriva över returaddressen så kan man hoppa "vart man vill", lämpligen till kod man själv har kontroll över, men om man inte får det så finns det ofta en massa kod att ta av på andra ställen, t.ex delade bibliotek och liknande. En bra buffer overflow har koden med sig i själva overflowdelen så att samma data som orsakar själva 'kraschen' även innehåller koden man vill få programmet att exekvera.

Så fort det här inträffar så kommer den som sände bufferten till programmet att kunna köra kod som exekveras med samma rättigheter som programmet självt. Är det en mailserver som har rätt att ändra i folks mailkataloger så kan elak kod radera samtliga personers mail. Är det ett program som körs med fulla rättigheter så kan koden göra i princip "allt", från att boota om datorn, mata ut cd-luckan eller formattera om diskarna.

Det är ju en av de stora anledningarna till att MacOS6->9 och Win3/W9x/WinME suger så hårt som server, för oavsett vilken kod/tjänst man lyckas bräcka på en sån dator så äger man hela maskinen. Iden att logga in som icke-administrator på moderna OS är just för att om inte du kan formatera disken så kan inte ett nyss inkommet mailvirus eller en exploit du åkt på göra det heller.

Det elaka i sammanhanget är att det oftast rör sig om storleksordningen 1k, 4k eller 8k för att flöda över en buffer normalt, så det är inga som helst problem att köra en attack från en modemlina eller liknande. Det syns liksom inte om ens maskin tar emot 8k extra när den är kopplad på nätet. Inte ens på modem. Men så fort de är inne så är man rökt, direkt. 1-8k är dessutom gott om utrymme för att kunna få in elak kod. Den senaste vågen som kom av Slammer/Sapphireviruset är ett bra exempel. Där var viruskoden inte mer än 376 bytes lång. Även om dagens system verkar bloatade och programmen hur stora som helst så tar det fortfarande inte många hundra bytes att skriva kod som raderar din hårddisk, ditt registry eller annan liknande vital del. Om den koden råkar skita sig på 99% av systemen spelar ju ingen roll för en angripare, han kommer leta upp nästa måltavla på nätet bara och attackera vidare.

Gamla befintliga metoder att skydda sig med

Ett sätt har varit att se till att minnet där programmets stack lagras har egenskapen "executable" avslagen, eftersom man normalt sett inte ska köra kod i stacken. Stacken är ju en mellanlagringsplats för data (och även kod) men räknas ju inte som en plats dit man skulle hoppa till inifrån programmet, så det är normalt sett en ganska bra metod att exekveringsskydda stacken. Dock finns det ett par kompilatorer och språk som ändå förlitar sig på att stackens utrymme är körbart för att kunna skapa kod on-the-fly, och i dessa fall måste man få till en ändring av dem för att de ska kunna köras alls, vilket är svårt i vissa fall. Det går dessutom att lagra bus-koden i andra utrymmen än stacken, så det är inte ett heltäckande skydd i sig, även om det är vanligt med stack-smash:ande exploits.

Ett annat är ju att se till att de programmen som exponeras mot nätet eller som tar in info på ett okontrollerat sätt (t.ex inmatning från users eller valfria filer) körs med så lite privilegier som det bara går. Även här kan det vara problem att få det att funka i praktiken, eftersom program som t.ex mailservrar faktiskt måste kunna ändra i allt folks mailkataloger om den ska kunna leverera mail till dem.

Ett tredje sätt är att helt enkelt skriva om gammal kod i andra språk som har mer inbyggda kontroller och som inte på samma vis låter sig påverkas av den här typen av attacker. Det brukar ofta innebära en förlust i prestanda, men med dagens maskiner är det kanske inte lika märkbart om man går över till ett språk på högre nivå. Nackdelen med att skriva om saker blir bland annat att man kan introducera en mängd helt nya buggar i ett annars beprövat system.

Dessutom är det ingen garanti för att det nya språkets slutkod är buggfri vad gäller all datahantering. Språk som php, perl, python är ju interpreterande språk vars interpretatorer är skrivna i C/C++, så det finns ju en chans att C-koden som de baseras på innehåller tankefel och missar som ärvs uppåt till högnivåspråket trots att högnivåspråket i sig kanske inte ens kan ha overflowproblem per design. Det är ju skillnad på designen och implementationen i det läget.

OpenBSDs skydd

OpenBSD har alltid letat i sourcekoden efter svagheter och problem. Precis som linuxjournal-artikeln ovan anger så finns det en bunt anrop och funktioner som är osäkra i sin design, som är svåra att ens få felfria utom i väldigt specifika sammanhang. Anledningen till att de kunnat bli kvar så länge är ju att man under lång tid inte såg just buffer overflows som ett problem i sig, utan när en buffer slog över så kraschade applikationen och sen letade man efter buggen och ev. fixade just den. Anropen blev standard och alla kompilatorer och system vill givetvis följa standarden.

Det OpenBSD valde att göra var att när en ny typ av buggar upptäcktes så gick man igenom all kod som kunde tänkas vara känslig för samma typ av attack och skrev om den snutten till en säkrare version. Det var tidigare rätt vanligt i C att folk slog ihop strängar med "sprintf()" vilket är en av de problematiska anropen, och alla dessa byttes ut mot "snprintf()" som har en längdbegränsning. Först tog man nätverksdemonerna och all kod som har setuid-biten satt (dvs körs som en annan user än den som startar programmet) men nu nyligen i all kod man överhuvudtaget hittat dem i, oavsett om det nånsin kommer vara exploaterbart eller inte.

Så för varje typ av problem som upptäcks (ocheckad stränghantering, signed-vs-unsigned-jämförelser, off-by-one, inte droppa privilegier fort nog, race i tempfils-skapande eller race i signalhanterare osv) så har man letat efter liknande instanser i all kod. Ser man ett program som skapar tempfiler på ett osäkert sätt med anropet mktemp() så letar man upp alla ställen där mktemp() anropas och byter ut mot mkstemp() som är bättre på att skapa temporärfiler utan att riskera att den byts ut under fötterna på en.

Tyvärr så visar det sig att få andra distar (om man nu kallar OpenBSD för en dist) gör på det viset. De förlitar sig på att varje programs team ska "laga" allting själva i stor utsträckning eftersom de är så stora att de inte kan hålla ordning på koden själva. Då får man inte den samordningsvinst som OpenBSD lyckats ha på sin kod. Allt från webservern till de terminalbaserade spelen i /usr/games har fått en (många!) översyn vad gäller alla kända typer av hål och buggar.

Detta har länge varit OpenBSD's stora "övertag" på säkerhetsfronten, vid sidan om krypto som amerikabaserade distar inte kunnat ha med p.g.a. USA's idiotregler om att krypto var likställt med ammunition/vapen och därmed inte kunde exporteras.

Men det räcker inte med att ha tittat igenom koden "ett par gånger". Även om det skulle råka fånga upp alla buggar i koden man distribuerar så kommer folk att ladda ner andra program och installera, så det är en klar fördel om man kan skydda systemet i sig och inte bara se till att ha buggfria applikationer. Problem är hur man skyddar systemet utan att göra det oanvändbart.

Ett av skydden var ProPolice, ett tillägg till C-kompilatorn som kontrollerar att returaddressen inte är förstörd innan man returnerar. Det är inte vrålnytt utan har funnits tidigare i olika skepnader, bl.a som StackGuard och speciella gcc-versioner, men de tidigare har ofta krävt att man kör antingen x86 eller linux eller bådadera. Till slut fick man tag på en version som inte var plattformsberoende utan som fungerade överlag och den åkte in direkt.

Det man gör då är lägga "canaries" runt returaddressen, dvs junkdata med känt värde (som slumpas för varje körning) runt returaddressen och när sedan funktionen hoppar ur så kontrollerar den att dessa inte är borta. Skulle de vara det så kraschar applikationen omedelbart och loggar problemet. Eftersom en overflow oftast går ut på att flöda över lite av varje, inklusive returaddressen, så blir det väldigt mycket svårare att genomföra en attack oupptäckt. Ordet "canary" kommer ju ifrån gammaldags gruvdrift när man hade en kanariefågel med sig ner i gruvan, och eftersom de andas så fort så dog de mycket snabbare om det kom giftig gas i gruvan. Dog fågeln var det bara att springa mot utgången. På samma vis sitter "canary"-värdet runtom returaddressen på stacken, och innan man returnerar via returaddressen kontrollerar man att inte ens "canary" är död.

Ytterligare en detalj var det man kallar "Stack gap", nämligen att inte låta stacken (och indirekt returaddressen) ligga på samma plats/offset varje gång man kör, utan att även slumpa en offset för varje gång som ett program exekveras som läggs till på stacken innan alla operationer görs, vilket ytterligare försvårar för den potentielle hackern. På OpenBSD 3.3-releasen tror jag den slumpar mellan 1-4095 bytes offset, så det kostar ju runt 4k per startat program i RAMminne, men det är en rätt blygsam kostnad. Maxvärdet för slumpen går numera att ställa ännu högre för den som vill ha större variation, men 4k är ett ganska rimligt värde troligen.

Den som läst min tidigare artikel om virtuellt minne vet ju att ett program som körs i ett operativsystem med virtuellt minne alltid ser "likadant" ut ur sitt eget perspektiv, det tycker att det ligger på addressen 0x2000 och framåt eller liknande, även om det är mappat till en helt annan plats i det fysiska RAM:et. Även stacken ligger på samma plats, och ens allokerade data hamnar på samma virtuella plats om man allokerar minne i samma ordning varje gång man kör. Filer som mappas in i minnet ser ut att vara på samma plats och delade bibliotek likaså.

När man då skapar en buffer overflow så har man enorm hjälp av detta, eftersom man vet att den buffer som ligger på 0x435F46A på min maskin gör det även på din, om du kör samma OS/cpu/program. Det går alltså att labba fram alla addresser man behöver veta hemma i lugn och ro (eller scripta och sova medans datorn provar) och när man väl fått fram rätt addresser och offsets så skjuter man över nätet på alla maskiner av samma typ (vanligtvis redhat på x86 ;-) och vinner varje gång. Av den anledningen kan det vara skoj att ha en icke-linux på en icke-x86, eftersom det försvårar enormt för den som attackerar.

Det är ju inte bara negativt att det är på det viset med addresseringen, för det hjälper för supportfolk att om ditt program kraschar på address 0x123456 så kan jag se på min dator att det motsvarar rad 2345 i programmet och leta efter felen där. Men allt som är bra för "folk som sysslar med debuggning" är ju samtidigt bra för "elaka hackers som letar buggar" eftersom buffer overflows går ut på att bugga programmen och få dem att krascha på ett kontrollerat sätt.

Ett annat av skydden som kommer med OpenBSD 3.3 är Write-xor-Execute (W^X), vilket går ut på att man ser till att alla minnessidor som har fått Write-permission satt på sig blir av med Execute och tvärsom. Det låter enkelt, men visade sig vara beroende av cpu-typ och ställde till det för en del programspråk som faktiskt ville dumpa kod lite här och där och sedan exekvera den. Dessa måste man fixa genom att lägga till lite kod som kör anropet mprotect() och anger att "här ska man nu få exekvera" innan de hoppar till den nyskapade koden. Givetvis försvinner Write-rättigheten där då.

Den som inte hunnit tänka sig för kanske tycker att anropet skulle ju givetvis busarna också kunna använda, men se så enkelt är det ju inte. mprotect() körs ju (givetvis) från redan exekverande kod, medans busens kod ligger ju i en buffer nånstans i inkommande-arean hos programmet, kanske en nätverksbuffert eller så. Denna har givetvis Write-permission på sig, och följdaktligen inte Execute. När buffern sedan flödar över och en returaddress pekar in till den så sitter ju fortfarande Write/Read men inte Execute på det minnet, varpå det inte går att exekvera. I Teorin(TM) kan man ju försöka hitta kod som kör mprotect() i binären som samtidigt måste kunna peka ut just överflödesbufferten och som just råkar sätta den till Execute och sedan peka hoppaddressen dit. Sannolikheten för att det finns exakt sån kod är en på ziljonen i princip. Alltså, kod som utan någon som helst annan förberedelse tar just dina 4/8k (av alla tänkbara 4G) och sätter Execute på den. Troligen större chans att Bingolotto ringer fel till mig och ger mig alla bilar och miljoner som inte lottades ut under 2002 istället för att återföra dem till detta årets lotterier.

Tyvärr var just x86 mindre bra designad så W^X fick vänta lite på den (och PPC), medans alpha, sparc64, och hp-pa (och AMDs hammer i 64bits-mod även om den inte är release:ad än för OpenBSD) har W^X redan nu. För x86 lyckades man göra ett ganska intressant trick. Den kunde nämligen inte sätta Execute på en per-sida-basis, dvs på 4/8k's noggrannhet, utan hade nåt skumt segmentregister som hade upplösningen 1Gig men som ändå gick att använda till just det här. Det man gjorde då var att man trixade med programladdaren och kompilatorn så att det data som är read-only i programmet och koden ligger 1G ifrån datat som man avser skriva till och allt minne som man allokerar under drift. Eftersom man har virtuellt minne så kan man göra sådana tricks, utan att programmet påverkas nämnvärt, men det gör en enorm skillnad för säkerheten.

Allt data man hämtat in från okända källor hamnar på fel sida om 1Gigs-staketet och all känd data (konstanter och kod från programmet) ligger på den "säkra" sidan. För PPC var det inte ens så enkelt, där hade man någon suspekt 256M's limit, men eftersom det inte alls är orimligt med kod och data som är större än 256M så kunde man inte bara dela mitt på, som man gjorde med x86, utan kommer sätta varannan 256M:are till W och de andra till X, och sen se till att dela in allt data på rätt plats allteftersom. Ett programs kod kan som det är nu redan delas in i olika segment i binären, så då får man fylla på tills en 256M-sektion är full och sen hoppa över en och fylla vidare på nästa osv. tills programmet är helt inlagt i minnet. Likaså när programmen allokerar minne eller mappar in filer. Det blir mer att hålla reda på, men det får det vara värt.

Men det är inte nog där, utan man jobbar även på andra saker. Jag nämnde ju att den som inte får med nog med kod i sin overflow kan leta efter kod i delade bibliotek där man kanske kan finna lite kod värd att peka den flödade returaddressen till. Detta låter sig göras om man vet att delade bibliotek alltid ligger på samma plats. Precis som med binärer på system med virtuellt minne så är det samma "tradition" att delade bibliotek ser ut att ligga på samma plats med. Men här jobbar OpenBSD på att slumpa i vilken ordning som de delade biblioteken ska mappas in till binären, så att ett program som har X stycken delade bibliotek som mappas in vid programladdningen då ger den potentielle busen (100/X) % chans att koden han vill "låna" ligger på rätt plats. Har slumpen placerat biblioteken i annan ordning så kommer han hoppa rätt in i gud-vet-vad och med enormt stor sannolikhet bara krascha programmet istället för att göra sitt bus. Tyvärr exponerar den här typen av tricks problem med diverse program så första försöket gick inte igenom 100%-igt och det fick tas bort, men jag förutsätter att de jobbar på att åter igen införa slumpad länkning när de rett ut problemen.

Många av de metoder som används är ju inte 100%-iga eller ofelbara, de är snarare till för att göra det osannolikt svårt att den som angriper lyckas på försök #1. Dessa "canaries" t.ex, som man har lagt in via ProPolice, kan ju anta ett par miljarder olika värden så genomsnittsattacken måste köras hälften så många gånger i snitt för att lyckas, och hälften av ett par miljarder blir "ett fåtal miljarder" gånger. Risken för att man blir upptäckt om man kraschar ett program "ett fåtal miljarder" gånger är rätt stor jämfört med att lyckas på första försöket som det var innan.

Andra metoder

Bortsett från de råa tekniska sätten att krångla med koden i minnet för att minska chansen att lyckas rent statistiskt, så jobbas det parallellt med nåt som heter "Priviledge Separation". Som jag nämnde i den historiska sektionen om att ha så lite privilegier som möjligt så är det inte helt enkelt att bara ta bort dem och köra som "nobody", eftersom många demoner behöver eleverade privilegier.

Ett par av anledningarna är t.ex sshd, dvs demonen som svarar på ssh-protokollet. När man loggar in via ssh så ska man efter att ha angivit rätt lösenord "bli" sin user på datorn och med fulla rättigheter för "mig". Det innebär ju att sshd måste köras med så mycket rättigheter att den får bli "mig" om jag anger rätt lösen, eller får bli "dig" om du anger rätt lösen. Det visar sig rätt fort att den måste ha i princip summan av alla personers rättigheter under stor del av tiden. Dock inte hela tiden, vilket är det PrivSep går ut på.

Tidigare har man ojat sig lite och sedan försökt hålla demoner av sshd's typ så buggfria som möjligt. Med PrivSep så ser man till att hålla så lite kod som möjligt under högsta nivån och sedan sänka sig till en lägre nivå direkt. Det innebär att maildemoner är root under en kort stund medans den binder till port 25, och sedan går ner till usern "smmsp" (i OpenBSD's fall) vilket i sin tur är en user som inte har ett hemkonto, inte kan logga in, men som får addera till folks maillådor och skriva/radera filer i spool-arean för mail. Enbart.

Det gör att under tiden den är root, vilket är ett par tiotal rader kanske, så är chansen för att den blir exploaterad väldigt liten eftersom enbart ett fåtal saker ska göras där och inget av det kräver att man tolkar user-input eller saker från nätet och det är mycket lättare att verifiera att den koden gör exakt det den ska och inget annat och sedan droppar man sina privilegier till en mail-user. Visserligen kan denne mail-user ställa till det på mailsidan, men den är åtminstone inte root, vilket är ett stort steg.

I den andan har OpenBSD skapat en massa nya users (en per tjänst), och sedan flyttat om all kod som kräver root-privilegier till början av programmet, kollat en extra gång och sedan går den ner till sin per-tjänst-user för att minimera den skada som ev. kan ske om någon tar full kontroll över demonen via nån sorts bugg under drift.

Man använder också anropet chroot() i samband med PrivSep (och i andra sammanhang med) som är ett komplement till att byta användare. Att byta användare ser ju till att man enbart kan skada de delar av systemet som tillhör den nya användaren, men med chroot() kan man minska även på det. chroot() gör så att ett program får en virtuell vy av filsystemet som inte längre täcker hela filsystemet utan enbart en del av det.

Man tar en katalog, gör chroot() dit och vips så tror programmet att filsystemet enbart består av de filer och kataloger som existerar under den katalogen. Alla andra processer och users kan (om rättigheterna är så satta) läsa och skriva normalt till den katalogen, men den process som är chroot:ad till katalogen kan inte se några som helst filer utanför katalogen. Det finns inget sätt (utom extrema buggar då) för en process att avsluta chroot(), så det är en oåterkallelig begränsning som inte går att ta sig runt.

Så länge man har lagt dit de filer som programmet nånsin kan tänkas behöva så klarar det sig alldeles utmärkt. Man kan även ha det på ett eget filsystem och de det filsystemet lämpliga icke-rättigheter som att "i detta filsystem får inga devicefiler existera, inga exekverbara program kan startas från det" alternativt: "Eventuella suid:ade program får suid-biten borttagen innan start" (nodev, noexec och nosuid respektive) för att förhindra att en buse som tagit kontroll över demonen placerar en massa binärer från nätet där för att kunna återkomma senare eller för att försöka skapa devicefiler som skulle kunna ge åtkomst till hårdvaran på maskinen om busen har tur.

I extrema fall kan det filsystemet vara monterat read-only och filerna ägs av någon annan och saknar writepermissions för servern, varpå det blir omöjligt på flera plan samtidigt för busen att kunna ändra på datat som ligger där.

Det innebär att t.ex webservern eller namnservern kan ha en katalog någonstans dit den (efter att ha bundit sin nätverksport) självmant låter sig chroot:as och sedan är den fast under den katalogen tills den dör. Är man rädd om sitt data så ser man till att inte lägga originalen på sin website eller sin dns-info där under utan kopierar ner det dit innan man startar sin server, och sen startar man upp tjänsten.

På så vis kan inte ens busen ändra i ditt original, utan bara i den temporära kopian om han får full kontroll över www/namnservern. Servern kör dessutom som en egen user som inte någon annan server delar, så trots att man har full kontroll så kan man inte göra mycket annat än att öda lite disk och cpu på servern, eller radera de temporära kopiorna. Punkt.

Dock är det inte sista ordet sagt om OpenBSDs säkerhet där. De har ytterligare en metod, som kom med OpenBSD 3.2 som kallas Systrace. Systrace kom till efter att man insett att program som går med höga privilegienivåer borde hindras att göra vissa saker som de aldrig ska kunna göra överhuvudtaget. Ett bra exempel är "ping". Den bakar sina egna paket och måste enligt gammal unixtradition köras med eleverade privilegier. Dock måste ping endast ha privilegierna för att sända egenhändigt bakade paket och inget annat. Inte för filåtkomster eller för att läsa andra personers lösenord i konsolen. Men om nu koden i ping har nån sorts bugg så att den som pingar min onda maskin får ett svar som i sin tur får nån buffert att flöda över och jag kan ta kontroll över din process så har jag helt plötsligt fått fulla rättigheter på ditt system och kan läsa alla dina filer osv.

Det man gjorde var en variant på runtime-debug-programmen strace/truss/ktrace som används för att lista vilka OS-anrop ett program gör under sin gång. Genom att modifiera anropen kunde man istället för att bara logga dem istället utsätta dem för en policy. Man kunde alltså skapa en policyfil som säger att "ping får använda OSanropet sendto() som root". Allt som inte passar i policyn kan antingen stoppa programmet, skapa en varning eller helt enkelt bara ignoreras. Man kan även se till att parametrarna till anropen är på ett visst sätt. T.ex att programmet Foo får öppna filen "foo.log" för skrivning, och enbart i katalogen "Foo/logs", eller att mailsändande program enbart får koppla sig över nätet till andra maskiner på port 25 (som mail använder) och jobbets browsers enbart får gå mot företagets proxy på datorn x.y.z.w på port 80.

På det viset kan program som "ping" hindras från att läsa filer eller formattera din hårddisk om man låter den köras inom ramen för systrace med en lagom policy trots att den körs med eleverade privilegier. Att testa policyn mot anropen var dessutom inte mycket dyrare än de tester som redan görs.

Men det fina med systrace är att den kan jobba åt två håll. Att hindra ping från att göra annat än nätverkshantering medans den har eleverade privilegier är ju en sorts "privilege degradation", dvs man har många rättigheter men kan inte bruka dem ohejdat. Ping har ju en flagga satt på sin binär som heter "setuid", dvs att när man kör ping så körs den som ägaren till filen, i unixens fall som root. Detta är just för att enbart root får sända konstiga hemsnickrade paket. Men med hjälp av systrace kan man vända på hela steken och istället göra "privilege escalation".

Istället för att ping (i sin helhet eller delvis via PrivSep) körs som root för att setuid-flaggan säger det, och sedan hindra alla anrop som inte är nätverksrelaterade så låter man systrace skapa en omvänd policy som säger: "När ping vill sända ett egensnickrat paket så anse att den är root". Då kan man ta bort setuid-biten på binären och all kod i ping körs som om det var min user precis som vanligt, men just enbart för ett anrop så är ping "root" och får sända sitt paket, och klarar då att komma förbi anropets kontroll att man är root. Under all annan tid är programmet helt opriviligierat.

Tycker man att det låter krångligt att skriva systrace-policies så finns det självklart hjälp att få. Det går att köra ett program som ännu inte har en policy, och logga alla anrop under en normal körning, och sen sätta det som policy efteråt. På så vis vet man till 99% vad som programmet kräver under normal drift och kan enkelt anpassa policyn senare vid behov. Samtidigt har man fått ett grymt bra skydd mot allehanda typer av oväntade problem. Det finns även grafiska frontends som låter dig välja Stora Gröna eller Stora Röda Knappen(tm) för varje anrop och därefter skapa en sån policy för programmet. Eller helt enkelt bara köra sina program med en lagom policy och sen när nåt oväntat händer som inte finns med i policyn så poppar gui:t upp och låter dig ange om du vill tillåta det eller inte, lite som ZoneAlarm gör med utgående paket på Windows. Givetvis finns det siter på nätet med färdiga policies för diverse program som man kan ladda ner om man vill.

Sammantaget gör alla sådana knep, metoder och system att man får en plattform som är extremt svår att få kontroll över som buse. Det har länge varit OpenBSDs policy att inte låta nätverksstacken bete sig på ett sätt som gör det onödigt svårt att veta vilket OS som körs på datorn. Det finns ju program som pratar över nätet med din maskin och beroende på hur den beter sig om det kommer konstiga paket så kan man göra en hyffsad gissning av vilket OS du kör. Vart 3:e månad poppar den frågan upp på OpenBSDs maillistor: "hur döljer jag vilket OS jag kör?", men hittils har det oftast mötts av stort motstånd. Dels är det ju inget skydd i sig att ens OS inte syns, har man en mailserver med ett gapande stort hål i så har man, vare sig busen kan läsa av ditt OS eller inte och dels så kan det faktiskt vara ett "skydd" att visa att man kör det "säkraste" OS:et. Precis som man sätter klisterlappar och dioder för att visa att man har ett dugligt larm på sin bil så kan det vara lika avhållande att faktiskt flagga tydligt vilket OS man kör.

Det sista kapitlet är ju knappast helt unikt för OpenBSD, men de har tagit det här ett steg seriösare än andra. Det innebär att det är lite lurigare för de som vill att alla users enkelt ska kunna ha hemsidor i sin hemkatalog under public_html/ eller liknande samtidigt som webservern inte kan komma ur sin chroot() till en katalog på en annan plats i filsystemet, men den typen av metoder ökar säkerheten och minskar exponeringen så mycket att det får vara värt det. OpenBSD skryter med "Endast ett fjärrexploaterbart hål i grundinstallationen på sju år" och det är med all rätt tycker jag. Att hålla sig så ren och samtidigt så buggfri att den som installerar det kan lita på att utvecklarna verkligen gjort sitt yttersta för att göra det säkert är nåt att sträva efter. Inget system är någonsin perfekt, men det betyder inte att man inte ska sträva efter det målet.




16/06-03 | IcePic | icepic@64bits.se