Ενότητα 5 · 5.1
Θύρες και υπηρεσίες σε αναμονή σύνδεσης
Ενότητα 5: Προστασία του δικτύου · Χρόνος ανάγνωσης: 10 λεπτά
Στόχος μαθήματος: Μετά από αυτό το μάθημα μπορείτε να δείτε ποιες υπηρεσίες ακούν στον server σας και σε ποια διεύθυνση. Μπορείτε επίσης να εξηγήσετε τη διαφορά ανάμεσα στο 0.0.0.0 και στο 127.0.0.1 και να ελέγξετε από έξω τι βλέπει ο καθένας στο internet από τον server σας.
Βασικές έννοιες: θύρα (port), TCP και UDP, αναμονή σύνδεσης (listening), ss -tulpn, 0.0.0.0 και [::], 127.0.0.1 και [::1], bind-address, ανοιχτή, κλειστή και φιλτραρισμένη θύρα, επιφάνεια επίθεσης, scanners
Μια διεύθυνση IP με 65.535 πόρτες
Ο server σας έχει μια διεύθυνση IP, για παράδειγμα 192.0.2.10 και 2001:db8::10. Σε αυτή τη διεύθυνση μπορούν να είναι προσβάσιμα ταυτόχρονα διάφορα προγράμματα, το καθένα σε δική του θύρα: έναν αριθμό από 1 έως 65.535. Ένα πρόγραμμα που δέχεται συνδέσεις ακούει σε μια θύρα. Μερικές γνωστές θύρες:
| Θύρα | Πρωτόκολλο | Υπηρεσία |
|---|---|---|
| 22 | TCP | SSH |
| 80 | TCP | http (web server) |
| 443 | TCP και UDP | https (UDP για HTTP/3) |
| 25 | TCP | email μεταξύ mail servers (SMTP) |
| 3306 | TCP | MySQL και MariaDB |
| 5432 | TCP | PostgreSQL |
| 6379 | TCP | Redis |
Το TCP είναι το πρωτόκολλο για συνδέσεις που πρέπει να φτάνουν αξιόπιστα (web, SSH, βάσεις δεδομένων). Το UDP προορίζεται για γρήγορα, μεμονωμένα πακέτα (DNS, VPN όπως το WireGuard, HTTP/3). Μια υπηρεσία ακούει σε TCP, σε UDP ή και στα δύο.
Κάθε θύρα σε αναμονή είναι μια πόρτα προς τον server σας. Πίσω από κάθε πόρτα υπάρχει λογισμικό που μπορεί να περιέχει σφάλματα. Το σύνολο των πορτών που είναι προσβάσιμες από έξω ονομάζεται επιφάνεια επίθεσης. Όσο μικρότερη, τόσο καλύτερα: ένας server με έναν ιστότοπο χρειάζεται από έξω μόνο τις θύρες 22, 80 και 443.
Δείτε τι ακούει: ss
Η εντολή ss (socket statistics) δείχνει τι ακούει στον server σας. Με τις επιλογές -t (TCP), -u (UDP), -l (μόνο όσα ακούν), -p (ποιο πρόγραμμα) και -n (αριθμοί, όχι ονόματα):
anna@web1:~$ sudo ss -tulpn
Netid State Local Address:Port Peer Address:Port Process
udp UNCONN 127.0.0.54:53 0.0.0.0:* users:(("systemd-resolve",pid=402,fd=16))
tcp LISTEN 0.0.0.0:22 0.0.0.0:* users:(("sshd",pid=611,fd=3))
tcp LISTEN 0.0.0.0:80 0.0.0.0:* users:(("nginx",pid=902,fd=6))
tcp LISTEN 0.0.0.0:443 0.0.0.0:* users:(("nginx",pid=902,fd=7))
tcp LISTEN 127.0.0.1:3306 0.0.0.0:* users:(("mariadbd",pid=755,fd=21))
tcp LISTEN 0.0.0.0:6379 0.0.0.0:* users:(("redis-server",pid=780,fd=6))
tcp LISTEN [::]:22 [::]:* users:(("sshd",pid=611,fd=4))
tcp LISTEN [::]:80 [::]:* users:(("nginx",pid=902,fd=8))
tcp LISTEN [::]:443 [::]:* users:(("nginx",pid=902,fd=9))Η σημαντικότερη στήλη είναι η Local Address: η διεύθυνση στην οποία ακούει το πρόγραμμα.
| Διεύθυνση | Σημασία |
|---|---|
0.0.0.0 | Όλες οι διευθύνσεις IPv4 του server, άρα και η δημόσια: προσβάσιμη από έξω (εκτός αν την μπλοκάρει ένα firewall) |
[::] | Όλες οι διευθύνσεις IPv6: το ίδιο για IPv6 |
127.0.0.1 ή [::1] | Μόνο ο ίδιος ο server (loopback): ποτέ προσβάσιμη από έξω |
127.0.0.53, 127.0.0.54 | Επίσης loopback· εδώ ακούει ο τοπικός βοηθός DNS του systemd-resolved |
192.0.2.10 | Μόνο αυτή η συγκεκριμένη διεύθυνση |
Στο παραπάνω παράδειγμα το MariaDB είναι εντάξει: ακούει στο 127.0.0.1, άρα μόνο προγράμματα στον ίδιο τον server (ο ιστότοπός σας) έχουν πρόσβαση. Το Redis όμως ακούει στο 0.0.0.0:6379. Αν το firewall δεν είναι σωστά ρυθμισμένο, έχει πρόσβαση ολόκληρο το internet. Ακριβώς αυτό το είδος σφάλματος αφορά το μάθημα.
Αναμονή στη σωστή διεύθυνση
Μια βάση δεδομένων, μια cache ή ένας πίνακας διαχείρισης σχεδόν ποτέ δεν πρέπει να είναι προσβάσιμα από έξω. Η πρώτη και καλύτερη άμυνα είναι η υπηρεσία να ακούει μόνο στο loopback. Ένα firewall (μάθημα 5.2) είναι το δεύτερο επίπεδο· μπορεί κατά λάθος να είναι απενεργοποιημένο ή να μην ισχύει (για παράδειγμα με το Docker, μάθημα 9.3).
Το πού το ρυθμίζετε διαφέρει ανά πρόγραμμα:
| Πρόγραμμα | Ρύθμιση | Αρχείο (Debian/Ubuntu) |
|---|---|---|
| MariaDB/MySQL | bind-address = 127.0.0.1 | /etc/mysql/mariadb.conf.d/50-server.cnf |
| PostgreSQL | listen_addresses = 'localhost' | /etc/postgresql/<versie>/main/postgresql.conf |
| Redis | bind 127.0.0.1 -::1 και protected-mode yes | /etc/redis/redis.conf |
Τα πακέτα του Debian και του Ubuntu ρυθμίζουν ήδη αυτές τις υπηρεσίες από προεπιλογή στο localhost. Συνήθως τα πράγματα πάνε στραβά όταν κάποιος ακολουθεί έναν οδηγό που λέει "ορίστε το bind-address σε 0.0.0.0 για να συνδέεστε από έξω". Αν θέλετε να έχετε πρόσβαση στη βάση δεδομένων από το laptop σας, χρησιμοποιήστε ένα SSH tunnel (μάθημα 2.3): η θύρα παραμένει κλειστή και πρόσβαση έχει μόνο όποιος συνδέεται μέσω SSH.
Μετά από μια αλλαγή, επανεκκινήστε την υπηρεσία και ελέγξτε ξανά με ss -tulpn.
Ανοιχτή, κλειστή και φιλτραρισμένη
Από έξω, μια θύρα μπορεί να βρίσκεται σε τρεις καταστάσεις:
- Ανοιχτή (open): κάτι ακούει και η σύνδεση επιτυγχάνει.
- Κλειστή (closed): τίποτα δεν ακούει ή ένα firewall απορρίπτει ενεργά. Ο server απαντά αμέσως με ένα "όχι" (στο TCP με ένα πακέτο RST). Η σύνδεση αποτυγχάνει αμέσως με "Connection refused", δηλαδή απόρριψη της σύνδεσης.
- Φιλτραρισμένη (filtered): ένα firewall πετάει σιωπηλά το πακέτο. Η σύνδεση παραμένει σε αναμονή μέχρι να λήξει το χρονικό όριο (time-out).
Για τη βάση δεδομένων σας, η κλειστή και η φιλτραρισμένη κατάσταση είναι και οι δύο καλές: κανείς δεν έχει πρόσβαση. Η διαφορά σάς λέει μόνο γιατί: φιλτραρισμένη σημαίνει σχεδόν πάντα ότι την μπλοκάρει το firewall σας.
Έλεγχος από έξω
Το ss δείχνει τι ακούει στον server, αλλά όχι τι είναι προσβάσιμο από έξω. Ανάμεσα υπάρχει ακόμη ένα firewall, και στον πάροχό σας μερικές φορές και ένα firewall δικτύου. Ο μόνος πραγματικός έλεγχος είναι επομένως: κοιτάξτε από έξω, από έναν άλλο υπολογιστή.
Από τον δικό σας υπολογιστή (όχι από τον ίδιο τον server, γιατί τότε περνάτε μέσω loopback) μπορείτε να το κάνετε με το nc (netcat) για μία θύρα:
anna@laptop:~$ nc -vz -w 3 192.0.2.10 6379
nc: connect to 192.0.2.10 port 6379 (tcp) failed: Connection refused
anna@laptop:~$ nc -vz -w 3 192.0.2.10 22
Connection to 192.0.2.10 22 port [tcp/ssh] succeeded!Στα Windows το PowerShell κάνει το ίδιο με Test-NetConnection 192.0.2.10 -Port 6379. Ένας port scanner όπως το nmap μπορεί να ελέγξει περισσότερες θύρες ταυτόχρονα· χρησιμοποιήστε έναν τέτοιο scanner μόνο στον δικό σας server.
Μην ξεχνάτε το IPv6. Ένα συχνό σφάλμα είναι ένα firewall με κανόνες μόνο για IPv4, ενώ η υπηρεσία ακούει και στο [::]. Ελέγξτε επομένως και τη διεύθυνση IPv6: nc -6 -vz -w 3 2001:db8::10 6379.
Γιατί αυτό είναι τόσο σημαντικό
Ο server σας σαρώνεται από το πρώτο λεπτό. Μηχανές αναζήτησης για συσκευές και υπηρεσίες στο internet, καθώς και bots εγκληματιών, δοκιμάζουν συνεχώς όλες τις διευθύνσεις IPv4 σε γνωστές θύρες. Ένα ανοιχτό Redis χωρίς κωδικό πρόσβασης, ένα cluster Elasticsearch ή ένα MongoDB χωρίς έλεγχο πρόσβασης εντοπίζεται μέσα σε σύντομο χρόνο. Διαρροές δεδομένων από ανοιχτές βάσεις δεδομένων και ανοιχτά clusters αναζήτησης εμφανίζονται τακτικά στις ειδήσεις, και σχεδόν πάντα πρόκειται ακριβώς για αυτό το σφάλμα: μια υπηρεσία που προοριζόταν για εσωτερική χρήση άκουγε σε όλες τις διευθύνσεις.
Και η θύρα του SSH δέχεται απόπειρες όλη μέρα. Αυτό είναι φυσιολογικό και, με κλειδιά (μάθημα 2.2) και fail2ban (μάθημα 5.3), δεν αποτελεί πρόβλημα.
Ο έλεγχος του μαθήματος
Στην άσκηση αυτού του μαθήματος, το πρόγραμμα του μαθήματος ελέγχει από έξω πέντε συγκεκριμένες θύρες βάσεων δεδομένων του server σας: 3306 (MySQL/MariaDB), 5432 (PostgreSQL), 6379 (Redis), 9200 (Elasticsearch/OpenSearch) και 27017 (MongoDB). Το πρόγραμμα δοκιμάζει μόνο αν δημιουργείται σύνδεση, δεν στέλνει δεδομένα και δεν συνδέεται πουθενά με λογαριασμό. Δεν σαρώνει άλλες θύρες. Οι έλεγχοι προέρχονται από τη διεύθυνση IP που αναφέρεται στην άσκηση, ώστε να μπορείτε να τους αναγνωρίσετε στο δικό σας αρχείο καταγραφής. Μια διεύθυνση μπορεί να ελεγχθεί μόνο λίγες φορές την ώρα.
Σε AlmaLinux και Rocky Linux
Το ss λειτουργεί με τον ίδιο τρόπο. Τα αρχεία των υπηρεσιών βρίσκονται σε άλλες θέσεις (για παράδειγμα /etc/my.cnf.d/ για το MariaDB, /var/lib/pgsql/data/postgresql.conf για το PostgreSQL). Επιπλέον, το SELinux μπορεί να μπλοκάρει μια υπηρεσία που θέλει να ακούει σε μια ασυνήθιστη θύρα· αυτό το βλέπετε τότε στο journalctl (μάθημα 6.2) και όχι στο ss.
Σύνοψη
- Κάθε θύρα σε αναμονή είναι μια πόρτα· αφήστε ανοιχτά προς τα έξω μόνο όσα χρειάζονται πραγματικά (συνήθως 22, 80 και 443).
- Το
sudo ss -tulpnδείχνει ποιο πρόγραμμα ακούει σε ποια διεύθυνση και σε ποια θύρα. - Τα
0.0.0.0και[::]σημαίνουν "όλες οι διευθύνσεις", τα127.0.0.1και[::1]σημαίνουν "μόνο ο ίδιος ο server". Βάσεις δεδομένων, caches και clusters αναζήτησης ανήκουν στο loopback. - Η κλειστή και η φιλτραρισμένη κατάσταση είναι και οι δύο καλές για μια βάση δεδομένων· η ανοιχτή είναι λάθος.
- Ελέγχετε πάντα από έξω, για IPv4 και για IPv6, γιατί το
ssδεν βλέπει το firewall.
Κουίζ
Άσκηση
Άσκηση Z5.1: Θύρες βάσεων δεδομένων κλειστές από έξω. Εκτελέστε το sudo ss -tulpn στον server σας και βρείτε σε ποιες διευθύνσεις ακούν οι υπηρεσίες σας. Στη συνέχεια, αφήστε το πρόγραμμα του μαθήματος να ελέγξει από έξω ότι οι θύρες 3306, 5432, 6379, 9200 και 27017 του server σας δεν είναι προσβάσιμες, για IPv4 και (αν ο server σας έχει εγγραφή AAAA) για IPv6. Συμπληρώστε επίσης ποιες υπηρεσίες ακούν στο δικό σας σύστημα στο 0.0.0.0 ή στο [::]. Το πρόγραμμα δημιουργεί μόνο μια σύνδεση προς αυτές τις πέντε θύρες και δεν στέλνει τίποτα.
