ťařina
Obsah Soubory
markdown

Nginx.md

6.8 kB 219 řádků Změněno Zobrazit na GitHubu Stáhnout
markdown
# Nginx Nejrozšířenější reverse proxy a webserver. Upovídanější než [Caddy](Caddy), ale najdeš k němu návod na cokoliv a při vysoké zátěži je nejrychlejší. Koncepty za tím jsou v [reverse proxy](Reverse-proxy) a [TLS](TLS-a-HTTPS). ## Struktura konfigurace ```/etc/nginx/├── nginx.conf              # hlavní, globální nastavení├── conf.d/*.conf           # sem se dávají vlastní konfigurace├── sites-available/        # Debian a Ubuntu: dostupné weby└── sites-enabled/          # symlinky na aktivní``` Debianovský systém `sites-available` a `sites-enabled` je jen konvence. Aktivace se dělá symlinkem: ```bashln -s /etc/nginx/sites-available/mujweb /etc/nginx/sites-enabled/nginx -t          # kontrola syntaxe, VŽDYCKY před reloadsystemctl reload nginx``` To `nginx -t` je návyk, který stojí za vypěstování. Reload s chybnou konfigurací nechá běžet starou, ale restart shodí celý server. ## Reverse proxy, minimální funkční verze ```nginxserver {    listen 80;    server_name nas.example.cz;    return 301 https://$host$request_uri;} server {    listen 443 ssl;    http2 on;    server_name nas.example.cz;     ssl_certificate     /etc/letsencrypt/live/nas.example.cz/fullchain.pem;    ssl_certificate_key /etc/letsencrypt/live/nas.example.cz/privkey.pem;    ssl_protocols TLSv1.2 TLSv1.3;     location / {        proxy_pass http://127.0.0.1:5000;         proxy_set_header Host              $host;        proxy_set_header X-Real-IP         $remote_addr;        proxy_set_header X-Forwarded-For   $proxy_add_x_forwarded_for;        proxy_set_header X-Forwarded-Proto $scheme;        proxy_set_header X-Forwarded-Host  $host;    }}``` Těch pět řádků s `proxy_set_header` je povinná výbava. Bez nich aplikace nevidí skutečného klienta ani neví, že běží pod HTTPS. Proč, je vysvětlené v [reverse proxy](Reverse-proxy). Nginx je nenastavuje sám a to je nejčastější důvod, proč „aplikace za nginxem zlobí". ## Sdílený blok hlaviček Ať to nepíšeš dvacetkrát, dej si to do souboru `/etc/nginx/snippets/proxy.conf`: ```nginxproxy_set_header Host              $host;proxy_set_header X-Real-IP         $remote_addr;proxy_set_header X-Forwarded-For   $proxy_add_x_forwarded_for;proxy_set_header X-Forwarded-Proto $scheme;proxy_set_header X-Forwarded-Host  $host; proxy_http_version 1.1;proxy_set_header Upgrade    $http_upgrade;proxy_set_header Connection $connection_upgrade; proxy_read_timeout    300s;proxy_send_timeout    300s;proxy_connect_timeout 30s;``` a v konfiguraci pak jen: ```nginxlocation / {    proxy_pass http://127.0.0.1:5000;    include snippets/proxy.conf;}``` ## WebSockety Ty tři řádky s `Upgrade` výše jsou pro WebSockety, ale samy nestačí. V `nginx.conf` v bloku `http` musíš přidat: ```nginxmap $http_upgrade $connection_upgrade {    default upgrade;    ''      close;}``` Bez toho tě čeká `Connection: upgrade` i u běžných požadavků a některé aplikace se z toho zblázní. Pozor taky na `proxy_read_timeout` — ve výchozím stavu je 60 sekund a nečinný WebSocket po nich tiše spadne. Souvislosti v [HTTP, QUIC a WebSocketu](HTTP-QUIC-a-WebSocket). Tohle je řešení problému „Home Assistant se načte, ale nic se neaktualizuje". ## Lomítko v proxy_pass Nejzáludnější detail v celém nginxu. Chování se liší podle toho, jestli je za portem lomítko: ```nginxlocation /app/ {    proxy_pass http://127.0.0.1:3000;      # BEZ lomítka    # /app/foo  →  /app/foo} location /app/ {    proxy_pass http://127.0.0.1:3000/;     # S lomítkem    # /app/foo  →  /foo}``` Bez lomítka se cesta předá celá. S lomítkem se prefix z `location` odřízne. Když ti aplikace pod podcestou vrací 404 na všechny statické soubory, je to skoro vždycky tohle. Většina aplikací navíc pod podcestou nefunguje vůbec, ať děláš co děláš — pokud to nemají výslovně podporované, dej jim vlastní subdoménu. ## Velké soubory ```nginxclient_max_body_size 10G;        # výchozí je 1 MB!proxy_request_buffering off;     # neukládat celý upload na disk proxy``` Výchozí megabajt je důvod, proč ti na Nextcloud nejde nahrát nic většího než dokument. Chyba se hlásí jako `413 Request Entity Too Large`. ## Kompletní příklad se vším ```nginxmap $http_upgrade $connection_upgrade {    default upgrade;    ''      close;} server {    listen 80;    listen [::]:80;    server_name foto.example.cz;    return 301 https://$host$request_uri;} server {    listen 443 ssl;    listen [::]:443 ssl;    http2 on;    server_name foto.example.cz;     ssl_certificate     /etc/letsencrypt/live/foto.example.cz/fullchain.pem;    ssl_certificate_key /etc/letsencrypt/live/foto.example.cz/privkey.pem;    ssl_protocols TLSv1.2 TLSv1.3;    ssl_session_cache shared:SSL:10m;     add_header Strict-Transport-Security "max-age=31536000" always;    add_header X-Content-Type-Options nosniff always;    add_header X-Frame-Options SAMEORIGIN always;     client_max_body_size 50G;    access_log /var/log/nginx/foto.access.log;     location / {        proxy_pass http://127.0.0.1:2283;        include snippets/proxy.conf;    }}``` Poslouchání na `[::]:443` je pro [IPv6](Jak-funguje-IPv6). Zapomíná se to a pak se na tebe přes IPv6 nikdo nedostane, i když DNS má `AAAA`. ## Omezení rychlosti ```nginx# v bloku httplimit_req_zone $binary_remote_addr zone=obecne:10m rate=10r/s; # v bloku locationlimit_req zone=obecne burst=20 nodelay;``` Ochrana proti robotům, kteří ti perou do přihlašovacího formuláře. Doplněk k [fail2ban](Fail2ban-a-CrowdSec), ne náhrada. ## Skutečné IP za další proxy Když je před nginxem ještě Cloudflare nebo jiná proxy, vidí nginx její adresu. Náprava: ```nginxset_real_ip_from 103.21.244.0/22;    # rozsahy Cloudflarereal_ip_header CF-Connecting-IP;real_ip_recursive on;``` Bez toho ti [fail2ban](Fail2ban-a-CrowdSec) zablokuje Cloudflare a s ním všechny návštěvníky. ## Diagnostika ```bashnginx -t                             # syntaxenginx -T                             # kompletní výsledná konfigurace včetně includesystemctl reload nginxtail -f /var/log/nginx/error.log``` `nginx -T` je nedoceněný. Ukáže ti složeninu všech souborů, takže hned vidíš, co se doopravdy načetlo — včetně toho, že máš dvě konfigurace pro stejnou doménu a použije se ta první. | Chyba | Příčina ||---|---|| `502 Bad Gateway` | aplikace za proxy neběží nebo je na jiném portu || `504 Gateway Timeout` | aplikace odpovídá moc dlouho, zvyš `proxy_read_timeout` || `413 Request Entity Too Large` | `client_max_body_size` || `404` na statické soubory pod podcestou | lomítko v `proxy_pass` || smyčka přesměrování | chybí `X-Forwarded-Proto` |