Prickle-Prickle, the 6 day of Discord in the YOLD 3176
IPv6, autokonfiguration och DNS
Inledning
I IPv6 kan ändnoder skaffa sig sin egen adress. Metoden kallas SLAAC (StateLess Address AutoConfiguration). En router skickar ut något som kallas Router Advertisments och talar om vilket nätprefix den är ansvarig för. Med hjälp av prefixet och sin egen Ethernet-adress kan en ändnod sedan bygga resten av sin IPv6-adress. Default route är naturligtvis routern som skickade ut meddelandet. Vips kan en nod komma ut på nätet!
Ett litet problem med det här är att det inte går att slå upp namn, för noden som just byggt sin egen IPv6-adress vet inte vilken DNS-server den skall prata med. För att kommunicera måste alltså alla tillämpningar känna till IPv6-adressen de skall prata med, till exempel 2001:888:22b3::2 snarare än ecki.hack.org. Oops.
I september 2007 publicerades RFC 5006 som uppdaterar Router Advertisments med ett tillägg som kallas Recursive DNS Server (RDNSS). Tillägget ger en eller flera adresser till rekursiva DNS-servrar. Det är bara det att RFC 5006 är markerad "Experimental". DHCPv6, som också löser problemet, har visserligen varit definierad sedan 2003, men implementationer, framför allt på serversidan, har det varit ganska ont om.
Det finns också en filosofisk skillnad: DHCPv6 skapar spårbarhet medan SLAAC inte gör det. Det kan finnas användning för båda, men ett typiskt hemmanät eller kanske ännu hellre ett sensornät med massor av små intelligenta manicker kanske hellre använder just SLAAC med RDNSS.
I jämförelse med DHCPv6 är det också lätt att skriva program som stöder RDNSS.
I ett typiskt ISP-scenario kan man tänka sig att kundens hemmarouter (ofta känd som CPE, Customer Premise Equipment på ISPiska) får information om vilken DNS-server som skall användas via DHCPv6, men att maskinerna i hemmanätet i stället får reda på det med SLAAC + RDNSS.
Min klient: radns
En dag när jag hade tråkigt på jobbet någon gång i mars 2008 skrev jag en klient för RDNSS. Jag satt och väntade på att Open Office (Brrr!) skulle kompilera klart och började medan jag väntade att skriva på en klient jag döpte till radns.
Den allra första versionen, som fungerade redan den kvällen, var ganska naiv och använde BPF-filter (med hjälp av libpcap) för att få tag i RA-meddelandena. Overkill! Jag hade inte ens läst Advanced Sockets API for IPv6, RFC 3542 ännu!
Jag skrev om radns att använda Advanced Sockets API:et lite senare. API:et innehåller nämligen en egen filtreringsmekanism som är mycket enkel. Med en setsockopt() kunde jag sätta ett filter som jag först byggde så här:
ICMP6_FILTER_SETBLOCKALL(&filter); ICMP6_FILTER_SETPASS(ND_ROUTER_ADVERT, &filter);
Efter det blir min socket läsbar när det finns ett RA-meddelande och jag kan läsa och börja parsa meddelandet. Enkelt, eller hur?
Min dåvarande arbetsköpare, Stickybit AB, lät mig släppa koden under BSD-licens. Jag versionshanterade i Stickybits Perforce-installation.
När jag slutade på Stickybit i slutet av 2008 kunde jag inte längre använda Perforce, så jag tog de releaser som hade gjorts och importerade dem i CVS i stället för att bevara åtminstone lite historia.
Versionerna av radns jag släppte 2008 tog emot en RA med RDNSS-tillägget och skrev adresserna till DNS-servrarna direkt i en fil som hade samma format som den resolv.conf som finns på de flesta Unix-varianter. Om man kör enbart IPv6 kan (och kunde redan då) radns skriva direkt till /etc/resolv.conf. Om man kör dual stack kan man med en hook till exempelvis dhclient få den att fläta ihop radns-listan med sin egen.
Det här räckte för mig, så utvecklingen stannade av…
Hopp till 2010. Även om jag i augusti 2009 blev pappa igen och nu för tiden är ganska upptagen med att ta hand om en bäbis så fick jag plötsligt för mig att hacka på radns igen. Det första jag gjorde var att börja använda Git i stället för CVS.
Det här är mitt första projekt i Git och dessutom första gången jag överhuvudtaget använder Git, så jag gör bergis några fel, men det är ju så man lär sig… Ni får ha överseende.
Min första hackattack ledde till att radns nu släpper root-privilegierna så fort den kan och dels kan anropa ett script när listan över DNS-servrarna har ändrats. Det betyder att radns kan fungera tillsammans med programmet resolvconf, som just är till för att fläta ihop DNS-resolvers från olika källor.
En andra hackattack ledde till att radns äntligen kan hantera livslängd så att DNS-servrar alltså kan plockas bort när de inte längre gäller.
På vägen har en del buggar också fixats. Där är vi nu.
Jag har inte gjort någon riktig release än av den nya koden och mycket är otestat. Här finns min distributionssida:
https://hack.org/mc/hacks/radns/
Jag har gjort en release från min feature-branch som heter radns-0.9-ttl3.tar.gz som finns på den där sidan. Eventuellt kommer fler testreleaser, så håll utkik där.
Git-repot lever på
https://hack.org/mc/git/radns/
men innehåller just nu bara master-grenen. Jag vet inte riktigt hur jag skall hantera det här med feature-grenar än.
En hel del tillfälliga debugsaker och mindre fin kod finns definitivt kvar. Det finns säkert också många buggar och mindre eleganta lösningar. Testa hemskt gärna ttl3-versionen, skicka klagomål och patchar till mig!
Den här versionen är bara testad under FreeBSD som jag utvecklar i. Tidigare versioner är testade också under Linux och MacOS X.
I MacOS X fungerar radns visserligen, men då OS X inte har någon /etc/resolv.conf måste man där sätta vilken DNS-server OS:et skall använda med kommandon i stället. Något script för att göra det har jag inte skrivit. Jag tar gärna emot ett förslag från någon Mac-användare!
IETF 77
Uppenbarligen är jag inte ensam om att få ett nyupptäckt intresse för RFC 5006, för på brevlistan för IETF:s arbetsgrupp v6ops skrev den ena ordföranden, Fred Baker, plötsligt så här den 17:e mars:
Jari Arkko tells us that he is getting requests from various sources to take RFC 5006 to Proposed Standard. It is now experimental.
[…]
- Please take a look at the document in the next few days; if you have comments on it (eg, you think it should be changed in some way), please comment to v6ops.
- Vendors, please advise on implementations. Are there any? Has interoperability been demonstrated?
- Operators, enterprise and/or service provider, please advise on deployment experience.
I'm adding a brief discussion to the agenda Monday morning with a view to getting a quick thumbs-up/thumbs-down to advise Jari, who can then take that to 6man later in the week if appropriate.
Wow!
IETF:s 77:e möte börjar nästa vecka. Jag hoppas det kommer ett beslut om att gå från Experimental till Proposed Standard och kommer försöka lyssna in på v6ops-mötet, även om jag förstås inte är på plats fysiskt den här gången.
Agendan för v6ops säger att RFC 5006-statusen är första punkten på måndag. Lyssna in och chatta med (xmpp:v6ops@jabber.ietf.org).
RFC 5006 som Proposed Standard skulle göra det mycket troligare att produkter stöder det. Å andra sidan verkar det som om mycket stöd redan finns där ute. Här är några citat från samma tråd i brevlistan:
Apple:
Both solicitor and advertiser sides of RFC 5006 are implemented in Apple's AirPort Extreme and Time Capsule (simultaneous dual-band II) firmware 7.5 and later. It was tested for interoperability with a Linux implementation prior to its release.
Nokia:
We have implemented this on Symbian OS and on Nokia S40 OS. Tested against RADVD and TAHI. Not released in products yet.
Firebrick:
Firebrick FB6000 series as of release V0.00.402-Gerald Alpha (9th Mar 2010) supports announcing RDNSS addresses as part of RA.
Quagga:
I patched quagga to support RFC 5006 too. Due to a more or less clever maintainership the patches are stalled somewhere[1]
So quagga supports RFC 5006.
Fria implementationer av klientsidan är alltså min radns, men också rdnssd, som nu underhålls som en del av ndisc6.
På serversidan känner jag till bara en fri implementation som kan RDNSS, radvd och det är den enda server jag testat radns mot.
Motsvarigheten till radvd i *BSD:erna och OS X, rtadvd, stöder ännu inte RDNSS, men jag har börjat titta lite på det och hoppas kunna åtgärda det. Några hackattacker till och en snäll bäbis kan kanske fixa det?