Modulul 7 · 7.2
Un server web cu nginx
Modulul 7: Domeniu, server web și https · Timp de citire: 12 minute
Obiectivul lecției: După această lecție veți putea instala nginx, configura un site web și un reverse proxy cu un server block, testa și reîncărca în siguranță o configurație și seta corect permisiunile directorului webroot.
Noțiuni cheie: nginx, server block, sites-available și 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
Ce face un server web
Un server web ascultă pe portul 80 (http) și 443 (https), primește cereri de la browsere și trimite ceva înapoi: un fișier de pe disc (un site static) sau răspunsul unui program care rulează în spatele lui (PHP, o aplicație Node.js, un container). În al doilea caz, serverul web se numește reverse proxy: el stă în față, se ocupă de https și transmite cererea mai departe aplicației, care ascultă doar pe 127.0.0.1.
Pe Linux, nginx și Apache sunt cele mai cunoscute servere web, iar Caddy (lecția 7.4) este o alternativă modernă care se ocupă singură de certificate. Această lecție folosește nginx: este inclus în fiecare distribuție, consumă puțină memorie și este standardul în multe ghiduri.
Instalarea și prima privire
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(Numărul versiunii este un exemplu.) Nu uitați de firewall: porturile 80 și 443 trebuie să fie deschise (lecția 5.2). Dacă accesați acum http://192.0.2.10, veți vedea pagina de bun venit a nginx.
Configurația se află în /etc/nginx/:
| Cale | Ce conține |
|---|---|
nginx.conf | fișierul principal; de obicei nu îl modificați |
sites-available/ | câte un fișier pentru fiecare site (Debian și Ubuntu) |
sites-enabled/ | legături (symlinks) către site-urile activate |
conf.d/*.conf | setări separate care sunt încărcate întotdeauna |
snippets/ | fragmente pe care le reutilizați în mai multe site-uri |
sites-available și sites-enabled sunt un obicei al Debian și Ubuntu: astfel activați sau dezactivați un site creând sau ștergând o legătură, fără a șterge fișierul.
Un prim site
Creați un director pentru site și o pagină de test:
anna@web1:~$ sudo mkdir -p /var/www/example.com
anna@web1:~$ echo '<h1>Het werkt</h1>' | sudo tee /var/www/example.com/index.htmlApoi creați un server block: descrierea unui singur site.
# /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;
}Citiți-l astfel:
listen 80;șilisten [::]:80;fac ca nginx să asculte pe IPv4 și pe IPv6. Dacă uitați a doua linie, înregistrarea dvs. AAAA nu va funcționa (lecția 7.1).server_nameindică pentru ce nume este valabil acest bloc. La fiecare cerere, nginx se uită la numele cerut de browser (antetul Host) și alege blocul potrivit.rooteste directorul cu fișiere, iarindexeste fișierul afișat atunci când se cere un director.try_filesîncearcă fișierul cerut, apoi un director, iar altfel returnează un 404. Fără o astfel de linie, o configurație greșită poate afișa mai mult decât doriți.- Fișierele de jurnal proprii pentru fiecare site fac căutarea mult mai ușoară (lecția 6.2).
Activați site-ul, eliminați site-ul implicit, testați și reîncărcați:
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 OKTransformați nginx -t într-un obicei fix înainte de fiecare reload. În caz de eroare, vă spune ce fișier și ce linie sunt de vină, iar site-ul care rulează rămâne neatins. Dacă reporniți fără să testați, nginx nu mai pornește din cauza erorii și toate site-urile dvs. cad (lecția 6.1).
Default server: ce primește un nume necunoscut?
Ce se întâmplă dacă cineva accesează serverul dvs. cu un nume care nu apare în niciun server_name sau pur și simplu cu adresa IP? Atunci nginx alege default server: blocul cu default_server după listen sau, în lipsa acestuia, primul bloc pe care l-a întâlnit. Dacă nu vă gândiți la asta, acesta este deci unul dintre site-urile dvs. reale.
Mai curat este un bloc separat care respinge astfel de cereri:
# /etc/nginx/sites-available/000-default
server {
listen 80 default_server;
listen [::]:80 default_server;
server_name _;
return 444;
}444 este un cod special al nginx: conexiunea este închisă fără răspuns. Scannerele care parcurg adrese IP nu văd astfel nimic. Pentru https (portul 443), un default server funcționează puțin diferit, deoarece necesită un certificat; revenim la acest subiect în lecția 7.3.
nginx ca reverse proxy
Dacă rulează o aplicație pe 127.0.0.1:3000 (lecția 6.3) sau un container pe 127.0.0.1:3001 (lecția 9.3), nginx o face accesibilă din exterior:
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;
}
}Cele patru linii proxy_set_header sunt importante. Fără Host, aplicația nu știe sub ce nume este accesată. Fără X-Forwarded-For, aplicația vede fiecare vizită ca venind de la 127.0.0.1 (proxy-ul), în loc de adresa reală a vizitatorului. Fără X-Forwarded-Proto, aplicația crede că totul trece prin http și uneori generează linkuri sau cookie-uri pentru http, deși site-ul dvs. rulează prin https. Multe aplicații au o setare pentru a avea încredere în aceste antete („trusted proxy”); introduceți acolo doar 127.0.0.1, altfel orice vizitator poate trimite o adresă falsă.
Aplicațiile care folosesc websockets (actualizări în timp real, cum ar fi Uptime Kuma) au nevoie de încă două linii: proxy_http_version 1.1; și transmiterea antetelor Upgrade și Connection. Documentația aplicației indică de obicei exact care sunt acestea.
Permisiunile directorului webroot
Pe Debian și Ubuntu, nginx rulează procesele de lucru ca utilizatorul www-data. Acesta trebuie să vă poată citi fișierele, dar nu trebuie să le poată scrie. O împărțire bună (lecția 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 {} \;Dumneavoastră (anna) administrați fișierele, grupul www-data poate citi, restul nimic. Dacă site-ul trebuie să scrie undeva, de exemplu într-un director pentru încărcări, acordați drepturi de scriere pentru www-data doar acelui director. Niciodată chmod 777 (lecția 10.2). Dacă primiți un 403 Forbidden, verificați jurnalul de erori al site-ului: acolo apare permission denied împreună cu calea.
Alte câteva obiceiuri:
- Fără secrete în webroot. Backupurile (
site.zip), fișierele.envși directoarele.gitnu au ce căuta acolo; dacă ajung totuși acolo din greșeală, pot fi descărcate. O plasă de siguranță suplimentară:location ~ /\. { deny all; }blochează toate fișierele care încep cu un punct (cu excepția celor pe care le permiteți explicit, cum ar fi/.well-known/, vedeți lecțiile 7.3 și 7.4). - Ascunderea versiunii.
server_tokens off;înnginx.confelimină numărul versiunii din antetulServerși din paginile de eroare. Nu este o protecție reală, dar oferă scannerelor mai puține informații.
PHP, pe scurt
Pentru site-urile PHP (cum ar fi WordPress), nginx comunică cu PHP-FPM, un serviciu separat. Pe Debian instalați php-fpm și adăugați în server block un bloc location ~ \.php$ cu include snippets/fastcgi-php.conf; și fastcgi_pass unix:/run/php/php8.4-fpm.sock; (numărul versiunii diferă de la o versiune a distribuției la alta). Cursul WordPress intră în mai multe detalii.
Pe AlmaLinux și Rocky Linux
Acolo nu există sites-available: puneți fiecare site ca fișier separat în /etc/nginx/conf.d/<naam>.conf. nginx rulează ca utilizatorul nginx în loc de www-data, iar webroot-ul implicit este /usr/share/nginx/html. În mod implicit, SELinux nu permite nginx să se conecteze la o aplicație din spatele proxy_pass; activați acest lucru cu setsebool -P httpd_can_network_connect 1. Fișierele aflate în afara directoarelor obișnuite au nevoie de o etichetă SELinux (semanage fcontext și restorecon).
Rezumat
- nginx servește fișiere sau, ca reverse proxy, transmite cererile unei aplicații pe
127.0.0.1. - Câte un server block pentru fiecare site în
sites-available, activat printr-o legătură însites-enabled; ascultați pe80și pe[::]:80. - Întotdeauna
nginx -tînainte desystemctl reload nginx. - Un default server propriu cu
return 444împiedică afișarea unuia dintre site-urile dvs. pentru un nume necunoscut sau pentru adresa IP simplă. - Ca reverse proxy transmiteți
Host,X-Forwarded-ForșiX-Forwarded-Proto; webroot-ul poate fi citit dewww-data, nu poate fi scris de acesta și nu conține secrete.
Test (quiz)
Exercițiu
Exercițiul O7.2: Primul dumneavoastră site. Instalați nginx (sau folosiți Caddy din lecția 7.4), creați un server block pentru un (sub)domeniu care indică spre serverul dvs., cu listen pentru IPv4 și IPv6, fișiere de jurnal proprii și un default server propriu. Testați cu nginx -t, reîncărcați și verificați cu curl -I prin IPv4 și IPv6. Setați permisiunile webroot-ului ca în lecție. Completați lista de verificare și lipiți server block-ul dvs.
Exercițiul O7.2: Primul dumneavoastră site
Acest exercițiu îl faceți singur; nimeni nu îl verifică. Bifați ce ați făcut și marcați exercițiul ca finalizat.
Pe IP-ul simplu nimic (conexiune închisă) sau o pagină neutră, niciodată site-ul unui client. Doar un director de încărcare cu drept de scriere pentru www-data, restul doar în citire. În spatele unui proxy: Host, X-Real-IP, X-Forwarded-For și X-Forwarded-Proto.
Bifele și notițele dumneavoastră rămân doar în acest browser; nu le trimitem nicăieri. Dacă sunteți autentificat, păstrăm în Cursurile mele doar faptul că ați finalizat exercițiul.
Lecturi suplimentare
- Interzis (403): Nu aveți permisiunea de a accesa / pe acest server
- Documentația nginx, How nginx processes a request (server_name și default server): https://nginx.org/en/docs/http/request_processing.html
- Documentația nginx, Beginner's Guide: https://nginx.org/en/docs/beginners_guide.html
- Documentația nginx,
ngx_http_proxy_module: https://nginx.org/en/docs/http/ngx_http_proxy_module.html
