Modul 7 · 7.2
En webbserver med nginx
Modul 7: Domän, webbserver och https · Lästid: 12 minuter
Lärandemål: Efter den här lektionen kan du installera nginx, sätta upp en webbplats och en reverse proxy med ett server block, testa och ladda om en konfiguration på ett säkert sätt och ge din webbrot rätt rättigheter.
Nyckelbegrepp: nginx, server block, sites-available och 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, webbrot, PHP-FPM
Vad en webbserver gör
En webbserver lyssnar på port 80 (http) och 443 (https), tar emot förfrågningar från webbläsare och skickar något tillbaka: en fil från disken (en statisk webbplats) eller svaret från ett program som körs bakom den (PHP, en Node.js-app, en container). I det andra fallet kallas webbservern för en reverse proxy: den står längst fram, sköter https och skickar förfrågan vidare till applikationen, som bara lyssnar på 127.0.0.1.
På Linux är nginx och Apache de mest kända webbservrarna, och Caddy (lektion 7.4) är ett modernt alternativ som själv tar hand om certifikat. Den här lektionen använder nginx: den finns i alla distributioner, är snål med minne och är standard i många guider.
Installera och ta en första titt
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(Versionsnumret är ett exempel.) Glöm inte brandväggen: port 80 och 443 måste vara öppna (lektion 5.2). Går du nu till http://192.0.2.10 ser du välkomstsidan för nginx.
Konfigurationen finns i /etc/nginx/:
| Sökväg | Vad |
|---|---|
nginx.conf | huvudfil; den låter du oftast vara |
sites-available/ | en fil per webbplats (Debian och Ubuntu) |
sites-enabled/ | länkar (symlinks) till de webbplatser som är påslagna |
conf.d/*.conf | enskilda inställningar som alltid laddas |
snippets/ | bitar som du återanvänder i flera webbplatser |
sites-available och sites-enabled är en vana från Debian och Ubuntu: så slår du på eller av en webbplats genom att skapa eller ta bort en länk, utan att radera filen.
En första webbplats
Skapa en mapp för webbplatsen och en testsida:
anna@web1:~$ sudo mkdir -p /var/www/example.com
anna@web1:~$ echo '<h1>Het werkt</h1>' | sudo tee /var/www/example.com/index.htmlSkapa sedan ett server block: beskrivningen av en webbplats.
# /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;
}Läs det så här:
listen 80;ochlisten [::]:80;får nginx att lyssna på både IPv4 och IPv6. Glömmer du den andra raden fungerar inte ditt AAAA-record (lektion 7.1).server_nameanger vilka namn blocket gäller för. Vid varje förfrågan tittar nginx på namnet som webbläsaren frågar efter (Host-headern) och väljer det block som passar.rootär mappen med filer,indexfilen som visas när någon begär en mapp.try_filesprovar den begärda filen, sedan en mapp, och ger annars en 404. Utan en sådan rad kan en felaktig konfiguration visa mer än du vill.- Egna loggfiler per webbplats gör det mycket enklare att söka (lektion 6.2).
Slå på webbplatsen, ta bort standardwebbplatsen, testa och ladda om:
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 OKGör nginx -t till en fast vana före varje reload. Vid ett fel får du veta vilken fil och vilken rad det gäller, och din webbplats som redan körs påverkas inte. Startar du om utan att testa startar nginx inte alls om det finns ett fel, och då ligger alla dina webbplatser nere (lektion 6.1).
Default server: vad får ett okänt namn?
Vad händer om någon anropar din server med ett namn som inte står i något server_name, eller bara med IP-adressen? Då väljer nginx default server: blocket med default_server efter listen, eller annars det första blocket den hittade. Utan eftertanke blir det alltså en av dina riktiga webbplatser.
Snyggare är ett separat block som avvisar sådana förfrågningar:
# /etc/nginx/sites-available/000-default
server {
listen 80 default_server;
listen [::]:80 default_server;
server_name _;
return 444;
}444 är en särskild kod i nginx: anslutningen stängs utan svar. Skannrar som går igenom IP-adresser får då inget att se. För https (port 443) fungerar en default server lite annorlunda, eftersom den behöver ett certifikat; det återkommer vi till i lektion 7.3.
nginx som reverse proxy
Kör du en applikation på 127.0.0.1:3000 (lektion 6.3) eller en container på 127.0.0.1:3001 (lektion 9.3), så gör nginx den nåbar utifrån:
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;
}
}De fyra proxy_set_header-raderna är viktiga. Utan Host vet applikationen inte under vilket namn den besöks. Utan X-Forwarded-For ser applikationen varje besök komma från 127.0.0.1 (proxyn) i stället för besökarens riktiga adress. Utan X-Forwarded-Proto tror applikationen att allt går via http och skapar ibland länkar eller cookies för http, fast din webbplats körs via https. Många applikationer har en inställning för att lita på dessa headers ("trusted proxy"); ange bara 127.0.0.1 där, annars kan vilken besökare som helst skicka med en falsk adress.
Applikationer som använder websockets (liveuppdateringar, som Uptime Kuma) behöver två rader till: proxy_http_version 1.1; och att Upgrade och Connection skickas vidare. Applikationens dokumentation säger oftast exakt vilka.
Rättigheter för webbroten
På Debian och Ubuntu kör nginx sina arbetsprocesser som användaren www-data. Den måste kunna läsa dina filer, men ska inte kunna skriva till dem. En bra uppdelning (lektion 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 {} \;Du (anna) hanterar filerna, gruppen www-data får läsa, alla andra ingenting. Behöver webbplatsen skriva någonstans, till exempel i en mapp för uppladdningar, ge då bara den mappen skrivrättigheter för www-data. Aldrig chmod 777 (lektion 10.2). Får du 403 Forbidden, titta i webbplatsens fellogg: där står permission denied med sökvägen.
Några andra goda vanor:
- Inga hemligheter i webbroten. Säkerhetskopior (
site.zip),.env-filer och.git-mappar hör inte hemma där; hamnar de där av misstag kan vem som helst hämta dem. Ett extra skyddsnät:location ~ /\. { deny all; }blockerar alla filer som börjar med en punkt (utom det du uttryckligen tillåter, som/.well-known/, se lektion 7.3 och 7.4). - Dölj versionen.
server_tokens off;inginx.conftar bort versionsnumret frånServer-headern och felsidorna. Det är inget riktigt skydd, men det ger skannrar mindre information.
PHP i korthet
För PHP-webbplatser (som WordPress) pratar nginx med PHP-FPM, en separat tjänst. På Debian installerar du php-fpm och lägger i ditt server block till ett location ~ \.php$-block med include snippets/fastcgi-php.conf; och fastcgi_pass unix:/run/php/php8.4-fpm.sock; (versionsnumret skiljer sig mellan utgåvor). WordPress-kursen går djupare in på det.
På AlmaLinux och Rocky Linux
Där finns ingen sites-available: du lägger varje webbplats som en egen fil i /etc/nginx/conf.d/<naam>.conf. nginx körs som användaren nginx i stället för www-data, och standardwebbroten är /usr/share/nginx/html. SELinux låter som standard inte nginx ansluta till en applikation bakom proxy_pass; slå på det med setsebool -P httpd_can_network_connect 1. Filer utanför de vanliga mapparna behöver en SELinux-etikett (semanage fcontext och restorecon).
Sammanfattning
- nginx serverar filer eller skickar som reverse proxy vidare förfrågningar till en applikation på
127.0.0.1. - Ett server block per webbplats i
sites-available, slå på det med en länk isites-enabled; lyssna på både80och[::]:80. - Alltid
nginx -tföresystemctl reload nginx. - En egen default server med
return 444förhindrar att ett okänt namn eller den nakna IP-adressen visar en av dina webbplatser. - Som reverse proxy skickar du vidare
Host,X-Forwarded-ForochX-Forwarded-Proto; webbroten är läsbar förwww-data, inte skrivbar, och fri från hemligheter.
Quiz
Uppgift
Uppgift O7.2: Din första webbplats. Installera nginx (eller använd Caddy från lektion 7.4) och skapa ett server block för en (sub)domän som pekar på din server, med listen för IPv4 och IPv6, egna loggfiler och en egen default server. Testa med nginx -t, ladda om och kontrollera med curl -I via IPv4 och IPv6. Ställ in rättigheterna för webbroten som i lektionen. Fyll i checklistan och klistra in ditt server block.
Uppgift O7.2: Din första webbplats
Den här uppgiften gör du själv; ingen kontrollerar den. Bocka av vad du har gjort och markera uppgiften som klar.
På den nakna IP-adressen ingenting (anslutningen stängs) eller en neutral sida, aldrig en kunds webbplats. Bara en uppladdningsmapp skrivbar för www-data, resten skrivskyddat. Bakom en proxy: Host, X-Real-IP, X-Forwarded-For och X-Forwarded-Proto.
Dina bockar och anteckningar sparas bara i den här webbläsaren; vi skickar dem ingenstans. Är du inloggad sparar vi i Mina kurser bara att du har gjort uppgiften.
Läs mer
- Förbjudet (403): Du har inte behörighet att komma åt / på den här servern
- nginx-dokumentationen, How nginx processes a request (server_name och default server): https://nginx.org/en/docs/http/request_processing.html
- nginx-dokumentationen, Beginner's Guide: https://nginx.org/en/docs/beginners_guide.html
- nginx-dokumentationen,
ngx_http_proxy_module: https://nginx.org/en/docs/http/ngx_http_proxy_module.html
