Ενότητα 7 · 7.2
Ένας web server με nginx
Ενότητα 7: Domain, web server και https · Χρόνος ανάγνωσης: 12 λεπτά
Στόχος μαθήματος: Μετά από αυτό το μάθημα μπορείτε να εγκαταστήσετε το nginx, να ρυθμίσετε έναν ιστότοπο και ένα reverse proxy με ένα server block, να ελέγξετε και να επαναφορτώσετε μια διαμόρφωση με ασφάλεια και να ορίσετε σωστά τα δικαιώματα του webroot σας.
Βασικές έννοιες: nginx, server block, sites-available και 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
Τι κάνει ένας web server
Ένας web server ακούει στη θύρα 80 (http) και 443 (https), δέχεται αιτήματα από browsers και στέλνει κάτι πίσω: ένα αρχείο από τον δίσκο (έναν στατικό ιστότοπο) ή την απάντηση ενός προγράμματος που εκτελείται πίσω του (PHP, μια εφαρμογή Node.js, ένα container). Στη δεύτερη περίπτωση ο web server ονομάζεται reverse proxy: βρίσκεται μπροστά, χειρίζεται το https και προωθεί το αίτημα στην εφαρμογή που ακούει μόνο στο 127.0.0.1.
Στο Linux οι πιο γνωστοί web servers είναι το nginx και ο Apache, ενώ το Caddy (μάθημα 7.4) είναι μια σύγχρονη εναλλακτική που διαχειρίζεται μόνη της τα πιστοποιητικά. Σε αυτό το μάθημα χρησιμοποιούμε το nginx: υπάρχει σε κάθε διανομή, καταναλώνει λίγη μνήμη και αποτελεί το πρότυπο σε πολλούς οδηγούς.
Εγκατάσταση και πρώτη ματιά
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(Ο αριθμός έκδοσης είναι παράδειγμα.) Μην ξεχάσετε το firewall: οι θύρες 80 και 443 πρέπει να είναι ανοιχτές (μάθημα 5.2). Αν τώρα μεταβείτε στο http://192.0.2.10, θα δείτε τη σελίδα καλωσορίσματος του nginx.
Η διαμόρφωση βρίσκεται στο /etc/nginx/:
| Διαδρομή | Τι περιέχει |
|---|---|
nginx.conf | κύριο αρχείο· συνήθως δεν το αγγίζετε |
sites-available/ | ένα αρχείο ανά ιστότοπο (Debian και Ubuntu) |
sites-enabled/ | συνδέσμους (symlinks) προς τους ιστότοπους που είναι ενεργοί |
conf.d/*.conf | μεμονωμένες ρυθμίσεις που φορτώνονται πάντα |
snippets/ | τμήματα που επαναχρησιμοποιείτε σε περισσότερους ιστότοπους |
Τα sites-available και sites-enabled είναι συνήθεια των Debian και Ubuntu: έτσι ενεργοποιείτε ή απενεργοποιείτε έναν ιστότοπο δημιουργώντας ή αφαιρώντας έναν σύνδεσμο, χωρίς να διαγράψετε το αρχείο.
Ένας πρώτος ιστότοπος
Δημιουργήστε έναν φάκελο για τον ιστότοπο και μια δοκιμαστική σελίδα:
anna@web1:~$ sudo mkdir -p /var/www/example.com
anna@web1:~$ echo '<h1>Het werkt</h1>' | sudo tee /var/www/example.com/index.htmlΣτη συνέχεια δημιουργήστε ένα server block: την περιγραφή ενός ιστότοπου.
# /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;
}Διαβάστε το ως εξής:
- Τα
listen 80;καιlisten [::]:80;κάνουν το nginx να ακούει σε IPv4 και σε IPv6. Αν ξεχάσετε τη δεύτερη γραμμή, το AAAA record σας δεν θα λειτουργεί (μάθημα 7.1). - Το
server_nameορίζει για ποια ονόματα ισχύει αυτό το block. Σε κάθε αίτημα το nginx κοιτάζει το όνομα που ζητά ο browser (την κεφαλίδα Host) και επιλέγει το block που ταιριάζει. - Το
rootείναι ο φάκελος με τα αρχεία και τοindexτο αρχείο που εμφανίζεται όταν ζητείται ένας φάκελος. - Το
try_filesδοκιμάζει το ζητούμενο αρχείο, μετά έναν φάκελο, και διαφορετικά επιστρέφει 404. Χωρίς μια τέτοια γραμμή, μια λανθασμένη διαμόρφωση μπορεί να εμφανίσει περισσότερα από όσα θέλετε. - Ξεχωριστά αρχεία καταγραφής ανά ιστότοπο κάνουν την αναζήτηση πολύ ευκολότερη (μάθημα 6.2).
Ενεργοποιήστε τον ιστότοπο, αφαιρέστε τον προεπιλεγμένο ιστότοπο, κάντε έλεγχο και επαναφόρτωση:
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Κάντε το nginx -t σταθερή συνήθεια πριν από κάθε reload. Σε περίπτωση σφάλματος σας λέει ποιο αρχείο και ποια γραμμή, ενώ ο ιστότοπος που εκτελείται μένει ανέγγιχτος. Αν κάνετε επανεκκίνηση χωρίς έλεγχο, το nginx με σφάλμα δεν ξεκινά πια και όλοι οι ιστότοποί σας πέφτουν (μάθημα 6.1).
Ο default server: τι παίρνει ένα άγνωστο όνομα;
Τι συμβαίνει αν κάποιος ζητήσει τον server σας με ένα όνομα που δεν υπάρχει σε κανένα server_name, ή απλώς με τη διεύθυνση IP; Τότε το nginx επιλέγει τον default server: το block με default_server μετά το listen, ή διαφορετικά το πρώτο block που συνάντησε. Αν δεν το σκεφτείτε, αυτό είναι λοιπόν ένας από τους πραγματικούς ιστότοπούς σας.
Πιο σωστό είναι ένα ξεχωριστό block που απορρίπτει τέτοια αιτήματα:
# /etc/nginx/sites-available/000-default
server {
listen 80 default_server;
listen [::]:80 default_server;
server_name _;
return 444;
}Το 444 είναι ένας ειδικός κωδικός του nginx: η σύνδεση κλείνει χωρίς απάντηση. Έτσι τα εργαλεία σάρωσης που περνούν από διευθύνσεις IP δεν βλέπουν τίποτα. Για το https (θύρα 443) ένας default server λειτουργεί λίγο διαφορετικά, επειδή απαιτεί πιστοποιητικό· θα επανέλθουμε σε αυτό στο μάθημα 7.3.
Το nginx ως reverse proxy
Αν εκτελείται μια εφαρμογή στο 127.0.0.1:3000 (μάθημα 6.3) ή ένα container στο 127.0.0.1:3001 (μάθημα 9.3), το nginx την εκθέτει προς τα έξω:
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;
}
}Οι τέσσερις γραμμές proxy_set_header είναι σημαντικές. Χωρίς το Host η εφαρμογή δεν γνωρίζει με ποιο όνομα την επισκέπτονται. Χωρίς το X-Forwarded-For η εφαρμογή βλέπει κάθε επίσκεψη να προέρχεται από το 127.0.0.1 (το proxy) αντί για την πραγματική διεύθυνση του επισκέπτη. Χωρίς το X-Forwarded-Proto η εφαρμογή νομίζει ότι όλα περνούν μέσω http και μερικές φορές δημιουργεί συνδέσμους ή cookies για http, ενώ ο ιστότοπός σας λειτουργεί μέσω https. Πολλές εφαρμογές έχουν μια ρύθμιση για να εμπιστεύονται αυτές τις κεφαλίδες ("trusted proxy")· βάλτε εκεί μόνο το 127.0.0.1, αλλιώς κάθε επισκέπτης μπορεί να στείλει μια ψεύτικη διεύθυνση.
Οι εφαρμογές που χρησιμοποιούν websockets (ενημερώσεις σε πραγματικό χρόνο, όπως το Uptime Kuma) χρειάζονται άλλες δύο γραμμές: proxy_http_version 1.1; και την προώθηση των Upgrade και Connection. Η τεκμηρίωση της εφαρμογής αναφέρει συνήθως ακριβώς ποιες.
Δικαιώματα του webroot
Στα Debian και Ubuntu το nginx εκτελεί τις διεργασίες εργασίας του ως χρήστης www-data. Αυτός πρέπει να μπορεί να διαβάζει τα αρχεία σας, αλλά δεν πρέπει να μπορεί να τα γράφει. Μια καλή διάταξη (μάθημα 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 {} \;Εσείς (anna) διαχειρίζεστε τα αρχεία, η ομάδα www-data μπορεί να διαβάζει, οι υπόλοιποι τίποτα. Αν ο ιστότοπος πρέπει να γράφει κάπου, όπως σε έναν φάκελο για uploads, δώστε δικαιώματα εγγραφής για τον www-data μόνο σε αυτόν τον φάκελο. Ποτέ chmod 777 (μάθημα 10.2). Αν λάβετε 403 Forbidden, κοιτάξτε στο αρχείο καταγραφής σφαλμάτων του ιστότοπου: εκεί εμφανίζεται το permission denied με τη διαδρομή.
Μερικές ακόμη καλές συνήθειες:
- Κανένα μυστικό στο webroot. Αντίγραφα ασφαλείας (
site.zip), αρχεία.envκαι φάκελοι.gitδεν ανήκουν εκεί· αν τοποθετηθούν κατά λάθος, μπορεί κανείς να τα ζητήσει. Ένα επιπλέον δίχτυ ασφαλείας: τοlocation ~ /\. { deny all; }μπλοκάρει όλα τα αρχεία που αρχίζουν με τελεία (εκτός από όσα επιτρέπετε ρητά, όπως το/.well-known/, δείτε τα μαθήματα 7.3 και 7.4). - Απόκρυψη έκδοσης. Το
server_tokens off;στοnginx.confαφαιρεί τον αριθμό έκδοσης από την κεφαλίδαServerκαι τις σελίδες σφαλμάτων. Δεν είναι πραγματική προστασία, αλλά δίνει λιγότερες πληροφορίες στα εργαλεία σάρωσης.
PHP, σύντομα
Για ιστότοπους PHP (όπως το WordPress) το nginx επικοινωνεί με το PHP-FPM, μια ξεχωριστή υπηρεσία. Στο Debian εγκαθιστάτε το php-fpm και βάζετε στο server block ένα block location ~ \.php$ με include snippets/fastcgi-php.conf; και fastcgi_pass unix:/run/php/php8.4-fpm.sock; (ο αριθμός έκδοσης διαφέρει ανά έκδοση της διανομής). Το μάθημα για το WordPress εμβαθύνει σε αυτό.
Στα AlmaLinux και Rocky Linux
Εκεί δεν υπάρχει sites-available: τοποθετείτε κάθε ιστότοπο ως ξεχωριστό αρχείο στο /etc/nginx/conf.d/<naam>.conf. Το nginx εκτελείται ως χρήστης nginx αντί για www-data, και το προεπιλεγμένο webroot είναι το /usr/share/nginx/html. Το SELinux από προεπιλογή δεν επιτρέπει στο nginx να συνδεθεί με μια εφαρμογή πίσω από το proxy_pass· ενεργοποιήστε το με setsebool -P httpd_can_network_connect 1. Τα αρχεία εκτός των συνηθισμένων φακέλων χρειάζονται μια ετικέτα SELinux (semanage fcontext και restorecon).
Σύνοψη
- Το nginx εξυπηρετεί αρχεία ή, ως reverse proxy, προωθεί αιτήματα σε μια εφαρμογή στο
127.0.0.1. - Ένα server block ανά ιστότοπο στο
sites-available, ενεργοποίηση με έναν σύνδεσμο στοsites-enabled· ακρόαση σε80και σε[::]:80. - Πάντα
nginx -tπριν από τοsystemctl reload nginx. - Ένας δικός σας default server με
return 444εμποδίζει ένα άγνωστο όνομα ή τη σκέτη διεύθυνση IP να εμφανίσει κάποιον από τους ιστότοπούς σας. - Ως reverse proxy προωθείτε τα
Host,X-Forwarded-ForκαιX-Forwarded-Proto· το webroot είναι αναγνώσιμο για τονwww-data, όχι εγγράψιμο, και χωρίς μυστικά.
Κουίζ
Άσκηση
Άσκηση O7.2: Ο πρώτος σας ιστότοπος. Εγκαταστήστε το nginx (ή χρησιμοποιήστε το Caddy από το μάθημα 7.4), δημιουργήστε ένα server block για ένα (sub)domain που δείχνει στον server σας, με listen για IPv4 και IPv6, δικά του αρχεία καταγραφής και έναν δικό σας default server. Ελέγξτε με nginx -t, κάντε επαναφόρτωση και επαληθεύστε με curl -I μέσω IPv4 και IPv6. Ορίστε τα δικαιώματα του webroot όπως στο μάθημα. Συμπληρώστε τη λίστα ελέγχου και επικολλήστε το server block σας.
Άσκηση O7.2: Ο πρώτος σας ιστότοπος
Αυτή την άσκηση την κάνετε μόνοι σας: κανείς δεν την ελέγχει. Σημειώστε τι έχετε κάνει και επισημάνετε την άσκηση ως ολοκληρωμένη.
Στη σκέτη IP τίποτα (η σύνδεση κλείνει) ή μια ουδέτερη σελίδα, ποτέ ιστότοπος πελάτη. Μόνο ένας φάκελος uploads εγγράψιμος για τον www-data, όλα τα υπόλοιπα μόνο για ανάγνωση. Πίσω από proxy: Host, X-Real-IP, X-Forwarded-For και X-Forwarded-Proto.
Τα τικ και οι σημειώσεις σας παραμένουν μόνο σε αυτό το πρόγραμμα περιήγησης· δεν τα στέλνουμε πουθενά. Αν έχετε εγγραφεί, αποθηκεύουμε στο Τα μαθήματά μου μόνο ότι έχετε ολοκληρώσει την άσκηση.
Για περαιτέρω μελέτη
- Απαγορευμένη πρόσβαση (403): Δεν έχετε δικαίωμα πρόσβασης στο / σε αυτόν τον διακομιστή
- Τεκμηρίωση nginx, How nginx processes a request (server_name και default server): https://nginx.org/en/docs/http/request_processing.html
- Τεκμηρίωση nginx, Beginner's Guide: https://nginx.org/en/docs/beginners_guide.html
- Τεκμηρίωση nginx,
ngx_http_proxy_module: https://nginx.org/en/docs/http/ngx_http_proxy_module.html
