Webový server s nginx
Modul 7: Doména, webový server a https · Doba čtení: 12 min.
Cíl lekce: Po této lekci budete umět nainstalovat nginx, nastavit web a reverse proxy pomocí server blocku, bezpečně otestovat a znovu načíst konfiguraci a správně nastavit oprávnění Vašeho webrootu.
Klíčové pojmy: nginx, server block, sites-available a sites-enabled, conf.d, listen, server_name, root, index, try_files, default server, nginx -t, reload, reverse proxy, proxy_pass, Host, X-Forwarded-For, X-Forwarded-Proto, webroot, PHP-FPM
Co dělá webový server
Webový server naslouchá na portu 80 (http) a 443 (https), přijímá požadavky prohlížečů a něco jim vrací: soubor z disku (statický web), nebo odpověď programu, který běží za ním (PHP, aplikace v Node.js, kontejner). Ve druhém případě se webovému serveru říká reverse proxy: stojí vpředu, stará se o https a předává požadavek aplikaci, která naslouchá jen na 127.0.0.1.
Na Linuxu jsou nejznámějšími webovými servery nginx a Apache, moderní alternativou je Caddy (lekce 7.4), který si certifikáty vyřizuje sám. Tato lekce používá nginx: je v každé distribuci, šetří paměť a je standardem v mnoha návodech.
Instalace a první pohled
anna@web1:~$ sudo apt install nginx
anna@web1:~$ systemctl status nginx
anna@web1:~$ curl -I http://localhost
HTTP/1.1 200 OK
Server: nginx/1.26.3
Content-Type: text/html(Číslo verze je jen příklad.) Nezapomeňte na firewall: porty 80 a 443 musí být otevřené (lekce 5.2). Když nyní otevřete http://192.0.2.10, uvidíte uvítací stránku nginx.
Konfigurace je uložena v /etc/nginx/:
| Cesta | Co obsahuje |
|---|---|
nginx.conf | hlavní soubor; většinou ho necháte být |
sites-available/ | jeden soubor na každý web (Debian a Ubuntu) |
sites-enabled/ | odkazy (symlinky) na weby, které jsou zapnuté |
conf.d/*.conf | samostatná nastavení, která se načítají vždy |
snippets/ | úryvky, které znovu používáte ve více webech |
sites-available a sites-enabled jsou zvyklostí Debianu a Ubuntu: web tak zapnete nebo vypnete vytvořením nebo odstraněním odkazu, aniž byste mazali samotný soubor.
První web
Vytvořte pro web adresář a testovací stránku:
anna@web1:~$ sudo mkdir -p /var/www/example.com
anna@web1:~$ echo '<h1>Het werkt</h1>' | sudo tee /var/www/example.com/index.htmlPotom vytvořte server block: popis jednoho webu.
# /etc/nginx/sites-available/example.com
server {
listen 80;
listen [::]:80;
server_name example.com www.example.com;
root /var/www/example.com;
index index.html;
location / {
try_files $uri $uri/ =404;
}
access_log /var/log/nginx/example.com.access.log;
error_log /var/log/nginx/example.com.error.log;
}Čtěte ho takto:
listen 80;alisten [::]:80;zajistí, že nginx naslouchá na IPv4 i IPv6. Pokud druhý řádek zapomenete, nebude fungovat Váš záznam AAAA (lekce 7.1).server_nameříká, pro která jména tento blok platí. nginx se u každého požadavku podívá na jméno, které prohlížeč žádá (hlavička Host), a vybere odpovídající blok.rootje adresář se soubory,indexsoubor, který se zobrazí při požadavku na adresář.try_fileszkusí požadovaný soubor, pak adresář, a jinak vrátí 404. Bez takového řádku může chybná konfigurace ukázat víc, než chcete.- Vlastní logy pro každý web výrazně usnadňují hledání (lekce 6.2).
Zapněte web, odstraňte výchozí web, otestujte a znovu načtěte:
anna@web1:~$ sudo ln -s /etc/nginx/sites-available/example.com /etc/nginx/sites-enabled/
anna@web1:~$ sudo rm /etc/nginx/sites-enabled/default
anna@web1:~$ sudo nginx -t
nginx: the configuration file /etc/nginx/nginx.conf syntax is ok
nginx: configuration file /etc/nginx/nginx.conf test is successful
anna@web1:~$ sudo systemctl reload nginx
anna@web1:~$ curl -I http://example.com
HTTP/1.1 200 OKUdělejte si z nginx -t před každým reloadem pevný zvyk. Při chybě Vám řekne, který soubor a který řádek, a běžící web zůstane nedotčen. Pokud restartujete bez testu, nginx se s chybou už nespustí a všechny Vaše weby budou mimo provoz (lekce 6.1).
Default server: co dostane neznámé jméno?
Co se stane, když někdo osloví Váš server jménem, které není v žádném server_name, nebo prostě IP adresou? Pak nginx vybere default server: blok s default_server za listen, nebo jinak první blok, na který narazil. Když o tom nepřemýšlíte, je to tedy jeden z Vašich skutečných webů.
Čistší je samostatný blok, který takové požadavky odmítne:
# /etc/nginx/sites-available/000-default
server {
listen 80 default_server;
listen [::]:80 default_server;
server_name _;
return 444;
}444 je zvláštní kód nginx: spojení se uzavře bez odpovědi. Skenery, které procházejí IP adresy, tak nic neuvidí. Pro https (port 443) funguje default server trochu jinak, protože k němu patří certifikát; k tomu se vrátíte v lekci 7.3.
nginx jako reverse proxy
Pokud na 127.0.0.1:3000 běží aplikace (lekce 6.3) nebo na 127.0.0.1:3001 kontejner (lekce 9.3), zpřístupní ji nginx navenek:
server {
listen 80;
listen [::]:80;
server_name app.example.com;
location / {
proxy_pass http://127.0.0.1:3000;
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;
}
}Čtyři řádky proxy_set_header jsou důležité. Bez Host aplikace neví, pod jakým jménem je navštěvována. Bez X-Forwarded-For vidí aplikace každou návštěvu přicházet z 127.0.0.1 (z proxy) místo ze skutečné adresy návštěvníka. Bez X-Forwarded-Proto si aplikace myslí, že vše jde přes http, a někdy vytváří odkazy nebo cookies pro http, přestože Váš web běží přes https. Mnoho aplikací má nastavení, kterým těmto hlavičkám důvěřuje („trusted proxy“); uveďte tam jen 127.0.0.1, jinak může každý návštěvník poslat falešnou adresu.
Aplikace, které používají websockety (živé aktualizace, například Uptime Kuma), potřebují ještě dva řádky: proxy_http_version 1.1; a předání Upgrade a Connection. Dokumentace aplikace obvykle přesně uvádí které.
Oprávnění webrootu
nginx na Debianu a Ubuntu spouští své pracovní procesy jako uživatel www-data. Ten musí Vaše soubory umět číst, ale neměl by do nich umět zapisovat. Dobré rozvržení (lekce 3.1):
anna@web1:~$ sudo chown -R anna:www-data /var/www/example.com
anna@web1:~$ sudo find /var/www/example.com -type d -exec chmod 750 {} \;
anna@web1:~$ sudo find /var/www/example.com -type f -exec chmod 640 {} \;Vy (anna) spravujete soubory, skupina www-data smí číst, ostatní nic. Pokud web musí někam zapisovat, například do adresáře pro nahrané soubory, dejte právo zápisu pro www-data jen tomuto adresáři. Nikdy chmod 777 (lekce 10.2). Pokud dostanete 403 Forbidden, podívejte se do chybového logu webu: najdete tam permission denied s cestou.
Několik dalších zvyků:
- Žádná tajemství ve webrootu. Zálohy (
site.zip), soubory.enva adresáře.gitdo něj nepatří; pokud se tam omylem přece jen ocitnou, dají se stáhnout. Další záchranná síť:location ~ /\. { deny all; }zablokuje všechny soubory začínající tečkou (kromě toho, co výslovně povolíte, například/.well-known/, viz lekce 7.3 a 7.4). - Skrýt verzi.
server_tokens off;vnginx.confodstraní číslo verze z hlavičkyServera z chybových stránek. Není to skutečné zabezpečení, ale skenery tak dostanou méně informací.
PHP ve zkratce
U webů v PHP (například WordPress) komunikuje nginx s PHP-FPM, samostatnou službou. Na Debianu nainstalujete php-fpm a do server blocku vložíte blok location ~ \.php$ s include snippets/fastcgi-php.conf; a fastcgi_pass unix:/run/php/php8.4-fpm.sock; (číslo verze se liší podle vydání). Podrobněji se tomu věnuje kurz o WordPressu.
Na AlmaLinux a Rocky Linux
Tam žádné sites-available není: každý web uložíte jako samostatný soubor do /etc/nginx/conf.d/<naam>.conf. nginx běží jako uživatel nginx místo www-data a výchozí webroot je /usr/share/nginx/html. SELinux ve výchozím stavu nedovolí nginx navázat spojení s aplikací za proxy_pass; povolíte to pomocí setsebool -P httpd_can_network_connect 1. Soubory mimo obvyklé adresáře potřebují štítek SELinux (semanage fcontext a restorecon).
Shrnutí
- nginx poskytuje soubory, nebo jako reverse proxy předává požadavky aplikaci na
127.0.0.1. - Jeden server block na web v
sites-available, zapnutí odkazem vsites-enabled; naslouchejte na80i[::]:80. - Vždy
nginx -tpředsystemctl reload nginx. - Vlastní default server s
return 444zabrání tomu, aby neznámé jméno nebo holá IP adresa zobrazily některý z Vašich webů. - Jako reverse proxy předáváte
Host,X-Forwarded-ForaX-Forwarded-Proto; webroot je prowww-datačitelný, ne zapisovatelný, a bez tajemství.
Kvíz
Úkol
Úkol O7.2: Váš první web. Nainstalujte nginx (nebo použijte Caddy z lekce 7.4) a vytvořte server block pro (sub)doménu, která směřuje na Váš server, s listen pro IPv4 i IPv6, vlastními logy a vlastním default serverem. Otestujte pomocí nginx -t, znovu načtěte a ověřte pomocí curl -I přes IPv4 i IPv6. Nastavte oprávnění webrootu jako v lekci. Vyplňte kontrolní seznam a vložte svůj server block.
Úkol O7.2: Váš první web
Tento úkol provádíte sami; nikdo ho nekontroluje. Odškrtněte, co jste udělali, a označte úkol jako splněný.
Na holé IP adrese nic (spojení uzavřeno) nebo neutrální stránka, nikdy web zákazníka. Zapisovatelná pro www-data je jen složka pro nahrávání, zbytek jen pro čtení. Za proxy: Host, X-Real-IP, X-Forwarded-For a X-Forwarded-Proto.
Vaše zaškrtnutí a poznámky zůstávají pouze v tomto prohlížeči; nikam je neposíláme. Pokud jste přihlášeni, ukládáme v sekci Moje kurzy pouze to, že jste úkol splnili.
Doporučujeme k přečtení
- Zakázáno (403): Nemáte oprávnění k přístupu k / na tomto serveru
- Dokumentace nginx, How nginx processes a request (server_name a default server): https://nginx.org/en/docs/http/request_processing.html
- Dokumentace nginx, Beginner's Guide: https://nginx.org/en/docs/beginners_guide.html
- Dokumentace nginx,
ngx_http_proxy_module: https://nginx.org/en/docs/http/ngx_http_proxy_module.html
