Ga naar hoofdinhoud

Online zetten: je domein met HTTPS

Over http gaat alles leesbaar over de lijn. Wie op hetzelfde wifi zit, of ergens onderweg een kabel beheert, kan meelezen: het wachtwoord waarmee een bezoeker inlogt, en de cookie met zijn sessie-id. Met https is het versleuteld, en weet de browser bovendien zeker dat hij met jouw server praat en niet met een die zich voor jou uitgeeft.

Daarvoor heb je een certificaat nodig: een bewijs, ondertekend door een bekende partij, dat jouw server bij jouw domeinnaam hoort. Traefik vraagt er zelf een aan, gratis, bij Let's Encrypt, en vernieuwt het op tijd.

Traefik op 443​

Open op de server de compose.yaml van Traefik:

cd ~/traefik
nano compose.yaml

Er komen vijf regels bij command bij, een poort, en een volume voor de certificaten:

services:
traefik:
image: traefik:v3
command:
- --providers.docker=true
- --providers.docker.exposedbydefault=false
- --entrypoints.web.address=:80
- --entrypoints.web.http.redirections.entrypoint.to=websecure
- --entrypoints.websecure.address=:443
- --entrypoints.websecure.http.tls.certresolver=letsencrypt
- --certificatesresolvers.letsencrypt.acme.httpchallenge.entrypoint=web
- --certificatesresolvers.letsencrypt.acme.storage=/letsencrypt/acme.json
ports:
- "80:80"
- "443:443"
volumes:
- /var/run/docker.sock:/var/run/docker.sock:ro
- letsencrypt:/letsencrypt
networks:
- web
restart: unless-stopped

volumes:
letsencrypt:

networks:
web:
external: true
NieuwBetekenis
web.http.redirections.entrypoint.to=websecurestuur elk verzoek op poort 80 door naar https
websecure.address=:443een tweede ingang, websecure, op poort 443
websecure.http.tls.certresolver=letsencryptelke site op 443 krijgt een certificaat van letsencrypt
letsencrypt.acme.httpchallenge.entrypoint=webLet's Encrypt controleert via poort 80 of de naam bij jouw server hoort
letsencrypt.acme.storage=…waar de certificaten bewaard worden: in het volume letsencrypt

Zonder dat volume vraagt Traefik bij elke herstart een nieuw certificaat aan, en Let's Encrypt geeft er maar een paar per week voor dezelfde naam. Start Traefik opnieuw:

docker compose up -d

Aan je site verandert niets: de labels uit les 23 gelden voor beide ingangen. Open https://gastenboek.voorbeeld.nl op je telefoon. Je site opent zonder waarschuwing over de verbinding.

Twee dingen moeten kloppen voordat het lukt: het A-record wijst naar je server (les 27), en poort 80 en 443 staan open in de firewall (les 28).

De hele weg​

Nu de route rond is, zie je de hele weg van een verzoek. Elke melding uit de lessen hiervoor hoort bij één stap.

Van je telefoon naar je container
  1. Browser: Je typt de naam van je site. De telefoon vraagt DNS welk adres erbij hoort: het A-record. · Een naam voor je server

  2. Browser: Een verzoek naar poort 443. Over internet naar dat adres, versleuteld met https.

  3. Hier zit de controleServer: ufw laat 443 door. Alleen 22, 80 en 443 staan open. Een poort die Docker publiceert, gaat hier langs. · De deuren dicht

  4. Hier zit de controleServer: Traefik kiest de container. Op de naam uit Host(…), en alleen een container die healthy is. Anders: 404 page not found. · Een voordeur met Traefik

  5. Server: Je site draait als app. fastapi run op poort 8000, in het netwerk web, met de databases in het volume. · Niet als root

  6. Browser: Het antwoord komt terug. Via Traefik, met het certificaat van Let’s Encrypt, op je telefoon. · Je domein met HTTPS

Een verzoek dat bij stap 3 niet door mag, krijgt geen antwoord: de browser wacht en geeft het op. Bij stap 4 antwoordt Traefik zelf, met 404 page not found of Bad Gateway. Pas bij stap 5 draait jouw code.

Controlevraag
Een bezoeker typt http://gastenboek.voorbeeld.nl, zonder s. Wat gebeurt er?
Kies wat jij denkt. Bij het goede antwoord zie je de uitleg.

Er gaat iets mis​

Geen certificaat​

De browser zegt dat de verbinding niet veilig is. Klik je op de details, dan is het certificaat van TRAEFIK DEFAULT CERT. In docker compose logs van Traefik staat Unable to obtain ACME certificate.

Oorzaak: Let's Encrypt kon niet controleren dat de naam bij jouw server hoort, en Traefik gebruikt zolang een certificaat dat hij zelf maakte. Meestal wijst het A-record nog niet naar je server, of poort 80 is dicht. Een derde oorzaak zie je niet met ping: een oud AAAA-record (een IPv6-adres) van de parkeerpagina van je domeinbedrijf. Let's Encrypt kiest dan dat adres, en komt niet bij jouw server.

Oplossing: controleer met getent ahosts gastenboek.voorbeeld.nl alle adressen van je naam: staat er een adres tussen dat niet van jouw server is, haal dan dat record weg bij je domeinbedrijf. Kijk met sudo ufw status of 80 en 443 openstaan. Wacht daarna even: Traefik probeert het zelf opnieuw. Herstart hem niet steeds: Let's Encrypt laat maar een paar mislukte pogingen per uur toe.

Je site werkt niet op het IP-adres​

Op http://203.0.113.10 krijg je een waarschuwing over de verbinding, en daarna 404 page not found.

Oorzaak: Traefik stuurt http door naar https, ook voor het IP-adres. Daar heeft hij geen certificaat voor, en geen site: je site hoort bij de naam.

Oplossing: open je site met je domeinnaam. Dat is ook het adres dat je aan anderen geeft.

Eerst op papier

Speel zonder computer na langs welke stations een verzoek reist, en waar het stopt bij elke melding uit deze route: Waar komt je verzoek langs?. Je docent kan de hand-out printen.

Opdrachten​

Opdracht 1: Run - HTTPS voor je site​

Zet de nieuwe regels in de compose.yaml van Traefik, start hem opnieuw, en open je site met https. Klik in de adresbalk op het pictogram voor het adres: wie heeft het certificaat ondertekend, en tot wanneer is het geldig?

Antwoord

Als uitgever staat er Let's Encrypt, met een korte naam als E5 of R11 erbij. Het certificaat is hooguit drie maanden geldig, en Traefik vernieuwt het vanzelf ruim voordat het afloopt.

Opdracht 2: Modify - Nooit meer http​

Traefik stuurt http door naar https, maar de allereerste keer gaat het verzoek nog onversleuteld. Met de kop Strict-Transport-Security vertel je de browser: gebruik voor deze naam voortaan altijd https, ook als iemand http typt. Zet bij de labels van je site twee regels:

- traefik.http.routers.gastenboek.middlewares=hsts
- traefik.http.middlewares.hsts.headers.stsSeconds=86400

De tweede maakt een middleware: een stap die Traefik doet met elk antwoord. De eerste zet die stap op je site. Commit, haal het op op de server, en start opnieuw. Hoe zie je in de ontwikkelaarstools dat de kop meekomt?

Tip

De koppen van een antwoord staan in het tabblad Netwerk, bij een verzoek. Zie Kijken wat de browser doet.

Antwoord

Klik in Netwerk op het verzoek van de pagina. Onder de koppen van het antwoord staat strict-transport-security: max-age=86400. max-age is in seconden: een dag lang gebruikt de browser alleen nog https voor je naam. Grote sites zetten hier een jaar (31536000), maar begin klein: een browser die de kop kent, gaat die tijd niet terug naar http, ook niet als je server later weg is of iets anders draait. Op je laptop zie je de kop niet: Traefik zet hem alleen bij een antwoord over https.

Door naar les 35: een nieuwe versie uitrollen.