# Reverse proxy

Služba, která přijímá požadavky z internetu a rozděluje je mezi vnitřní aplikace podle doménového jména. Pro self-hosting je to prakticky povinná součást.

Stručný přehled ostatních možností vzdáleného přístupu je ve [vzdáleném přístupu](Vzdaleny-pristup).

## Co řeší

```mermaid
flowchart LR
    I[Internet] --> P[Reverse proxy<br/>:443]
    P -->|nas.example.cz| A[NAS :5000]
    P -->|foto.example.cz| B[Immich :2283]
    P -->|home.example.cz| C[Home Assistant :8123]
    P -->|git.example.cz| D[Forgejo :3000]
```

**Jeden otevřený port místo pěti.** Ven čouhá jen 443, všechno ostatní zůstane na `127.0.0.1`.

**Certifikáty na jednom místě.** Proxy je vyřídí a obnovuje, aplikace o TLS nemusí vědět.

**Aplikace nemusí umět HTTPS.** A většina self-hosted aplikací ho neumí dobře.

**Jednotné přihlášení.** Před aplikace, které autentizaci nemají, můžeš postavit [Authelii nebo Authentik](Autentizace-pred-sluzbami).

**Změny bez zásahu do aplikace.** Přesměrování, komprese, omezení rychlosti, blokace podle IP.

## Základní princip

Proxy se rozhoduje podle hlavičky `Host`, respektive podle [SNI](TLS-a-HTTPS) při navazování spojení. Ta samá IP adresa a port obslouží libovolný počet domén.

Aby to fungovalo, potřebuješ mít **DNS záznamy pro všechny domény směřující na stejnou adresu**. Nejjednodušší je wildcard:

```
*.example.cz    A     85.207.12.34
*.example.cz    AAAA  2a02:8308:1234:ab00::10
```

Nezapomeň na `AAAA`, když máš [IPv6](Jak-funguje-IPv6).

## Hlavičky, kvůli kterým to nefunguje

Tohle je nejčastější zdroj potíží a je dobré rozumět proč. Aplikace za proxy nevidí skutečného klienta — vidí proxy. Musíš jí to říct hlavičkami.

| Hlavička | Co nese | Co se pokazí bez ní |
|---|---|---|
| `Host` | původní doména | aplikace generuje odkazy na interní adresu |
| `X-Forwarded-For` | IP klienta | v logu máš pořád adresu proxy, [fail2ban](Fail2ban-a-CrowdSec) blokuje proxy |
| `X-Forwarded-Proto` | http nebo https | přesměrovací smyčka, odkazy s `http://` |
| `X-Real-IP` | IP klienta | totéž co X-Forwarded-For, jiná konvence |

V [nginx](Nginx) je musíš napsat ručně. [Caddy](Caddy) a [Traefik](Traefik) je nastavují samy.

Aplikace navíc musí být nastavená, aby těm hlavičkám **věřila**. Django má `USE_X_FORWARDED_HOST`, Nextcloud `trusted_proxies`, Home Assistant blok `http.use_x_forwarded_for`. Bez toho je bude ignorovat, protože věřit jim naslepo by byla bezpečnostní díra.

## WebSockety

Aplikace s živou aktualizací (Home Assistant, Grafana, chaty, terminály v prohlížeči) potřebují WebSockety. Ty vyžadují speciální zacházení, protože se HTTP spojení „povýší" na trvalé.

Když ti aplikace načte, ale živá data nechodí a v konzoli prohlížeče vidíš chyby okolo `wss://`, je to tohle. Řešení je u každé proxy jiné a je popsané na jejich stránkách.

Jak přepnutí spojení probíhá a proč se láme právě tady je v [HTTP, QUIC a WebSocketu](HTTP-QUIC-a-WebSocket).

## Velké soubory a časové limity

Výchozí nastavení jsou dělaná pro webové stránky, ne pro nahrávání videí na Nextcloud. Když ti upload padá po minutě nebo u větších souborů, jde o tyhle limity — každá proxy je má jinde.

## Kterou vybrat

| | [Caddy](Caddy) | [Nginx](Nginx) | [Traefik](Traefik) |
|---|---|---|---|
| HTTPS automaticky | ano, bez konfigurace | ne, přes certbot | ano |
| Konfigurace | nejjednodušší | nejupovídanější | přes štítky kontejnerů |
| Docker integrace | ruční | ruční | automatická |
| Výkon při vysoké zátěži | dobrý | nejlepší | dobrý |
| Materiálů na internetu | méně | nejvíc | středně |

**Doporučení pro homelab: [Caddy](Caddy).** Tři řádky konfigurace, certifikáty se vyřídí samy, hlavičky nastaví správně bez ptaní. Ušetří ti to hodiny.

**[Nginx](Nginx)** vezmi, když ho už umíš, když potřebuješ něco specifického, nebo když jedeš vysokou zátěž.

**[Traefik](Traefik)** vezmi, když máš hodně kontejnerů, které často přibývají a ubývají — konfiguruje se ze štítků, takže novou službu nastavíš přímo v `compose.yml`.

## Bezpečnostní poznámky

**Proxy neznamená, že je aplikace bezpečná.** Vystavíš-li ven aplikaci s dírou, proxy ti nepomůže. Před cokoliv bez pořádné autentizace dej [Authelii](Autentizace-pred-sluzbami), nebo to nech jen za [VPN](WireGuard).

**Vnitřní služby publikuj jen na loopback.** `-p 127.0.0.1:3000:3000`, viz [Docker a firewall](Docker-a-firewall). Jinak jsou dostupné i mimo proxy a všechna tvoje pravidla jsou k ničemu.

**Nastav rozumné limity.** Omezení rychlosti požadavků a maximální velikosti těla požadavku ti ušetří problémy s roboty.

**Loguj skutečné IP.** Bez správně nastaveného `X-Forwarded-For` je log k ničemu a fail2ban zablokuje tvoji vlastní proxy.
