Direct naar de inhoud

Cookie-instellingen

Kies per soort welke cookies je toestaat. Je kunt je keuze altijd wijzigen via Cookie-instellingen onderaan elke pagina. Privacyverklaring

Noodzakelijk

Altijd aan

Nodig om in te loggen, je winkelwagen te bewaren en je keuzes te onthouden. Deze staan altijd aan.

Welke cookies?
  • weboke_sessie, weboke_klant, weboke_remember: je sessie en ingelogd blijven
  • weboke_basket: je winkelwagen
  • wkBtwIncl: prijzen met of zonder btw tonen
  • wok_cookies: je cookiekeuze, 12 maanden

Meet welke advertentie tot een bezoek of bestelling leidt, zodat we niet betalen voor advertenties die niets doen.

Welke cookies?
  • Google Ads via Google Tag Manager (_gcl_au, _gcl_aw), tot 90 dagen
  • OpenAI Ads, advertenties in ChatGPT
  • wok_aff: via welke partner je bij ons kwam (affiliateprogramma), 60 dagen

4,6

Land en taal

Elk land heeft zijn eigen site, met prijzen en btw van dat land.

Bekijken

Module 7 · 7.2

Een webserver met nginx

Module 7: Domein, webserver en https · Leestijd: 12 minuten

Leerdoel: Na deze les kun je nginx installeren, een website en een reverse proxy inrichten met een server block, een configuratie veilig testen en herladen, en de rechten van je webroot goed zetten.

Kernbegrippen: nginx, server block, sites-available en 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

Wat een webserver doet

Een webserver luistert op poort 80 (http) en 443 (https), neemt verzoeken van browsers aan en stuurt iets terug: een bestand van schijf (een statische site), of het antwoord van een programma dat erachter draait (PHP, een Node.js-app, een container). In dat tweede geval heet de webserver een reverse proxy: hij staat vooraan, regelt https, en geeft het verzoek door aan de applicatie die alleen op 127.0.0.1 luistert.

Op Linux zijn nginx en Apache de bekendste webservers, en Caddy (les 7.4) is een modern alternatief dat certificaten zelf regelt. Deze les gebruikt nginx: hij zit in elke distributie, is zuinig met geheugen en is de standaard in veel handleidingen.

Installeren en de eerste blik

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

(Het versienummer is een voorbeeld.) Vergeet de firewall niet: poort 80 en 443 moeten open (les 5.2). Ga je nu naar http://192.0.2.10, dan zie je de welkomstpagina van nginx.

De configuratie staat in /etc/nginx/:

PadWat
nginx.confhoofdbestand; laat je meestal met rust
sites-available/één bestand per site (Debian en Ubuntu)
sites-enabled/koppelingen (symlinks) naar de sites die aan staan
conf.d/*.conflosse instellingen die altijd geladen worden
snippets/stukjes die je in meer sites hergebruikt

sites-available en sites-enabled zijn een gewoonte van Debian en Ubuntu: zo zet je een site aan of uit door een koppeling te maken of weg te halen, zonder het bestand te verwijderen.

Een eerste site

Maak een map voor de site en een testpagina:

anna@web1:~$ sudo mkdir -p /var/www/example.com
anna@web1:~$ echo '<h1>Het werkt</h1>' | sudo tee /var/www/example.com/index.html

Maak dan een server block: de beschrijving van één 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;
}

Lees het zo:

  • listen 80; en listen [::]:80; laten nginx luisteren op IPv4 én IPv6. Vergeet je de tweede regel, dan werkt je AAAA-record niet (les 7.1).
  • server_name zegt voor welke namen dit blok geldt. nginx kijkt bij elk verzoek naar de naam die de browser vraagt (de Host-kop) en kiest het blok dat past.
  • root is de map met bestanden, index het bestand dat getoond wordt bij een map.
  • try_files probeert het gevraagde bestand, dan een map, en geeft anders een 404. Zonder zo'n regel kan een verkeerde configuratie meer tonen dan je wilt.
  • Eigen logbestanden per site maken zoeken veel makkelijker (les 6.2).

Zet de site aan, haal de standaardsite weg, test en herlaad:

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 OK

Maak van nginx -t vóór elke reload een vaste gewoonte. Bij een fout vertelt het je welk bestand en welke regel, en je draaiende site blijft ongemoeid. Herstart je zonder te testen, dan start nginx met een fout niet meer en liggen al je sites plat (les 6.1).

De default server: wat krijgt een onbekende naam?

Wat gebeurt er als iemand je server opvraagt met een naam die in geen enkel server_name staat, of gewoon met het IP-adres? Dan kiest nginx de default server: het blok met default_server achter listen, of anders het eerste blok dat het tegenkwam. Zonder nadenken is dat dus een van je echte sites.

Netter is een apart blok dat zulke verzoeken afwijst:

# /etc/nginx/sites-available/000-default
server {
    listen 80 default_server;
    listen [::]:80 default_server;
    server_name _;
    return 444;
}

444 is een bijzondere code van nginx: de verbinding wordt gesloten zonder antwoord. Scanners die IP-adressen aflopen, krijgen zo niets te zien. Voor https (poort 443) werkt een default server iets anders, omdat er een certificaat bij hoort; daar kom je in les 7.3 op terug.

nginx als reverse proxy

Draait er een applicatie op 127.0.0.1:3000 (les 6.3) of een container op 127.0.0.1:3001 (les 9.3), dan zet nginx die naar buiten:

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 vier proxy_set_header-regels zijn belangrijk. Zonder Host weet de applicatie niet onder welke naam hij bezocht wordt. Zonder X-Forwarded-For ziet de applicatie elk bezoek komen van 127.0.0.1 (de proxy) in plaats van het echte adres van de bezoeker. Zonder X-Forwarded-Proto denkt de applicatie dat alles via http gaat, en maakt hij soms links of cookies voor http, terwijl je site via https draait. Veel applicaties hebben een instelling om deze kopregels te vertrouwen ("trusted proxy"); zet daar alleen 127.0.0.1 in, anders kan elke bezoeker een vals adres meesturen.

Applicaties die websockets gebruiken (live-updates, zoals Uptime Kuma) hebben nog twee regels nodig: proxy_http_version 1.1; en het doorgeven van Upgrade en Connection. De documentatie van de applicatie zegt meestal precies welke.

Rechten van de webroot

nginx draait zijn werkprocessen op Debian en Ubuntu als de gebruiker www-data. Die moet je bestanden kunnen lezen, maar hoort ze niet te kunnen schrijven. Een goede indeling (les 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 {} \;

Jij (anna) beheert de bestanden, de groep www-data mag lezen, de rest niets. Moet de site ergens schrijven, zoals een map voor uploads, geef dan alleen die map schrijfrechten voor www-data. Nooit chmod 777 (les 10.2). Krijg je een 403 Forbidden, kijk dan in het foutlogboek van de site: daar staat permission denied met het pad.

Een paar andere gewoonten:

  • Geen geheimen in de webroot. Back-ups (site.zip), .env-bestanden en .git-mappen horen er niet in; worden ze toch per ongeluk neergezet, dan zijn ze op te vragen. Een extra vangnet: location ~ /\. { deny all; } blokkeert alle bestanden die met een punt beginnen (behalve wat je expliciet toestaat, zoals /.well-known/, zie les 7.3 en 7.4).
  • Versie verbergen. server_tokens off; in nginx.conf haalt het versienummer uit de Server-kop en foutpagina's. Dat is geen echte beveiliging, maar het geeft scanners minder informatie.

PHP, kort

Voor PHP-sites (zoals WordPress) praat nginx met PHP-FPM, een aparte dienst. Op Debian installeer je php-fpm en zet je in het server block een location ~ \.php$-blok met include snippets/fastcgi-php.conf; en fastcgi_pass unix:/run/php/php8.4-fpm.sock; (het versienummer verschilt per release). De WordPress-cursus gaat daar verder op in.

Op AlmaLinux en Rocky Linux

Daar is er geen sites-available: je zet elke site als eigen bestand in /etc/nginx/conf.d/<naam>.conf. nginx draait als de gebruiker nginx in plaats van www-data, en de standaard webroot is /usr/share/nginx/html. SELinux laat nginx standaard geen verbinding maken met een applicatie achter proxy_pass; zet dat aan met setsebool -P httpd_can_network_connect 1. Bestanden buiten de gebruikelijke mappen hebben een SELinux-label nodig (semanage fcontext en restorecon).

Samenvatting

  • nginx serveert bestanden of geeft verzoeken als reverse proxy door aan een applicatie op 127.0.0.1.
  • Een server block per site in sites-available, aanzetten met een koppeling in sites-enabled; luister op 80 én [::]:80.
  • Altijd nginx -t vóór systemctl reload nginx.
  • Een eigen default server met return 444 voorkomt dat een onbekende naam of het kale IP-adres een van je sites toont.
  • Als reverse proxy geef je Host, X-Forwarded-For en X-Forwarded-Proto door; de webroot is leesbaar voor www-data, niet schrijfbaar, en zonder geheimen.

Quiz

1. Je hebt een server block aangepast. Wat is de veilige volgorde?



2. Je site werkt via IPv4, maar niet via IPv6, terwijl het AAAA-record klopt en de firewall IPv6 toelaat. Wat ontbreekt waarschijnlijk in het server block?



3. Iemand opent http://192.0.2.10 (het kale IP-adres) en ziet de website van een klant van je. Hoe voorkom je dat?



4. Je applicatie achter proxy_pass ziet bij elk bezoek het adres 127.0.0.1. Wat ontbreekt?



5. Welke rechten passen bij de bestanden van een statische website in /var/www/example.com?



Opdracht

Opdracht O7.2: Je eerste site. Installeer nginx (of gebruik Caddy uit les 7.4), maak een server block voor een (sub)domein dat naar je server wijst, met listen voor IPv4 en IPv6, eigen logbestanden en een eigen default server. Test met nginx -t, herlaad, en controleer met curl -I via IPv4 en IPv6. Zet de rechten van de webroot zoals in de les. Vul de checklist in en plak je server block.

Opdracht O7.2: Je eerste site

Deze opdracht doe je zelf; niemand kijkt hem na. Vink af wat je gedaan hebt en markeer de opdracht als gedaan.




Je vinkjes en aantekeningen blijven alleen in deze browser; we sturen ze nergens heen. Ben je aangemeld, dan bewaren we in Mijn cursussen alleen dat je de opdracht gedaan hebt.

Verder lezen

Even geduld…

Stel je domeinen in

Regel per domein de nameservers, de koppeling aan je hosting en wie de eigenaar wordt.

Je domeinen laden…