Jonas Grenfeldt skrev så här på Twitter:
Ibland tänker jag att jag är för trög för att jobba med internetsaker. Fattar fortfarande knappt dns och htaccess.
Det är ofta jag hör folk fråga om DNS så jag tänkte att jag lika gärna kan skriva ner en introduktion för Grenfeldt och andra i en bloggpost. En kort introduktion till det viktigaste helt enkelt. Låt oss köra igång!
DNS är en akronym för Domain Name System och precis som det låter är det ett system för domännamn. Det fungerar lite som nummerupplysningen för telefoner: vem har telefonnummer 123456? vilket telefonnummer har Jonas Björk i Helsingborg? Skillnaden är att DNS hanterar datorers namn och deras IP-adresser.
När internet fortfarande var litet behövdes inget sådant system. Det var så pass få datorer anslutna så man lade till dem i en fil som heter hosts. Den filen finns fortfarande kvar i UNIX-system som Linux och Mac OSX som filen /etc/hosts och i Microsoft Windows hittar vi den i c:windowssystem32driversetchosts (rätta mig gärna om jag har fel på sökvägen, jag har ingen Windows att kontrollera mot nu). Hosts-filen byggs upp enligt en enkel princip: IP-adress Hostname, så här:
127.0.0.1 localhost 91.223.232.31 jonasbjork.net ...
Varje gång du skriver www.facebook.com i din webbläsare (eller vilket program som helst som använder TCP/IP) kommer det första som händer vara att din dator tar reda på vilken IP-adress www.facebook.com har. Innan din dator ens kan klura ut vilket IP-nät den skall skicka frågan till så måste den ha vetskap om vilken IP-adress den skall skicka frågan till. De flesta datorer är inställda på att kontrollera hosts först och sedan skicka frågan till en DNS-server. Vilket gör det ganska roligt att lägga in andra IP-adresser för t.ex. facebook.com, aftonbladet.se, expressen.se, .. med flera i hosts-filen. Men det är en annan historia.
Eftersom att det är jobbigt att hantera en fil med miljontals IP-adresser byggdes DNS som delegerar ut ansvaret för olika DNS TLDer (top level domain, toppdomän). De servrar som har huvudansvaret för att hitta till rätt toppdomän kallas root name server och det finns 13 stycken sådana i världen: a.root-servers.net., b.root-servers.net., c.root-servers.net., .. m.root-servers.net. . i.root-servers.net. fanns i Stockholm från början, men idag är alla (a-m) servrar utspridda över hela världen (runt 400 stycken) och använder anycast för att vi skall komma åt den server som är närmst oss själva. Top Level Domain servrarna anges som en punkt (.) i varje domännamn, mer om det snart.
Domännamn ja, det är ju så vi brukar säga. I DNS-sammanhang pratar man inte om domäner, utan zoner. jonasbjork.net är alltså en zon i DNS. Det korrekta sättet att skriva det på är jonasbjork.net. och zonen skall läsas från höger till vänster enligt: under root server (.) finns toppdomänen (net) som hanterar zonen jonasbjork (jonasbjork) – eller jonasbjork.net. . Zonen kan ha subzoner eller hostnames, vanligast är hostnames som till exempel: www, ftp och mail.
Så när vi skriver www.jonasbjork.net i vår webbläsare för att komma till den här sidan kommer DNS gå från root servern till den DNS som är ansvarig för TLDn net som sedan pekar på vilken namnserver som är ansvarig för jonasbjork. Den namnservern kommer titta i zonfilen efter www och om den finns kommer vår klient få ett svar. Nu är det ju inte så att du frågar DNS:erna varje gång du skall till en specik adress. Din webbläsare kommer spara svaret ett stund, din DNS-server du använder kommer spara det en stund så den slipper fråga hela tiden. Din DNS-server kommer fråga andra DNS-servrar (beroende på hur den är konfigurerad) och så vidare. Har du någon gång använt Domänhanteraren hos IIS (punkt se) har du ställt in dina namnservrar för din domän där. Dvs, hur .se toppdomänen skall hitta till din domän. Skall man vara riktigt korrekt förresten så finns det två TLDer: ccTLD (landskoder som .se, .dk, .de) och gTLD (generiska toppdomäner som .com, .org, .net).
Ok, så hur fungerar DNS-servern? Den vanligaste DNS-servern är BIND (Berkeley Internet Name Daemon) och har ett zonfilsformat som redigeras med valfri texteditor. Filen innehåller records som kan ses som poster i en databas. De vanligaste records vi använder är SOA-record, NS-record, A-record, MX-record, CNAME-record och i och med IPv6 har vi börjat använda AAAA-record också (som är som ett A-record, fast för IPv6).
Jag har för mig att standarden kräver två records för att en zon skall vara giltig: SOA-record och NS-record. Det kan vara så att det räcker med ett SOA-record, men det verkar knasigt att ha en zon utan namnservrar i vilket fall. Ett SOA-record (Start of Authority) beskriver zonen, vilken server som äger den och vilken mailadress man kan nå administratören på och lite inställningar som anger hur länge ett record från zonen får cachas (mellanlagras) hos andra DNS-servrar som inte äger zonen (non-authorative). Exempel på ett SOA-record:
jonasbjork.net. IN SOA ns.jonasbjork.net. jonas.jonasbjork.net. ( 201309152020 ; ett serienummer som alltid skall ökas med ett 1d ; hur ofta en slavserver skall hämta zonen 2h ; hur lång tid som skall gå efter att en slavserver misslyckats hämta zonen 4w ; hur lång tid som skall gå innan slaven skall släppa zonen (vid ej svar) 1h ; hur länge ett svar får mellanlagras när fel uppstått )
Den översta raden namnger zonen jonasbjork.net. (notera punkten i slutet, root server!) och vilken e-postadress som hanterar zonen jonas.jonasbjork.net., här ersätts @ med en punkt. Resterande är olika inställningar som gäller för hela zonen. Semikolon (;) är kommentarer i zonfilen. Allt efter ; till nästa radbrytning tolkas som en kommentar.
Varje zon behöver ha en namnserver. Det är vad vi har NS-record till:
jonasbjork.net. IN NS dns ; dns.jonasbjork.net. är namnserver för jonasbjork.net jonasbjork.net. IN NS dns.minandradns.com. ; dns.minadradns.com är namnserver för jonasbjork.net
Inte så krångligt, eller hur? Du har säkert någon gång hört talas om Time To Live (TTL). TTL är ett värde som säger hur länge ett svar är giltigt och vi kan sätta det globalt för hela zonen genom att börja zonfilen med $TTL 3600, där 3600 är 3600 sekunder (60 minuter). Vi kan ange TTL med bland annat timmar (h), dagar (d), veckor (w) och år (y) också till exempel: $TTL 3W för tre veckor. $TTL sätter time to live för alla records i zonen om inget annat anges för varje record, så hur sätter vi TTL per record?
jonasbjork.net. 3600 IN NS dns ; dns.jonasbjork.net. är namnserver för jonasbjork.net jonasbjork.net. 7D IN NS dns.minandradns.com. ; dns.minadradns.com är namnserver för jonasbjork.net
Genom att sätta TTL innan record-typen så sätter vi den per record. Så SOA-record och NS-record är avklarade, men hur hittar våra besökare till vår hemsida (www.jonasbjork.net) ? Det är record-typen A (för adress) som gör om ett hostname till en IP-adress:
www.jonasbjork.net. 3600 IN A 91.223.232.31
Så www.jonasbjork.net. har IP-adressen 91.223.232.31. Enkelt ju! Men om jag har flera hostnames till olika hemsidor på samma server? Vi kan sätta flera A-records som pekar på samma IP-adress:
www.jonasbjork.net. 3600 IN A 91.223.232.31 www2.jonasbjork.net. 3600 IN A 91.223.232.31 static.jonasbjork.net. 3600 IN A 91.223.232.31
Eller så använder vi ett record som heter CNAME (cannonical name, som ett alias ungefär):
static.jonasbjork.net. 3600 IN CNAME www.jonasbjork.net.
När vi frågar efter ett record som är ett CNAME kommer DNS slå upp CNAME:t och leta reda på rätt A-record (IP-adress) åt oss.
Vill vi kunna ta emot e-post också behöver vi ett MX-record:
jonasbjork.net. 3600 IN MX 10 mail.jonasbjork.net. jonasbjork.net. 3600 IN MX 20 mail2.jonasbjork.net. jonasbjork.net. 3600 IN MX 30 mailbackup.supermailserver.com.
MX-records slås alltid upp av e-postprogram för att hitta vilken mailserver som tar emot mail för en specifik zon (i vårt fall jonasbjork.net). Notera att det måste finnas A eller CNAME records för namnen vi pekar på med våra MX-records. MX-records är också lite speciella då de har prioritet (10, 20, 30 ovanför). E-postservrar kommer försöka leverera e-posten till den mailserver som har lägst prioritet först, når vi inte den kommer vi ta nästa (med näst lägst prioritet) och så vidare.
Har vi IPv6-adresser är det AAAA-records vi skall sätta för IP-adresserna:
ipv6.jonasbjork.net. 3600 IN AAAA fe80::4545:b952:cb28:f00d
Så där bygger vi upp en DNS-zon med hjälp av BIND. Tröttar du på att skriva jonasbjork.net. på varje rad i zonfilen kan du skriva $ORIGIN jonasbjork.net. högst upp i zonfilen och sedan använda @ för att ange zonen i dina records:
@ 3600 IN NS dns ; dns.jonasbjork.net. är namnserver för jonasbjork.net @ 7D IN NS dns.minandradns.com. ; dns.minadradns.com är namnserver för jonasbjork.net
Det fungerar för MX-records också och för A och CNAME records räcker det att skriva www istället för www.jonasbjork.net. för att BIND skall förstå vad du menar.
Ett annat record som är intressant i DNS är PTR-record, som är pointer record. PTR slår upp namnet för en IP-adress. 91.223.232.31 är www.jonasbjork.net. ungefär.
Slutligen, hur kontrollerar vi att vår DNS är konfigurerad korrekt? Vi använder verktyget host som finns i Linux och OSX, eller dig om vi tycker det är bättre. dig kan mycket mer än host, men host räcker för vad vi gör här.
Vi tar reda på SOA-record för en zon med -t soa:
$ host -t soa jonasbjork.net jonasbjork.net has SOA record ns1.hyp.net. hostmaster.domeneshop.no. 1351449069 7200 900 1209600 3600
För att se vilka DNS-servrar som hanterar zonen använder vi -t ns:
$ host -t ns jonasbjork.net jonasbjork.net name server ns1.hyp.net. jonasbjork.net name server ns3.hyp.net. jonasbjork.net name server ns2.hyp.net.
För att se vilken IP-adress www.jonasbjork.net har skriver vi:
$ host www.jonasbjork.net www.jonasbjork.net is an alias for server1.jonasbjork.net. server1.jonasbjork.net has address 91.223.232.31
Oops, det var tydligen ett alias (CNAME) det där, www. pekar på server1.jonasbjork.net. Så host slår upp A-recordet för server1.jonasbjork.net också åt oss och vi får fram IP-adressen. Vill vi göra det själva så skriver vi:
$ host server1.jonasbjork.net server1.jonasbjork.net has address 91.223.232.31
Det här var en snabb genomgång om vad DNS är och hur det fungerar. Jag reserverar mig för eventuella felaktigheter då jag bara skrivit allt ur huvudet, med undantag för de sista host-kommando-sakerna som jag körde i en terminal på min Mac. Hoppas det klarnat lite nu!