Resultaten

RESTful EPP (EPP maar dan anders)

  • Door: Maarten Wullink
  • 26 april 2012 - 13:30 uur

Het Domeinnaamregistratiesysteem (DRS) van SIDN kan via twee verschillende kanalen worden aangesproken. Er is een Web-GUI, waarmee handmatig de DRS-handelingen kunnen worden uitgevoerd. En er is een EPP-interface (API), die erg geschikt is om op een geautomatiseerde manier DRS aan te spreken.[meer...]

EPP (Extensible Provisioning Protocol) is een op XML gebaseerd protocol en een internet standaard van de IETF. Het protocol beschrijft de interface en de input/output van een registratiesysteem. Wie geïnteresseerd is in de details, kan kijken naar RFC 5730, RFC 5731, RFC 5732, RFC 5733 en RFC 5734.

Bij SIDN wordt sinds de introductie van DRS5 gebruik gemaakt van EPP als vervanging van de voormalige e-mailformulieren. De EPP-interface maakt gebruik van een TCP-verbinding die met TLS wordt gecodeerd.  Een cliënt maakt een connectie met de EPP-server en zal vervolgens XML-requests versturen. Dit werkt op zich prima, alleen hebben we gemerkt dat het gebruik van een ‘stateful’ TCP verbinding een aantal bezwaren kent.

Bezwaren van EPP
EPP is gedefinieerd als een ‘stateful protocol’. Dat wil zeggen dat de server van elke cliënt informatie moet bijhouden over de lopende sessie. Dat impliceert (in onze setup), dat de cliënt gedurende de duur van een sessie steeds bij dezelfde server moet terug komen voor een volgend EPP-verzoek. Onze load-balancers zorgen daar dan ook voor.  Dat maakt het echter lastig om een bepaalde server, waarop sessies actief zijn, voor onderhoud uit de pool van beschikbare servers te halen. En het is jammer dat een load-balancer verzoeken niet simpelweg kan doorsturen naar de op dat moment minst belaste EPP-server. Als oplossing kan ‘session state’ op een andere manier worden bijgehouden, maar dat maakt de infrastructuur weer complexer.

Wanneer de TCP-verbinding van een lopende sessie onverwachts verbroken wordt  (zonder eerst het <logout> commando te versturen), bestaat de EPP-sessie nog steeds op de server. Dat kan een probleem opleveren, aangezien bij SIDN sprake is van een maximaal aantal simultane sessies. Wanneer nieuwe sessies worden opgezet, terwijl de oude sessie nog niet is opgeruimd, kan een registrar tegen een sessie-limiet aan lopen. Ook hier moet dus omheen worden gewerkt.

Internet draft: RESTful EPP (REPP)
Toen we aan het nadenken waren over dit onderwerp, ontstond het idee om EPP te gaan doen op een ‘stateless’ manier, dus op een manier waarop ‘state’ niet meer bijgehouden hoeft te worden. Dat idee hebben we uitgewerkt in een internet-draft, waarvan versie ‘00’ onlangs is ingediend bij de IETF.

We hebben er bij ons idee voor gekozen om gebruik te maken van ‘Representational state transfer’ (REST), een bepaalde software-architectuurstijl, die de laatste jaren toenemende belangstelling geniet.

De oplossing moest zo dicht mogelijk bij de bestaande EPP-standaarden blijven, vonden we, omdat deze wereldwijd al veel wordt gebruikt. Daarnaast hadden we de volgende wensen:

  • Stateless;
  • XML-gebruik minimaliseren;
  • Simpel te integreren.

Het was al snel duidelijk dat een ‘stateless’ API veel van de bezwaren zou oplossen. Stateless  is de natuurlijke tegenhanger van stateful. HTTP is het misschien wel bekendste voorbeeld van een stateless protocol. 

REST is een architectuurstijl die bovenop HTTP is gedefinieerd. Met REST is het mogelijk om een API te ontwerpen die eenvoudig leesbaar is en ook eenvoudig te gebruiken is. REST definieert een zogenaamde ‘resource’, die een object definieert waarop een operatie moet worden uitgevoerd. Deze operatie wordt bepaald door de ‘HTTP method’, zoals GET of POST. Een API die werkt volgens de principes van REST wordt aangeduid als ‘RESTful’ API. De nieuwe interface heeft dan ook de naam REPP gekregen, wat staat voor “RESTful EPP”.

Eigenlijk werkt REPP heel eenvoudig. Een domein <check> commando is bijvoorbeeld:

HEAD /rest/v1/domains/sidn.nl

Met de RESTful EPP-interface wordt een EPP-commando dus niet meer verstuurd door middel van een XML request, maar als een REST resource. Bijvoorbeeld een domeinnaam-resource “/rest/v1/domains/sidn.nl” en een  HTTP methode die aangeeft wat er met deze resource moet  gebeuren, bijvoorbeeld een GET voor een <info> of een HEAD voor een <check> commando.

Zie hieronder het verschil tussen een RESTful en een stateful domeinnaam check:

RESTful

HEAD /rest/v1/domains/sidn.nl
X-REPP-cltrid: ABC-12345

Stateful

<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<epp xmlns="urn:ietf:params:xml:ns:epp-1.0">
   <command>
      <check>
        <domain:check
          xmlns:domain="urn:ietf:params:xml:ns:domain-1.0">
          <domain:name>sidn.nl </domain:name>
        </domain:check>
      </check>
      <clTRID>ABC-12345</clTRID>
   </command>
</epp>

Het verschil t.o.v. het huidige EPP is, dat er minder XML nodig is en een aantal commando’s veel efficiënter zijn geworden. De <login> en <logout> commando’s zijn zelfs helemaal niet meer nodig.

Er is een nieuwe EPP-extensie ontworpen welke gebruikt kan worden om, als het nodig is, een EPP XML request naar de server te versturen. Daarnaast is een ‘mapping’ gemaakt van de bestaande EPP-commandostructuur naar een RESTful-interface in de vorm van een verzameling van URL’s.

Het resultaat is een hybride oplossing, een API die bestaat uit een mix van een EPP-extensie en een ‘EPP protocol mapping’. Of het resultaat officieel nog EPP genoemd kan worden was al snel onderwerp van discussie. Dit, omdat REPP afwijkt van een duidelijke uitspraak uit RFC 5730, namelijk dat EPP stateful moet zijn. En dat was het nou net niet  :-)

Referentie implementatie
Om het resultaat te testen is er een referentie implementatie gemaakt, maar dat is iets voor het volgende artikel.

Onze draft is te lezen op: http://tools.ietf.org/html/draft-wullink-restful-epp-00 .

Tags
meer

Geautomatiseerd testen van OpenDNSSEC

  • Door: Nick van den Heuvel
  • 12 december 2011 - 09:30 uur

Voor het signeren van een zonefile met DNSSEC bestaan er verschillende softwareoplossingen. Eén ervan is OpenDNSSEC (hierna te noemen ODS), dat wordt ontwikkeld door een team van ontwikkelaars en testers uit verschillende organisaties, waaronder NLnetLabs, Nominet, .SE, SURFnet en SIDN. Ook de .nl-zone wordt gesigneerd met behulp van ODS.[meer...]

Acceptatie – en regressietesten
ODS is opensource software voor UNIX-platformen (waaronder Linux). SIDN neemt het zogenaamde ‘acceptatie – en regressietesten’ van de software voor haar rekening. De resultaten geven we terug aan de OpenDNSSEC-community. Aangezien er veel testgevallen zijn, hebben we dit zoveel mogelijk geautomatiseerd. Dat zorgt namelijk voor een consistente testuitvoering, een betere benutting van tijd en goed te vergelijken resultaten: bij elke run worden dezelfde scenario's doorlopen met exact dezelfde testgegevens.

Test tool
Omdat er nog geen goede automatische test tool voor ODS bestond, hebben we er zelf één gebouwd. Op basis van specificaties van onze testanalist (degene die de testscenario's bedenkt, uitvoert en analyseert), heeft onze testautomatiseerder (die o.a. voor de technische ondersteuning zorgt) een ‘test engine’ gemaakt. Deze is geschreven in Perl en maakt  gebruik van enkele CPAN- modules, o.a. om testscripts, die gebouwd zijn in Excel, te kunnen uitvoeren.

Actiewoord-gedreven-testen
De werking is gebaseerd op de methodologie: ‘actiewoord-gedreven-testen’. De definitie van een actiewoord is als volgt: een gedefinieerde combinatie van acties, die aangeeft hoe de testgevallen uitgevoerd moeten worden. Met behulp van een verzameling van actiewoorden, al dan niet voorzien van parameters, is het mogelijk om de testscenario's in een script te beschrijven. Een paar voorbeelden van actiewoorden die de test engine kan lezen en uitvoeren zijn:

  • start: het starten van de ODS-applicatie;
  • CheckLog: het controleren van de message logging, waarbij je in een parameter kan aangeven 
  • naar welke string/tekst je precies zoekt;
  •  ODSSetup: het draaien van het commando ‘ods-ksmutil setup’, waarmee o.a. de nieuwe 
  • configuratie bestanden voor ODS worden ingeladen;
  • LoadConfig: het verplaatsen van de gewenste configuratie naar de default configuratie 
  • directory van OpenDNSSEC, zodat deze gebruikt worden bij het uitvoeren van een testgeval.

Hieronder staat een screenshot van een deel van een testscript. Aan de linkerkant staan de actiewoorden, en in de twee kolommen ernaast de specifieke parameters.



Wanneer het testscript start, worden de testgevallen uitgevoerd vanuit een terminal. De stappen die uitgevoerd worden, alsmede het resultaat, worden zichtbaar op het scherm, maar worden tevens gelogd in een bestand. Ook de ‘syslog’-bestanden kunnen gearchiveerd worden, mits dit in het testscripts staat aangegeven.


Key tag
In bovenstaande schermafbeelding wordt er gecontroleerd of een ‘key tag’ (een identificatie waarmee snel en eenvoudig de juiste publieke sleutel bij een DS- of RRSIG-record gekozen kan worden) in een gesigneerde zone overeen komt met de verwachting. Wanneer dit het geval is (zoals in bovenstaande voorbeeld), geeft de test engine als resultaat ‘PASSED’. Wanneer dit niet het geval is zal het resultaat ‘FAILED’ worden gegeven.

Testresultaten
Voorlopig worden de verschillende testscripts nog handmatig ‘afgetrapt’. In de nabije toekomst zullen ze echter gaan draaien in Jenkins, zodat bij een nieuwe release de testresultaten veel vlotter beschikbaar zijn. De testresultaten zullen in de vorm van een samenvatting per testcluster (verzameling van testgevallen) worden gegenereerd.

Onze test engine is, net als ODS, open source software. Om een indruk te krijgen is deze hier te downloaden.

De officiële website van OpenDNSSEC is http://www.opendnssec.org/ . Hier is ook de laatste versie van SoftHSM (Hardware Security Module) te vinden.

OpenDNSSEC is opensource, dus vrijelijk te gebruiken voor het signeren van je eigen domeinnamen.

Ldns als iOS ‘universal library’

  • Door: Marc Groeneweg
  • 19 oktober 2011 - 11:00 uur

Mijn collega Maarten Wullink heeft in zijn iEnum app de ldns software van NLNetLabs opgenomen als broncode, precies zoals de mensen van Telnic dat hebben gedaan in hun iOS apps. Maar, zo vroeg ik me af, kan dat misschien beter? Zou het niet slimmer zijn wanneer je ldns als een ‘library’ kon opnemen in je Xcode-projecten? [meer...]

Dat kan veel onderhoud schelen in het geval er een nieuwe versie van ldns uitkomt (en dat gebeurt nogal eens). Je hoeft dan niet meer in elk afzonderlijk Xcode-project de ldns software bij te werken. Wil je DNSSEC doen, dan heb je ook nog OpenSSL nodig. Daarmee wordt het upgradeprobleem alleen maar groter.
 
Kortom; Is het niet mogelijk om Unix-libraries ook in Xcode-projecten als een echte library te gebruiken in plaats van deze steeds los op te nemen als broncode?

Het antwoord is: ja, dit kan. Apple duidt dit aan als de ‘universal library’. Dat zijn statische libraries die werken op zowel de emulator als op de verschillende typen hardware van Apple. Er zijn verschillende voorbeelden op internet te vinden die uitleggen hoe je zo’n ‘universal library’ maakt. Nog prettiger; al snel vond ik een goed werkend voorbeeld om OpenSSL als ‘universal library’ aan de praat te krijgen. Precies wat ik zocht.

Als eerste moest ik hiervoor een script van Felix Schulze downloaden en licht aanpassen (naar OpenSSL 1.0.0e en iOS 5.0). Dat leverde vervolgens een werkende, universele ’libcrypto’ en ‘libssl’ op. Goed, OpenSSL als ‘universal libary’ onder Xcode bleek dus eenvoudig. Op deze wijze moest het ook mogelijk zijn om ldns te bouwen.

Ldns build script
Geinspireerd door het script van Felix Schulze heb ik een eigen script voor ldns gemaakt, met de toepasselijke naam: ‘build-libldns.sh’. Met dit script maak je op simpele wijze een ‘libldns.a’, een ldns ‘universal library’ voor in je Xcode-projecten.

Het script kun je hier bekijken.

Om de goede werking van deze ‘universal library’ te kunnen testen, heb ik een simpele demonstratie-app gemaakt. Voeren we die uit in de iPhone emulator, dan zien we meteen het resultaat; netjes de regel met ldns versie 1.6.10 en OpenSSL versie 1.0.0e. Maar op de iPhone hardware werkt hij ook, waarmee is aangetoond dat de benodigde code voor de ARM architectuur  ook keurig in de ‘universal library’ zit.

De demonstratie app nader bekeken
De app werkt door In de ‘MainViewController’ direct een resolver-object aan te maken. Om precies te zijn bij ‘viewDidLoad’:

if (! resolver)
        resolver = [[DnsResolver alloc] init];

De genoemde ‘DnsResolver’ bevat de volgende ‘private method’ waarin je de link ziet tussen de objective-C methode en de daarbij behorende functie uit de ldns library:

- (ldns_resolver *)createLdnsResolver {
    ldns_resolver *resolver;
    ldns_pkt *p;

    p = NULL;
    resolver = NULL;

    /* create a new resolver from resolv.conf */
    /* on the iphone we may not have a resolv.conf so we provide one */

    NSString *resolverFilePath = [[NSBundle mainBundle] pathForResource:@"resolv" ofType:@"conf"];

    const char *txt = [resolverFilePath cStringUsingEncoding:NSASCIIStringEncoding];

    s = ldns_resolver_new_frm_file(&resolver, txt);

    return resolver;

}

Om nu bijvoorbeeld een ANY query uit te laten voeren kun je de volgende methode maken en gebruiken:

NSString *requestedDomain = [domainSearchBar text];
 ldns_rr_type dnsTypeField = LDNS_RR_TYPE_ANY;
 resolvTxt = [resolver getTypeForDomain:requestedDomain dnsType:dnsTypeField];

Waarbij de volgende methode binnen ‘DnsResolver’ gehanteerd wordt:

- (ldns_pkt *)retrievePacketOfType:(ldns_rr_type)rrType fromDomain:(NSString *)reqDomain {

    domain = ldns_dname_new_frm_str([reqDomain UTF8String]);

    if (!domain) {
        NSLog(@"Can't do ldns_dname_new_frm_str");
        return NULL;
    }

    ldns_pkt *p;
    ldns_resolver_set_dnssec(res, true);
    p = ldns_resolver_query(res,
                            domain,
                            rrType,
                            LDNS_RR_CLASS_IN,
                            LDNS_RD);

    if (!p)  {
        NSLog(@"Can't do ldns_resolver_query");
        return NULL;
    }

    return p;
}

Je krijgt dan uiteindelijk de volgende schermuitvoer op je iPhone te zien:

Zelf proberen
Wil je zelf eens aan de slag, dan vind je het gehele door mij gebruikte Xcode-project hier. Hiermee kun je dus OpenSSL en ldns als een ‘universal library’ in je projecten opnemen en eenvoudig onderhouden. Het is maar een proof of concept. De volgende stap is om echte DNSSEC resolving en -validatie op de iPhone te krijgen. Voer voor een volgend blog!

Kwaliteit van je DNS checken

  • Door: Peter Popma
  • 15 augustus 2011 - 09:00 uur

Als .nl-registrar krijg je maandelijks een overzicht van de kwaliteit van je DNS-servers in de vorm van een ranking en een overzicht van problemen zoals lame delegations, inconsistentie van SOA versienummers, etc. De basis voor deze kwaliteits controle vormt de DNS-check. De software voor deze check is ontwikkeld door medewerkers van de Zweedse registry .SE (met medewerking van SIDN). Deze check is ook per domeinnaam uit te voeren via de SIDN-website. [meer...]

Integreren in eigen softwareVoorbeeld DNS Report
Het kan handig zijn om de DNS-check te integreren in eigen software, bijvoorbeeld om je DNS-servers te monitoren. Dat kan, heel eenvoudig, want de DNS-check is open-source software.
Hier volgt een korte instructie om je op weg te helpen de DNS-check in je software toe te passen:

1. Source code downloaden
Ga naar https://github.com/dotse/dnscheck om de source code op te halen. De SIDN DNS-check gebruikt op het moment van schrijven versie 1.2.1

2. Database aanmaken
In /engine/db vind je de code om het schema aan te maken. Deze is in MySQL dialect en het is dan ook aan te raden MySQL als database engine te gebruiken.

3. Taal instellen
De DNS-check beschikt standaard over meldingen in de Zweedse, Engelse en Nederlandse taal. Deze meldingen zijn te vinden in .yaml-files en moeten in de database worden geïmporteerd. Er is een perl script beschikbaar om de sql te genereren. Om de Engelse berichten te genereren gebruik je:   ../util/locale2sql.pl ../locale/en.yaml > messages.sql. Vervolgens kun je met bijvoorbeeld de MySQL commandline deze SQL-file importeren in de database.

4. Configureren
In config.yaml/site_config.yaml kun je aanpassingen doen om je databaselocatie in te stellen. Ook kun je policy.yaml aanpassen om te bepalen of een bepaalde bevinding door de DNS-check als fout moet worden gezien, of alleen maar ‘ter informatie’ wordt geregistreerd.

5. Bouwen en installeren
De engine van de DNS-check bestaat uit perl scripts. De volgende commando’s zijn nodig om de engine te bouwen en te installeren (zie ook de DNS-check read me file)

  • perl Makefile.PL
  • make
  • make install

Nu kun je ook de daemon opstarten met ‘dnscheck-dispatcher’. (In stap 7 wordt uitgelegd waarvoor deze gebruikt wordt)

6. Testen
Je kunt eenvoudig testen of de check werkt door hem vanaf de command-line uit te voeren, bijvoorbeeld:

dnscheck sidn.nl

7. Integreren
Bij de DNS-Check wordt een user-interface in PHP geleverd waarmee je te testen domeinnamen kunt invoeren. Zodra je via deze interface een domeinnaam invoert, wordt deze toegevoegd aan de ‘queue-tabel’. De domeinnamen uit deze tabel worden door de daemon opgepikt om getest te worden. Resultaten van de check komen in de ’tests-’ en ’results–tabellen’ te staan.

Je kunt ook zelf via eigen software deze ‘queue–tabel’ vullen met domeinnamen die je wilt testen. Bijvoorbeeld met een cron-job die eenmaal daags al je domeinnamen checkt. Vervolgens kun je een bijvoorbeeld een PHP-pagina maken om de resultaten uit de results-tabel online te kunnen bekijken of een script maken waarmee je een e-mail alert ontvangt als er een ongewenst resultaat verschijnt in de results-tabel.

Op deze manier kan de DNS-check kan een waardevolle tool zijn om de kwaliteit van je DNS te monitoren. Omdat de check via een database werkt is het eenvoudig om met eigen software in elke gewenste taal de DNS-check te laten uitvoeren en resultaten te verwerken.