Let's Encrypt-module in Apache
Let's-Encrypt-module bij Apache
Een volgende release van de Apache-webserver krijgt een module die zonder hulp van buitenaf voor SSL/TLS-certificaten kan zorgen en deze kan vernieuwen. Daar hoef je niet veel voor te configureren.
Vanaf release 2.5.0 moet de module ‘mod_md' toegevoegd zijn, die het automatisch verkrijgen van certificaten voor Apache-websites een stuk makkelijker maakt. Dan verdwijnen de beperkingen van de tot nu toe gangbare tools zoals de ‘Certbot' van de EFF (Electronic Frontier Foundation). Die hebben geen toegang tot de webserver-processen. Daarom lezen ze de configuratie van een Apache-server, proberen die te begrijpen en op de juiste manier te herschrijven – een niet-triviale actie omdat die configuraties aardig complex kunnen zijn.
Het kan nog een tijdje duren voordat de gangbare distributies een Apache-webserver met de module mod_md aanbieden. Het volstaat helaas niet om die module aan een bestaande Apache-installatie toe te voegen. Om ervoor te zorgen dat hij zijn werk kan doen moet ook de module ‘mod_ssl' aangepast worden, die voor de SSL/TLS-verbindingen verantwoordelijk is. Als je niet wilt wachten, is er een UbuntuPPA met een al aangepast Apache-pakket, waarvoor je alleen mod_md op de juiste manier hoeft te compileren. De benodigde stappen daarvoor staan in de mod_md-wiki op GitHub (zie de link onder aan dit artikel).
Wat is nieuw?
Een voorbeeldconfiguratie laat zien hoe mod_md werkt. Een HTTPS-website in Apache ziet er sterk vereenvoudigd zo uit:
<VirtualHost *:443>
ServerName example.com
SSLEngine on
SSLCertificateFile /etc/mycerts ... SSLCertificateKeyFile /etc/ ...
...
</VirtualHost>
De bestanden waar de SSLCertificate-opties naar verwijzen, moest je als serverbeheerder tot nu toe zelf bij een certificeringsinstantie aandragen. Met mod_md doe je daarentegen:
MDomain example.com <VirtualHost *:443> ServerName example.com SSLEngine on
...
</VirtualHost>
en dan neemt Apache zelf contact op met de Let's-Encrypt-server, vraagt om een certificaat voor example.com en geeft antwoord op de vragen die moeten garanderen dat je server het domein ook echt mag beheren. Daarna wordt het certificaat gedownload en na een reload van de server heb je dan een website die door browsers met een groen slotje weergegeven wordt.
Als de site onder een andere naam bereikbaar moet zijn, volstaat het het volgende toe te voegen:
MDomain example.com
<VirtualHost *:443>
ServerName example.com ServerAlias www.example.com SSLEngine on
...
</VirtualHost>
Dan herkent mod_md dat het certificaat niet meer alle benodigde namen afdekt en wordt een nieuw aangevraagd.
Voor meerdere van dergelijke sites kun je nog meer MDomain-regels toevoegen
of een domein uitbreiden naar meerdere websites door de naam aan een bestaande MDomain-regel te hangen:
MDomain example.com example.net <VirtualHost *:443>
ServerName example.com
...
</VirtualHost>
<VirtualHost *:443> ServerName example.net ...
</VirtualHost>
Op die manier genereert de module een enkel certificaat dat voor beide geldt. Het voordeel is dat browsers bij HTTP/2-servers dan dezelfde verbinding gebruiken. Een voordeel van afzonderlijke MDomain-regels is dat de certificaten niet onnodig groot worden, want de server stuurt die bij elke verbindingsopbouw naar de client.
Opstartproblemen?
Apache is een zeer krachtige server. Het aantal verschillende configuratie- en gebruiksmogelijkheden is groot. Het kan dus zeker gebeuren dat er iets over het hoofd gezien wordt. De module is nog nieuw, maar er is al wel het nodige bekend over wat er aan moet gebeuren om het aan de praat te krijgen.
Om te beginnen: om Let's Encrypt te gebruiken, moet je het eens zijn met de ‘Terms of Service'. Dat doe je door in de configuratie de volgende regel te zetten:
MDCertificateAgreement https:// .letsencrypt.org/documents/LE-SA- .v1.2-November-15-2017.pdf
Zonder dat werkt het niet. De exacte url kan wellicht nog wijzigen, maar die hoeft alleen bij de eerste aanmelding te kloppen. Als Let's Encrypt de agreement niet goedkeurt of als die ontbreekt, komt er een overeenkomstige ERROR in de serverlog te staan. Bovendien moet de optie ServerAdmin naar een geldig e-mailadres verwijzen waar Let's Encrypt de statusberichten naartoe kan sturen.
De Apache-server kan pas beginnen met het aanvragen van certificaten als hij gestart is. Managed-domains die nog geen ‘goed' certificaat hebben, gebruiken daarom eerst een dummy-certificaat. Veel servers bedienen een veelvoud aan managed-domains en de wensen van één domein mogen de toegang tot alle andere niet blokkeren. Een door Let's Encrypt gevalideerde goedkeuring die meteen zichtbaar is na de eerste keer starten van de server is wat teveel gevraagd.
Om ervoor te zorgen dat een server de nieuw opgehaalde certificaten ook uitlevert, heeft hij een ‘gracefull restart' nodig – ook wel een ‘reload' genoemd. Een indicatie dat dit nodig is, staat als NOTICE in de serverlog. Heeft een admin dan ook een nieuw domein als ‘managed' geconfigureerd, dan kan hij in de log lezen wanneer een reload zinvol is. Meestal duurt dat een paar seconden.
Tot het zover is, laten nieuwe domeinen alleen een zelf-ondertekend certificaat zien dat browsers niet vertrouwen. Ontvangen requests worden door de server alleen met de status 503 beantwoord, oftewel service niet beschikbaar.
De module bekommert zich al weken voor de verloopdatum om het vernieuwen van de bestaande certificaten. Het precieze tijdstip van het activeren van de nieuwe certificaten is dan ook minder kritisch. Het is aan te raden eenmaal per week een reload uit te voeren, bijvoorbeeld met een cron-job. Een reload heeft geen gevolgen voor lopende requests. De afzonderlijke Apache-processen starten pas opnieuw op als ze alle verbindingen netjes afgesloten hebben.
Als het niet soepel loopt
Alle activiteiten van mod_md komen in de serverlog te staan. Op level INFO staan daar meldingen over normale dingen. Belangrijkere meldingen komen te staan als NOTICE en bij fouten als WARNING of ERROR.
De module controleert tweemaal per dag of alle certificaten nog lang genoeg geldig zijn. Certificaten van Let's Encryt hebben een geldigheidsduur van 90 dagen. Na twee derde van die termijn probeert de module een nieuwe aan te vragen, dus 30 dagen voor de verloopdatum. Bij een fout wordt een paar seconden later een tweede poging gedaan. Als het fout blijft gaan, maakt de module de tussentijd langer, tot aan enkele uren. Als het wel lukt, wordt dat weer verkort.
Security
De Apache-daemon draait bij de gangbare installaties onder Unix-achtige besturingssystemen onder een gebruiker met beperkte rechten (vaak www-data). Alle Apache-processen die requests van buitenaf verwerken, gebruiken dat account. Daarmee heb je normaal gesproken geen schrijfrechten voor het bestandssysteem, zodat een kwaadwillend Apache-proces zich niet op de harde schijf kan nestelen.
De server kan een dergelijk proces niet stoppen of herstarten – daar heeft hij de rechten niet voor. Hetzelfde geldt voor mod_md, dat altijd in een van die processen zijn werk doet. Elke communicatie met de servers van Let's Encrypt vindt ook daar plaats. Dat verklaart de noodzaak van een reload door de admin of via een cron-job.
Nieuwe certificaten, die bij een reload geactiveerd worden, krijgen automatisch toegangsrechten die alleen de rootgebruiker (of wie de server start) toestaan ze te lezen en schrijven. Privésleutels, die de module bij het aanvragen aanmaakt en in het bestandssysteem neerzet, worden door een willekeurig gekozen wachtwoord afgeschermd.
In het bestandssysteem staan al deze bestanden in de directory md. Standaard bevindt die zich in de ServerRoot van de Apache-server. MDStoreDir kan hem veranderen. Beschrijvingen van de lay-out en de opgeslagen bestanden staan voor geïnteresseerden in de GitHub-wiki van mod_md en in de Apache-documentatie (zie de link hieronder).
TLS-SNI-protocol
Op dit moment gebruikt de module poort 80 voor het aanvragen en vernieuwen van certificaten. Het is licht ironisch dat voor een veilige HTTPS-verbinding op dit moment eerst nog HTTP nodig is. Eigenlijk is ook een methode gedefinieerd, namelijk TLS-SNI-01, die poort 443 gebruikt – die de server voor HTTPS sowieso al nodig heeft.
Helaas kwam Let's Encrypt er begin 2018 achter dat bij bepaalde set-ups bij grote hosters iemand de methode via poort 443 gebruiken kan om een certificaat voor een domein van een andere gebruiker te krijgen. TLS-SNI-01 werd daarop meteen uitgezet. Er werd ter plekke melding gemaakt van die mogelijkheid.
Er wordt op dit moment over gediscussieerd hoe en onder welke omstandigheden TLS-SNI-01 weer geactiveerd kan worden en of er een nieuwe methode ontwikkeld moet worden. Voor gebruikers van mod_md is dat verder niet van belang. Apache en Let's Encrypt onderhandelen bij elke aanvraag over de te gebruiken methode. Als Let's Encrypt TLSSNI-01 weer vrijgeeft, zal Apache dat ook gebruiken. (nkr)