Hoppa till innehållet

Cookieinställningar

Välj vilka typer av cookies du tillåter. Du kan alltid ändra ditt val via Cookieinställningar längst ned på varje sida. Integritetspolicy

Nödvändiga

Alltid på

Behövs för att logga in, spara din varukorg och komma ihåg dina val. De är alltid på.

Vilka cookies?
  • weboke_sessie, weboke_klant, weboke_remember: din session och att du förblir inloggad
  • weboke_basket: din varukorg
  • wkBtwIncl: visa priser med eller utan moms
  • wok_cookies: ditt cookieval, 12 månader

Mäter vilken annons som leder till ett besök eller en beställning, så att vi inte betalar för annonser som inte ger något.

Vilka cookies?
  • Google Ads via Google Tag Manager (_gcl_au, _gcl_aw), upp till 90 dagar
  • OpenAI Ads, annonser i ChatGPT
  • wok_aff: via vilken partner du kom till oss (affiliateprogram), 60 dagar

4,6

Land och språk

Varje land har en egen webbplats med landets priser och moms.

Visa

Caddy, HSTS och security.txt

Modul 7: Domän, webbserver och https · Lästid: 12 minuter

Lärandemål: Efter den här lektionen kan du använda Caddy som en enkel webbserver med automatisk https, slå på HSTS och de viktigaste säkerhetsheadersen (i Caddy och nginx) utan att göra din webbplats onåbar, och publicera en giltig security.txt.

Nyckelbegrepp: 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 utan att du behöver tänka på det

I lektion 7.2 och 7.3 byggde du en webbplats med https med hjälp av nginx och certbot. Det är två program, några filer och en timer. Caddy gör allt i ett: det är en webbserver med en inbyggd ACME-klient. Om ett namn finns i konfigurationen, pekar på servern och port 80 och 443 går att nå, hämtar Caddy själv ett certifikat, förnyar det i tid och skickar vidare http till https.

Caddy finns i paketkällan för Debian och Ubuntu (en något äldre version). Utvecklarna erbjuder också en egen apt-källa med den senaste versionen, med en egen nyckel och Signed-By som i lektion 4.1. I modul 9 kör du Caddy som container för dina Docker-tjänster (lektion 9.4). Här använder du det som en vanlig tjänst.

anna@web1:~$ sudo apt install caddy
anna@web1:~$ systemctl status caddy

Använd antingen nginx eller Caddy på port 80 och 443, inte båda: bara ett program kan lyssna på en port.

Caddyfilen

Konfigurationen finns i /etc/caddy/Caddyfile. En statisk webbplats och en applikation bakom en omvänd 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 är allt. Caddy lyssnar automatiskt på IPv4 och IPv6, begär certifikat för de tre namnen, skickar vidare http till https och skickar vid reverse_proxy automatiskt med headerraderna X-Forwarded-For och X-Forwarded-Proto (det du gjorde för hand i nginx, lektion 7.2).

Testa och ladda om på samma sätt 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 -f

I journalen ser du hur certifikaten hämtas. Om något går fel står orsaken där: oftast samma som med certbot (port 80 stängd, namnet pekar någon annanstans, IPv6 fungerar inte; lektion 7.3).

HSTS: låt webbläsaren komma ihåg att det är https

Att skicka vidare http till https har en svag punkt: den allra första förfrågan via http går fortfarande okrypterad. Någon på samma nätverk kan fånga upp den och hålla kvar besökaren på http. HSTS (HTTP Strict Transport Security, RFC 6797) löser det. Din webbplats skickar med den här headerraden via https:

Strict-Transport-Security: max-age=31536000

Webbläsaren kommer då ihåg i ett år (31.536.000 sekunder) att det här namnet bara får användas via https. Om besökaren senare skriver http:// gör webbläsaren själv om det till https, innan något skickas över nätverket. En HSTS-header som kommer in via http ignoreras av webbläsaren; den gäller bara via https.

Det finns en baksida. Om en webbläsare har sparat HSTS och ser ett certifikatfel (utgånget, fel namn) får besökaren ingen knapp för att fortsätta ändå. Din webbplats är då onåbar för de besökarna tills certifikatet stämmer. Därför:

  1. Slå på HSTS först när https fungerar överallt och förnyelsen sker automatiskt (lektion 7.3).
  2. Börja med en kort max-age, till exempel en dag (86400), och öka stegvis till ett år.
  3. Var försiktig med includeSubDomains: det gäller för varje underdomän, även en gammal underdomän med en enhet eller tjänst utan giltigt certifikat.
  4. preload begär att domänen tas med i en lista som är inbyggd i webbläsare (hstspreload.org). Där krävs bland annat en max-age på minst ett år, includeSubDomains och https på alla underdomäner. Att komma bort från listan tar månader. Gör det bara om du är säker på att hela domänen är https för gott.

De andra säkerhetsheadersen

Förutom HSTS finns det några headerrader som hjälper mycket med liten insats:

HeaderradSkyddar motVärde att börja med
X-Content-Type-Optionswebbläsaren gissar vad en fil är, så att en uppladdad "bild" kan köras som skriptnosniff
Content-Security-Policy: frame-ancestors (eller den äldre X-Frame-Options)clickjacking: en annan webbplats laddar din sida osynligt i en ramframe-ancestors 'self' (eller X-Frame-Options: SAMEORIGIN)
Referrer-Policyadressen till din sida (med sökord eller ordernummer) läcker till andra webbplatserstrict-origin-when-cross-origin

En fullständig Content-Security-Policy (vilka skript och stilmallar som får laddas) måste anpassas för varje webbplats och ingår inte i den här kursen; börja med bara frame-ancestors.

I Caddy sätter du dem med header-direktivet i blocket för en webbplats:

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 sätter inte HSTS och de här headerraderna själv, så du måste verkligen lägga in dem. -Server tar bort headerraden Server. I lektion 9.4 lägger du i samma sorts block in din egen headerrad X-Weboke-Cursus för uppgiften.

I nginx lägger du samma rader i server-blocket för 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 gör att de skickas med även på felsidor. Se upp för en känd fälla i nginx: om ett location-block själv innehåller en enda add_header, gäller inte längre add_header-raderna från server-blocket för den location. Kontrollera därför 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-origin

security.txt: så kan någon rapportera en sårbarhet till dig

Anta att någon hittar en sårbarhet på din server, till exempel en öppen katalog eller en föråldrad tjänst. Hur vet den personen vem som ska varnas? Det är vad security.txt (RFC 9116) är till för: en liten textfil på en fast plats, 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.txt

Reglerna:

  • Contact är obligatoriskt: en mailto:-, https://- eller tel:-adress dit rapporterna går. Använd en adress som någon faktiskt läser.
  • Expires är obligatoriskt och får bara förekomma en gång: datumet då filen räknas som föråldrad. RFC:n rekommenderar ett datum inom ett år. På så vis blir det inte kvar en fil med en sedan länge bortglömd adress. Skriv in i din kalender när du behöver förlänga den.
  • Preferred-Languages, Canonical och Policy (en länk till din policy för rapporter) är valfria.
  • Filen måste levereras via https, som ren text (text/plain, UTF-8). Den gamla platsen /security.txt får användas som komplement, men /.well-known/ har företräde.

Så lägger du den på plats för en statisk webbplats:

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-8

Om du i nginx använder skyddsnätet location ~ /\. { deny all; } från lektion 7.2, lägg då ett undantag före det: location ^~ /.well-known/ { }. För en applikation bakom en omvänd proxy kan du i Caddy låta sökvägen /.well-known/security.txt peka på en fil med ett handle-block och file_server.

Ett vanligt misstag: en webbplats eller applikation som svarar på varje okänd sökväg med startsidan och status 200. Då "finns" security.txt, men den är HTML. Kontrollera därför även innehållet.

På AlmaLinux och Rocky Linux

Där hämtar du Caddy från utvecklarnas källa eller från EPEL/COPR. Precis som med nginx måste SELinux tillåta en omvänd proxy (setsebool -P httpd_can_network_connect 1). Caddyfilen och headersen är desamma.

Sammanfattning

  • Caddy sköter certifikat, förnyelse och vidarebefordran till https själv; reverse_proxy skickar automatiskt med rätt headerrader.
  • HSTS låter webbläsare komma ihåg att din webbplats bara är https; bygg upp max-age stegvis, var försiktig med includeSubDomains och mycket försiktig med preload.
  • Sätt dessutom X-Content-Type-Options: nosniff, frame-ancestors 'self' och en Referrer-Policy; i Caddy med header, i nginx med add_header ... always, och kontrollera med curl -I.
  • security.txt ligger på /.well-known/security.txt, via https, som ren text, med obligatoriskt Contact och en enda Expires inom ett år.

Quiz

1. Varför hjälper HSTS, när du redan skickar vidare http till https?



2. Du slår på HSTS med max-age=31536000; includeSubDomains. En vecka senare visar det sig att camera.example.com saknar giltigt certifikat. Vad märker besökare som har besökt din webbplats tidigare?



3. Vilka fält är obligatoriska i en security.txt?



4. Du har lagt säkerhetsheadersen i server-blocket i nginx, men för /api/ skickas de inte med. I blocket location /api/ finns en egen add_header. Vad är problemet?



5. Vad måste du göra innan du lägger till preload i din HSTS-header?



Uppgift

Uppgift Z7.4: HSTS, headers och security.txt. Slå på HSTS för din webbplats (minst 180 dagar, efter att https har fungerat bra ett tag), X-Content-Type-Options: nosniff och frame-ancestors 'self' (eller X-Frame-Options), och publicera en security.txt med Contact och en Expires inom ett år. Fyll i ditt värdnamn. Programmet hämtar https://<hostnaam>/ och kontrollerar headerraderna, och hämtar https://<hostnaam>/.well-known/security.txt och kontrollerar fälten. Det sparar inget annat än resultatet och Expires-datumet.

Uppgift Z7.4: HSTS, headers och security.txt

Bara för inloggade kursdeltagare. Vi hämtar https://<naam>/ och /.well-known/security.txt (bara GET).




Det du fyller i och det vi hittar sparar vi inte. Din webbläsare kommer ihåg dina svar och om du klarade uppgiften. Är du inloggad sparar vi bara att du klarade uppgiften (nästan) i Mina kurser; där kan du också ta bort det.

Läs mer

Ett ögonblick…

Ställ in dina domäner

Ställ in namnservrar, koppling till ditt webbhotell och vem som blir innehavare för varje domän.

Hämtar dina domäner…