Toekomstbestendige hosting voor web en e-mail (update)

Ik liep al enige tijd rond met het idee om wat nieuwe technieken in te zetten ten behoeve van mijn hosting praktijk. Een aantal weken geleden vond ik dan eindelijk de tijd én motivatie om ermee aan de slag te gaan, en uiteindelijk heeft dit geresulteerd in de implementatie van IPv6, SPF, DKIM, DMARC, DNSSEC en DANE. Hiermee wordt de bereikbaarheid en veiligheid van gehoste websites en de e-mailvoorziening verder verbeterd. Op dit moment pas ik de technieken uitsluitend toe op mijn eigen domeinen, maar ik ben inmiddels bezig met de uitrol naar de domeinen van alle klanten. Mijn ambitie is om deze technieken voortaan standaard in te gaan zetten. In deze blogpost vertel ik je per bovengenoemde techniek over mijn ervaringen tijdens de implementatie ervan.

Stap 1: Internet Protocol v6 (IPv6)

Mijn internet service provider XS4ALL biedt IPv6 al vele jaren native aan als gevolg van een zogenaamde Dual IP Stack implementatie. In het verleden heb ik IPv6 op zowel het modem als op mijn Linux servers uitgeschakeld (sysctl -w net.ipv6.conf.eth0.disable_ipv6=1), omdat ik niet zomaar een nieuw ongecontroleerd pad naar het internet wilde opzetten. Alvorens IPv6 in te schakelen wilde ik eerst beter begrijpen hoe de IPv6 nummering in elkaar zat, en wilde ik een firewall gereed hebben. Van een netwerk engineer bij een klant kreeg ik de tip om gewoon eens te beginnen met een IPv6 nummerplan, dus ging ik op zoek naar meer informatie. Al snel stuitte ik op twee documenten van SURFnet die me erg hebben geholpen om de in de ‘IPv6 mindset’ te geraken, en los te komen van het oude ‘IPv4 NAT denken’: de handleiding IPv6 nummerplan opstellen, en het rapport IPv6 Beveiliging. Ook de volgende documenten zijn interessant voor hen die zich wat verder willen verdiepen in IPv6 en de beveiligingsaspecten ervan: het IPv6 whitepaper van het NCSC, het rapport Testing the security of IPv6 implementations, en de IPv6 hardening guides van ERNW (Linux, Windows, OS X).

Na het realiseren van een op iptables gebaseerd firewall script voor IPv6, schakelde ik IPv6 in op het modem van XS4ALL en op de interface van mijn Linux servers (sysctl -w net.ipv6.conf.eth0.disable_ipv6=0). En hoppa, voor ik het wist kreeg de interface netjes een IPv6 adres toegewezen. Daarna volgden nog twee stappen: het aanpassen van de configuraties van alle serverapplicaties (Apache, Postfix, etc) zodat ze ook verzoeken op het IPv6 adres afhandelen, en het toevoegen van een AAAA resource record in de DNS zones van de gehoste domeinen. Ik heb overigens een hele tijd lopen zoeken naar de reden waarom ik vanaf het internet geen IPv6 verbinding kon opzetten naar bijvoorbeeld Apache. Uiteindelijk kwam ik erachter dat ik de ‘anywhere’ variabele in mijn firewall script (deze gebruik ik om aan te geven dat elk willekeurig IP-adres toegang heeft tot een bepaalde poort) niet goed had ingesteld. Ik had er in eerste instantie  0:0:0:0:0:0:0:0 van gemaakt, maar ontdekte dat dit ::/0 moet zijn.

De eerste week leek het allemaal prima te werken, totdat een van mijn hosting klanten een “Undelivered Mail Returned to Sender” naar me doorstuurde. Het versturen van e-mail naar een @gmail.com adres resulteerde in een “550-5.7.1 error van de Google mailserver:

Our system has detected that this message does not meet IPv6 sending guidelines regarding PTR records and authentication. Please review https://support.google.com/mail/?p=ipv6_authentication_error for more information.

Op deze site staat onder andere het volgende:

The sending IP must have a PTR record (i.e., a reverse DNS of the sending IP) and it should match the IP obtained via the forward DNS resolution of the hostname specified in the PTR record. Otherwise, mail will be marked as spam or possibly rejected.

Een snelle controle wees inderdaad uit dat er geen reverse DNS lookup mogelijk was voor wat betreft mijn IPv6 adres. De oplossing was het toevoegen van een PTR record in de zone van XS4ALL en dus niet in een van mijn eigen zones. Ik logde in op Mijn XS4ALL en ontdekte dat het momenteel alleen mogelijk is om reverse DNS in te stellen voor mijn IPv4 adres. Dan maar even bellen met de helpdesk.

En dan weet je weer waarom je klant bent bij XS4ALL. Ik kreeg Coen aan de lijn, en Coen begreep snel wat ik wilde. Hij gaf zelfs aan dat er wordt gewerkt aan de mogelijkheid om dit in de toekomst zelf te kunnen doen via Mijn XS4ALL. Omdat Coen alleen weet welke IPv6 prefix ik toegewezen heb gekregen, stuurde ik hem een e-mail met daarin het volledige IPv6 adres wat ik middels een PTR record wilde verankeren in de DNS. Coen sloot het telefoongesprek af door me te informeren over de verdere procedure, en tot mijn genoegen merkte ik dat de wijziging binnen het uur werd doorgevoerd. Dat is nou service!

PTR verplicht?
Nieuwsgierig naar ‘de regels’ omtrent het gebruik van PTR records, dook ik er kort in. Door de jaren heen heb ik zelf ervaren dat ISP’s in het geval van IPv4 de PTR records automatisch genereren wanneer ze niet handmatig (voor of door klanten) ingevuld worden. Ik ben nu al een aantal providers tegengekomen die dat voor IPv6 niet standaard doen. Gezien de enorme grote aantallen IPv6 adressen begrijp ik dat, maar is het eigenlijk wel de bedoeling dat ISP’s dat (net als bij IPv4) blijven doen?

In het geval van IPv4 zegt RFC 1912 hierover het volgende:

Make sure your PTR and A records match.  For every IP address, there should be a matching PTR record in the in-addr.arpa domain.

Het document Policy Issues for Receiving Email in a World with IPv6 Hosts van het M3AAWG zegt hierover:

Many operators configure their inbound MTAs to reject connection attempts from IP addresses without reverse DNS (PTR) records, or at least to consider email from such IP addresses highly suspicious. This technique can be an even more effective high-pass filter under IPv6. This is the case even though operators are unlikely to publish reverse DNS records for the vast majority of the IPv6 addresses in their allocation, since there is limited benefit to doing so and the process is cumbersome due to the large number of addresses.  In contrast the number of hosts dedicated to relaying email across administrative boundaries is quite small by comparison, as is the number of addresses they use, and it is feasible for operators to publish and maintain reverse DNS records for this smaller set of dedicated IP addresses.

Op Zytrax.com lees ik dat het niet verplicht is voor IPv6, maar wel is aan te raden:

IPv4 reverse mapping is not mandatory though, as indicated by the mail example, it is essential for hosts that send mail, using either a Mail Transfer Agent (MTA) or a Mail User Agent (MUA). In the case of IPv6 reverse-mapping was originally mandatory but as part of the seemingly relentless move to relax the goals of the original specifications (doubtless for good operational reasons) it is no longer a mandatory requirement.

Ook staat op dezelfde website beschreven dat het bij IPv6 de bedoeling is dat de verantwoordelijkheid voor reverse mapping verplaatst naar de gebruiker:

Unlike IPv4, where reverse mapping is frequently not delegated to the end user, IPv6 allows and encourages delegated reverse mapping. The end user can therefore be responsible for creation of reverse-mapping zone files using the IP6.ARPA domain for the address range they have been assigned, depending on the policies of the IPv6 address assignor – RIR/LIR/ISP (Regional Internet Registry/Local Internet Registry/Internet Service Provider).

Er wordt echter ook verwezen naar de hierboven aangehaalde RFC 1912 met de opmerking dat dit voor IPv6 niet zo makkelijk is als voor IPv4, maar dat het wel belangrijk is om dit voor e-mailsystemen geregeld te hebben:

It is worth noting however, that as with the equivalent IPv4 addresses, the only current applications which are known to use reverse mapping consistently are mail systems. Thus, steps should be taken to ensure that, at least, these hosts have a valid IPv6 reverse-map.

Kortom, de verantwoordelijkheid voor PTR records verschuift naar de gebruiker/afnemer van een dienst, en het lijkt erop dat het alleen voor mailservers belangrijk is dat de PTR records aanwezig én correct zijn.

Stap 2: SPF, DKIM en DMARC

Deze technieken worden gebruikt om de betrouwbaarheid van e-mail te verhogen door de authenticiteit van de afzender (DKIM) en verzender (SPF) te controleren, én door te melden hoe er met e-mail moet worden omgegaan wanneer een of meerdere van deze controles falen (DMARC). Erg nuttig in de strijd tegen spam. In de korte tijd dat ik deze technieken toepas voor het controleren van inkomende e-mail, heb ik al het idee dat mijn spamfilter (SpamAssassin) spam nog beter kan detecteren. Over DMARC schreef ik al eerder een blog in 2013, maar ook het interview met Tim Draegen op dnssec.nl is het lezen waard. Zoek je een goede how-to voor alle drie de technieken, kijk dan eens naar deze how-to op skelleton.net. Ik heb deze zelf met succes toegepast, maar wil er wel nog een paar opmerkingen bij plaatsen.

Wat ik mis in deze how-to is aandacht voor het belang van de rotatie van je DKIM sleutels. Vreemd genoeg vond ik daarover niks terug in RFC 6376, maar M3AAWG heeft het over minimaal een keer per half jaar. Uiteraard eerder wanneer er ernstige kwetsbaarheden worden ontdekt in de gebruikte cryptografische standaarden. Op deze website kun je lezen hoe je de zogenaamde key rotation aan kunt pakken, en in deze blog lees je hoe Microsoft het automatisch roteren voor Office 365 heeft aangepakt.

Ook miste ik het behandelen van de minimale key length. Een minimale lengte van 1024 bit is het advies. Hoger is in principe beter, maar ga momenteel niet hoger dan 2048 bit. Volgens RFC 6376 is de ondersteuning daarvan niet verplicht: “Verifiers MUST be able to validate signatures with keys ranging from 512 bits to 2048 bits, and they MAY be able to validate signatures with larger keys”. Daarnaast heb ik ontdekt dat het handig is om je DMARC e-mailadres (dmarc [at] example [dot] com) te whitelisten in je spamfilter. Tot slot vind je op dmarc.org een handig overzicht met testtools.

Door te testen ontdekte ik zelf dat je niet zomaar een e-mailadres van een ander domein in je DMARC record kunt gebruiken. Als je dit wel wil doen, dan dien je een extra zone record toe te voegen aan de zone van het domein van het e-mailadres. Zo wilde ik bijvoorbeeld de reports voor mijn domein baaten.com laten versturen naar een e-mailadres van traxotic.net. In de zonefile van baaten.com staat dan  _dmarc IN TXT "v=DMARC1; p=quarantine; rua=mailto:mailadres@traxotic.net; ruf=mailto:mailadres@traxotic.net; fo=0; adkim=r; aspf=r; pct=100; rf=afrf; ri=86400; sp=quarantine", terwijl in de zonefile van traxotic.net baaten.com._report._dmarc.traxotic.net. TXT "v=DMARC1" staat. Het is eigenlijk een soort autorisatie mechanisme. Heel handig, want anders is het wel heel makkelijk om een DDoS e-mailbom te veroorzaken.

Overigens doe je er verstandig aan om even te kijken naar de website dmarcian.com. Je kunt hier je ontvangen XML reports (geautomatiseerd) uploaden en je krijgt er makkelijk interpreteerbare informatie voor terug. De eerste twee weken is het gratis, en daarna zijn er in een aantal gevallen kosten aan verbonden. Ik ben overigens bij dmarcian.com uitgekomen, omdat ik in mijn logfiles zag dat er reports werden gestuurd naar @ag.dmarcian.com. Inmiddels ben ik er, met dank aan Bart, achter dat dit komt doordat andere organisaties ook gebruik maken van dmarcian.com en in hun DMARC record een @ag.dmarcian.com e-mailadres hebben opgenomen. Omdat mijn server is ingesteld om DMARC reports te versturen, worden deze rechtstreeks verstuurd naar de in de DMARC zone vermelde e-mailadressen. Vandaar de melding in mijn logfiles. Logisch, maar dat kwartje viel niet meteen. :-) Ik heb zelf namelijk voor een andere opzet gekozen waarbij ik de reports ontvang op een eigen e-mailadres, maar deze wel automatisch doorstuur (postfix recipient_bcc_maps) naar dmarcian.com.

Stap 3: DNSSEC

Ik maakte eerder gebruik van DNSSEC voor een enkel domein, maar na een upgrade naar Debian Jessie ontdekte ik dat de door mij gebruikte software DNSSEC-tools plotseling geen onderdeel meer uitmaakte van de distributie. En zaten blijkbaar een aantal bugs in die niet tijdig werden opgelost. In de planning had ik hier echter geen rekening mee gehouden, dus besloot ik last-minute het gebruik van DNSSEC te staken. Ik had wel vaker gehoord van OpenDNSSEC, maar ik vond (en vind) de website onoverzichtelijk en niet bepaald uitnodigend om met DNSSEC aan de slag te gaan. Begrijp me niet verkeerd; de functies en werking van OpenDNSSEC zijn zeer goed gedocumenteerd, maar dat maakt nog geen toegankelijke how-to van A tot Z zoals ik die door de jaren heen vaker heb gezien. Wat dat betreft wekt opendnssec.org de indruk dat je de puzzelstukjes met veel leeswerk zelf nog bij elkaar moet zoeken, en dat legt de lat toch even wat hoger. Zeker als je er vooraf geen rekening mee hebt gehouden.

Tegelijkertijd begrijp ik ook dat de impact van een DNSSEC implementatie een tikkeltje zwaarder is dan gemiddeld, waardoor wat meer lees- en denkwerk wel gerechtvaardigd is. De website die ik uiteindelijk heb gebruikt als startpunt voor de implementatie van DNSSEC, is www.dnssec.nl. De hands-on op deze website is echt een aanrader voor iedereen die met OpenDNSSEC aan de slag gaat. Het hoe en het waarom worden op uitstekende wijze gecombineerd, waardoor je ook leert begrijpen waar je mee bezig bent. Op basis van deze hands-on configureerde ik OpenDNSSEC voor een enkel domein middels “input en output files” (in plaats van de “bump-in-the-wire” opzet) en met MySQL als back-end database.

Wat ik echter in het verhaal miste is een korte toelichting op de key states die je tegenkomt bij het uploaden van het KSK-sleutelmateriaal naar de registry. Ook kreeg ik een foutmelding in syslog toen ik Signer en Enforcer startte middels ods-control start: “ods-signerd: [file] unable to stat file /var/lib/opendnssec/signconf/domeinnaam.xml: ods_fopen() failed”. Het signconf bestand werd niet aangemaakt, waardoor er ook geen signed zonefile werd gecreëerd. Door een wat onoverzichtelijke trial-and-error fase kan ik niet met 100% zekerheid zeggen hoe ik dit probleem uiteindelijk heb opgelost. Ik meende dat het probleem werd veroorzaakt door de te hoge snelheid waarmee ods-control de Enforcer en de Signer na elkaar opstart. Nadat ik eerst de Enforcer handmatig startte en daarna de Signer, werkte het namelijk wel. Ik kwam dezelfde foutmelding echter ook tegen bij het toevoegen van een nieuwe zone na de initiële configuratie en start van OpenDNSSEC, en toen bleek de oplossing elders te liggen.

Dat brengt me eigenlijk op het tweede onderdeel dat ik miste in deze hands-on, en dat is hoe je na de initiële setup een nieuwe zone toevoegt aan OpenDNSSEC. De documentatie op opendnssec.org biedt de nodige hulp, waarmee ik uiteindelijk (voor mijn configuratie) op de volgende procedure uitkwam:

  1. Voeg de nieuwe zone toe met het commando ods-ksmutil zone add --zone traxotic.net --policy com_net_org --signerconf /var/lib/opendnssec/signconf/traxotic_net.xml --input /etc/bind/external/db.traxotic.net --output /etc/bind/external/signed/db_signed.traxotic.net.
  2. Start OpenDNSSEC opnieuw op door ods-control stopgevolg door ods-control start. Je ziet dan de eerder genoemde foutmelding weer verschijnen in syslog: “ods-signerd: [file] unable to stat file /var/lib/opendnssec/signconf/traxotic_net.xml: ods_fopen() failed”.
  3. Je lost dit op door na de herstart een backup van je keys door het uitvoeren van ods-ksmutil backup prepare gevolgd door ods-ksmutil backup commit
  4. Herstart daarna OpenDNSSEC opnieuw (ods-control stop en ods-control start) en je ziet dat het signconf bestand en de gesigneerde zonefile deze keer wel zijn aangemaakt. Het aparte is dat het maken van de backup (stap 3) niet mogelijk is zonder de eerste herstart van OpenDNSSEC (stap 2).
  5. Pas nu de configuratie van je DNS server aan (in mijn geval BIND) door de getekende zonefile te koppelen aan het desbetreffende domein.
  6. Als je daarna kijkt naar de status van je keys ( ods-ksmutil key list --verbose ) dan zie je dat de status van je KSK op “publish” staat.
  7. Wanneer de nieuwe zonefile goed over het internet is verspreid (daarom is stap 5 belangrijk), dan verandert de KSK key status in “ready”. Ik vermoed dat de wachttijd gehanteerd door OpenDNSSEC, is gekoppeld aan de TTL gedefinieerd in je zonefile. Zodra de status is veranderd in “ready” krijg je een e-mail van de OpenDNSSEC daemon met het verzoek de publieke sleutel horende bij je KSK te uploaden naar de registry. Je kunt de te uploaden data opvragen met behulp van ods-ksmutil key export --zone traxotic.net of  ods-ksmutil key export --zone traxotic.net --ds.
  8. Nadat je de public key hebt geupload naar de registry, vertel je OpenDNSSEC dat je dit hebt gedaan met  ods-ksmutil key ds-seen -z traxotic.net. -x 12345 waarbij 12345 de bijhorende keytag is. Je zult daarna zien dat de status van je KSK is gewijzigd naar “active”.

Een deel van deze commando’s kun je ook gebruiken in het geval van een key rollover. Bijvoorbeeld wanneer de huidige KSK verloopt en je een nieuwe wil aanmaken en uploaden naar je registry. Daarnaast kun je in het geval van wijzigingen in je OpenDNSSEC configuratie, de wijzigingen laten doorvoeren in de onderliggende database door ods-ksmutil update all uit te voeren. Verander je de inhoud van je unsigned zonefile, geeft OpenDNSSEC dan de opdracht om de zonefile opnieuw te ondertekenen met ods-signer sign traxotic.net.

Als je helemaal klaar bent zijn er verschillende online tools beschikbaar waarmee je je DNSSEC kunt testen. Bijvoorbeeld internet.nl, dnsviz.net of dnssec-debugger.

Stap 4: DNS-based Authentication of Named Entities (DANE)

DANE bouwt verder op de veilige infrastructuur die middels DNSSEC is gerealiseerd. Op www.dnssec.nl staat in de vorm van een tweeluik helder uitgelegd wat DANE is en hoe het werkt, dus dat ga ik niet uitgebreid overdoen. In het kort komt het erop neer dat je een (extra) vertrouwensanker creëert in je DNS zone (TLSA), waarmee clients de authenticiteit van het door de server aangeboden TLS certificaat kunnen vaststellen. Lees het tweeluik voor meer informatie. Begin met deel 1 voor het web, en lees daarna deel 2 voor mail.

Ik ging aan de slag met beide DANE smaken, te beginnen met DANE voor HTTP. Aangezien ik certificaten gebruik die zijn getekend door de CA van een derde partij (dus geen self-signed certificaten), kies ik voor usage type 1. De output van het commando tlsa --create --output rfc secure.traxotic.net --certificate /etc/ssl/traxotic_certificaat.crt --usage 1 voeg ik toe aan de desbetreffende zonefile, en daarmee is DANE TLSA ondersteuning een feit.

Implementeren van DANE voor SMTP gaat op bijna dezelfde manier. Vanwege beperkingen van de tooling moet je de regel voor je zonefile zelf samenstellen waarbij je de hash genereert met openssl x509 -in /etc/ssl/traxotic_mail_certificaat.crt -outform DER | openssl sha256. Uiteindelijk heb ik dus de onderstaande drie regels toegevoegd aan de zonefile van traxotic.net:

_443._tcp.secure.traxotic.net. IN TLSA 1 0 1 820eeea3acd11d01bbf580e18269001caa3524d52a13aa6e6fc88ebab4d94ae0
_25._tcp.mail.traxotic.net. IN TLSA 3 0 1 2a7c931277beff439cfa98e3bfb3d645aba3ebd1c74e2aad298c5ca511f635c2
_25._tcp.mail2.traxotic.net. IN TLSA 3 0 1 41e5591a8095717d5b8ea10c117b6c54b5f454632ba2f3deb759eed9eb68fbb3

In principe ben je nu klaar, en kunnen derden jouw web- en mailserver certificaten verifiëren op basis van ankers in je zonefile. Vergeet niet te testen of het inderdaad werkt. Wanneer je ook je eigen mailserver DANE controles wil laten uitvoeren, moet je dat wel instellen. In het geval van Postfix doe je dit door het onderstaande in te stellen in main.cf. Zie 1, 2, en 3 voor meer informatie.

smtp_dns_support_level = dnssec
smtp_tls_security_level = dane
smtp_host_lookup = dns

Hopelijk gaan alle behandelde standaarden meer en meer gebruikt worden. Samen maken we het internet dan weer een beetje veiliger.

Update 9-12: Na een paar goede tips van Bart Knubben, heb ik een aantal kleine aanpassingen doorgevoerd. Het betreft voornamelijk extra verwijzingen naar relevante en interessante externe bronnen.

Afbeelding van Robert Phoenix.

2 antwoorden

Plaats een Reactie

Meepraten?
Draag gerust bij!

Geef een reactie

Je e-mailadres wordt niet gepubliceerd. Vereiste velden zijn gemarkeerd met *

Deze site gebruikt Akismet om spam te verminderen. Bekijk hoe je reactie-gegevens worden verwerkt.