# TLS

## Vad det är

TLS, utskrivet Transport Layer Security, är det nätverksprotokoll som en klient och en server kör
innan de utbyter några applikationsdata, så att det som följer är privat, inte kan ändras obemärkt
och når den part som klienten avsåg. Produktmenyer och certifikatbutiker kallar det fortfarande SSL,
efter Secure Sockets Layer, protokollet som TLS ersatte. RFC 7568 förklarade den sista SSL-versionen
föråldrad i juni 2015, så allt som heter SSL i dag är TLS under ytan, eller borde vara det.

TLS ligger mellan ett applikationsprotokoll och transportlagret under det. HTTPS är HTTP som färdas
inuti en TLS-anslutning, och samma lager skyddar inlämning av e-post, IMAP, databasanslutningar och
protokollet Gemini. HTTP/3 går längre: det körs över QUIC, som bygger in handskakningen från TLS 1.3
i själva transporten i stället för att lägga den ovanpå TCP, så som RFC 9001 beskriver.

Den aktuella versionen är TLS 1.3, definierad i RFC 8446 från augusti 2018, som ersatte
specifikationen för TLS 1.2. En anslutning börjar med en handskakning. Klienten skickar ett
ClientHello med de versioner, chiffersviter och nyckelandelar den stöder, tillsammans med Server
Name Indication (SNI), det värdnamn den vill nå, så att en adress kan betjäna många webbplatser.
Servern väljer, svarar med sin egen nyckelandel, och från den stunden är allt krypterat, även
certifikatet den visar upp. Certifikatkedjan knyter serverns nyckel till en certifikatutfärdare (CA)
som klienten redan litar på. Klienten kontrollerar kedjan, namnet och datumen, och servern bevisar
att den har den matchande privata nyckeln genom att signera handskakningen.

Tre saker skiljer 1.3 från 1.2. En fullständig handskakning tar en enda tur och retur över nätet (en
round trip) i stället för två. Varje nyckelutbyte är efemärt, så en inspelning av dagens trafik
förblir förseglad även om serverns privata nyckel läcker nästa år; den egenskapen kallas
framåtsekretess (forward secrecy). Och en klient som återvänder får skicka ”tidiga data” redan i
sitt första meddelande, så kallad 0-RTT, till ett pris som RFC:n skriver ut: tidiga data har varken
framåtsekretess eller skydd mot att spelas upp igen på en annan anslutning.

## Varför det spelar roll

Att använda TLS är redan avgjort. Kvar finns två beslut: vilka versioner du godtar och var den
krypterade anslutningen tar slut.

Först versionerna. RFC 8996, publicerad i mars 2021, säger att TLS 1.0 och 1.1 inte får användas.
RFC 9325, den gällande bästa praxisen (BCP 195), kräver stöd för 1.2, rekommenderar 1.3 och säger
att 1.3 ska föredras när båda sidor har det. Den säger också att 1.2, konfigurerad på det sätt den
beskriver, är lika säker som 1.3: ECDHE som nyckelutbyte för framåtsekretess, AES-GCM och inga av
sviterna i CBC-läge. Det verkliga valet står alltså mellan ”1.2 och 1.3” och ”bara 1.3”. En tjänst
med bara 1.3 har en mindre attackyta och en kortare konfiguration, och den stänger ute varje klient
som högst talar 1.2: en äldre telefon, en kortterminal, en partners integration på en gammal
Java-körmiljö. Den avvägningen är billig att avgöra med belägg. Logga den förhandlade versionen i
några veckor och bestäm sedan utifrån siffrorna, inte utifrån vad som låter modernt.

Sedan termineringen. Där TLS slutar finns den privata nyckeln, och där blir trafiken klartext igen.
Det finns tre vanliga platser för det:

- **Ett CDN eller en lastbalanserare i molnet.** Leverantören har nyckeln, eller ett certifikat den
  själv har utfärdat, tar handskakningslasten och ser varje förfrågan i klartext. Steget därifrån
  till ursprungsservern behöver ett eget TLS, annars går det okrypterat över nätet.
- **En omvänd proxy på värddatorn,** t.ex. nginx, Apache, HAProxy eller Caddy. En enda process har
  nycklarna för alla webbplatser på maskinen och skickar okrypterade förfrågningar vidare till
  applikationerna bakom, över loopback eller en lokal socket.
- **Applikationen själv.** Varje tjänst har sin egen nyckel. Det passar trafik mellan tjänster och
  ömsesidig TLS (mutual TLS), där också klienten visar upp ett certifikat, och det mångdubblar de
  ställen där ett certifikat måste förnyas.

De flesta miljöer blandar alla tre. Det som räknas är att någon för varje steg kan säga var
klartexten finns och vem som skulle kunna läsa den.

## Så ser det ut i praktiken

Företagets egen produktionsvärd visar hur lite TLS-terminering kräver. Värden är en molninstans med
en kärna, 10 GB disk och 512 MB minne, och där
[terminerar webbservern TLS för sju domäner](/sv/portfolio/ran-the-whole-company-on-one-512mb-host-109/)
på samma maskin som git-forgen, onion-tjänsten för Tor, servrarna för Gemini och Gopher, de
krypterade säkerhetskopiorna och spärren mot intrångsförsök. Det är terminering på värden i sin
enklaste form: en enda webbserver svarar för alla sju webbplatserna, och krypteringen för dem kostar
varken en extra maskin eller en extra tjänst. Designen behandlade minnet som den bindande
begränsningen, och allt på den listan, termineringen inräknad, får plats i det användbara minnet på
ungefär 464 MB.

Regeln som företaget arbetar efter står på
[sidan om hur vi arbetar säkert](/sv/security/): kryptering under överföring överallt, med
certifikat som utfärdas och förnyas automatiskt och en förnyelse som övervakas. Skälet som anges där
är att TLS oftast fallerar genom ett certifikat som ingen höll ett öga på. Felen nedan är de som
återstår när förnyelsen sköter sig själv.

## Var det går fel

**Vissa klienter faller bort med ett handskakningsfel medan webbläsare ansluter som vanligt.** De
två sidorna delar ingen version eller chiffersvit. Någon har smalnat av servern till bara 1.3, eller
till en kort lista sviter, och en äldre klient erbjuder inget som finns på den. Eller så möter en
server som fortfarande bara erbjuder CBC-sviter en klient som har slutat med dem. Felmeddelandet
säger ”handshake failure” eller ”protocol version” och inte mycket mer. Testa varje version
utifrån:

```sh
openssl s_client -connect example.com:443 \
    -servername example.com -tls1_2 </dev/null
```

Logga den förhandlade versionen och sviten innan du smalnar av något, och behåll 1.2 med ECDHE och
AES-GCM bredvid 1.3 tills loggarna visar att ingen använder den.

**Webbläsare litar på certifikatet, medan skript, curl och mobilappar avvisar det.** Servern skickar
sitt eget certifikat utan det mellanliggande certifikat som länkar det till roten. Webbläsare fyller
ofta luckan med mellanliggande certifikat som de har sett förut, eller hämtar det som saknas själva.
De flesta TLS-bibliotek gör inget av det och rapporterar en okänd utfärdare. Konfigurera hela
kedjefilen, serverns certifikat först och sedan de mellanliggande, och testa med en klient som inte
sparar något i cache: raden med `openssl s_client` ovan skriver ut den kedja som servern faktiskt
skickade.

**Certifikatkontrollen stängs av ”tills vidare”, och inställningen följer med ut i produktion.** En
testserver med ett självsignerat certifikat, eller en företagsproxy som signerar om trafiken, och
någon lägger till `verify=False`, `curl -k`, `InsecureSkipVerify` eller
`NODE_TLS_REJECT_UNAUTHORIZED=0`. Anslutningen förblir krypterad, men till den som svarar: vem som
helst däremellan kan visa upp ett eget certifikat och läsa allt. Lägg rätt CA-certifikat i
klientens förtroendelager, eller peka klienten uttryckligen mot det, och låt CI stoppa bygget när de
flaggorna dyker upp.

**Vissa besökare får ett certifikat för en annan webbplats.** Servern visar sitt standardcertifikat
när ett ClientHello nämner ett värdnamn som den saknar konfiguration för, eller inget namn alls. Det
händer när en ny domän pekas mot adressen innan dess serverblock finns, och när en övervakningssond
eller en gammal klient skickar sin förfrågan utan SNI. Webbläsaren visar att namnet inte stämmer,
och på en delad värd avslöjar den dessutom för besökaren vilka andra webbplatser som bor där. Ge
varje publikt namn ett eget block och ett certifikat som täcker det, och låt standardblocket vägra
handskakningen i stället för att visa upp en främlings certifikat.

**En betalning, eller vilken annan förfrågan som helst, utförs två gånger.** Termineringspunkten
godtar tidiga data via 0-RTT, en POST kommer in bland dem, och en angripare eller ett omförsök i
nätet skickar samma byte igen på en ny anslutning. RFC 8446 låter en server ta emot tidiga data och
lämnar skyddet mot uppspelning mellan anslutningar åt applikationen. Godta tidiga data bara för
förfrågningar som tål att upprepas, eller låt termineringspunkten vägra dem för allt annat. RFC 8470
definierar statusen 425 Too Early för just den överlämningen.

## Läs mer

- [RFC 8446: The Transport Layer Security (TLS) Protocol Version 1.3](https://www.rfc-editor.org/rfc/rfc8446)
  — handskakningen, postlagret (record layer) och bilagan om varför data i 0-RTT kan spelas upp
  igen.
- [RFC 9325: Recommendations for Secure Use of TLS and DTLS](https://www.rfc-editor.org/rfc/rfc9325)
  — BCP 195: vilka versioner som ska tillåtas, vilka sviter i 1.2 som ska behållas och reglerna för
  SNI.
- [RFC 8996: Deprecating TLS 1.0 and TLS 1.1](https://www.rfc-editor.org/rfc/rfc8996)
  — det formella slutet för de två äldre versionerna och skälen bakom det.
- [RFC 8470: Using Early Data in HTTP](https://www.rfc-editor.org/rfc/rfc8470)
  — hur en termineringspunkt och en server kommer överens om vilka förfrågningar som får skickas i
  0-RTT, och statusen 425.

<https://engineer.company/sv/glossary/tls/>
