Hands-on: de implementatie van DANE op Exim
Cryptografische beveiliging van je mailtransport
Cryptografische beveiliging van je mailtransport
In dit artikel bespreken we de installatie en configuratie van de internetbeveiligingsstandaard DANE voor de Exim-mailserver. DANE gaat het afluisteren van mailverkeer tegen door, waar mogelijk, het gebruik van TLS-encryptie tijdens het transport af te dwingen. Voor onze setup gaan we uit van een CentOS 8.2 Linux-server met daarop een goed werkende standaardinstallatie van de betreffendemail server, en een recht-toe-recht-aan zonefile voor het met DNSSEC beveiligde domein example.nl. Deze setup breiden we vervolgens uit met: • de configuratie van (START)TLS • de publicatie van TLSA records • de specificatie van de cryptografische algoritmen • de validatie van DANE voor mail Voor de basis-setup van de mailserver zelf verwijzen we je naar dit hands-on artikel voor de implementatie van SPF, DKIM en DMARC voor Exim. Net zoals we daar hebben gedaan, combineren we ook in dit artikel concrete configuraties met uitleg over de werking van de DANE-standaard zelf.
DANE gaat het afluisteren van mailverkeer tegen door waar mogelijk het gebruik van TLS-encryptie tijdens het transport af te dwingen. Hoewel we de implementatie van SPF, DKIM en DMARC van harte aanbevelen – voor Nederlandse overheidsorganisaties is dit zelfs verplicht – staat DANE helemaal los van deze drie standaarden. Waar SPF, DKIM en DMARC zorgen voor de authenticatie en autorisatie van de afzender en verzender van een mailbericht (op SMTP-protocolniveau), richt DANE zich op de beveiliging (vertrouwelijkheid) van het transport (op STARTTLS-verbindingsniveau). Omdat SPF, DKIM en DMARC enerzijds en DANE voor mail anderzijds volledig onafhankelijk zijn van elkaar, maakt het ook niet uit welke van deze twee je eerst implementeert. Wel is het gebruik van DNSSEC verplicht voor DANE, terwijl dit voor SPF, DKIM en DMARC alleen aanbevolen is. Op onze DNSSEC-pagina vind je hands-on beschrijvingen voor de implementatie van DNSSEC-ondertekening en -validatie voor Unbound, Infoblox, PowerDNS en BIND. Wie liever eerst met de configuratie van SPF, DKIM en DMARC aan de slag wil, verwijzen we naar dit hands-on artikel voor Exim. De setup daarvan hebben we als uitgangspunt genomen voor dit artikel.
DANE, kort voor DNS-based Authentication of Named Entities, is een protocol voor het veilig publiceren van publieke sleutels en certificaten. Daarbij bouwt deze standaard verder op de cryptografisch beveiligde DNS-infrastructuur die met DNSSEC wordt aangelegd. Hoewel DANE dus breder inzetbaar is, vindt deze standaard op dit moment vooral opgang in de beveiliging van het mail transport (SMTP). De toepassing ervan in de wereld van de webcertificaten (HTTPS) komt vooralsnog niet van de grond, onder andere vanwege de snel groeiende populariteit van de (gratis) Let’s Encrypt-certificaten, en omdat DNSSEC niet altijd en overal beschikbaar is. Voor DANE is het DNS-protocol uitgebreid met het TLSA-record. Dat kan worden gebruikt om sleutelinformatie – in de vorm van een hash-code, een digitaal uittreksel – aan een adres/poort/protocol-combinatie te koppelen. Op die manier kan in principe van elke versleutelde internetservice de authenticiteit van het servercertificaat via DNS worden geverifieerd (gevalideerd). Komt de hash-code van het servercertificaat niet overeen met de hash-code in het TLSA-record, dan weet de client dat de verbinding – ondanks de versleuteling – niet te vertrouwen is. DANE is gestandaardiseerd in RFC 6698, met verduidelijkingen in RFC 7671 en 7673. DANE voor mail heeft zijn eigen specificatie in RFC 7672.
Voor het begrijpen van mailuitwisseling is het van belang onderscheid te maken tussen de communicatie tussen de eindgebruiker en zijn mailservers enerzijds en tussen mailservers onderling anderzijds. Bij communicatie tussen de gebruiker en zijn mailservers gaat het in eerste instantie om het ophalen en lezen door de gebruiker. Zijn mailclient (de Mail User Agent, MUA) gebruikt daarvoor de protocollen POP en IMAP om met de server (de Mail Delivery Agent, MDA) te communiceren. De traditionele TCP-poorten voor deze twee protocollen zijn respectievelijk 110 en 143. Voor TLS-beveiligde verbindingen zijn dat respectievelijk poortnummer 995 (POP3S) en 993 (IMAPS). Verbindingen naar de onbeveiligde poorten (110/pop en 143/imap) kunnen door de client wel worden opgewaardeerd naar een versleutelde verbinding met het STARTTLS-commando. Maar tegenwoordig geef je in de clientconfiguratie meestal expliciet aan gebruik te willen maken van IMAPS op poort 993. Voor het versturen van berichten gebruikt de mailclient het SMTP-protocol. Tegenwoordig gebeurt dat meestal via een private SMTP-gateway voor de eigen gebruikers op TCP-poort 587, afgeschermd voor ongewenste relay door spammers met behulp van een paswoord. Poortnummer 465 was ooit gereserveerd voor TLS-beveiligde gateways (SMTPS), maar die poort is inmiddels aan een ander protocol toegewezen. Cryptografische beveiliging van deze SMTP-verbindingen gebeurt nu dus altijd via STARTTLS (na authenticatie).
Voor het afleveren van berichten maakt de SMTP-gateway op zijn beurt (als client) ook weer gebruik van het SMTP-protocol. Dat gebeurt dan op TCP-poortnummer 25 van de mailserver die als ingang gespecificeerd staat in het MX-record op het ontvangersdomein. Ook hier is weer geen aparte poort beschikbaar voor TLS-beveiligde verbindingen. Clients (mailservers) kunnen hun verbinding met de MX-gateway wel weer opwaarderen via het STARTTLS-commando. Ondanks alle gelijkenissen is er een belangrijk verschil tussen SMTP-verbindingen voor het versturen van mail (door de mailclient) enerzijds en die voor het transport van berichten tussen mailservers (Message Transfer Agents, MTA's) onderling anderzijds. Beheerders van SMTP-gateways kunnen hun eigen gebruikers dwingen om STARTTLS te gebruiken als ze mail willen laten versturen. Dat geldt echter niet voor MX-gateways: omdat zij een publieke ingang zijn voor het afleveren van berichten moeten zij (vooralsnog) ook SMTP-clients (mailservers) kunnen bedienen die geen STARTTLS ondersteunen. In die zin lijkt de SMTP-service dus op het web waar bezoekers in het algemeen ook kunnen kiezen of zij een server bezoeken op TCP-poortnummer 80 (HTTP) of op poort 443 (HTTPS). Belangrijke nuancering is wel dat een bezoeker die met 'https' in zijn URL naar de beveiligde poort 443 surft nooit een automatische fallback naar de onbeveiligde poort 80 zal doen, terwijl een SMTP-client die een bericht wil afleveren op poort 25 ‘gedwongen’ kan worden om dat onbeveiligd te doen, simpelweg door de STARTTLS capability op de server uit te zetten. Het probleem is dat een man-in-the-middle (MITM) hetzelfde kan bereiken door de STARTTLS capability tijdens de nog onbeveiligde SMTP-handshake weg te filteren (STARTTLS stripping). Dergelijke downgrade (STRIPTLS)-aanvallen bleken ook regelmatig door internet access providers te worden uitgevoerd op hun eigen gebruikers, als die gebruik maakten van een eigen SMTP-gateway.
Waar een webgebruiker expliciet aangeeft TLS ('https') te willen gebruiken en ook bericht terug krijgt als dat niet lukt, kan een mail client (vooralsnog) geen beveiligd transport afdwingen en is er ook geen mogelijkheid voor een terugmelding naar de client (anders dan via een bounce message). Uit een mailadres of de MX-records is immers niets af te leiden over de beveiliging van het transport. Wel impliceert de aanwezigheid van een TLSA-record altijd dat de MX-gateway TLS ondersteunt, waarmee een downgrade-aanval op de STARTTLS capability van de gateway wordt voorkomen. Het gebruik van TLS door de SMTP-client is echter optioneel – het kan immers zijn dat deze zelf helemaal geen TLS ondersteunt – waarmee DANE voor mail een zogenaamd opportunistisch protocol blijft. Dat wil zeggen dat een SMTP-client die zelf DNSSEC, DANE en STARTTLS ondersteunt zijn verbindingen met een server waarvoor DNSSEC-ondertekende TLSA-records zijn gepubliceerd (en die dus STARTTLS aanbiedt) ‘moet’ versleutelen. Maar ontbreekt een van deze onderdelen, dan vindt noodgedwongen een fallback naar TLS zonder DANE of zelfs een volledig onbeveiligd transport plaats. Zo wordt gewaarborgd dat het afleveren van berichten – waar immers geen mens aan te pas komt – zo veel mogelijk doorgang kan vinden. Met de publicatie van RFC 8314 in 2018 is onversleuteld transport voor zowel SMTP als POP en IMAP echter officieel "obsolete" verklaard.
Een TLSA-record bevat niet veel meer dan een hash en informatie over de gebruikte cryptografische protocollen. De enige parameter die wat uitleg behoeft is de zogenaamde 'usage'. Deze geeft aan hoe de betreffende hash geïnterpreteerd moet worden:
0: PKIX-TA: Certificate Authority Constraint: verankert een specifiek CA-certificaat in de vertrouwensketen (in aanvulling op de traditionele PKI-validatie)
1: PKIX-EE: Service Certificate Constraint: verankert een specifiek servercertificaat (in aanvulling op de traditionele PKI-validatie)
2: DANE-TA: Trust Anchor Assertion: verankert een specifiek CA-certificaat in de vertrouwensketen, dat daarmee als trust anchor fungeert
3: DANE-EE: Domain Issued Certificate: verankert een specifiek server-certificaat, dat overeen moet komen met het door de server aangeboden certificaat
Usage nummer 0 en 1 verankeren een certificaat van respectievelijk een CA of een server in aanvulling op de traditionele PKI-verankering met behulp van de trust anchors meegeleverd in de client (voor het web: de browser). Daarmee wordt het probleem van een gekraakte CA gelokaliseerd (usage 0) of helemaal geneutraliseerd (usage 1). Bovendien worden op deze manier discrepanties tussen de 2 vertrouwensketens gesignaleerd. Hieronder zien we echter dat dit laatste eerder als een bug dan als een feature moet worden beschouwd: DANE is echt ontwikkeld als opvolger en vervanger van de bestaande PKI-verankering, en usage 0 en 1 zijn alleen bedoeld om ook met deze legacy overweg te kunnen. Usage 2 en 3 werken helemaal onafhankelijk van de traditionele PKI-verankering, en dat maakt ze geschikt voor self-signed certificaten. Bovendien kunnen op deze manier clients bediend worden die helemaal geen trust anchors aan boord hebben, zoals dat ook het geval is bij SMTP clients (mailservers).
De DANE-standaard schrijft voor dat bij usage 0 en 1 beide vertrouwensketens moeten valideren. Dat levert een probleem op als de ene keten wel en de andere niet goed valideert. Voor een webbrowser is dit op dezelfde manier op te lossen als wanneer een traditioneel PKI-certificaat om een of andere reden geen positieve validatie oplevert: de gebruiker krijgt een pop-up scherm met een waarschuwing en de optie om toch door te gaan. SMTP-clients hebben alleen nooit PKI trust anchors aan boord gehad, vandaar dat usage 0 en 1 bij DANE voor mail volgens de standaard helemaal niet gebruikt mogen worden. Feitelijk zijn de in de client (browser) ingebouwde PKI-certificaten die we nog steeds voor het web gebruiken een inmiddels achterhaalde en bewezen onveilige legacy. Hoewel deze infrastructuur beter vervangen zou kunnen worden door self-signed certificaten lokaal geborgd met TLSA-records, zijn we ons ervan bewust dat de daarvoor benodigde onderliggende technologie – DNSSEC – in de rest van de wereld nog lang niet overal zo ver doorgevoerd is als hier in Nederland [1, 2].
Voordat je mailserver STARTTLS überhaupt als optie (SMTP capability) kan aanbieden, moet deze zijn voorzien van een cryptografisch sleutelpaar. Daaruit wordt dan weer het certificaat (de self-signed publieke sleutel) afgeleid dat aan clients wordt aangeboden om de verbinding te versleutelen (na een STARTTLS-verzoek).
Voor Exim wordt bij de installatie van het software package al een TLS-sleutelpaar aangemaakt. De publieke en geheime sleutel bevinden zich respectievelijk in de files '/etc/pki/tls/certs/exim.pem' en '/etc/pki/tls/private/exim.pem'. In het Exim-configuratiebestand '/etc/exim/exim.conf' worden deze locaties aangegeven middels deze twee opties:
tls_certificate = /etc/pki/tls/certs/exim.pem tls_privatekey = /etc/pki/tls/private/exim.pem
We maken echter liever gebruik van ons eigen sleutelpaar. Bovendien willen we niet alleen de RSA-gebaseerde encryptie-algoritmen ondersteunen, maar ook de efficiënte ECDSA-gebaseerde algoritmen. De voordelen van dit moderne cryptografische algoritme hebben we hier uitgelegd voor DNSSEC. We verwijderen daarvoor eerst de bestaande sleutels en genereren vervolgens twee nieuwe sleutelparen als volgt:
trash /etc/pki/tls/certs/exim.pem /etc/pki/tls/private/exim.key
[root@mail ~]# cd /etc/pki/tls/private/ [root@mail private]# openssl req -newkey rsa:4096 -sha512 -x509 -nodes -days 3650 \ -keyout exim-rsa.key -out exim-rsa.cert Generating a RSA private key ......................................................++++ ...........................++++ writing new private key to 'exim-rsa.key' ----- You are about to be asked to enter information that will be incorporated into your certificate request. What you are about to enter is what is called a Distinguished Name or a DN. There are quite a few fields but you can leave some blank For some fields there will be a default value, If you enter '.', the field will be left blank. ----- Country Name (2 letter code) [XX]:NL State or Province Name (full name) []: Locality Name (eg, city) [Default City]:Gepermuiden Organization Name (eg, company) [Default Company Ltd]:Acme Corporation Organizational Unit Name (eg, section) []:Exim TLS key Common Name (eg, your name or your server's hostname) []:mail.example.nl Email Address []:postmaster@example.nl [root@mail private]# chmod 640 exim-rsa.key exim-rsa.cert [root@mail private]# chown root:exim exim-rsa.key exim-rsa.cert [root@mail private]# mv exim-rsa.cert ../certs/ [root@mail ~]# cd /etc/pki/tls/private/ [root@mail private]# openssl ecparam -out exim-ecdsa.key -name prime256v1 -genkey [root@mail private]# openssl req -new -sha512 -key exim-ecdsa.key -out exim-ecdsa.csr You are about to be asked to enter information that will be incorporated into your certificate request. What you are about to enter is what is called a Distinguished Name or a DN. There are quite a few fields but you can leave some blank For some fields there will be a default value, If you enter '.', the field will be left blank. ----- Country Name (2 letter code) [XX]:NL State or Province Name (full name) []: Locality Name (eg, city) [Default City]:Gepermuiden Organization Name (eg, company) [Default Company Ltd]:Acme Corporation Organizational Unit Name (eg, section) []:Exim TLS key Common Name (eg, your name or your server's hostname) []:mail.example.nl Email Address []:postmaster@example.nl Please enter the following 'extra' attributes to be sent with your certificate request A challenge password []: An optional company name []: [root@mail private]# openssl req -x509 -sha512 -days 3650 -key exim-ecdsa.key \ -in exim-ecdsa.csr -out exim-ecdsa.cert [root@mail private]# chmod 640 exim-ecdsa.key exim-ecdsa.cert [root@mail private]# chown root:exim exim-ecdsa.key exim-ecdsa.cert [root@mail private]# mv exim-ecdsa.cert ../certs/
Waarna we de nieuwe sleutelbestanden in de Exim-configuratie (in de file '/etc/exim/exim.conf') opnemen:
tls_certificate = /etc/pki/tls/certs/exim-ecdsa.cert:/etc/pki/tls/certs/exim-rsa.cert tls_privatekey = /etc/pki/tls/private/exim-ecdsa.key:/etc/pki/tls/private/exim-rsa.key
Verifieer nu dat TLS ook verder goed geconfigureerd is. In de file '/etc/exim/exim.conf' hebben we nu de volgende TLS-gerelateerde opties staan:
# Allow any client to use TLS. tls_advertise_hosts = * # For OpenSSL, prefer EC- over RSA-authenticated ciphers tls_require_ciphers = ECDSA:RSA:!COMPLEMENTOFDEFAULT # In order to support roaming users who wish to send email from anywhere, # you may want to make Exim listen on other ports as well as port 25, in # case these users need to send email from a network that blocks port 25. # The standard port for this purpose is port 587, the "message submission" # port. See RFC 4409 for details. Microsoft MUAs cannot be configured to # talk the message submission protocol correctly, so if you need to support # them you should also allow TLS-on-connect on the traditional but # non-standard port 465. daemon_smtp_ports = 25 : 587 # This setting, if uncommented, allows users to authenticate using # their system passwords against saslauthd if they connect over a # secure connection. If you have network logins such as NIS or # Kerberos rather than only local users, then you possibly also want # to configure /etc/sysconfig/saslauthd to use the 'pam' mechanism # too. Once a user is authenticated, the acl_check_rcpt ACL then # allows them to relay through the system. # auth_advertise_hosts = ${if eq {$tls_cipher}{}{}{*}} # Unless you run a high-volume site you probably want more logging # detail than the default. Adjust to suit. log_selector = +smtp_protocol_error +smtp_syntax_error \ +tls_certificate_verified
De optie 'auth_advertise_hosts' specificeert voor welke clients de AUTH capability door de Exim gateway wordt aangegeven. In dit geval is dat dus voor alle clients en voor alle SMTP-poorten (als TLS inderdaad geconfigureerd is). In de 'acl_check_auth' Access Control List (ACL) verderop is authenticatie zelf wel inperkt tot TLS-versleutelde verbindingen, die bovendien binnen moeten komen via poort 587:
acl_check_auth: # deny authentication on unencrypted links deny !encrypted = * message = encryption before AUTH is required # deny if AUTH isn't on submission port (autolist enabled) deny !condition = ${if eq {$interface_port}{587}} message = AUTH only via submission port # accept if encrypted (should not get here if unencrypted) accept encrypted = *
Dat betekent dus dat geauthentiseerde verbindingen (voor relay) alleen binnen kunnen komen op poort 587, en dat dat alleen over een versleutelde verbinding mag. Dat laatste is belangrijk vanwege de afscherming van de logingegevens. Opmerkzame lezers zien bovendien dat ongeautoriseerde verbindingen naar poort 587 hetzelfde worden behandeld als verbindingen over poort 25 (die niet geautoriseerd kunnen worden). De standaard configuratie maakt verder geen onderscheid tussen lokale accounts, hosts/netwerken waarvoor we als mail relay fungeren ('relay_from_hosts'), en geauthentiseerde clients. In de 'acl_check_rcpt' ACL kunnen we zien dat voor alle drie de gevallen DKIM- en DMARC-validatie worden uitgeschakeld:
control = dkim_disable_verify control = dmarc_disable_verify
Na de restart van de Exim-server staat deze voorzien van de nieuwe sleutelparen te wachten op binnenkomende verbindingen. We kunnen onze configuratie testen met behulp van het 'ssltest'-commando. Hieronder zie je dat onze mailserver nu inderdaad twee self-signed certificaten aanbiedt: de eerste gebaseerd op RSA, de tweede gebaseerd op ECDSA.
systemctl restart exim.service systemctl status exim.service
testssl -t smtp localhost:25
Op vergelijkbare wijze checken we de SMTP-gateway op poort 587:
testssl -t smtp localhost:587
Doen we nog een telnet naar poort 587, dan kunnen we verifiëren dat inloggen inderdaad niet mag voordat we onze verbinding opgewaardeerd hebben met STARTTLS:
[root@system ~]# telnet localhost 587 Trying ::1... Connected to localhost. Escape character is '^]'. 220 mail.example.nl ESMTP Exim 4.94 Wed, 20 Jan 2021 12:37:54 +0100 ehlo verzender.example.nl 250-mail.example.nl Hello verzender.example.nl [::1] 250-SIZE 52428800 250-PIPELINING 250-X_PIPE_CONNECT 250-CHUNKING 250-STARTTLS 250-PRDR 250 HELP auth 503 AUTH command used when not advertised quit 221 mail.example.nl closing connection Connection closed by foreign host.
Wil je de interactie met de mail server testen via een TLS-verbinding, dan gebruik je daarvoor het volgende commando:
openssl s_client -connect localhost:587 -tls1_3
We komen straks nog terug op de configuratie van TLS, als we in detail kijken naar de cryptografische algoritmen die we wel en niet willen gebruiken voor de versleuteling van ons verkeer.
Er zijn verschillende manieren om een TLSA-record voor je MX-gateway te genereren. Dat kan met OpenSSL direct op de command line op basis van je server-certificaat. Voor het RSA-gebaseerde certificaat ziet dat er als volgt uit:
[root@mail exim]$ openssl x509 -in /etc/pki/tls/certs/exim-rsa.cert -outform DER | openssl sha256 (stdin)= f61bf58d20d9a3898a02a2ff031e6103d267c9e86e05fccba73b5de109b1032f
De output is de hash (volgens het SHA-256 algoritme) van het (self-signed) certificaat dat door je mailserver aan clients aangeboden wordt om de verbinding te versleutelen (na een STARTTLS-verzoek). Alternatief voor SHA-256 is het veel sterkere SHA-512 algoritme. Deze is ontwikkeld voor gebruik op 64-bits systemen, maar dat is inmiddels ook op mobiele apparaten de standaard. Bovenstaande hash-waarde kun je direct in je TLSA-records opnemen:
# DANE for mail _25._tcp.mx.example.nl IN TLSA 3 0 1 f61bf58d20d9a3898a02a2ff031e6103d267c9e86e05fccba73b5de109b1032f _587._tcp.smtp.example.nl IN TLSA 3 0 1 f61bf58d20d9a3898a02a2ff031e6103d267c9e86e05fccba73b5de109b1032f _465._tcp.smtp.example.nl IN TLSA 3 0 1 f61bf58d20d9a3898a02a2ff031e6103d267c9e86e05fccba73b5de109b1032f
Daarbij geeft het eerste veld (hier met de waarde 3) de zojuist besproken usage aan. Het tweede veld (hier met de waarde 0) specificeert de selector: bij de waarde 0 wordt de hash over het volledige certificaat (als blob) genomen, bij de waarde 1 over het DER-formaat. En het laatste veld (het matching type, hier met de waarde 1) geeft aan welk hash-algoritme wordt gebruikt: 0 voor een exacte match, 1 voor de SHA-256 hash, en 2 voor de SHA-512 hash. Zoals je ziet hebben we voor de volledigheid ook de TLSA records voor de TCP-poorten 587 en 465 erbij gezet. Voor zover ons bekend zijn er op dit moment echter nog geen mailclients die DANE-validatie doen op de SMTP-gateway (of op de POP/IMAP/POPS/IMAPS-poorten). Voor het ECDSA-gebaseerde certificaat doen we precies hetzelfde, resulterend in een tweede set TLSA-records.
Er zijn ook diverse tools beschikbaar waarmee je je TLSA-record(s) direct kunt genereren. De eerste is hash-slinger van Paul Wouters. Dit pakket maakt inmiddels geen onderdeel meer uit van de Fedora/CentOS/RHEL-distributies, maar na de handmatige installatie van de software (en het 'python3-m2crypto' package) kunnen we het TLSA-record direct genereren op basis van het aangeboden certificaat:
[root@mail hash-slinger-master]# ./tlsa --create --port 25 --starttls smtp --output rfc mail.example.nl Got a certificate with Subject: /C=NL/ST=/L=Gepermuiden/O=Acme Corporation/OU=Exim TLS key/ CN=mail.example.nl/emailAddress=postmaster@example.nl _25._tcp.mail.example.nl. IN TLSA 3 0 1 f61bf58d20d9a3898a02a2ff031e6103d267c9e86e05fccba73b5de109b1032f
Let op dat hier voor het genereren van de hash-waarde het certificaat gebruikt wordt zoals dat door de mailserver online op TCP-poort 25 wordt aangeboden. In het algemeen mag je dit alleen doen op hetzelfde systeem als waar je server draait of op een vertrouwd netwerk, anders loop je het (hele kleine) risico dat een man-in-the-middle (MITM) het aangeboden certificaat onderweg vervangt door een vals certificaat. Beter kun je (maar dat moet dan wel op hetzelfde systeem) het certificaat zelf nog als optie meegeven:
--certificate /etc/pki/tls/certs/exim-rsa.cert
Wie liever met een online tool werkt voor het genereren van een TLSA-record, kan daarvoor terecht op deze pagina van Shumon Huque.
Op deze pagina kun je tenslotte checken of je TLSA-record inderdaad overeenkomt met het aangeboden certificaat.
TLSRPT (gedefinieerd in RFC 8460) is een mechanisme waarmee houders van mail-domeinen foutmeldingen van clients (verzendende mailservers) kunnen ontvangen bij het mislukken van de TLS-versleuteling naar hun MX-gateways. Dit mechanisme is vergelijkbaar met dat van DMARC.
Hoewel TLSRPT tegelijkertijd met MTA-STS is gedefinieerd en door dezelfde partijen, werkt dit mechanisme net zo goed voor DANE voor mail.
Om TLSRPT-meldingen voor zijn maildomein te ontvangen, publiceert de houder een speciaal TXT-record als volgt (parallel aan de MX-records dus):
_smtp._tls.example.nl IN TXT "v=TLSRPTv1; rua=mailto:tls-rua@example.nl"
Zoals je ziet bevat dit record niet veel meer dan een mailadres waarop gestandaardiseerde berichten voor automatische verwerking kunnen worden afgeleverd.
Voor de geautomatiseerde verwerking van de TLSRPT-berichten kun je terecht bij dezelfde dienstverleners die ook DMARC doen.
Dat we nu een goed werkende en goed verankerde TLS-configuratie hebben, betekent nog niet noodzakelijk dat onze verbindingen nu ook sterk genoeg beveiligd zijn. Dat hangt namelijk erg af van de versie van het gebruikte TLS-protocol en van de ondersteunde cryptografische algoritmen. Gebruiken we verouderde protocollen en/of algoritmen, dan zijn die inmiddels niet meer veilig. Maar bieden we alleen de nieuwste en sterkste opties aan, dan kan het zijn dat een oudere SMTP client deze niet kan matchen en deze alsnog terugvalt op een onversleutelde verbinding. Het NCSC heeft richtlijnen opgesteld voor zowel TLS-verbindingen in het algemeen als voor de versleuteling van mail transport in het bijzonder. Hun aanbevelingen betreffen zowel het TLS-protocol zelf als de verschillende cryptografische primitieven (die tezamen de cipher suite vormen). In hun laatste update (d.d. 19 januari 2021) van de 'ICT-beveiligingsrichtlijnen voor Transport Layer Security (TLS)' heeft het NCSC TLS versie 1.2 afgewaardeerd van 'Goed' naar 'Voldoende'. We hebben die update in dit artikel verwerkt.
Hieronder zie je wat de rol is van de verschillende cryptografische algoritmen die (onder andere) door TLS gebruikt worden:
een algoritme voor de uitwisseling van geheime sleutels, bijvoorbeeld ECDHE, DHE, RSA
een public key algoritme (asymmetrische cryptografie) voor X.509-certificaten (ketens van ondertekende publieke sleutels), bijvoorbeeld RSA, ECDSA
(symmetrische) cryptografie voor de bulkversleuteling van verkeer (want public key cryptografie is te langzaam/inefficiënt om dit direct te doen), bijvoorbeeld 3DES, AES
een hash-functie als onderdeel bij het creëren van digitale handtekeningen, bijvoorbeeld SHA-1, SHA-256, SHA-512
In hoofdstuk 4 van de 'ICT-beveiligingsrichtlijnen voor Transport Layer Security (TLS)' raadt het NCSC aan om alleen TLS-versie 1.2 en 1.3 te gebruiken – en dan bij voorkeur die laatste. In de tabel hieronder zie je welke cryptografische algoritmen (de ondersteuning kan verschillen voor verschillende versies van TLS) aangeraden worden.
Voor de certificaten kan ook EdDSA gebruikt worden, maar dat algoritme wordt nog niet ondersteund door de certificaatleveranciers. En let op dat de SHA-1 hash-functie uitsluitend gebruikt mag worden als onderdeel van de bulkversleuteling (MAC), en absoluut niet als hash in digitale handtekeningen. Bij de encryptie-algoritmen valt nog op te merken dat RSA minstens een sleutellengte van 2048 bits, maar beter nog van 3072 of 4096 bits moet hebben. En voor de Elliptic-Curve Cryptography (ECC)-gebaseerde algoritmen (ECDHE, ECDSA en EdDSA) geldt dat deze alleen gebaseerd mogen zijn op de secp384r1, secp256r1, x448 en x25519 curves (als onderliggende wiskundige functie). Voor DHE geldt iets soortgelijks: als je dit (minder efficiënte) algoritme nog wilt ondersteunen, neem dan alleen die varianten gebouwd op de 'finite field'-groepen ffdhe4096 en ffdhe3072 (zoals besproken in RFC 7919). Verderop laten we zien hoe je de parameters voor deze algoritmen instelt.
Na het maken van een selectie uit de (tientallen) mogelijke algoritmen, moeten we deze vertalen naar een specificatie-string die in de configuratie van onze mailserver geplaatst moet worden. Op zijn beurt geeft de mailserver deze specificatie (in dit geval letterlijk) weer door aan de onderliggende cryptografische library (typisch OpenSSL). Hieronder zie je de instellingen die we voor Exim gebruiken (in de file '/etc/exim/exim.conf'). Deze string wordt precies zo doorgegeven aan OpenSSL bij het aanroepen ervan. Voor de details ervan verwijzen we je dan ook naar de OpenSSL-documentatie. Verderop laten we zien hoe je OpenSSL op de command line ook direct kunt vragen welke geldige cipher suites overblijven bij gebruik van een bepaalde specificatie.
# Disable SSLv2, SSLv3, TLSv1, TLSv1.1, leaving only TLSv1.2 and TLSv1.3 openssl_options = +no_sslv2 +no_sslv3 +no_tlsv1 +no_tlsv1_1 +single_dh_use +single_ecdh_use +cipher_server_preference +no_compression +no_session_resumption_on_renegotiation
# For OpenSSL, prefer EC- over RSA-authenticated ciphers #tls_require_ciphers = ECDSA:RSA:!COMPLEMENTOFDEFAULT tls_require_ciphers = HIGH:!SSLv2:!SSLv3:!TLSv1:!TLSv1.1: !EXP:!LOW:!MEDIUM:!aNULL:!eNULL: !SRP:!PSK:!kDH:!DH:!kRSA:!DHE:!DSS:!RC4:!DES:!IDEA:!SEED:!ARIA:!CAMELLIA:!AESCCM8:!3DES: !ECDHE-ECDSA-AES256-SHA384:!ECDHE-ECDSA-AES128-SHA256:!ECDHE-RSA-AES256-SHA384:!ECDHE-RSA-AES128-SHA256: !MD5:!SHA
tls_dhparam = /etc/exim/dh4096.pem
Maar let op: de variabele 'tls_require_ciphers' wordt vooralsnog alleen gebruikt voor TLS versie 1.2. Volgens de Exim documentatie staan de cipher suites voor versie 1.3 nu (januari 2021) nog hard ingesteld op:
TLS_AES_256_GCM_SHA384:TLS_CHACHA20_POLY1305_SHA256:TLS_AES_128_GCM_SHA256
We zien straks welke cipher suites hier precies zijn weggelaten.
Dan over de configuratie zelf: Om te beginnen gebruiken we alleen TLS-versies 1.2 en 1.3, en sluiten we de verouderde SSL-protocollen en TLS versies 1 en 1.1 expliciet uit. Let daarbij op dat de resterende protocollen wel altijd een reeks van opeenvolgende versies moeten opleveren. Met de optie 'HIGH' maken we een eerste selectie op de beschikbare cryptografische algoritmen. Hiermee beperken we ons tot alleen de sterkste algoritmen (met een securitylevel van minstens 128 bits. En omdat we alleen TLS-versies 1.2 en 1.3 willen gebruiken, sluiten we de verouderde SSL-protocollen en TLS-versies 1 en 1.1 expliciet uit. In de rest van de string specificeren we tenslotte in meer detail de algoritmen die we perse niet willen gebruiken. We herhalen hier eerst nog eens alles onder de gradatie 'HIGH'. Andere algoritmen die we expliciet uitsluiten zijn:
sleuteluitwisseling via SRP, PSK, (k)DH, (k)RSA en DHE (aRSA kan wel voor certificaten; DHE kan eventueel wel, maar alleen gebaseerd op de ffdhe4096 en ffdhe3072 functies)
bulkversleuteling via RC4, DES, IDEA, SEED, ARIA, CAMELLIA, AES/CCM8, 3DES en AES/CBC (AES/GCM kan wel)
Zoals je ziet is dit een strenge instelling: we gebruiken hier alleen de algoritmen die van het NCSC het predicaat 'Goed' hebben meegekregen en niet die met de kwalificatie 'Voldoende'. In bovenstaande lijst van uitzonderingen staan bovendien ook algoritmen (zoals RC4, DES en MD5) die door de voorafgaande selectie al niet meer meedoen. De reden om deze toch expliciet te specificeren is dat je ze niet per ongeluk wilt activeren als je later misschien zelf combinaties van crypto-primitieven toevoegt. Om dezelfde reden hebben we ook aNULL en eNULL toegevoegd (de NULL operators voor respectievelijk authenticatie en encryptie).
Draaien we nu opnieuw het 'testssl'-commando, dan zien we dat onze mailserver nu acht cipher suites aanbiedt, allemaal gebaseerd op de 'ECDHE-ECDSA-'- en 'ECDHE-RSA-'-algoritmen. De meest recente versies van testssl laten nog vier andere cipher suites zien, maar dat betreft alleen een verkorte notatie voor dezelfde combinaties, ingevoerd met TLS-versie 1.3.
Door onze crypto-configuratie-string een klein beetje om te bouwen, kunnen we OpenSSL ook direct vragen welke geldige cipher suites overblijven:
[user@system ~]$ openssl ciphers -s -tls1_2 \ 'HIGH, !EXP, !LOW, !MEDIUM, !aNULL, !eNULL, \ !SRP, !PSK, !kDH, !DH, !kRSA, !DHE, !DSS, !RC4, !DES, !IDEA, !SEED, !ARIA, !CAMELLIA, !AESCCM8, !3DES, \ !ECDHE-ECDSA-AES256-SHA384, !ECDHE-ECDSA-AES128-SHA256, !ECDHE-RSA-AES256-SHA384, !ECDHE-RSA-AES128-SHA256, \ !MD5, !SHA' ECDHE-ECDSA-AES256-GCM-SHA384 ECDHE-RSA-AES256-GCM-SHA384 ECDHE-ECDSA-CHACHA20-POLY1305 ECDHE-RSA-CHACHA20-POLY1305 ECDHE-ECDSA-AES256-CCM ECDHE-ECDSA-AES128-GCM-SHA256 ECDHE-RSA-AES128-GCM-SHA256 ECDHE-ECDSA-AES128-CCM
Wil je ook de combinaties met de NCSC-kwalificatie 'Voldoende' toestaan, dan wordt de crypto-specificatie-string als volgt:
smtpd_tls_exclude_ciphers = EXP, LOW, MEDIUM, aNULL, eNULL, SRP, PSK, kDH, ADH, AECDH, kRSA, DSS, RC4, DES, IDEA, SEED, ARIA, AESCCM8, 3DES, MD5
Een check met OpenSSL levert nu het volgende lijstje op:
[user@system ~]# openssl ciphers -s -tls1_2 \ 'HIGH, !EXP, !LOW, !MEDIUM, !aNULL, !eNULL, \ !SRP, !PSK, !kDH, !ADH, !AECDH, !kRSA, !DSS, !RC4, !DES, !IDEA, !SEED, !ARIA, !AESCCM8, !3DES, !MD5' ECDHE-ECDSA-AES256-GCM-SHA384 ECDHE-RSA-AES256-GCM-SHA384 DHE-RSA-AES256-GCM-SHA384 ECDHE-ECDSA-CHACHA20-POLY1305 ECDHE-RSA-CHACHA20-POLY1305 DHE-RSA-CHACHA20-POLY1305 ECDHE-ECDSA-AES256-CCM DHE-RSA-AES256-CCM ECDHE-ECDSA-AES128-GCM-SHA256 ECDHE-RSA-AES128-GCM-SHA256 DHE-RSA-AES128-GCM-SHA256 ECDHE-ECDSA-AES128-CCM DHE-RSA-AES128-CCM ECDHE-ECDSA-AES256-SHA384 ECDHE-RSA-AES256-SHA384 DHE-RSA-AES256-SHA256 ECDHE-ECDSA-CAMELLIA256-SHA384 ECDHE-RSA-CAMELLIA256-SHA384 DHE-RSA-CAMELLIA256-SHA256 ECDHE-ECDSA-AES128-SHA256 ECDHE-RSA-AES128-SHA256 DHE-RSA-AES128-SHA256 ECDHE-ECDSA-CAMELLIA128-SHA256 ECDHE-RSA-CAMELLIA128-SHA256 DHE-RSA-CAMELLIA128-SHA256 ECDHE-ECDSA-AES256-SHA ECDHE-RSA-AES256-SHA DHE-RSA-AES256-SHA DHE-RSA-CAMELLIA256-SHA ECDHE-ECDSA-AES128-SHA ECDHE-RSA-AES128-SHA DHE-RSA-AES128-SHA DHE-RSA-CAMELLIA128-SHA
Naast de als 'Goed' gekwalificeerde cipher suites zien we nu ook die gebaseerd op DHE, AES/CCM(16), CAMELLIA en SHA(-1) (voor HMAC) er bij staan.
Zoals hierboven besproken staan de cipher suites voor TLS versie 1.3 nu hard ingesteld op:
TLS_AES_256_GCM_SHA384:TLS_CHACHA20_POLY1305_SHA256:TLS_AES_128_GCM_SHA256
Hieronder kun je zien dat OpenSSL voor TLS 1.3 maar vier cipher suites ondersteunt, waarvan de laatste (gebruikmakend van CCM) in het rijtje hierboven dus is weggelaten.
user@system ~]$ openssl ciphers -s -tls1_3 TLS_AES_256_GCM_SHA384 TLS_CHACHA20_POLY1305_SHA256 TLS_AES_128_GCM_SHA256 TLS_AES_128_CCM_SHA256
Combineren we onze eerdere selectie voor de als 'Goed' gekwalificeerde cipher suites met TLS-versie 1.3 – zoals aangeraden als veiligste optie in het laatste advies van het NCSC – dan zie je dat daarmee alle vier suites geselecteerd worden:
[user@system ~]$ openssl ciphers -s -tls1_3 \ 'HIGH, !EXP, !LOW, !MEDIUM, !aNULL, !eNULL, \ !SRP, !PSK, !kDH, !DH, !kRSA, !DHE, !DSS, !RC4, !DES, !IDEA, !SEED, !ARIA, !CAMELLIA, !AESCCM8, !3DES, \ !ECDHE-ECDSA-AES256-SHA384, !ECDHE-ECDSA-AES128-SHA256, !ECDHE-RSA-AES256-SHA384, !ECDHE-RSA-AES128-SHA256, \ !MD5, !SHA' TLS_AES_256_GCM_SHA384 TLS_CHACHA20_POLY1305_SHA256 TLS_AES_128_GCM_SHA256 TLS_AES_128_CCM_SHA256
De reden dat we (NCSC) zich sowieso beperkt tot ECDHE en DHE voor de sleuteluitwisseling, heeft te maken met de zogenaamde forward secrecy die deze twee algoritmen bieden. Door per bericht steeds eerst een hele nieuwe (symmetrische) sessiesleutel uit te wisselen — vandaar de E van Ephemeral (vluchtig) in de namen van deze twee algoritmen — blijft andere versleutelde informatie beschermd ingeval een sessiesleutel zou uitlekken. De optie 'smtpd_tls_eecdh_grade = ultra' zorgt ervoor dat de parameters voor het EECDH-algoritme zodanig ingesteld worden dat deze een security level van 192 bits heeft (128 bits is op dit moment het nog veilig geachte minimum). De optie 'tls_dhparam = /etc/exim/dh4096.pem' verwijst naar een bestand met parameters voor sterke encryptie op basis van het (minder efficiënte) DHE-algoritme. Je maakt dit bestand aan als volgt:
openssl dhparam -out /etc/exim/dh4096.pem 4096
De 'openssl'-vlag '+no_compression' zorgt ervoor dat de arbeidsintensieve (en soms onveilige) compressie van het dataverkeer wordt uitgeschakeld. De vlag '+no_session_resumption_on_renegotiation' maakt dat een eenmaal uitonderhandeld cryptografisch protocol niet halverwege de uitwisseling aangepast kan worden. En de vlag '+cipher_server_preference' tenslotte zorgt ervoor dat de SMTP server (vanaf SSL versie 3) zijn eigen volgorde voor de cryptografische algoritmen afdwingt in plaats van dat aan de remote client te laten.
Het mag duidelijk zijn dat wanneer je je sleutelpaar en dus je certificaat verandert, ook de hash in het TLSA-record aangepast moet worden. Dat betekent dat je bij de omwisseling een kleine roll-over zult moeten doen, zoals beschreven in Appendix A.4 van RFC 6698: Het nieuwe TLSA-record moet (naast het oude record) gepubliceerd worden voordat het certificaat wordt vervangen. Pas na het verlopen van de TTL, als de oude TLSA-informatie overal uit alle DNS-caches is verdwenen, mag het nieuwe certificaat in de server geactiveerd worden. Doe je dat eerder, dan loop je het risico dat validerende clients op basis van de oude informatie het nieuwe certificaat (nog) niet accepteren. Na ingebruikname van het nieuwe servercertificaat kun je het oude TLSA-record wel gelijk verwijderen.
Met al deze aandacht voor de cryptografische algoritmen en instellingen zitten we op dezelfde lijn als het NCSC, het Forum Standaardisatie en het Platform Internetstandaarden: het zo snel mogelijk invoeren van DANE, en wel op een zo veilig mogelijk manier, gebaseerd op de laatste technische inzichten. Het nadeel van deze aanpak is dat een verouderde client die deze moderne standaarden niet ondersteunt een fallback zal doen naar een geheel onversleutelde verbinding; de aflevering van mail moet immers doorgaan. Er is dan ook een alternatieve school die uitgaat van het principe 'iets is beter dan niets'. Een versleutelde verbinding biedt immers altijd nog enige vorm van bescherming – ook als geen serverauthenticatie heeft plaatsgevonden of de cryptografische cipher suite verouderd is. Die pragmatische interpretatie van opportunistische beveiliging is vastgelegd in RFC 7435. Volgens Viktor Dukhovni, de auteur van RFC 7435 en een warm pleitbezorger voor STARTTLS en DANE, zullen de client en server in samenspraak meestal het best mogelijke beveiligingsprotocol voor hun verbinding selecteren, en is het tweaken van de cryptografische instellingen niet nodig. Verouderde en onveilige algoritmen verdwijnen vanzelf op organische wijze van het internet naarmate apparatuur en software opgewaardeerd wordt. Wat Dukhovni betreft zijn operationele aspecten veel belangrijker: het gebruik van up-to-date software, een goed werkend monitoringsysteem en een goedlopend roll-over proces. Hoewel we het belang van de operationele kant onderschrijven, valt dat onderwerp niet binnen de scope van dit artikel. Bovendien blijven we van mening dat de structurele ondersteuning van zwakke cypher suites geen goed idee is. Zwak beveiligde verbindingen leveren een schijnveiligheid op tegen actieve aanvallen.
Zoals aanbiedende mailservers ons DANE-record kunnen controleren, en daarmee ons certificaat (de self-signed publieke TLS-sleutel) kunnen valideren, zo kan onze eigen server (als client) op zijn beurt de TLS-certificaten van andere servers valideren bij het aanbieden van mail-berichten.
Voor het gebruik van opportunistische TLS (STARTTLS) door Exim, hoef je niets te doen: Exim zal bij het afleveren van mail-berichten altijd proberen om eerst een STARTTLS-sessie op te zetten. DANE-validatie wordt officieel door Exim ondersteund vanaf versie 4.91. Zoals hierboven beschreven, is DNSSEC verplicht voor de implementatie van DANE. Zijn je DNS records niet ondertekend, dan ontbreekt immers de cryptografische vertrouwensketen (chain of trust) voor de verankering van je TLSA records. Check daarom eerst of de algemene optie 'dns_dnssec_ok' aan staat (in de file '/etc/exim/exim.conf'):
# The setting below causes Exim to try to initialize the system resolver # library with DNSSEC support. It has no effect if your library lacks # DNSSEC support.
dns_dnssec_ok = 1
Voeg vervolgens de modifier 'hosts_try_dane = *' toe aan je 'remote_smtp'-transport:
# This transport is used for delivering messages over SMTP connections. # Refuse to send any message with over-long lines, which could have # been received other than via SMTP. The use of message_size_limit to # enforce this is a red herring.
remote_smtp: driver = smtp message_size_limit = ${if > {$max_received_linelength}{998} {1}{0}} hosts_try_dane = *
Hiermee zijn je verbindingen beschermd tegen MITM downgrade-aanvallen zoals hierboven beschreven. De 'hosts_require_dane'-modifier biedt een nog sterkere beveiliging door DANE-gevalideerde authenticatie te verplichten. Dat betekent dat mail helemaal niet afgeleverd wordt als de MX gateway van de ontvangende partij geen positieve DANE-validatie oplevert. Maar deze optie is niet bruikbaar voor de algemene aflevering van mail naar Internet. Tenslotte is er nog de mogelijkheid om middels de 'dane_require_tls_ciphers'-modifier een aparte specificatie voor de cipher suites voor DANE-gevalideerde verbindingen op te geven. Maar als die niet is gespecificeerd, dan wordt gewoon de reeks in 'tls_require_ciphers' gebruikt.
Let op dat het systeem waarop je verzendende mail server draait ook daadwerkelijk zelfstandig de DNSSEC-validatie uitvoert. Vertrouwt je server daarvoor op een validerende resolver op een andere/extern systeem (via de AD-vlag), dan is het laatste stuk van de vertrouwensketen niet cryptografisch beveiligd. Die zogenaamde 'last mile' maakt je in dit geval kwetsbaar voor downgrade-aanvallen en vervalsing van TLSA-certificaten door een man in the middle. En daarmee is onze DANE setup helemaal compleet! Je kunt je mail-configuratie testen op Internet.nl.
Exim op CentOS 8.2 bevat volledige ondersteuning voor inkomende en uitgaande TLS-verbindingen en DANE-validatie. Daarmee ligt er een solide fundament om zelf een veilig mail-systeem gebaseerd op Exim op te bouwen. Dit eerdere hands-on artikel laat zien dat voor de implementatie van SPF, DKIM en DMARC aanzienlijk meer configuratiewerk nodig was. Daarbij is het bovendien van belang om de werking en betekenis van de statements in de Exim-configuratie eerst goed te doorgronden. Wat dat betreft is de zojuist beschreven implementatie van DANE veel minder ingrijpend. Wat we in dit hands-on artikel hebben besproken levert je een volledige implementatie op van de DANE mail-beveiligingsstandaard. Combineer je deze setup nog met IPv6 en SPF/DKIM/DMARC, dan is dit alles genoeg voor een honderdprocentscore op Internet.nl. Dat betekent dat je mailsystemen helemaal up-to-date zijn en voldoen aan de laatste eisen en inzichten van onder andere Forum Standaardisatie en NCSC. Bovendien is mailbeveiliging op domeinniveau een praktische voorwaarde bij de transitie van IPv4 naar IPv6, waar je niet langer kunt filteren op IP-adres. Als nieuwe DANE-functionaliteit voor Exim beschikbaar komt, verwerken we die in dit artikel. Ook feedback op dit artikel is natuurlijk van harte welkom.
Gebruik je al Postfix, dan verwijzen we je naar dit hands-on artikel, waarin we de configuratie van DANE voor Postfix op vergelijkbare wijze bespreken als we dat hier voor Exim hebben gedaan.