DNSSEC Validator Afstudeerverslag voor de opleiding Informatica aan de Hogeschool van Amsterdam
Door: Martin Pels Studentnummer 154311 In opdracht van: NLnet Labs
Versie 1.05 7 juni 2004
Samenvatting Het Domain Name System (DNS) is het systeem dat zorgt voor de vertaling van domeinnamen (bijvoorbeeld www.example.org) naar IP-adressen (bijvoorbeeld 192.168.0.1) en andersom. Het is e´ e´ n van de belangrijkste pijlers van het Internet. Helaas is er gedurende de twintig jaar dat het systeem bestaat een belangrijk probleem aan het licht gekomen. DNS client-applicaties zijn namelijk niet in staat om te controleren of ontvangen informatie authentiek en compleet is. Door technieken als spoofing en cache poisoning kan dit probleem misbruikt worden door kwaadwillenden. Het DNSSEC protocol poogt bovenstaand probleem op te lossen met behulp van drie technieken: zone signing (toevoegen van een cryptografische handtekening aan recordsets), opbouwen van een chain of trust vanaf een vertrouwd punt in de DNS tree tot aan de zone met de gevraagde informatie en authenticated denial of existence (garanderen dat niet verkregen informatie daadwerkelijk niet bestaat). Valideren van DNSSEC informatie kan op twee manieren: bottom-up (vanaf de zone met de gevraagde informatie naar boven) en top-down (vanaf een vertrouwd punt in de DNS tree naar beneden). Het nadeel van de eerste techniek is dat wanneer validatie mislukt niet altijd te achterhalen is wat de oorzaak is. Top-down validatie heeft dit probleem niet. Het nadeel van deze techniek is echter dat het aflopen van de DNS tree niet kan worden overgelaten aan een caching forwarder. De DNSSEC client-software bestaat uit vier delen: een getaddrinfo() library functie die het ophalen ¨ van informatie coordineert, een applicatie die gebruik maakt van deze functie, een resolver die DNS informatie ophaalt en een validator die de chain of trust top-down af loopt en met behulp van OpenSSL routines controleert of de opgehaalde informatie authentiek en compleet is. De in dit document beschreven software is een proof of concept om aan te tonen dat het mogelijk is om een resolver/validator te schrijven in deze vorm. Het is dus niet bedoeld voor gebruik door applicaties op het Internet. De software dient als basis voor verdere ontwikkeling van DNSSEC client-software door NLnet Labs en andere leden van de open source community die meewerken aan de standaardisatie en implementatie van DNSSEC. Abstract The Domain Name System (DNS) provides the service of translating domainnames (e.g. www.example.org) to IP-addresses (e.g. 192.168.0.1). The system is one of the most important foundations of the Internet. Unfortunately a serious weakness was identified during the twenty years the system exists. DNS client-applications are currently not capable of checking whether received data is authentic and complete. Malicious users can exploit this weakness using techniques like spoofing and cache poisoning. The DNSSEC protocol tries to provide a solution to the above problem, using three techniques: zone signing (adding a cryptographic signature to recordsets), creating a chain of trust from a trusted point in the DNS tree to the zone that holds the requested information, and authenticated denial of existence (to guarantee that unacquired information is indeed non-existant). Validation of DNSSEC information can be done in two ways: bottom-up (upwards from the zone with requested information) and top-down (downwards from a trusted point in the tree). The downside of the former technique is that when validation fails it is not always possible to determine the cause. Top-down validation does not suffer from this problem. With this technique it is however not possible to leave walking down the DNS tree up to a caching forwarder. The DNSSEC client-software consists of four parts: a getaddrinfo() library function that coordinates the data retrieval, an application that utilizes the function, a resolver that retrieves DNS information, and a validator that walks down the chain of trust and uses OpenSSL routines to check if the gathered information is authentic and complete. The software described in this document is a proof of concept to show that it is possible to build a resolver/validator of this type. It is not to be used by applications on the Internet. The software forms a basis for further development of DNSSEC client-software by NLnet Labs and other members of the open source community that are working on the standardisation and implementation of DNSSEC.
Voorwoord Als afsluiting van de studie Informatica aan de Hogeschool van Amsterdam dient een afstudeerstage voltooid te worden van om en nabij honderd werkdagen. Ik heb ervoor gekozen om af te studeren bij de stichting NLnet Labs te Amsterdam. De stage loopt van 23 februari tot 25 juni 2004. Het resultaat van de stage bestaat uit dit document en een stuk software, geschreven in de programmeertaal C.
Dankbetuiging Mijn dank gaat uit naar iedereen die in meer of mindere mate bij heeft gedragen aan de totstandkoming van dit document en aan de voltooiing van mijn studie in het algemeen. Allereerst wil ik het complete NLnet Labs team bedanken voor het aanbieden van de afstudeerstage en voor een gezellige en leerzame tijd. Bijzondere dank gaat uit naar Ted Lindgreen en Miek Gieben voor hun begeleiding en adviezen. Verder bedank ik de mensen van Kern Automatiseringsdiensten voor hun hulp bij het vinden van een stageplaats. De docenten van de Hogeschool van Amsterdam worden bedankt voor een leerzame studietijd, in het bijzonder Gerard Baas voor de begeleiding tijdens mijn afstudeerstage en Dick Heinhuis voor de waardevolle adviezen die mij geholpen hebben mijn studie in 4 jaar af te ronden. Bijzondere dank gaat uit naar mijn familie en vrienden, met name naar Marco Kitzen en Sebastiaan Willemsen. Solvay Pharmaceuticals Weesp dank ik voor de financi¨ele ondersteuning van mijn studie. Dank en excuses tenslotte aan eenieder die ik hier vergeten ben.
1
Inhoudsopgave 1
Inleiding 1.1 Over NLnet Labs . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1.2 Inhoud . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
2
Het Domain Name System 2.1 Historie . . . . . . . . . . . . 2.2 Structuur . . . . . . . . . . . 2.3 Applicaties . . . . . . . . . . 2.3.1 Nameserver . . . . . 2.3.2 Full service resolver 2.3.3 Stubresolver . . . . . 2.3.4 Caching forwarder . 2.4 Queries . . . . . . . . . . . . 2.5 Probleemdefinitie . . . . . . 2.5.1 Spoofing . . . . . . . 2.5.2 Cache Poisoning . .
3
4
5 5 6
. . . . . . . . . . .
. . . . . . . . . . .
. . . . . . . . . . .
. . . . . . . . . . .
. . . . . . . . . . .
. . . . . . . . . . .
. . . . . . . . . . .
. . . . . . . . . . .
. . . . . . . . . . .
. . . . . . . . . . .
. . . . . . . . . . .
. . . . . . . . . . .
. . . . . . . . . . .
. . . . . . . . . . .
. . . . . . . . . . .
. . . . . . . . . . .
. . . . . . . . . . .
. . . . . . . . . . .
. . . . . . . . . . .
. . . . . . . . . . .
. . . . . . . . . . .
. . . . . . . . . . .
. . . . . . . . . . .
. . . . . . . . . . .
. . . . . . . . . . .
. . . . . . . . . . .
. . . . . . . . . . .
. . . . . . . . . . .
. . . . . . . . . . .
7 7 7 8 8 8 9 9 9 10 10 10
DNS Security Extensions 3.1 Werking . . . . . . . . . . . . . . . . . . . 3.1.1 Zone signing . . . . . . . . . . . . 3.1.2 Chain of trust . . . . . . . . . . . . 3.1.3 Authenticated denial of existence . 3.1.4 Validatietechnieken . . . . . . . . . 3.2 Effect op resolvers . . . . . . . . . . . . . . 3.3 Records . . . . . . . . . . . . . . . . . . . . 3.3.1 DNSKEY record . . . . . . . . . . . 3.3.2 RRSIG record . . . . . . . . . . . . 3.3.3 DS record . . . . . . . . . . . . . . 3.3.4 NSEC record . . . . . . . . . . . .
. . . . . . . . . . .
. . . . . . . . . . .
. . . . . . . . . . .
. . . . . . . . . . .
. . . . . . . . . . .
. . . . . . . . . . .
. . . . . . . . . . .
. . . . . . . . . . .
. . . . . . . . . . .
. . . . . . . . . . .
. . . . . . . . . . .
. . . . . . . . . . .
. . . . . . . . . . .
. . . . . . . . . . .
. . . . . . . . . . .
. . . . . . . . . . .
. . . . . . . . . . .
. . . . . . . . . . .
. . . . . . . . . . .
. . . . . . . . . . .
. . . . . . . . . . .
. . . . . . . . . . .
. . . . . . . . . . .
. . . . . . . . . . .
. . . . . . . . . . .
. . . . . . . . . . .
. . . . . . . . . . .
. . . . . . . . . . .
12 12 12 13 13 13 15 15 15 16 16 17
Uitvoering stageopdracht 4.1 Getaddrinfo . . . . . . . . . . . . . . . 4.2 DNSSEC getaddrinfo . . . . . . . . . . 4.3 Resolver . . . . . . . . . . . . . . . . . 4.3.1 Versturen van queries . . . . . 4.3.2 Converteren van een antwoord 4.4 Validator . . . . . . . . . . . . . . . . . 4.4.1 DNSKEY record validatie . . . 4.4.2 Recordset validatie . . . . . . . 4.4.3 Resource record validatie . . . 4.4.4 Cryptografische functies . . . . 4.5 Gebruik van getaddrinfo . . . . . . . . 4.5.1 Testapplicatie . . . . . . . . . . 4.5.2 Overige applicaties . . . . . . .
. . . . . . . . . . . . .
. . . . . . . . . . . . .
. . . . . . . . . . . . .
. . . . . . . . . . . . .
. . . . . . . . . . . . .
. . . . . . . . . . . . .
. . . . . . . . . . . . .
. . . . . . . . . . . . .
. . . . . . . . . . . . .
. . . . . . . . . . . . .
. . . . . . . . . . . . .
. . . . . . . . . . . . .
. . . . . . . . . . . . .
. . . . . . . . . . . . .
. . . . . . . . . . . . .
. . . . . . . . . . . . .
. . . . . . . . . . . . .
. . . . . . . . . . . . .
. . . . . . . . . . . . .
. . . . . . . . . . . . .
. . . . . . . . . . . . .
. . . . . . . . . . . . .
. . . . . . . . . . . . .
. . . . . . . . . . . . .
. . . . . . . . . . . . .
. . . . . . . . . . . . .
. . . . . . . . . . . . .
. . . . . . . . . . . . .
18 18 20 21 24 25 26 29 29 31 31 33 33 35
. . . . . . . . . . .
. . . . . . . . . . .
. . . . . . . . . . .
. . . . . . . . . . .
. . . . . . . . . . .
. . . . . . . . . . .
. . . . . . . . . . .
. . . . . . . . . . . . .
. . . . . . . . . . . . .
2
DNSSEC Validator
5
7 juni 2004
Conclusie & evaluatie 5.1 Toekomst . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 5.2 Evaluatie . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
36 36 36
Bibliografie
37
Thesaurus
38
c Martin Pels, NLnet Labs
3
Lijst van figuren 2.1
Gedeelte van de DNS tree . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
8
3.1 3.2
Opbouwen chain of trust (bottom-up) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Opbouwen chain of trust (top-down) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
14 15
4.1 4.2 4.3 4.4 4.5 4.6 4.7 4.8 4.9 4.10 4.11 4.12 4.13 4.14 4.15
Overzicht geschreven software . . . . DNSSEC getaddrinfo() functie . . Resolver . . . . . . . . . . . . . . . . . Versturen van queries . . . . . . . . . . Converteren van antwoord . . . . . . Overzicht plaatsing validator . . . . . Validator . . . . . . . . . . . . . . . . . DNSKEY record validatie . . . . . . . RRset validatie . . . . . . . . . . . . . . Record validatie . . . . . . . . . . . . . Digest validatie . . . . . . . . . . . . . Signature validatie . . . . . . . . . . . Gebruikersopties testapplicatie . . . . Voorbeeld ophalen service informatie Voorbeeld ophalen DNS informatie . .
19 21 23 25 26 27 28 30 30 31 32 33 34 34 35
. . . . . . . . . . . . . . .
. . . . . . . . . . . . . . .
. . . . . . . . . . . . . . .
4
. . . . . . . . . . . . . . .
. . . . . . . . . . . . . . .
. . . . . . . . . . . . . . .
. . . . . . . . . . . . . . .
. . . . . . . . . . . . . . .
. . . . . . . . . . . . . . .
. . . . . . . . . . . . . . .
. . . . . . . . . . . . . . .
. . . . . . . . . . . . . . .
. . . . . . . . . . . . . . .
. . . . . . . . . . . . . . .
. . . . . . . . . . . . . . .
. . . . . . . . . . . . . . .
. . . . . . . . . . . . . . .
. . . . . . . . . . . . . . .
. . . . . . . . . . . . . . .
. . . . . . . . . . . . . . .
. . . . . . . . . . . . . . .
. . . . . . . . . . . . . . .
. . . . . . . . . . . . . . .
. . . . . . . . . . . . . . .
. . . . . . . . . . . . . . .
. . . . . . . . . . . . . . .
. . . . . . . . . . . . . . .
. . . . . . . . . . . . . . .
. . . . . . . . . . . . . . .
. . . . . . . . . . . . . . .
Hoofdstuk 1
Inleiding Het Domain Name System (DNS) is het systeem dat zorgt voor de vertaling van domeinnamen (bijvoorbeeld www.example.org) naar IP-adressen (bijvoorbeeld 192.168.0.1) en andersom. Door de robuustheid en schaalbaarheid van het systeem heeft het een belangrijke bijdrage geleverd aan het succes van het Internet. Helaas is er gedurende de twintig jaar dat het systeem bestaat een belangrijk probleem aan het licht gekomen. Het is voor een client die informatie ophaalt bij een server namelijk niet mogelijk om te controleren of de informatie die hij krijgt wel overeenkomt met de informatie zoals die op de servers staat. Hierdoor is het voor een kwaadwillende mogelijk om een gebruiker verkeerde informatie toe te sturen. In 1990 is er begonnen aan de ontwikkeling van een nieuwe DNS standaard om bovenstaand probleem aan te pakken. Vanaf 1995 gebeurt dit binnen de IETF1 . Inmiddels is de nieuwe standaard, genaamd Domain Name System Security Extensions (DNSSEC), in een vergevorderd stadium en zijn er reeds een aantal serverimplementaties die hiervan gebruik maken. Aan de gebruikerskant is echter nog weinig werk verricht. De software aan de gebruikerskant van DNSSEC dient een tweetal zaken te doen. Allereerst dient de informatie die de gebruiker wil hebben (bijvoorbeeld het IP van een bepaald domein) samengesteld te worden door de verschillende onderdelen van de informatie op te vragen bij e´ e´ n of meerdere servers. Daarnaast dient gecontroleerd te worden of de opgevraagde informatie authentiek is. Het stuk software dat de DNS informatie ophaalt wordt ook wel een resolver genoemd. De reeds bestaande resolvers die gebruik maken van de huidige DNS standaard hebben niet de intelligentie om de verkregen informatie te controleren. Hierdoor ontstaat de behoefte aan een nieuw stuk software, de validator. De validator kan een stand-alone applicatie of library zijn, maar het kan ook een onderdeel zijn van een resolver-applicatie. Deze applicatie wordt daardoor security aware. Het doel van dit document is uit te leggen hoe DNSSEC het probleem in DNS poogt op te lossen en welke rol de DNSSEC validator hierin speelt. Tevens geef ik in dit document een diepgaande uitleg over de werking van de software die ik tijdens mijn stage geschreven heb.
1.1
Over NLnet Labs
De Stichting NLnet Labs is in 1999 opgericht door Stichting NLnet2 . Doelstelling van de stichting is ontwikkeling en standaardisatie van nieuwe protocollen en applicaties voor het Internet. Standaardisatie vindt plaats in de IETF middels het Request for Comments mechanisme3 . Naast DNSSEC houdt de stichting zich onder andere bezig met de ontwikkeling van een DNS server-applicatie, genaamd NSD. Verder is de stichting betrokken bij ontwikkelingen op het gebied van cryptografie en IP versie 6.
1 Internet
Engineering Task Force
2 http://www.nlnet.nl 3 http://www.rfc-editor.org
5
DNSSEC Validator
1.2
7 juni 2004
Inhoud
Ik begin dit document met een beschrijving van het huidige DNS, en het probleem dat in dit systeem aanwezig is. Vervolgens geef ik een uitleg over de theorie en werking van DNSSEC en de huidige status van deze standaard. In hoofdstuk 4 ga ik dieper in op de stageopdracht die ik uitgevoerd heb. Ik eindig dit document met een conclusie en een evaluatie van de stage.
c Martin Pels, NLnet Labs
6
Hoofdstuk 2
Het Domain Name System In dit hoofdstuk geef ik een kort overzicht van de historie van het Domain Name System. Vervolgens geef ik uitleg over de structuur van het systeem, de verschillende typen applicaties die binnen DNS onderscheiden worden en de manier waarop informatie verstuurd wordt tussen servers en clients. Tenslotte geef ik een beschrijving van het probleem in het systeem.
2.1
Historie
In de begindagen van het Internet was er reeds behoefte aan een adresseringssysteem voor computers op het net. Ondanks dat het aantal aangesloten computers vele keren lager was dan nu het geval is was het onthouden van IP-adressen al ondoenlijk. In eerste instantie werd een oplossing hiervoor gelanceerd[Harr] in de vorm van een tekstbestand (HOSTS.TXT), vergelijkbaar met het telefoonboek. Dit tekstbestand bevatte de IP-adressen en namen van alle machines op het Internet. Bij veranderingen werden deze centraal doorgevoerd door het Network Information Center van het Stanford Research Institute (SRI-NIC), en werd het bestand via FTP verspreid naar alle computers op het Internet. Naarmate het Internet verder groeide werd deze methode steeds minder geschikt. Het onderhouden van het bestand was steeds meer werk en het distribueren veroorzaakte een steeds grotere last op de FTP-server van het NIC. Een andere aanpak was daarom noodzakelijk. De nieuwe oplossing voor het probleem diende snel, robuust, makkelijk uitbreidbaar en netwerken applicatie-onafhankelijk te zijn[Mock1]. Daarnaast diende het organisatie- en nationaliteit-gerelateerd te zijn, en makkelijk te onthouden en te begrijpen voor mensen. Tenslotte diende het systeem autoratief volledig gedecentraliseerd te zijn, zodat elk land, organisatie of bedrijf verantwoordelijk is voor zijn eigen deel van het systeem. Kortom: een systeem gericht op de toekomst, en een groeiend gebruik van het Internet. Dit systeem werd het Domain Name System.
2.2
Structuur
DNS is een hi¨erarchisch opgebouwd systeem met een boomvormige structuur (een tree). Elke naam in het systeem eindigt in de top (de root). Deze wordt genoteerd doormiddel van een punt. Vanuit de root lopen vertakkingen naar de verschillende onderdelen (zones) van de tree. Om de relatie tussen twee zones in de tree te verduidelijken wordt gebruik gemaakt van de termen parent zone en child zone, waarbij de parent zone zich in de tree boven de child zone bevindt.
7
DNSSEC Validator
7 juni 2004
Figuur 2.1: Gedeelte van de DNS tree De verschillende zones worden gescheiden door middel van een punt. Het adres in de DNS tree van de machine www in de zone nlnetlabs in figuur 2.1 is dus “www.nlnetlabs.nl.”. De onderdelen tussen de punten noemt men labels. In de verschillende zones van de DNS tree wordt verschillende soorten informatie opgeslagen. Dit gebeurt in zogenaamde resource records (RR). Elk record bevat informatie over een onderdeel van de zone. Dit kan bijvoorbeeld het IP-adres van een machine (A record), informatie over een E-mailserver in een zone (MX record), of informatie over een server die de zone beheert (NS record) zijn[Mock2]. Een groep van meerdere records voor hetzelfde onderdeel van een zone (bijvoorbeeld twee records met verschillende IP-adressen voor 1 domeinnaam) is een resource record set (RRset). Dit is de kleinste eenheid die gebruikt wordt binnen DNS.
2.3
Applicaties
Binnen DNS worden, zowel aan de server- als aan de gebruikerskant verschillende typen applicaties onderscheiden. In deze paragraaf geef ik een overzicht van deze applicaties.
2.3.1
Nameserver
Het belangrijkste type applicatie binnen DNS is de nameserver. Nameservers bevatten alle informatie voor de zone waarin zij zich bevinden en weten welke child zones zich onder deze zone bevinden; zij worden daardoor gezien als een autoriteit (authority) voor hun deel van de DNS tree. Elke zone wordt beheerd door tenminste twee nameservers. Voor de rootzone, de belangrijkste zone, zijn er 13 nameservers. Deze staan verspreid over de wereld om de risico’s voor uitval bij bijvoorbeeld een natuurramp te beperken.
2.3.2
Full service resolver
Een applicatie die informatie ophaalt uit de DNS tree noemen we een resolver. Het ophalen van informatie kan op twee manieren. Bij de eerste wordt gebruik gemaakt van een recursive of full service resolver. Dit type resolver haalt informatie op door de tree vanaf de root omlaag af te lopen. Dit gebeurt door bij elke zone informatie op te halen over de nameservers in de zone eronder. Wanneer de resolver de tree heeft afgelopen tot de zone die de gewenste informatie bevat wordt deze informatie opgevraagd bij een nameserver in die zone. Het nadeel van dit type resolver is dat voor elke query de authoritative servers benaderd worden. Hierdoor worden deze zwaar belast. Full service resolvers worden hierom vrijwel niet gebruikt in de praktijk. In plaats daarvan wordt gebruik gemaakt van een combinatie van stubresolvers en caching forwarders.
c Martin Pels, NLnet Labs
8
DNSSEC Validator
2.3.3
7 juni 2004
Stubresolver
De stubresolver is een eenvoudiger type resolver. Deze applicatie vraagt een nameserver of caching forwarder om informatie en laat het aflopen van de tree aan deze server over. In de praktijk wordt vrijwel altijd gebruik gemaakt van de combinatie stubresolver - caching forwarder. De stubresolver is hierbij een onderdeel van een gebruikersapplicatie (bijvoorbeeld een browser), en de caching forwarder een centraal geplaatste server, beheerd door de Internet provider van de gebruiker.
2.3.4
Caching forwarder
Een caching forwarder is een server-applicatie die informatie uit zones tijdelijk opslaat. Wanneer een stubresolver een caching forwarder om informatie uit een bepaalde zone vraagt haalt de caching forwarder deze op bij de authoritative nameserver voor de betreffende zone. Vervolgens slaat de caching forwarder deze informatie lokaal op gedurende een vooraf gedefinieerde tijd. Wanneer een andere stubresolver nu dezelfde informatie opvraagt bij de caching forwarder hoeft deze niet nogmaals de complete tree af te lopen, maar kan deze de informatie uit de lokale cache terugsturen naar de stubresolver. Dit zorgt voor een aanzienlijke beperking in de belasting op de authoritative nameservers. Tot een aantal jaren terug konden vrijwel alle authoritative nameservers ook als caching forwarder gebruikt worden. Dit brengt echter risico’s tot overbelasting met zich mee. Wanneer iedereen bijvoorbeeld de rootservers als caching forwarder gaat gebruiken zorgt dit voor een grote last op deze servers. Hierom is in de afgelopen jaren op steeds meer authoritative servers de caching forwarder functionaliteit uitgeschakeld, zodat gebruikers gedwongen worden om de caching forwarder van hun Internet provider te gebruiken. Hierdoor wordt de belasting van de authoritative servers beperkt.
2.4
Queries
Communicatie tussen resolvers en nameservers gebeurt door middel van queries. Een query naar een DNS server bestaat uit drie onderdelen; de naam van de zone waarin de door de resolver gevraagde informatie zich bevind, het type van het record waar de informatie in staat en de class; de klasse waarin de informatie zich bevindt (bijvoorbeeld IN voor Internet). Een voorbeeld: voor het opvragen van het IP-adres van de machine bohr.nlnetlabs.nl is de query “bohr.nlnetlabs.nl A IN”. Het antwoord dat een resolver krijgt op een query bestaat uit een vijftal onderdelen: ;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 10008 ;; flags: qr aa rd ra; QUERY: 1, ANSWER: 1, AUTHORITY: 3, ADDITIONAL: 5 Het eerste deel van het antwoord is een header. Hierin staat algemene informatie. Zo geeft het status veld aan of de query goed verwerkt is en geven de ANSWER, AUTHORITY en ADDITIONAL velden aan hoeveel informatie er in de gelijknamige secties staat. ;; QUESTION SECTION: ;bohr.nlnetlabs.nl.
IN
A
In de question section wordt de vraag die de client aan de nameserver heeft gesteld herhaald. ;; ANSWER SECTION: bohr.nlnetlabs.nl.
86400
IN
A
213.154.224.43
De answer section bevat het antwoord op de query. In dit geval staat hierin het IP-adres van bohr.nlnetlabs.nl. ;; AUTHORITY SECTION: nlnetlabs.nl. nlnetlabs.nl. nlnetlabs.nl.
86400 86400 86400
IN IN IN
NS NS NS
open.nlnetlabs.nl. omval.tednet.nl. bureau.sidn.nl.
De authority section bevat informatie over de nameservers van de zone waarbinnen het opgevraagde record zich bevindt. Wanneer de answer section leeg is (en de nameserver de gevraagde informatie dus niet heeft) geeft de authority section aan welke nameservers in de zone onder de huidige deze informatie misschien wel hebben. In dat geval spreekt men van een delegatie. c Martin Pels, NLnet Labs
9
DNSSEC Validator
;; ADDITIONAL SECTION: open.nlnetlabs.nl. open.nlnetlabs.nl. omval.tednet.nl. bureau.sidn.nl. bureau.sidn.nl.
7 juni 2004
86400 86400 28800 86400 86400
IN IN IN IN IN
A AAAA A A AAAA
213.154.224.1 2001:7b8:206:1:250:daff:fe3d:1d6 213.154.224.17 193.176.144.162 2001:610:118:0:290:27ff:fe9c:2386
Het laatste onderdeel is de additional section. Deze sectie bevat extra informatie die voor de resolver handig kan zijn bij het opvragen van volgende records. Door deze informatie nu alvast mee te sturen hoeft de resolver misschien geen volgende query uit te voeren. Door deze aanpak blijft de belasting op de nameservers beperkt. De additional section kan ook informatie bevatten die noodzakelijk is voor de resolver om verder af te kunnen dalen in de tree en niet in een oneindige cirkel terecht te komen.
2.5
Probleemdefinitie
Bij het ontwerpen van het Domain Name System werd vooral gelet op robuustheid, schaalbaarheid en gebruikersvriendelijkheid van het systeem. Het Internet was in het begin voornamelijk toegankelijk voor academici en research & development afdelingen van bedrijven, en er werd minder rekening gehouden met moedwillig misbruik en sabotage. Het is dan ook niet verwonderlijk dat pas na verloop van tijd een security-risico gesignaleerd werd[Schu]. Het probleem van DNS is dat een client die informatie ophaalt bij een server niet kan controleren of de informatie die hij krijgt wel overeenkomt met de informatie zoals die op de authoritative servers staat. Hierdoor is het voor een kwaadwillende mogelijk om een gebruiker verkeerde informatie toe te sturen. In deze paragraaf behandel ik de belangrijkste technieken waarmee dit probleem kan worden misbruikt door kwaadwillenden.
2.5.1
Spoofing
De eerste techniek die ik behandel is spoofing. Bij spoofing doet een kwaadwillende gebruiker zich voor als iemand anders door in berichten die hij stuurt het IP-adres van de verzender te vervangen. Om deze techniek te verduidelijken gebruik ik een voorbeeld van een gebruiker X die een website wil bezoeken op Host A. In de normale situatie zal de gebruiker het IP-adres van Host A opvragen bij de caching forwarder van zijn Internet provider. Deze caching forwarder noemen we CF A. CF A stuurt vervolgens het IP-adres van Host A (IP A) terug naar de gebruiker, waarna deze de website kan gaan bezoeken. Kwaadwillend persoon Y heeft een webserver draaien op Host B met IP-adres IP B, en wil ervoor zorgen dat X de website op deze server bezoekt, in plaats van die op Host A. Wanneer Y zich nu voordoet als CF A en de query van X sneller beantwoord dan CF A zelf, met als antwoord IP B in plaats van het correcte adres IP A, zal X aannemen dat dit het IP-adres is van Host A en vervolgens de website op IP B gaan bezoeken. Wanneer X nu bijvoorbeeld een wachtwoord invoert op de website komt dit in handen van Y. Wanneer Y niet kan zien welke query X naar CF A verstuurt (bijvoorbeeld omdat X en Y zich niet op hetzelfde netwerksegment bevinden) is deze techniek aanmerkelijk moeilijker, omdat Y moet raden welke query X verstuurt.
2.5.2
Cache Poisoning
De tweede techniek is cache poisoning. Bij deze techniek maakt een kwaadwillende misbruik van de manier waarop DNS applicaties omgaan met records uit de additional section van een DNS-pakket om de cache van een client-applicatie te vullen met incorrecte data. We gebruiken nog steeds het voorbeeld van gebruiker X die de website op Host A wil bezoeken. Om het IP-adres van Host A op te halen maakt X gebruik van een stubresolver die verbinding maakt met caching forwarder CF A. Kwaadwillende Y heeft ditmaal zijn eigen authoritative nameserver (NS B). Op NS B heeft hij een zone met bijvoorbeeld een MX record voor Host B, welke verwijst naar Host A. Verder heeft hij op NS B een A record aangemaakt dat Host A koppelt aan IP B. Wanneer nu het MX record voor Host B opgevraagd wordt zullen zowel het MX record als het bijbehorende A record teruggestuurd worden. Om nu te zorgen dat Host A in de cache van CF A terecht komt met het IP-adres IP B stuurt Y een query naar CF A waarin hij vraagt om het MX record van Host B. Omdat NS B de authoritative c Martin Pels, NLnet Labs
10
DNSSEC Validator
7 juni 2004
nameserver is voor de zone waarin Host B zich bevind zal CF A aan NS B vragen wat de mail exchange is van Host B. NS B zal vervolgens antwoord geven met het MX record van Host B in de answer section en in de additional section het record met Host A gekoppeld aan IP B. Wanneer de caching forwarder de informatie uit de query effectief benut zal hij zowel de records uit de answer section als die uit de additional section opslaan, ook al bevat deze laatste informatie waarom niet direct is gevraagd. Het effect van bovenstaande is dat wanneer een willekeurige gebruiker nu aan CF A vraagt om het IP-adres van Host A deze in zijn cache zal kijken of hij deze informatie al bezit, daar vervolgens IP B vindt voor de betreffende host en dit terugstuurt naar de gebruiker. Iedereen die gebruik maakt van CF A (bijvoorbeeld alle klanten van een internet provider) zal dus bij het bezoeken van Host A terecht komen op IP B, met alle gevolgen van dien. Tegenwoordig slaan de betere caching forwarder implementaties informatie uit de additional section niet zomaar meer op. Hierdoor is cache poisoning aanmerkelijk moeilijker geworden. Er zijn echter op dit moment nog steeds veel caching forwarders aanwezig op het Internet die vatbaar zijn voor deze techniek.
c Martin Pels, NLnet Labs
11
Hoofdstuk 3
DNS Security Extensions In het vorige hoofdstuk behandelde ik een belangrijk probleem waar het Domain Name System mee te kampen heeft. Hoewel er sinds de ontdekking van dit probleem in 1990 geen grote incidenten geweest zijn is de kans hierop wel degelijk aanwezig. Daarom is in 1995 begonnen met de ontwikkeling van een nieuwe versie van DNS. Van deze nieuwe standaard, Domain Name System Security Extensions (DNSSEC), zijn in 1997[East1] en 1999[East2] de eerste RFC’s gepubliceerd. De nieuwste versie nadert op dit moment voltooiing[Aren1][Aren2][Aren3]. In dit hoofdstuk geef ik uitleg over de werking van DNSSEC en welke veranderingen die de nieuwe standaard vereist in resolvers.
3.1
Werking
Het doel van DNSSEC is garantie te kunnen geven dat DNS informatie afkomstig is van een betrouwbare bron en dat deze informatie compleet en accuraat is. Hierdoor kunnen spoofing en cache poisoning gedetecteerd worden. DNSSEC kan niet controleren of de informatie in een zone ook daadwerkelijk correct is (met andere woorden: of de inhoud van records klopt). De realisatie van DNSSEC is verdeeld in een drietal onderdelen. Deze zijn: • Zone signing • Chain of trust • Authenticated denial of existence Wat deze drie onderdelen inhouden behandel ik in deze paragraaf. Daarnaast behandel ik de verschillende technieken om DNSSEC informatie te valideren en de nieuwe recordtypes die de DNSSEC standaard introduceert.
3.1.1
Zone signing
Het eerste onderdeel van DNSSEC is zone signing. Bij dit principe wordt iedere recordset in een zone voorzien van een cryptografische handtekening. Hierbij wordt gebruikt gemaakt van public key cryptografie[Vieg]. Elke recordset krijgt een cryptografische handtekening (signature), opgeslagen in een apart record; het RRSIG record. Een RRSIG record wordt gecree¨erd door een recordset te coderen met behulp van een geheime sleutel (private key). De enige manier om de signature te valideren is met behulp van een publieke sleutel (public key). Deze wordt door de beheerder van een zone gepubliceerd, en is opgeslagen in een DNSKEY record. Omdat de private key alleen bekend is bij de beheerder van de zone waar de recordset zich in bevindt, kan alleen hij signatures genereren die met behulp van de public key zijn te valideren. Wanneer een gebruiker nu in bezit is van de public key voor een zone kan hij door middel van het RRSIG record controleren of een ontvangen RRset inderdaad uit die zone afkomstig is en of deze correct en compleet is.
12
DNSSEC Validator
3.1.2
7 juni 2004
Chain of trust
Zoals gezegd dient een gebruiker in het bezit te zijn van het DNSKEY record voor een zone om de overige recordsets van de zone te controleren. Hier ontstaat echter het probleem dat wanneer de gebruiker een DNSKEY record ophaalt om andere records te controleren hij niet weet of de DNSKEY zelf wel te vertrouwen is. Daarom dient de DNSKEY ook weer gecontroleerd te worden. Dit gebeurt doormiddel van de chain of trust. De chain of trust is een ketting van vertrouwde punten in de DNS tree. Door te beginnen bij een punt in de tree waarvan gegarandeerd kan worden dat deze te vertrouwen is en vervolgens de chain of trust af te lopen naar de zone waarvoor informatie dient te worden opgevraagd kan van de informatie in deze zone ook gegarandeerd worden dat deze authentiek, compleet en correct is. Voor het opbouwen van een chain of trust wordt gebruik gemaakt van het DS record. Een DS record bevindt zich in een parent zone, en bevat een digest. Dit is een cryptografische waarde die gegenereerd is uit een DNSKEY van een child zone. Om de chain of trust te controleren dient een client-applicatie een secure entry point (SEP) te hebben in de DNS tree. Dit houdt in dat de applicatie e´ e´ n of meerdere DNSKEY of DS records moet bezitten waarvan zeker is dat deze valide zijn1 . Dit is bijvoorbeeld het DS record van de rootzone.
3.1.3
Authenticated denial of existence
Door het aflopen van de chain of trust en het controleren van signatures kan gecontroleerd worden of data authentiek en compleet is. Wanneer een zone echter niet bestaat (NXDOMAIN) worden er geen recordsets en bijbehorende signatures teruggestuurd. Om bij dit type respons op een query toch het antwoord te kunnen verifi¨eren is het NSEC record toegevoegd. NSEC records zorgen voor authenticated denial of existence. Dit houdt in dat zelfs wanneer de domeinnaam waarover in de query informatie wordt opgevraagd niet bestaat er toch een antwoord gestuurd wordt, zodat gecontroleerd kan worden dat de domeinnaam inderdaad niet bestaat. Een NSEC record bevat de naam van de eerstvolgende domeinnaam in een zone na de gevraagde naam, en geeft daarbij weer welke recordtypes er voor deze naam beschikbaar zijn. Wanneer een resolver bijvoorbeeld een record opvraagt voor een niet bestaande domeinnaam “a.example.org” zal de nameserver hierop een NSEC record terugsturen met daarin de naam van de volgende, wel bestaande zone (bijvoorbeeld b.example.org) en de recordtypes die er voor deze naam beschikbaar zijn (bijvoorbeeld A en AAAA).
3.1.4
Validatietechnieken
Een chain of trust kan op twee manieren worden gevalideerd, namelijk door middel van bottom-up of top-down validatie. Figuur 3.1 toont de werking van de eerste techniek.
1 Deze
zijn bijvoorbeeld opgeslagen in een configuratiebestand en extra gecontroleerd op authenticiteit.
c Martin Pels, NLnet Labs
13
DNSSEC Validator
7 juni 2004
Figuur 3.1: Opbouwen chain of trust (bottom-up) Bij bottom-up validatie wordt onderaan de tree begonnen, bij de zone met de gevraagde informatie. Allereerst worden het RRSIG record van de gevraagde RRset(1) en het bijbehorende DNSKEY record(2) uit de zone (welke dit is staat aangegeven in het RRSIG record) opgehaald. Deze informatie vervolgens gevalideerd(3). Hierna worden het DS record(4) voor de zone opgehaald bij de parent zone. Vervolgens wordt het DNSKEY record gevalideerd met het DS record(5). Wanneer het gevalideerde DS record een secure entry point is(6) hebben we een complete chain of trust(7). Is dit niet het geval dan wordt de complete cyclus herhaald met het DS record, in plaats van de door de gebruiker gevraagde RRset. Figuur 3.2 hieronder toont de tweede techniek; top-down validatie. Bij top-down validatie wordt begonnen bovenaan de tree bij een secure entry point(1). Vervolgens worden voor elke onderliggende zone de DNSKEY records opgehaald(2) en deze worden gecontroleerd met het bovenliggende DS record(3). Hierna wordt voor de huidige zone het DS record opgehaald(4) en wordt de signature van dit record gevalideerd met behulp van de gecontroleerde DNSKEY records uit de child zone(5). De stappen 2 t/m 5 worden herhaald totdat de zone waarin de gevraagde informatie zich bevindt bereikt is(6). Vervolgens wordt de gevraagde informatie gevalideerd met behulp van het bijbehorende RRSIG record en de DNSKEY records uit de zone(7). Het nadeel van bottom-up validatie is dat een chain of trust pas als secure kan worden beschouwd wanneer een secure entry point bereikt is. Daarnaast is bij bottom-up validatie niet altijd te achterhalen wat de oorzaak is wanneer er informatie mist of wanneer validatie van een signature faalt. Top-down validatie heeft dit probleem niet, wanneer validatie faalt is meteen duidelijk waarom dit gebeurt. Het nadeel van top-down validatie is echter dat het aflopen van de tree niet kan worden overgelaten aan een caching forwarder. Wanneer informatie opgehaald wordt bij een caching forwarder krijgt de resolver namelijk altijd direct de gevraagde informatie, en niet de verschillende delegaties vanaf de rootzone tot aan de zone die de informatie bevat. De delegaties hebben we echter wel nodig om de chain of trust te controleren. Voor de software die ik heb geschreven is gekozen voor de top-down methode, met een resolver/validator die zelf de delegaties in de DNS tree af loopt. c Martin Pels, NLnet Labs
14
DNSSEC Validator
7 juni 2004
Figuur 3.2: Opbouwen chain of trust (top-down)
3.2
Effect op resolvers
Het gebruik van DNSSEC in resolvers vereist een aantal aanpassingen. Allereerst dient de resolver naast de gewone DNS informatie ook de DNSSEC records te kunnen ophalen. Daarnaast dient de applicatie voldoende intelligentie te bezitten om de cryptografische signatures van records te controleren. Tenslotte moet de resolver de chain of trust kunnen aflopen en controleren door middel van de DS records. Er zijn verschillende mogelijkheden om DNSSEC te implementeren in client-applicaties. De eerste mogelijkheid is om bovengenoemde functionaliteit in te bouwen in resolver-applicaties. Deze groeien hierdoor uit tot security aware resolvers. Een tweede mogelijkheid is om gebruik te maken van bestaande resolvers en de DNSSEC functionaliteit onder te brengen in een aparte applicatie, de validator. De validator maakt in deze opzet gebruik van de standaard resolver om DNS en DNSSEC records op te halen, en controleert vervolgens zelf de signatures en de chain of trust. Het voordeel van deze laatste aanpak is dat bestaande resolvers gewoon kunnen worden blijven gebruikt en niet of nauwelijks aangepast hoeven te worden. Dit kan de snelheid waarmee DNSSEC ge¨ımplementeerd wordt op het Internet gunstig be¨ınvloeden.
3.3
Records
In paragraaf 3.1 gaf ik aan uit welke onderdelen DNSSEC bestaat. Ik noemde hierbij al de verschillende typen resource records die DNSSEC gebruikt. In deze paragraaf geef ik een beschrijving van de record-specifieke data die opgeslagen is in deze records. In het volgende hoofdstuk leg ik uit hoe deze data gebruikt wordt door de validator.
3.3.1
DNSKEY record
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | Flags | Protocol | Algorithm | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ / / / Public Key / / / +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
c Martin Pels, NLnet Labs
15
DNSSEC Validator
7 juni 2004
Het DNSKEY record bevat een viertal velden. Het flags veld bevat een aantal waardes die aangeven wat voor type key zich in het record bevindt. Zo is er een bit gedefinieerd dat aangeeft dat de key gebruikt is om een RRSIG record mee te maken voor een RRset, en een bit dat aangeeft dat de key gebruikt is om een DS record te maken. Het protocol veld bevat het protocol van de key, en het algorithm veld geeft aan welk algoritme gebruikt is om de waarde in het public key veld te maken. Dit laatste veld bevat zoals de naam al zegt een publieke sleutel.
3.3.2
RRSIG record
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | Type Covered | Algorithm | Labels | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | Original TTL | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | Signature Expiration | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | Signature Inception | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | Key Tag | / +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ Signer’s Name / / / +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ / / / Signature / / / +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ Het RRSIG record is het meest uitgebreidde DNSSEC record. Allereerst bevat dit record een type covered veld, met daarin het type RRset waarover de signature gemaakt is. Het algorithm veld bevat net als bij het DNSKEY record het type algoritme dat gebruikt is. Het labels veld bevat een waarde met het aantal labels in de domeinnaam van de recordset waarover de signature gemaakt is. Het original TTL bevat de originele waarde van het time to live veld van de recordset. De time to live geeft aan hoelang een record in de cache van een resolver of caching forwarder mag worden bewaard. De velden signature expiration en signature inception bevatten de data waartussen het RRSIG record gebruikt mag worden om een RRset te valideren. Het keytag veld bevat een (niet unieke) identificatie voor het DNSKEY record dat gebruikt is om het RRSIG record te genereren, en wordt gebruikt om validatie effici¨enter te laten verlopen (zie paragraaf 4.4.2). Hetzelfde geldt voor het signer’s name veld. Dit veld bevat de domeinnaam van het DNSKEY record waarmee het RRSIG record is gegenereerd. Het signature veld bevat tenslotte de cryptografische handtekening.
3.3.3
DS record
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | Key Tag | Algorithm | Digest Type | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ / / / Digest / / / +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ Het DS record bevat net als het RRSIG record een keytag en algorithm veld met informatie over het DNSKEY record waarmee de DS gemaakt is. Het digest type veld geeft aan welk type algoritme gebruikt is om de digest waarde te genereren. Het laatste veld in het DS record is het veld met de digest waarde.
c Martin Pels, NLnet Labs
16
DNSSEC Validator
3.3.4
7 juni 2004
NSEC record
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ / Next Domain Name / +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ / Type Bit Maps / +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ Het laatste record is het NSEC record. Dit record bevat een tweetal velden. Het eerste is het next domain name veld. Dit geeft aan wat de volgende domeinnaam in de zone is waarvoor een record beschikbaar is. In het type bit maps veld staat opgeslagen welke recordtypes er voor deze domeinnaam beschikbaar zijn.
c Martin Pels, NLnet Labs
17
Hoofdstuk 4
Uitvoering stageopdracht In de vorige hoofdstukken gaf ik een beschrijving van de werking van DNS en DNSSEC. In dit hoofdstuk geef ik uitleg over de DNSSEC client-software die ik tijdens mijn afstudeerstage geschreven heb. Allereerst ga ik in op de software die momenteel gebruikt wordt door applicaties om DNS informatie op te halen. Vervolgens geef ik uitleg over de verschillende onderdelen van de nieuwe, op DNSSEC aangepaste versie van de software. Tenslotte vertel ik het e´ e´ n en ander over hoe de nieuwe software gebruikt kan worden door applicaties. Figuur 4.1 toont de verschillende onderdelen van de software die ik geschreven heb. De gebruikersapplicatie(1) roept een zogenaamde library functie met de naam getaddrinfo()(2) aan om DNS informatie op te halen (zie paragraaf 4.1). Getaddrinfo() gebruikt een resolver(3) om deze informatie uit het Domain Name System(4) op te halen (zie paragraaf 4.3). Vervolgens wordt deze informatie teruggestuurd naar de applicatie en kan deze contact maken met een service(5) op het Internet.
4.1
Getaddrinfo
Veruit de meeste programma’s op UNIX-achtige systemen (inclusief UNIX zelf) zijn geschreven in de programmeertaal C. Om te zorgen dat programma’s geschreven in deze taal kunnen communiceren met het besturingssysteem maken zij gebruik van een zogenaamde C library (Libc). Libc is de standaard library onder UNIX waarin alle system calls en bijbehorende standaardfuncties zitten om zowel met het systeem als het netwerk te praten. Door een in C geschreven applicatie te koppelen aan de library kan gebruik worden gemaakt van deze system calls en functies. E´en van de bekendste C libraries is de GNU C library (Glibc)1 . Glibc is de meest gebruikte C library op Linux-systemen. E´en van de standaardfuncties in Libc is de functie getaddrinfo(). Getaddrinfo() combineert de functionaliteit van een aantal andere functies om informatie over een netwerkadres of dienst (service) op te halen. Deze informatie kan door een applicatie worden gebruikt om te communiceren met het netwerkadres of de service. De getaddrinfo() functie-aanroep is als volgt gedefinieerd: int getaddrinfo(const char *node, const char *service, const struct addrinfo *hints, struct addrinfo **res); De functie heeft een viertal parameters. Node bevat de hostname of het IP-adres waarover informatie moet worden opgevraagd. Wanneer informatie over een service wordt gevraagd bevat service de naam of het poortnummer hiervan. Hints bevat criteria waaraan de opgevraagde informatie moet voldoen, en in res wordt de gevraagde informatie opgeslagen. Getaddrinfo() geeft de waarde 0 (nul) terug wanneer het opvragen van informatie geslaagd is, of een standaard foutcode wanneer dit niet het geval is. Het ophalen van informatie doet getaddrinfo() op twee manieren. Allereerst is er het ophalen van informatie over services. Dit doet getaddrinfo() met behulp van de getservbyname() functie, welke de gevraagde service opzoekt in het bestand /etc/services. Het tweede gedeelte is het ophalen van host- en adresinformatie. Dit gebeurt door een DNS query te sturen naar de caching forwarders die opgegeven zijn in het bestand /etc/resolv.conf. 1 http://www.gnu.org/software/libc/
18
DNSSEC Validator
7 juni 2004
Figuur 4.1: Overzicht geschreven software De informatie in hints en res wordt opgeslagen in een zogenaamde structure, een verzameling variabelen van verschillende types. Hints en res zijn structures van het type addrinfo, en hebben de volgende vorm: struct addrinfo { int ai_flags; int ai_family; int ai_socktype; int ai_protocol; size_t ai_addrlen; struct sockaddr *ai_addr; char *ai_canonname; struct addrinfo *ai_next; }; Het belangrijkste onderdeel van een addrinfo structure is ai addr, een structure van het type sockaddr. Deze structure bevat alle informatie die een applicatie nodig heeft om verbinding te maken met het netwerkadres of de service waar informatie over werd opgevraagd. De overige variabelen in de addrinfo structure bevatten informatie over de sockaddr structure. De variabele ai family geeft aan of de informatie in ai addr gaat over een IPv4 (PF INET) of een IPv6 (PF INET6) netwerkadres. Wanneer deze variabele de waarde PF UNSPEC heeft in de hints structure wordt informatie opgehaald over beide typen netwerkadressen (bijvoorbeeld wanneer een machine op een netwerk zowel een IPv4 als een IPv6 adres heeft). Ai socktype geeft (wanneer informatie over een service wordt opgevraagd) aan welk type verbindingsprotocol gebruikt wordt (connectieloos of connectiegeori¨enteerd), en ai protocol het protocol nummer. De ai addrlen variabele geeft aan hoeveel geheugen de ai addr structure inneemt, zodat applicaties voldoende geheugen kunnen reserveren. Ai canonname bevat de canonical name van het netwerkadres in ai addr. Dit is de standaard domeinnaam van het IP-adres, die wordt verkregen door het PTR record voor het adres op te vragen. De Ai flags variabele bevat een rij met bits die verschillende eigenschappen van de informatie in de addrinfo structure aangeven. Zo geeft het AI CANONNAME bit bijvoorbeeld aan of de ai canonname variabele wel of niet gevuld is. Het laatste onderdeel van een addrinfo structure is ai next. Deze variabele wordt gebruikt wanneer de c Martin Pels, NLnet Labs
19
DNSSEC Validator
7 juni 2004
getaddrinfo() functie meerdere resultaten terug geeft, bijvoorbeeld wanneer een hostname meerdere IP-adressen heeft. De ai next variabele wordt dan gebruikt om de addrinfo structures met de informatie over de individuele adressen aan elkaar te koppelen. Wanneer er geen volgende addrinfo structure gedefinieerd is heeft ai next de waarde NULL. Zoals gezegd is ai addr een structure van het type sockaddr. Deze structure heeft de volgende vorm: struct sockaddr{ unsigned short char };
sa_family; sa_data[14];
Om de informatie in deze structure makkelijker toegankelijk te maken zijn een tweetal andere structures gedefinieerd die naar de informatie in een sockaddr structure verwijzen. Dit zijn sockaddr in voor IPv4 informatie en sockaddr in6 voor IPv6 informatie. Deze structures hebben de volgende vorm: struct sockaddr_in { int sin_family; int sin_port; struct in_addr sin_addr; char *sin_zero[8]; }; struct sockaddr_in6 { unsigned short int unsigned short int unsigned int struct in6_addr unsigned int };
sin6_family; sin6_port; sin6_flowlabel; sin6_addr; sin6_scope_id;
Er is geen groot verschil tussen de twee typen structures. Beide bevatten een family variabele voor het adrestype, een port variabele voor het poortnummer wanneer er via getaddrinfo() een service is opgevraagd, en een addr variabele waarin het netwerkadres is opgeslagen door middel van het datatype long. Een netwerkadres van dit type kan met behulp van de inet ntop() library functie worden omgezet naar een leesbaar formaat. Naast de variabelen die ik zojuist noemde heeft de sockaddr in structure nog een variabele sin zero, welke de structure aanvult zodat deze dezelfde grootte heeft als de sockaddr structure. Sockaddr in6 bevat de extra variabelen sin6 flowlabel en sin6 scope id welke additionele IPv6 informatie bevatten.
4.2
DNSSEC getaddrinfo
Om de uitrol van DNSSEC op het Internet voorspoedig te laten verlopen is het wenselijk dat bestaande applicaties die gebruik maken van DNS makkelijk over kunnen schakelen naar DNSSEC. Daarom is ervoor gekozen om bestaande getaddrinfo() functies te vervangen door een nieuwe, op DNSSEC aangepaste versie. Het voordeel hiervan is dat bestaande applicaties niet aangepast hoeven te worden. Er dient slechts een aanpassing gedaan te worden in de C library. Als basis voor de nieuwe versie van getaddrinfo() heb ik de gelijknamige functie uit het BIND 9.42 pakket gebruikt. Dit omdat deze overzichtelijker en beter gedocumenteerd is dan bijvoorbeeld de versie uit Glibc. Aan de buitenkant lijkt de DNSSEC versie van getaddrinfo() hetzelfde als het origineel; de functie heeft dezelfde naam en vraagt dezelfde parameters. Onder de motorkap zijn er echter grote verschillen tussen beide functies. Figuur 4.2 toont de werking van de nieuwe getaddrinfo() functie. Als eerste controleert de functie of de waarden in de hints parameter correct zijn, en of er wel een waarde is ingevuld in de node of service parameter(2). Wanneer dit niet het geval is kan de functie namelijk geen informatie ophalen en zal deze een foutmelding terugsturen. De tweede stap is het ophalen van de informatie voor de service(3) (mits de service parameter is ingevuld). Dit gebeurt op dezelfde manier als bij de originele getaddrinfo() functie. De functie kijkt of de opgegeven service parameter een naam is of een poortnummer(4). In het eerste geval wordt met behulp van de Libc 2 http://www.isc.org/bind
c Martin Pels, NLnet Labs
20
DNSSEC Validator
7 juni 2004
Figuur 4.2: DNSSEC getaddrinfo() functie functie getservbyname() het poortnummer van de service opgehaald en opgeslagen in de res structure(6). In het tweede geval wordt het poortnummer direct opgeslagen(6). Het laatste onderdeel van getaddrinfo() is het ophalen van de DNS informatie (mits de node parameter is ingevuld(8)). Hiervoor kijkt de functie eerst of de node parameter een hostname is(8). Wanneer dit het geval is worden de IPv4 en IPv6 adressen opgevraagd(9) met behulp van de resolver en opgeslagen(12), afhankelijk van welke er gevraagd werden in de hints parameter. Wanneer bij het ophalen van het IP-adres een CNAME record ontvangen wordt zal de functie voor de naam in dit record het adres opvragen(10). De laatste stap bij het ophalen van DNS informatie is , wanneer de AI CANONNAME vlag aan staat in de hints parameter(12), het ophalen(13) en opslaan(14) van de canonical name voor de IP-addressen. Tenslotte wordt de opgehaalde informatie teruggestuurd naar de gebruiker(15). Indien het ophalen van IP-adressen of de canonical name faalt wordt een foutmelding teruggestuurd.
4.3
Resolver
In de vorige paragraaf beschreef ik de nieuwe versie van de getaddrinfo() functie en gaf ik aan dat deze gebruik maakt van een resolver voor het ophalen van DNS informatie. In deze paragraaf leg ik uit hoe het ophalen van DNS informatie met behulp van de resolver precies werkt. De resolver is het belangrijkste verschil tussen de oude en de nieuwe versie van getaddrinfo(). De originele versie van getaddrinfo() maakt namelijk gebruik van een standaard stubresolver, die de DNS informatie ophaalt bij een caching forwarder. Het probleem hierbij is dat de resolver altijd direct de gevraagde informatie ontvangt, en niet de verschillende delegaties vanaf de rootzone tot aan de zone die de informatie bevat. Deze informatie hebben we echter wel nodig om de chain of trust te controleren.
c Martin Pels, NLnet Labs
21
DNSSEC Validator
7 juni 2004
Om deze rede was het noodzakelijk om zelf een nieuwe resolver-functie te schrijven die de DNS tree afloopt en informatie over de verschillende delegaties ophaalt. Deze functie-aanroep ziet er als volgt uit: int treewalk(const char *qname, const char *qtype, struct qsoptions *options, struct dnsrr **res, int *depth); De belangrijkste parameters van de resolver functie zijn qname en qtype, welke de naam en het type record bevatten waarover informatie dient te worden opgehaald. De parameter depth geeft aan hoe diep de recursieve functie is afgedaald in de DNS tree. Dit wordt gebruikt om te voorkomen dat de functie in een oneindige cirkel blijft doorgaan waarneer er zich fouten bevinden in de tree. Options is een structure met overige informatie. Deze heeft de volgende vorm: struct qsoptions { int qs_dnssec; int qs_maxudp; char qs_nameservers[MAXBUF][MAXBUF]; }; In de options structure is een lijst opgenomen met nameservers die gebruikt dienen te worden, evenals de maximale grootte van het datapakket dat de lokale machine ondersteunt en een variabele die aangeeft of gebruik moet worden gemaakt van DNSSEC. De parameter Res wijst naar een structure met het antwoord op de query, in de vorm van e´ e´ n of meer aan elkaar gekoppelde resource records. Deze dnsrr structure heeft de volgende vorm: struct dnsrr { char *rr_name; unsigned int rr_type; unsigned int rr_class; unsigned int rr_ttl; unsigned int rr_rdlength; union { struct rdata_a *a_data; struct rdata_ns *ns_data; [...] } rr_rdata; char *rr_rdatastr; struct dnsrr *rr_next; }; De structure bevat alle onderdelen van een standaard resource record; de naam, het type, de class, de time to live en de lengte van de record-specifieke data in het record. De waarde rr rdatastr is een tekstuele representatie van de record-specifieke data en rr next verwijst naar de volgende resource record, of naar NULL wanneer er geen volgend record is. De record-specifieke data is opgeslagen in een aparte structure, die afhankelijk is van het type van het record. Het zou te ver gaan om in dit document de structures voor alle typen resource records te beschrijven. Als voorbeeld geef ik daarom hieronder de structure voor de data van een 1 type record, het A record. Dit type record heeft als inhoud een karakterreeks met een IPv4 adres. struct rdata_a { char *address; }; Om de gevraagde DNS informatie op te halen loopt de resolver de DNS tree af. Figuur 4.3 toont de stappen die de functie hierbij doorloopt. De resolver krijgt een query van getaddrinfo()(1) en haalt een lijst met nameservers voor de rootzone op uit een configuratiebestand(2). Deze lijst is nodig om bovenaan de tree te kunnen beginnen. Wanneer het bestand niet aanwezig is of er geen servers in staan(3) wordt een foutmelding teruggestuurd(4). De resolver stuurt vervolgens een query met de gevraagde informatie naar de c Martin Pels, NLnet Labs
22
DNSSEC Validator
7 juni 2004
Figuur 4.3: Resolver
c Martin Pels, NLnet Labs
23
DNSSEC Validator
7 juni 2004
rootservers en wacht op een antwoord(5). Afhankelijk van het antwoord wordt ofwel een melding dat de gevraagde domeinnaam niet bestaat(6), een set dnsrr structures met het gevraagde antwoord(8) of een foutmelding teruggestuurd. Wanneer de rootservers de gevraagde informatie niet zelf hebben, maar de informatie zich bevindt in een onderliggende zone zal een lijst met nameservers voor de betreffende zone teruggestuurd worden(10). In dat geval wordt de resolver recursief aangeroepen om de IP-adressen van de betreffende nameservers op te halen(11). De inhoud van de serverlijst wordt vervolgens vervangen door deze adressen(12), waarna opnieuw queries worden verstuurd, net zo lang tot wel een antwoord wordt verkregen.
4.3.1
Versturen van queries
Het versturen van queries naar een nameserver is eveneens een proces dat bestaat uit een aantal stappen. De functie die deze stappen uitvoert ziet er als volgt uit: int send_query(const char *qname, const char *qtype, struct qsoptions *options, struct dnspacket *res); De eerste drie parameters van deze functie heb ik in de vorige paragraaf reeds behandeld. De laatste is een structure genaamd res van het type dnspacket. In deze structure worden alle onderdelen opgeslagen van het DNS pakket dat als antwoord op een query wordt ontvangen. De structure ziet er als volgt uit: struct dnspacket { int struct { unsigned unsigned unsigned unsigned unsigned unsigned unsigned unsigned unsigned unsigned } flags; unsigned int unsigned int unsigned int unsigned int struct dnsrr struct dnsrr struct dnsrr struct dnsrr };
dp_id; dp_qr dp_opcode dp_aa dp_tq dp_rd dp_ra dp_z dp_ad dp_cd dp_rcode
: : : : : : : : : :
1; 4; 1; 1; 1; 1; 1; 1; 1; 4;
dp_qdcount; dp_ancount; dp_nscount; dp_arcount; *dp_question; *dp_answer; *dp_authority; *dp_additional;
Allereerst bevat de structure een variabele dp id, welke het identificatienummer van het pakket aangeeft. De tweede variabele bevat alle mogelijke opties die meegegeven kunnen worden aan een pakket. De overige variabelen zijn een viertal waarden die aangeven hoeveel resource records er zijn voor elk van de secties in het pakket, en verwijzingen naar het eerste record voor elke sectie (of naar NULL wanneer er voor een sectie geen resource records zijn). Figuur 4.4 toont de stappen die door de send query() functie doorlopen worden.
c Martin Pels, NLnet Labs
24
DNSSEC Validator
7 juni 2004
Figuur 4.4: Versturen van queries Allereerst controleert de functie of de gevraagde(1) naam en het gevraagde type geldig zijn(2). Is dit niet het geval dan wordt een foutmelding teruggestuurd(3). Vervolgens worden deze geconverteerd naar het DNS wire formaat volgens het compressiemechanisme beschreven in [Mock2], zodat ze verstuurd kunnen worden over het Internet(4). Hierna wordt gecontroleerd of de DNSSEC optie is geactiveerd in de options structure(5). Is dit het geval dan wordt een extra record toegevoegd aan het query pakket(6). In dit record, met type OPT, wordt ondersteuning voor grote datapakketten geactiveerd volgens de Extension Mechanisms for DNS (EDNS0) standaard[Vixi]. Dit is noodzakelijk omdat bij een DNSSEC pakket meer, en grotere resource records meegestuurd worden dan normaal en het hierdoor mogelijk is dat de standaard pakketgrootte van 512 bytes overschreden wordt. In het OPT record wordt tevens aangeven dat DNSSEC ondersteund wordt[Conr]. Wanneer het query pakket voltooid is wordt het verstuurd naar de servers uit de lijst(7), net zo lang tot een geldig antwoord ontvangen wordt(8), of er geen servers meer over zijn om te proberen(11). Het antwoord wordt vervolgens geconverteerd naar een dnspacket structure(9) en, indien het geen foutmelding bevat(10), teruggestuurd naar de resolver functie(12).
4.3.2
Converteren van een antwoord
Het converteren van het ontvangen pakket naar een structure gebeurt in de make dnspacket() functie, volgens de stappen beschreven in figuur 4.5.
c Martin Pels, NLnet Labs
25
DNSSEC Validator
7 juni 2004
Figuur 4.5: Converteren van antwoord Als eerste wordt de header informatie (het identificatienummer, de flags en de waarden met het aantal records per sectie) toegevoegd(1). Vervolgens worden de verschillende secties om de beurt afgegaan(2) en wordt voor elk record(4) een nieuwe dnsrr structure aangemaakt(5). Wanneer het type record ondersteund wordt(6) maakt de functie tevens een structure aan voor de record-specifieke data van het betreffende type(7). Tenslotte wordt het pakket teruggestuurd naar de send query() functie(8).
4.4
Validator
In de vorige paragraaf beschreef ik de nieuwe resolver die in de DNSSEC versie van getaddrinfo() wordt geplaatst. Een nieuwe resolver alleen is echter niet genoeg om getaddrinfo() security aware te maken. Om de informatie die opgehaald wordt door de resolver te controleren is een validator noodzakelijk. Deze wordt geplaatst tussen getaddrinfo() en de resolver, zoals te zien is in figuur 4.6.
c Martin Pels, NLnet Labs
26
DNSSEC Validator
7 juni 2004
Figuur 4.6: Overzicht plaatsing validator De validator(3) haalt nu de door de getaddrinfo() functie(2) gewenste informatie op bij de resolver(4) en voert een aantal controles uit om te bepalen of de teruggekregen informatie valide is. De validator functie-aanroep ziet er als volgt uit: int sec_treewalk(const char *qname, const char *qtype, struct qsoptions *options, struct dnsrr **res, int *depth, int *secstatus); De validator vraagt grofweg dezelfde parameters als de resolver. E´en parameter, genaamd secstatus is toegevoegd. In deze parameter wordt, wanneer er data terug wordt gestuurd naar getaddrinfo(), opgeslagen wat de security status is van deze data. De waarde in deze parameter is 0 (nul) wanneer de data secure bevonden is, 1 (´ee´ n) wanneer de data verifieerbaar insecure is (bijvoorbeeld wanneer de chain of trust eindigt op een NSEC record) en 2 wanneer de security status niet kan worden vastgesteld (bijvoorbeeld doordat geen secure entry point kon worden gevonden). Wanneer wel data gevonden wordt door de resolver, maar de security status hiervan aantoonbaar onjuist (bogus) is (bijvoorbeeld omdat validatie van een signature faalt) wordt geen data teruggestuurd maar wordt in plaats daarvan een security foutmelding geplaatst in de returnwaarde van de functie. De taken die de validator functie uitvoert beschrijf ik in figuur 4.7. Als eerste dient de validator een chain of trust op te bouwen vanaf een secure entry point naar de zone waarin de gevraagde informatie zich bevindt. Hiervoor heeft de validator een configuratiebestand met DS records. Deze DS records zijn records waarvan zeker is dat ze valide zijn, bijvoorbeeld doordat ze gepubliceerd zijn op een vertrouwde website, of doordat ze gevonden zijn bij het opbouwen van een eerdere chain of trust. Voor het opbouwen van de chain of trust is gekozen voor top-down validatie. De rede hiervoor is dat deze techniek robuust is, in tegenstelling tot bottom-up validatie. Bij bottom-up validatie kan een chain of trust namelijk pas als secure worden beschouwd wanneer een secure entry point bereikt is. Bij top-down validatie is er al vanaf het begin een secure chain of trust omdat bij een secure punt begonnen wordt. Daarnaast is bij bottom-up validatie niet altijd te achterhalen wat de oorzaak is wanneer er informatie mist of wanneer validatie van een signature faalt. Wanneer bijvoorbeeld het ophalen van een DS record uit een parent zone mislukt is onduidelijk of dit record helemaal niet
c Martin Pels, NLnet Labs
27
DNSSEC Validator
7 juni 2004
Figuur 4.7: Validator
c Martin Pels, NLnet Labs
28
DNSSEC Validator
7 juni 2004
bestaat, zich bevindt in een zone boven de parent zone, of dat er sprake is van een derde partij die moedwillig foutieve informatie toestuurt. De validator functie loopt de DNS tree af vanaf de root naar beneden(2), en zoekt onderweg naar zones waarvoor reeds een DS record opgeslagen is(3). Wanneer zo’n zone gevonden wordt(4) kan de functie beginnen met het opbouwen van de chain of trust. Het opbouwen van de chain of trust begint met het ophalen en valideren(5) van DNSKEY records uit de child zone met behulp van de bijbehorende RRSIG records. Vervolgens worden de DNSKEY records gevalideerd(7) met het DS record van het secure entry point (hoe dit precies werkt behandel ik in paragraaf 4.4.1). Wanneer de DNSKEY records valide zijn bevonden is de koppeling tussen het secure entry point en de zone secure(8). Vervolgens wordt afgedaald naar de volgende zone(10), en wordt hiervoor het DS record opgehaald(3) (dit is dus het DS record van de zone die onder de child zone ligt). Vervolgens wordt dit DS record gevalideerd met het bijbehorende RRSIG record en herhaalt het proces zich, net zo lang tot de chain of trust zich uitstrekt tot aan de zone met de gevraagde informatie(9). Hierna wordt, mits de chain of trust secure is, de gevraagde informatie opgehaald uit de zone en gevalideerd met behulp van het RRSIG record van de informatie en de reeds gevalideerde DNSKEY records uit de zone(17). Tenslotte wordt het resultaat teruggestuurd(19) naar getaddrinfo(). Het kan voorkomen dat het opbouwen van de chain of trust halverwege mislukt, bijvoorbeeld doordat een DS record ontbreekt in het configuratiebestand(14) of een NSEC record teruggekregen wordt bij het opvragen van DNSKEY of DS records(15). In dit geval zal de validator doorgaan met het aflopen van de DNS tree en proberen in een lagere zone alsnog een DS record te vinden dat opgeslagen is in het configuratiebestand. Wanneer zo’n record gevonden wordt is er sprake van een island of security, een onderdeel van de DNS tree met informatie die valideerbaar is, ondanks dat er geen chain of trust aanwezig is vanaf de root. Wanneer de validator er niet in slaagt de chain of trust op te bouwen om e´ e´ n van bovenstaande redenen zal de validator alsnog de gevraagde, ongevalideerde informatie terug proberen te sturen(18), vergezeld met een melding dat de informatie ofwel verifieerbaar insecure is (wanneer een NSEC record ontvangen is), of dat de status niet vast te stellen is (wanneer er geen secure entry point gevonden is). Het is ook mogelijk dat het opbouwen van een chain of trust om een serieuzere rede mislukt (bijvoorbeeld doordat signatures ongeldig zijn). In dit geval wordt niet geprobeerd verder te gaan met het opbouwen van de chain of trust of het ophalen van informatie, maar wordt direct een security foutcode[Gieb] teruggestuurd naar de applicatie. Deze foutmelding is een waarde van e´ e´ n bit, omdat getaddrinfo() niet meer dan e´ e´ n bit kan terugsturen naar de applicatie. Gebruik van de in [Gieb] beschreven array is daardoor niet mogelijk. De oplettende lezer zal opgemerkt hebben dat de validator met bovenstaande aanpak een deel van het werk van de resolver overneemt, namelijk het aflopen van de tree. De rede hiervoor is dat wanneer we de resolver vragen om een bepaalde query we altijd een antwoord terugkrijgen en nooit een delegatie. Om de delegaties te kunnen controleren is het voor de validator dus noodzakelijk om zelf de tree af te lopen.
4.4.1
DNSKEY record validatie
Figuur 4.8 toont hoe de validator bij het valideren van een DNSKEY record te werk gaat. Voor het eerste DNSKEY record in de RRset wordt doormiddel van een hash functie gecontroleerd of deze behoort bij het DS record(1). Is dit niet het geval(2) dan wordt de volgende DNSKEY uit de RRset gecontroleerd(4), net zolang tot er een geldige key gevonden is(5), of er geen DNSKEY records meer zijn(6). De werking van de hash behandel ik in paragraaf 4.4.4.
4.4.2
Recordset validatie
Het valideren van een RRset met behulp van het bijbehorende RRSIG record en een DNSKEY record bestaat uit een serie stappen. Figuur 4.9 toont deze stappen. In principe volstaat alleen het uitvoeren van de cryptografische validatie. Dit proces kan echter veel computercapaciteit eisen wanneer grote hoeveelheden signatures moeten worden gevalideerd. Daarom worden eerst een aantal andere controles uitgevoerd. Allereerst wordt een aantal checks(1) uitgevoerd om te controleren of het RRSIG record behoort bij de records uit de RRset (welke dat zijn behandel ik in paragraaf 4.4.3). Vervolgens wordt gecontroleerd of het signer’s name veld van het RRSIG record overeenkomt met de domeinnaam van het DNSKEY record(3), en of het algorithm veld van beide records overeenkomt(5). Hierna wordt de keytag van het c Martin Pels, NLnet Labs
29
DNSSEC Validator
7 juni 2004
Figuur 4.8: DNSKEY record validatie
Figuur 4.9: RRset validatie
c Martin Pels, NLnet Labs
30
DNSSEC Validator
7 juni 2004
Figuur 4.10: Record validatie DNSKEY record berekend en vergeleken met de waarde in het gelijknamige veld van het RRSIG record(7). Wanneer al deze controles slagen wordt de cryptografische validatie uitgevoerd(9). Hoe deze validatie werkt behandel ik in paragraaf 4.4.4. De laatste stap is het controleren van de inception time en expiration time(11). Deze geven aan of de gevalideerde signature geldig is op het huidige tijdstip.
4.4.3
Resource record validatie
Om te controleren of een RRSIG record bij een RRset hoort wordt voor elk record in de set een drietal controles uitgevoerd. Figuur 4.10 toont een overzicht. Allereerst wordt gecontroleerd of de domeinnnaam en class resource record wel overeenkomen met de corresponderende velden van het RRSIG record(1). Hierna volgt een controle of het signer’s name veld van het RRSIG record overeenkomt met de domeinnaam van het resource record(3). Als laatste wordt gecontroleerd of het aantal labels in de domeinnaam van het resource record overeenkomt met de waarde in het labels veld van het RRSIG record(5).
4.4.4
Cryptografische functies
Voor het valideren van DS en RRSIG records maakt de validator gebruik van een aantal cryptografische functies. Deze functies communiceren met de OpenSSL library. OpenSSL is een C implementatie van het Secure Socket Layer (SSL) protocol. Het wordt gebruikt door applicaties om veilig over een netwerk te kunnen communiceren. OpenSSL bezit een groot aantal routines die verschillende berekeningen kunnen uitvoeren voor verschillende cryptografische systemen. Een aantal van deze routines wordt gebruikt door de validator Voor het valideren van een digest heeft de validator de volgende functie: int verify_digest(char *digest,int *digest_type, struct dnsrr *keyrr); Deze functie heeft drie parameters. De eerste is de digest waarde die moet worden gevalideerd. De tweede is het type algoritme dat gebruikt is om deze waarde te genereren. De laatste parameter is een dnsrr structure met het DNSKEY record waaruit de digest mogelijk is gegenereerd. Figuur 4.11 toont de werking van de functie.
c Martin Pels, NLnet Labs
31
DNSSEC Validator
7 juni 2004
Figuur 4.11: Digest validatie Om een digest te genereren worden allereerst het ruwe dataformaat van de domeinnaam(1) en de datasectie van het DNSKEY record aan elkaar geplakt(2). Vervolgens wordt, mits het algoritme in de digest type parameter ondersteunt wordt(3), het resultaat door de EVP Digest routines van OpenSSL gehaald(4). De resulterende waarde van deze berekening dient vervolgens gelijk te zijn aan de digest waarde die meegegeven is aan de functie(5). De functie-aanroep voor het valideren van een signature ziet er als volgt uit: int verify_rrsig(struct rdata_dnskey *key, struct dnsrr *rrset); Ook deze functie vraagt een tweetal parameters. De eerste is een dnsrr structure met de public key die gebruikt moet worden bij de validatie. De tweede is de complete RRset die gevalideerd moet worden, inclusief het RRSIG record. Anders dan bij het valideren van een digest kan bij het valideren van een signature niet de waarde opnieuw worden gegenereerd en vergeleken met het origineel. De signature is namelijk gegenereerd met behulp van een private key, en we hebben slechts een public key tot onze beschikking. Hierom gebruiken we voor het valideren van een signature de EVP Verify routines van OpenSSL. Figuur 4.12 toont het validatieproces.
c Martin Pels, NLnet Labs
32
DNSSEC Validator
7 juni 2004
Figuur 4.12: Signature validatie Om een signature te valideren worden de datasectie(1) van het RRSIG record (behalve de signature) en de complete overige records uit de RRset achter elkaar geplakt(3). De TTL velden in de records binnen de RRset worden vervangen door de TTL in het Original TTL veld van het RRSIG record. Het resultaat wordt vervolgens, mits het gebruikte algoritme ondersteund wordt(4), door de EVP Verify routines gehaald met de signature en de public key uit het DNSKEY record als parameters(5). De OpenSSL routines geven nu de waarde 1 (´ee´ n) terug wanneer het geheel valide is(7), en de waarde 0 (nul) wanneer dit niet het geval is(8).
4.5
Gebruik van getaddrinfo
In de vorige paragrafen heb ik uitgelegd hoe de nieuwe getaddrinfo() library functie in elkaar zit. In deze paragraaf ga ik in op het gebruik van de nieuwe functie. Als eerste beschrijf ik het gebruik van de functie in een zelfgeschreven testapplicatie. Vervolgens vertel ik het e´ e´ n en ander over gebruik in andere applicaties op UNIX-achtige systemen. Het testen vond plaats op een Fedora Core 1 Linux systeem, met gebruik van gcc versie 3.3.2 en glibc 2.3.2.
4.5.1
Testapplicatie
Om de nieuwe versie van getaddrinfo() te testen heb ik een kleine applicatie geschreven die gebruik maakt van de functie. Figuur 4.13 toont de gebruikersopties van deze applicatie. De applicatie kan zowel gebruikt worden om informatie over services op te halen, als om DNS informatie op te halen. Figuur 4.14 toont de resultaten van de applicatie bij het ophalen van informatie over de service FTP. c Martin Pels, NLnet Labs
33
DNSSEC Validator
7 juni 2004
Figuur 4.13: Gebruikersopties testapplicatie
Figuur 4.14: Voorbeeld ophalen service informatie
c Martin Pels, NLnet Labs
34
DNSSEC Validator
7 juni 2004
Figuur 4.15: Voorbeeld ophalen DNS informatie De applicatie laat zien welke velden in de addrinfo structure de getaddrinfo() functie gevuld heeft. In dit geval zijn dit het socket type (gezet op de waarde 1, wat staat voor TCP), de grootte van de sockaddr structure (28), en het poortnummer van de FTP service (21). Bij het ophalen van DNS informatie is de teruggekregen informatie wat uitgebreider, zoals te zien is in figuur 4.15. Omdat ik geen adresfamilie opgegeven heb geeft de functie alle adressen terug die beschikbaar zijn. In dit geval zijn dit twee adressen van familie 2 (IPv4), en e´ e´ n adres van familie 10 (IPv6). Wanneer het ophalen van informatie mislukt omdat deze niet te vinden is of omdat de informatie bogus is toont de applicatie de foutcode die getaddrinfo() terug gaf.
4.5.2
Overige applicaties
Aan het begin van dit hoofdstuk gaf ik aan dat getaddrinfo() in veel applicaties op UNIX-achtige systemen gebruikt wordt. Deze applicaties kunnen, wanneer de getaddrinfo() functie uit Libc vervangen wordt door de nieuwe versie, zonder aanpassing gebruik maken van DNSSEC. Dit is echter niet bij alle applicaties het geval. In paragraaf 4.2 gaf ik al aan dat de getaddrinfo() functie uit BIND als basis diende voor de DNSSEC versie. BIND is niet de enige applicatie die een eigen getaddrinfo() heeft gedefinieerd. Zo heeft de veelgebruikte webbrowser Mozilla3 ook een eigen versie van de functie. Wanneer in Glibc getaddrinfo() vervangen wordt door de nieuwe versie zullen deze applicaties hier dus geen gebruik van maken. Om in deze applicaties DNSSEC te kunnen implementeren zullen de getaddrinfo() functies van de applicatie zelf moeten worden aangepast, of tijdens het linken moeten worden overschreven met de nieuwe functie.
3 http://www.mozilla.org
c Martin Pels, NLnet Labs
35
Hoofdstuk 5
Conclusie & evaluatie Het Domain Name System is e´ e´ n van de belangrijkste pijlers van het Internet. Helaas is er gedurende de twintig jaar dat het systeem bestaat een belangrijk beveiligingsprobleem aan het licht gekomen. Het DNSSEC protocol poogt dit probleem op te lossen. De ontwikkeling van een client-applicatie vormt een belangrijke stap richting de implementatie van dit protocol op het Internet. Door de getaddrinfo() functie in een C library te vervangen kunnen client-applicaties die van deze library gebruik maken op een relatief eenvoudige manier DNSSEC aware gemaakt worden. Aanpassingen aan de applicatie zelf zijn dan niet noodzakelijk. Dit zal hoogstwaarschijnlijk een positief effect hebben op de snelheid waarmee DNSSEC in gebruik wordt genomen.
5.1
Toekomst
De library functie die ik geschreven heb is een zogenaamde proof of concept. Dit houdt in dat de software slechts bedoeld is om aan te tonen dat het mogelijk is om een resolver/validator te schrijven in deze vorm. Het is dus niet bedoeld voor gebruik door applicaties op het Internet. De belangrijkste rede hiervoor is dat het geheel niet beschikt over een cache. Dit zorgt ervoor dat voor elke query alle authoritative servers benaderd worden vanaf de root tot aan de zone met de gewenste informatie. Wanneer alle resolvers op het Internet zo te werk zouden gaan heeft dit een desastreus effect op de hoeveelheid werk die de servers te verduren krijgen. Daarnaast mist de software een aantal optimalisaties (bijvoorbeeld het benaderen van meerdere servers tegelijk in plaats van opeenvolgend). Hierdoor is het geheel te traag om effectief gebruikt te kunnen worden in applicaties. Ondanks bovenstaande nadelen is toch voor deze aanpak gekozen om duidelijk te krijgen of het geheel praktisch mogelijk en implementeerbaar is. Hierop kan vervolgens worden voortgebouwd. Mijn werk dient zo als basis voor verdere ontwikkeling van DNSSEC client-software door NLnet Labs en andere leden van de open source community die meewerken aan de standaardisatie en implementatie van DNSSEC. Waarschijnlijk heeft dit als resultaat dat bestaande onaangepaste applicaties in de toekomst gebruik kunnen maken van een security aware resolver.
5.2
Evaluatie
Ik vond het erg leuk om bij NLnet Labs te werken. De sfeer was goed en ik heb er veel geleerd. Tijdens mijn stage heb ik veel opgestoken over DNS, DNSSEC, C, Libc, (public key) cryptografie en OpenSSL. Verder ben ik veel te weten gekomen over hoe Internet standaarden ontwikkeld worden binnen de IETF en de open source community in het algemeen, mede dankzij mijn bezoek aan een workshop over de uitrol van DNSSEC op het Internet van het Security and Stability Advisory Committee van de ICANN1 . Een workshop die 3 mei 2004 gehouden werd in Amsterdam. Al met al vond ik het een geslaagde afstudeerstage en een mooie manier om mijn Informatica studie af te sluiten.
1 Internet
Corporation For Assigned Names and Numbers
36
Bibliografie [Aren1]
DNS Security Introduction and Requirements (draft; rev. 10) , R. Arends e.a., 2004, (work in progress), http://www.ietf.org/internet-drafts/draft-ietf-dnsext-dnssec-intro-10.txt
[Aren2]
Protocol Modifications for the DNS Security Extensions (draft; rev. 06) , R. Arends e.a., 2004, (work in progress), http://www.ietf.org/internet-drafts/draft-ietf-dnsext-dnssec-protocol-06.txt
[Aren3]
Resource Records for DNS Security Extensions (draft; rev. 08) , R. Arends e.a., 2004, (work in progress), http://www.ietf.org/internet-drafts/draft-ietf-dnsext-dnssec-records-08.txt
[Conr]
RFC 3225 - Indicating Resolver Support of DNSSEC , D. Conrad, 2001, http://www.ietf.org/rfc/rfc3225.txt
[East1]
RFC 2065 - Domain Name System Security Extensions , D. Eastlake e.a., 1997, http://www.ietf.org/rfc/rfc2065.txt
[East2]
RFC 2535 - Domain Name System Security Extensions , D. Eastlake, 1997, http://www.ietf.org/rfc/rfc2535.txt
[Gieb]
DNSSEC Resolver Interface to Applications (draft; rev. 00) , R. Gieben e.a., 2004, (work in progress), http://www.nlnetlabs.nl/dnssec/draft-gieben-resolver.txt
[Harr]
RFC 952 - DoD Internet host table specification , K. Harrenstien e.a., 1985, http://www.ietf.org/rfc/rfc952.txt
[Mock1]
RFC 1034 - Domain names - concepts and facilities , P. Mockapetris, 1987, http://www.ietf.org/rfc/rfc1034.txt
[Mock2]
RFC 1035 - Domain names - implementation and specification , P. Mockapetris, 1987, http://www.ietf.org/rfc/rfc1035.txt
[Schu]
Addressing Weaknessess in the Domain Name System Protocol , C. Schuba, 1993, http://ftp.cerias.purdue.edu/pub/papers/christoph-schuba/schuba-DNSmsthesis.pdf
[Vieg]
Network security with OpenSSL , J. Viega e.a., 2002, ISBN 0-596-00270-X
[Vixi]
RFC 2671 - Extension Mechanisms for DNS (EDNS0) , P. Vixie, 1999, http://www.ietf.org/rfc/rfc2671.txt
37
Thesaurus A Additional section Onderdeel van een DNS bericht met extra informatie over records in een zone. Zie ook: Domain Name System, resource record, zone Answer section Onderdeel van een DNS bericht met het antwoord op een query. Zie ook: Domain Name System, query Authenticated denial of existence Controleerbaarheid van het antwoord van een nameserver wanneer gevraagde informatie niet bestaat. Zie ook: nameserver Authority section Onderdeel van een DNS bericht met informatie over nameservers die gevraagde informatie beheren. Zie ook: Domain Name System, nameserver
B Bottom-up validatie Techniek waarbij de chain of trust van beneden naar boven opgebouwd en gevalideerd wordt. Zie ook: chain of trust, validator
C C library [ Libc ] Set van standaard C functies die het voor in de programmeertaal C geschreven applicaties mogelijk maakt om te communiceren met het besturingssysteem. Zie ook: GNU C library Cache poisoning Het vervuilen van de cache van een DNS-applicatie met incorrecte data. Zie ook: Domain Name System Caching forwarder Server-applicatie die zelf niet authoritative is voor een zone, maar die informatie over zones bewaard voor gebruik door resolvers. Zie ook: resolver, zone Canonical name De standaard domeinnaam voor een IP-adres, opgeslagen in het PTR record voor het adres. Zie ook: resource record Chain of trust Ketting van DS en DNSKEY records vanaf een secure entry point tot aan een zone met gevraagde informatie. Zie ook: secure entry point, zone 38
DNSSEC Validator
7 juni 2004
Child zone Zone in de DNS tree die een andere zone boven zich heeft. Zie ook: DNS tree, zone Class Aanduiding voor de classificering van records binnen de DNS tree. Zie ook: DNS tree, resource record
D Delegatie DNS bericht waarin een nameserver aangeeft dat gevraagde informatie zich in een onderliggende zone bevindt. Zie ook: Domain Name System, zone DNS tree Hi¨erarchisch opgebouwde boomstructuur waarin DNS informatie is opgeslagen. Zie ook: Domain Name System Digest Cryptografische waarde in een DS record, gegenereerd uit een DNSKEY record. Wordt gebruikt om de chain of trust te controleren. Zie ook: chain of trust, resource record Domain Name System [ DNS ] Systeem dat zorgt voor de vertaling van domeinnamen naar IP-adressen, en andersom. Domain Name System Security Extensions [ DNSSEC ] Beveiligde versie van het Domain Name System. Zie ook: Domain Name System
E Extension Mechanisms for DNS [ EDNS0 ] Set technieken die het mogelijk maakt om grotere DNS pakketten te maken dan de standaard 512 bytes. Zie ook: Domain Name System
F Full service resolver Type resolver dat voor het ophalen van informatie de volledige DNS tree afloopt vanaf de root tot aan de zone met de opgevraagde informatie. Zie ook: Domain Name System, (recursive) resolver, tree, zone
G GNU C library [ Glibc ] C library ontwikkelt door GNU (http://www.gnu.org). Deze versie van de C library wordt veel gebruikt op Linux systemen. Zie ook: GNU C library
I Island of security Onderdeel van de DNS tree dat informatie bevat die kan worden gevalideerd, ondanks dat er geen chain of trust aanwezig is vanaf de rootzone. Zie ook: chain of trust, DNS tree, validator, zone c Martin Pels, NLnet Labs
39
DNSSEC Validator
7 juni 2004
K Keytag Een (niet uniek) identificatiemiddel voor een DNSKEY record dat gebruikt wordt om validatie effici¨enter te laten verlopen. Zie ook: validator
L Label Onderdeel van een domeinnaam, gescheiden van andere labels door een punt.
N Nameserver Server-applicatie die informatie beheert voor een DNS zone. Zie ook: Domain Name System, zone
O OpenSSL C library implementatie van het Secure Socket Layer protocol. Zie ook: Secure Socket Layer
P Parent zone Zone in de DNS tree die e´ e´ n of meerdere zones onder zich heeft. Zie ook: DNS tree, zone Private key Cryptografische sleutel waarmee signatures gecre¨eerd worden. Deze sleutel wordt niet publiekelijk bekend gemaakt. Zie ook: signature Public key Cryptografische sleutel waarmee signatures gevalideerd kunnen worden. Deze sleutel is publiekelijk bekend. Zie ook: signature, validator
Q Query Aanvraag van DNS informatie door een resolver. Zie ook: Domain Name System, resolver
R Recursive resolver Type resolver dat voor het ophalen van informatie de volledige DNS tree afloopt vanaf de root tot aan de zone met de gevraagde informatie. Zie ook: Domain Name System, (full service) resolver, tree, zone Resolver Applicatie die informatie ophaalt uit de DNS tree. Zie ook: Domain Name System, DNS tree
c Martin Pels, NLnet Labs
40
DNSSEC Validator
7 juni 2004
Resource record [ RR ] Dataset met informatie over een onderdeel van een zone. Zie ook: zone Resource Record set [ RRset ] Groep van records voor hetzelfde onderdeel van een zone met hetzelfde type. Zie ook: resource record, zone
S Security aware resolver Resolver die tevens in staat is DNSSEC informatie te valideren. Zie ook: Domain Name System Security Extensions, resolver, validator Secure entry point [ SEP ] Punt in de DNS tree waarvan de authenticiteit gegarandeerd kan worden en waarvandaan een chain of trust kan worden opgebouwd. Zie ook: DNS tree, chain of trust Secure Socket Layer [ SSL ] Protocol om applicaties veilig te laten communiceren op het Internet, door gebruik van cryptografie. Signature Digitale handtekening van een recordset in een zone. Zie ook: resource record set, signing, zone Signing Het toevoegen van een digitale handtekening aan recordsets in een zone. Zie ook: resource record set, zone Spoofing Het voordoen als iemand anders doormiddel van het vervangen van IP-adressen in berichten. Structure Datatype in de programmeertaal C dat een verzameling variabelen van verschillende typen bevat. Stubresolver Resolver die zelf niet de DNS tree afloopt, maar dit door een recursive nameserver of caching forwarder laat doen. Zie ook: caching forwarder, Domain Name System, DNS tree, nameserver, resolver
T Top-down validatie Techniek waarbij de chain of trust van boven naar beneden opgebouwd en gevalideerd wordt. Zie ook: chain of trust, validator Time to live [ TTL ] Veld in een resource record dat aangeeft hoelang het record in de cache van een resolver of caching forwarder mag worden bewaard. Zie ook: caching forwarder, resource record, resolver
V Validator Losstaand stuk software voor het valideren van DNSSEC informatie. Zie ook: Domain Name System Security Extensions c Martin Pels, NLnet Labs
41
DNSSEC Validator
7 juni 2004
Z Zone Onderdeel van de DNS tree waarin records zijn geplaatst. Zie ook: Domain Name System, DNS tree, resource record
c Martin Pels, NLnet Labs
42