Modul 7 · 7.4
Caddy, HSTS og security.txt
Modul 7: Domene, webserver og https · Lesetid: 12 minutter
Læringsmål: Etter denne leksjonen kan du bruke Caddy som en enkel webserver med automatisk https, sette HSTS og de viktigste sikkerhetsheaderne (i Caddy og nginx) uten at nettstedet ditt blir utilgjengelig, og publisere en gyldig security.txt.
Nøkkelbegreper: Caddy, Caddyfile, automatisk https, reverse_proxy, file_server, header, HSTS (Strict-Transport-Security), max-age, includeSubDomains, preload, X-Content-Type-Options, frame-ancestors, Referrer-Policy, security.txt, Contact, Expires, /.well-known/
Caddy: https uten å tenke på det
I leksjon 7.2 og 7.3 bygde du et nettsted med https ved hjelp av nginx og certbot. Det er to programmer, noen filer og en timer. Caddy gjør alt i ett: det er en webserver med en innebygd ACME-klient. Står et navn i konfigurasjonen, peker det til serveren og er port 80 og 443 tilgjengelige, henter Caddy selv et sertifikat, fornyer det i tide og videresender http til https.
Caddy finnes i pakkekilden til Debian og Ubuntu (en litt eldre versjon). Utviklerne tilbyr også en egen apt-kilde med nyeste versjon, med egen nøkkel og Signed-By som i leksjon 4.1. I modul 9 kjører Caddy som container for Docker-tjenestene dine (leksjon 9.4). Her bruker du det som en vanlig tjeneste.
anna@web1:~$ sudo apt install caddy
anna@web1:~$ systemctl status caddyBruk enten nginx eller Caddy på port 80 og 443, ikke begge: bare ett program kan lytte på en port.
Caddyfile
Konfigurasjonen ligger i /etc/caddy/Caddyfile. Et statisk nettsted og en applikasjon bak en reverse proxy:
example.com, www.example.com {
root * /var/www/example.com
file_server
encode zstd gzip
}
app.example.com {
reverse_proxy 127.0.0.1:3000
}Det er alt. Caddy lytter automatisk på IPv4 og IPv6, bestiller sertifikater for de tre navnene, videresender http til https, og sender ved reverse_proxy automatisk med headerne X-Forwarded-For og X-Forwarded-Proto (det du gjorde for hånd i nginx, leksjon 7.2).
Testing og omlasting gjøres som med nginx:
anna@web1:~$ caddy validate --config /etc/caddy/Caddyfile
Valid configuration
anna@web1:~$ sudo systemctl reload caddy
anna@web1:~$ sudo journalctl -u caddy -fI journalen ser du at sertifikatene hentes. Går noe galt, står årsaken der: som regel den samme som med certbot (port 80 stengt, navnet peker et annet sted, IPv6 fungerer ikke; leksjon 7.3).
HSTS: la nettleseren huske at det er https
Videresending fra http til https har ett svakt punkt: den aller første forespørselen over http går fortsatt ukryptert. Noen på samme nettverk kan fange den opp og holde besøkeren på http. HSTS (HTTP Strict Transport Security, RFC 6797) løser dette. Nettstedet ditt sender denne headeren over https:
Strict-Transport-Security: max-age=31536000Nettleseren husker da i ett år (31.536.000 sekunder) at dette navnet bare skal brukes over https. Skriver besøkeren senere http://, gjør nettleseren det selv om til https, før noe går ut på nettverket. En HSTS-header som kommer inn over http, ignoreres av nettleseren; den teller bare over https.
Det finnes en bakside. Har en nettleser husket HSTS og ser den en sertifikatfeil (utløpt, feil navn), får besøkeren ingen knapp for å fortsette likevel. Nettstedet ditt er da utilgjengelig for disse besøkerne til sertifikatet er i orden. Derfor:
- Slå på HSTS først når https fungerer overalt og fornyelsen går automatisk (leksjon 7.3).
- Begynn med en kort
max-age, for eksempel én dag (86400), og øk trinnvis til ett år. - Vær forsiktig med
includeSubDomains: det gjelder for alle underdomener, også et gammelt underdomene med en enhet eller tjeneste uten gyldig sertifikat. preloadber om å bli tatt inn i en liste som er bygd inn i nettleserne (hstspreload.org). Kravene er blant annet enmax-agepå minst ett år,includeSubDomainsog https på alle underdomener. Å komme av listen tar måneder. Gjør det bare hvis du er sikker på at hele domenet skal være https for godt.
De andre sikkerhetsheaderne
I tillegg til HSTS finnes det noen headere som gir mye beskyttelse for liten innsats:
| Header | Beskytter mot | Verdi å begynne med |
|---|---|---|
X-Content-Type-Options | at nettleseren gjetter hva en fil er, slik at et opplastet "bilde" kan kjøre som skript | nosniff |
Content-Security-Policy: frame-ancestors (eller den eldre X-Frame-Options) | clickjacking: et annet nettsted laster siden din usynlig inn i en ramme | frame-ancestors 'self' (eller X-Frame-Options: SAMEORIGIN) |
Referrer-Policy | at adressen til siden din (med søkeord eller ordrenumre) lekker til andre nettsteder | strict-origin-when-cross-origin |
En fullstendig Content-Security-Policy (hvilke skript og stiler som får lastes) må tilpasses hvert nettsted og ligger utenfor dette kurset; begynn med bare frame-ancestors.
I Caddy setter du dem med header-direktivet i blokken til et nettsted:
example.com, www.example.com {
root * /var/www/example.com
file_server
header {
Strict-Transport-Security "max-age=31536000"
X-Content-Type-Options "nosniff"
Content-Security-Policy "frame-ancestors 'self'"
Referrer-Policy "strict-origin-when-cross-origin"
-Server
}
}Caddy setter ikke HSTS og disse headerne selv; du må altså faktisk legge dem inn. -Server fjerner headeren Server. I leksjon 9.4 setter du i samme type blokk din egen header X-Weboke-Cursus for oppgaven.
I nginx setter du de samme linjene i server-blokken for port 443:
add_header Strict-Transport-Security "max-age=31536000" always;
add_header X-Content-Type-Options "nosniff" always;
add_header Content-Security-Policy "frame-ancestors 'self'" always;
add_header Referrer-Policy "strict-origin-when-cross-origin" always;always sørger for at de også sendes med på feilsider. Pass på en kjent felle i nginx: står det én add_header i en location-blokk, gjelder ikke lenger add_header-linjene fra server-blokken for den location. Kontroller derfor alltid resultatet:
anna@laptop:~$ curl -sI https://example.com | grep -iE 'strict|nosniff|frame|referrer'
strict-transport-security: max-age=31536000
x-content-type-options: nosniff
content-security-policy: frame-ancestors 'self'
referrer-policy: strict-origin-when-cross-originsecurity.txt: slik kan noen melde fra om et sikkerhetshull
Tenk deg at noen finner et sikkerhetshull på serveren din, for eksempel en åpen mappe eller en utdatert tjeneste. Hvordan vet den personen hvem som skal varsles? Det er det security.txt (RFC 9116) er til for: en liten tekstfil på et fast sted, https://<jouwdomein>/.well-known/security.txt.
Contact: mailto:security@example.com
Expires: 2027-10-31T23:00:00Z
Preferred-Languages: nl, en
Canonical: https://example.com/.well-known/security.txtReglene:
Contacter påkrevd: enmailto:-,https://- ellertel:-adresse der meldingene havner. Bruk en adresse som noen faktisk leser.Expireser påkrevd og skal bare forekomme én gang: datoen da filen regnes som utdatert. RFC-en anbefaler en dato innen ett år. Slik blir det ikke liggende en fil med en adresse som for lengst er glemt. Skriv i kalenderen når du må forlenge den.Preferred-Languages,CanonicalogPolicy(en lenke til retningslinjene dine for meldinger) er valgfrie.- Filen må leveres over https, som ren tekst (
text/plain, UTF-8). Den gamle plasseringen/security.txter tillatt i tillegg, men/.well-known/har forrang.
Slik legger du den ut for et statisk nettsted:
anna@web1:~$ sudo mkdir -p /var/www/example.com/.well-known
anna@web1:~$ sudoedit /var/www/example.com/.well-known/security.txt
anna@laptop:~$ curl -sI https://example.com/.well-known/security.txt | grep -i content-type
content-type: text/plain; charset=utf-8Bruker du sikkerhetsnettet location ~ /\. { deny all; } fra leksjon 7.2 i nginx, legg da inn et unntak foran det: location ^~ /.well-known/ { }. For en applikasjon bak en reverse proxy kan du i Caddy la stien /.well-known/security.txt peke til en fil med en handle-blokk og file_server.
En vanlig feil: et nettsted eller en applikasjon som svarer på alle ukjente stier med forsiden og status 200. Da "finnes" security.txt, men det er HTML. Kontroller derfor også innholdet.
På AlmaLinux og Rocky Linux
Der kommer Caddy fra utviklernes egen kilde eller fra EPEL/COPR. Som med nginx må SELinux tillate en reverse proxy (setsebool -P httpd_can_network_connect 1). Caddyfile og headerne er de samme.
Oppsummering
- Caddy ordner sertifikater, fornyelse og videresending til https selv;
reverse_proxysender automatisk med de riktige headerne. - HSTS får nettlesere til å huske at nettstedet ditt bare bruker https; bygg opp
max-agegradvis, vær forsiktig medincludeSubDomainsog svært forsiktig medpreload. - Sett i tillegg
X-Content-Type-Options: nosniff,frame-ancestors 'self'og enReferrer-Policy; i Caddy medheader, i nginx medadd_header ... always, og kontroller medcurl -I. - security.txt ligger på
/.well-known/security.txt, over https, som ren tekst, med påkrevdContactog énExpiresinnen ett år.
Quiz
Oppgave
Oppgave Z7.4: HSTS, headere og security.txt. Sett HSTS for nettstedet ditt (minst 180 dager, etter at https har fungert godt en stund), X-Content-Type-Options: nosniff og frame-ancestors 'self' (eller X-Frame-Options), og publiser en security.txt med Contact og en Expires innen ett år. Fyll inn vertsnavnet ditt. Programmet henter https://<hostnaam>/ og kontrollerer headerne, og henter https://<hostnaam>/.well-known/security.txt og kontrollerer feltene. Det lagrer ingenting annet enn resultatet og Expires-datoen.
Les mer
- HSTS og sikkerhetsheadere for nettstedet ditt
- Caddy, Automatic HTTPS: https://caddyserver.com/docs/automatic-https
- Caddy, header-direktivet: https://caddyserver.com/docs/caddyfile/directives/header
- RFC 6797, HTTP Strict Transport Security: https://www.rfc-editor.org/rfc/rfc6797.html
- HSTS-preload-listen og kravene: https://hstspreload.org/
- RFC 9116, security.txt: https://www.rfc-editor.org/rfc/rfc9116.html
- securitytxt.org (lag og kontroller): https://securitytxt.org/
