ťařina
Obsah Soubory
TLS a reverse proxy

TLS a HTTPS

Aktualizováno 4 min čtení 742 slov

TLS a HTTPS prakticky

Reverse proxy je z velké části správa TLS, takže bez téhle stránky nedávají ty další smysl. Nejde tu o kryptografii, ale o věci, které tě reálně potkají v konfiguraci.

Když tě zajímá, co se pod tím děje, je to na TLS handshake krok za krokem.

Co TLS řeší

Tři věci naráz, a je užitečné je oddělovat:

Šifrování — nikdo po cestě nepřečte obsah.

Integrita — nikdo po cestě obsah nezmění, aniž by to bylo poznat.

Autenticita — mluvíš se serverem, za který se vydává. Tohle dělá certifikát a je to ta část, která nejčastěji zlobí.

Šifrování bez autenticity je k ničemu. Kdyby ti stačilo šifrování, útočník se prostě postaví doprostřed a šifruje s tebou sám.

Průběh spojení

sequenceDiagram
    participant K as Klient
    participant S as Server
    K->>S: ClientHello (umím tyto šifry, chci doménu X)
    S->>K: ServerHello + certifikát
    K->>K: ověří podpis proti CA a datum platnosti
    K->>S: výměna klíčů
    Note over K,S: dál je vše šifrované
    K->>S: GET / HTTP/1.1

To „chci doménu X" v prvním kroku je SNI a je klíčové pro pochopení reverse proxy.

Tohle je zjednodušení. V TLS 1.3 přiloží klient svou část výměny klíčů rovnou do prvního paketu, takže celý handshake trvá jedno kolo a certifikát letí už zašifrovaný — rozbor je na TLS handshake krok za krokem, samotná výměna na Diffie-Hellman.

SNI

Na jedné IP adrese může běžet sto webů. Server ale musí vybrat certifikát dřív, než se spojení zašifruje a než uvidí HTTP hlavičku Host.

Řeší to SNI: klient v úvodním nešifrovaném pozdravu pošle jméno domény, na kterou se chce připojit. Podle toho server vybere certifikát.

Praktické důsledky:

Jméno domény jde po drátě nešifrovaně. Obsah nikdo nepřečte, ale to, na které weby chodíš, ano. Řeší to až Encrypted Client Hello, které se teprve nasazuje.

Reverse proxy může podle SNI rozhodovat, aniž by TLS rozbalovala. Tomu se říká SNI routing.

Bez SNI dostaneš výchozí certifikát. Když se připojíš na IP adresu místo na jméno, server neví, co chceš, a pošle první certifikát v pořadí — proto to varování v prohlížeči.

Řetěz certifikátů

Certifikát sám o sobě nic nedokazuje. Důvěra se odvozuje řetězem:

kořenová CA (v prohlížeči a v OS)
    └── mezilehlá CA
            └── tvůj certifikát pro example.cz

Server musí poslat svůj certifikát i mezilehlé. Kořenový ne, ten už klient má.

Tohle je nejčastější chyba při ručním nasazení certifikátů. Projeví se tak, že web funguje v prohlížeči na desktopu (ten si mezilehlý certifikát domyslí z keše) a nefunguje v curl, na mobilu nebo v jiné aplikaci.

Ověř si to:

openssl s_client -connect example.cz:443 -servername example.cz < /dev/null

V hlavičce výstupu je Certificate chain — musí tam být víc než jedna položka. A na konci Verify return code: 0 (ok).

Online kontrola: ssllabs.com/ssltest, která ti ukáže i „chain issues".

Caddy a Traefik tenhle problém nemají, protože řetěz sestavují samy.

Verze a šifry

Jednoduše: TLS 1.2 a 1.3, nic staršího. TLS 1.0 a 1.1 jsou vyřazené, SSL v jakékoliv verzi je prolomené.

Rozumná konfigurace pro nginx:

ssl_protocols TLSv1.2 TLSv1.3;
ssl_prefer_server_ciphers off;
ssl_session_cache shared:SSL:10m;
ssl_session_timeout 1d;
ssl_session_tickets off;

U TLS 1.3 se seznam šifer neladí — protokol nabízí jen bezpečné. To ssl_prefer_server_ciphers off je dnes doporučení, protože klient obvykle ví lépe, co má hardwarově akcelerované.

To ssl_session_tickets off na posledním řádku není kosmetika: tikety šifruje server dlouhodobým klíčem, a když se ten nerotuje a unikne, dá se zpětně dešifrovat provoz všech obnovených relací. Vysvětlení je v TLS handshake.

Generátor konfigurací pro všechny běžné servery: ssl-config.mozilla.org.

HSTS

Hlavička, kterou serveru řekneš prohlížeči „na tuhle doménu chodím vždycky přes HTTPS":

add_header Strict-Transport-Security "max-age=31536000; includeSubDomains" always;

Chrání proti útoku, kdy tě někdo při prvním requestu na http:// přesměruje jinam.

Pozor na includeSubDomains. Platí to na rok a prohlížeč si to zapamatuje. Když máš pod doménou něco, co běží jen na HTTP, přestane to fungovat a nedá se to jednoduše vzít zpět. Nasazuj nejdřív s krátkým max-age, třeba 300, a zvyšuj až po ověření.

Ukončení TLS a co dál

Reverse proxy TLS obvykle ukončí a dovnitř posílá nešifrované HTTP. Je to standardní a v důvěryhodné síti v pořádku — vnitřní provoz mezi proxy a aplikací neopouští stroj nebo důvěryhodný segment.

Alternativy:

TLS passthrough — proxy nerozbaluje, jen podle SNI přepošle dál. Nutné, když aplikace potřebuje vidět klientský certifikát.

Re-encrypt — proxy rozbalí a k aplikaci naváže nové TLS. Užitečné, když provoz jde přes nedůvěryhodnou síť, třeba mezi VM na různých hostitelích.

Pro homelab je ukončení na proxy správná volba.

Časté chyby

„NET::ERR_CERT_AUTHORITY_INVALID" → chybí mezilehlý certifikát, nebo je certifikát podepsaný sám sebou. Případně ho vystavila vlastní CA, kterou tenhle klient nezná.

Funguje v prohlížeči, ne v curl → skoro vždycky chybějící mezilehlý certifikát.

„certificate has expired" → neproběhla obnova. Viz certifikáty a Let's Encrypt.

Aplikace generuje odkazy s http:// → aplikace neví, že běží za proxy. Chybí hlavička X-Forwarded-Proto, viz reverse proxy.

Přesměrovací smyčka → proxy přesměrovává na HTTPS a aplikace taky, přičemž aplikace vidí interní HTTP a myslí si, že je potřeba přesměrovat znovu. Řeší se stejnou hlavičkou.