FAQ

Αυτός είναι ο οδηγός εγκατάστασης, ρύθμισης και συντήρησης του Arcivéo Monitor. Οι ενότητες είναι ομαδοποιημένες: γενική επισκόπηση, ανάπτυξη του πίνακα, σύνδεση εργαλείων ασφαλείας, ενσωματωμένες μονάδες και διαγνωστικά. Οι εντολές αντιγράφονται με το κουμπί δεξιά.

Από πού να ξεκινήσετε

01. Εγκατάσταση του πίνακα — επιλέξτε μέθοδο

Η εγκατάσταση του πίνακα βρίσκεται σε ξεχωριστές σελίδες βήμα προς βήμα. Επιλέξτε μέθοδο:

Αν δεν είστε σίγουροι, επιλέξτε την αυτόματη. Αυτός ο οδηγός παραμένει η ενιαία πηγή για SSL, εργαλεία, cron και διαγνωστικά — οι σελίδες εγκατάστασης παραπέμπουν στις ενότητές του, χωρίς να επαναλαμβάνουν τίποτα.

Επισκόπηση

02. Τι είναι το Arcivéo Monitor

Arcivéo Monitor — πίνακας ασφαλείας διακομιστή. Συλλέγει δεδομένα από τα εγκατεστημένα εργαλεία (Fail2ban, UFW, Lynis, ModSecurity, AIDE, ClamAV, Auditd, CrowdSec, Suricata, Falco κ.ά.) και τα εμφανίζει σε ενιαία διεπαφή με dashboard, χάρτη επιθέσεων και αναλυτικές σελίδες για κάθε εργαλείο.

Το Monitor δεν είναι ενεργό μέσο προστασίας — δεν μπλοκάρει επιθέσεις από μόνο του. Ο σκοπός του είναι να συγκεντρώνει τις πληροφορίες από τα ήδη ενεργά εργαλεία και να τις παρουσιάζει με βολικό τρόπο.

03. Πώς λειτουργεί ο monitor στον διακομιστή

Ο monitor λειτουργεί μόνο τοπικά — πρέπει να εγκατασταθεί στον ίδιο διακομιστή που παρακολουθεί. Δεν χρησιμοποιεί SSH ούτε απομακρυσμένο API.

Όλες τις εντολές (fail2ban-client, ufw status, ipset list κ.λπ.) το dashboard τις εκτελεί ως χρήστης του web server (συνήθως www-data, στα hosting panel — ο λογαριασμός του site) με περιορισμένο σύνολο δικαιωμάτων sudo — μόνο σε συγκεκριμένα εργαλεία, χωρίς γενική πρόσβαση root. Τα αποτελέσματα αναλύονται και εμφανίζονται στον browser.

Για πολλούς διακομιστές εγκαταστήστε τον monitor ξεχωριστά σε καθέναν, με μοναδικό domain.

04. Πώς υπολογίζεται η Βαθμολογία ασφάλειας

Η βαθμολογία ξεκινά από το μέγιστο και μειώνεται για κάθε πρόβλημα που εντοπίζεται:

  • Το UFW δεν είναι ενεργό — −30
  • Το Fail2ban δεν εκτελείται (καμία ενεργή jail) — −25
  • Χωρίς κλειδιά WebAuthn — −15
  • Lynis hardening index < 60 — −20· 60–79 — −10
  • Το IPset ipsum δεν φορτώθηκε — −10
  • Απειλές που βρέθηκαν από το ClamAV — −20
  • Αλλαγές αρχείων από το AIDE — −15
  • Το SSL έληξε — −30, λήγει σε <14 ημέρες — −15, <30 ημέρες — −5
  • Το CrowdSec είναι εγκατεστημένο αλλά δεν εκτελείται — −5
  • Το Suricata είναι εγκατεστημένο αλλά δεν εκτελείται — −5
  • Βάσεις/cache (MySQL, PostgreSQL, Redis…) προσβάσιμες από έξω — −10
  • Επιτρέπεται η σύνδεση root μέσω SSH (PermitRootLogin yes) — −20
  • Εκκρεμούν ενημερώσεις ασφαλείας — −5

Σύνολο: 80+ = Προστατευμένος, 60–79 = Προσοχή, <60 = Σε κίνδυνο.

Οι αφαιρέσεις για ClamAV, AIDE, CrowdSec και Suricata εφαρμόζονται μόνο αν το εργαλείο είναι εγκατεστημένο. Το Lynis και το AIDE χωρίς αρχικοποιημένη βάση εμφανίζονται ως «χωρίς δεδομένα» και δεν μειώνουν τη βαθμολογία. Το πλήθος επιθέσεων για σήμερα εμφανίζεται στο dashboard, αλλά δεν επηρεάζει τη Βαθμολογία ασφάλειας.

Ρυθμίσεις και άδεια

05. WebAuthn — έλεγχος ταυτότητας δύο παραγόντων

WebAuthn — πρότυπο ελέγχου ταυτότητας χωρίς κωδικό μέσω κλειδιού υλικού. Υποστηρίζει YubiKey, Touch ID, Face ID, Windows Hello, Passkey.

Μετά την είσοδο με κωδικό, το σύστημα ζητά επιβεβαίωση μέσω του καταχωρημένου κλειδιού. Ακόμη κι αν διαρρεύσει ο κωδικός, η είσοδος είναι αδύνατη χωρίς το φυσικό κλειδί ή τη βιομετρία.

Για ρύθμιση, ανοίξτε τα Κλειδιά WebAuthn στο πλαϊνό μενού και πατήστε «Καταχώριση κλειδιού». Καταχωρίστε αμέσως δύο κλειδιά: αν το μοναδικό κλειδί χαθεί ή χαλάσει, η είσοδος στον πίνακα με αυτό θα είναι αδύνατη.

Το WebAuthn λειτουργεί μόνο μέσω HTTPS. Σε σύνδεση HTTP, η καταχώριση και η είσοδος με κλειδί δεν είναι διαθέσιμες.

06. Ειδοποιήσεις: Telegram και Email

Ο πίνακας μπορεί να στέλνει την αναφορά ασφαλείας στο Telegram και στο email (με κουμπί ή προγραμματισμένα). Ρυθμίζεται στην ενότητα «Ρυθμίσεις».

Telegram. Χρειάζονται το token του bot και το chat id:

  1. Στο Telegram γράψτε στο @BotFather/newbot → λάβετε το token της μορφής 123456:ABC....
  2. Στείλτε στο νέο σας bot ένα οποιοδήποτε μήνυμα (ώστε να μπορεί να σας απαντά).
  3. Βρείτε το chat id σας: γράψτε στο bot @userinfobot, ή ανοίξτε το https://api.telegram.org/bot<TOKEN>/getUpdates και βρείτε το "chat":{"id":...}.
  4. Επικολλήστε το token και το chat id στις «Ρυθμίσεις» → Telegram, πατήστε «Αποθήκευση και δοκιμαστική αποστολή».

Email. Δύο τρόποι επιλογής στις «Ρυθμίσεις» → Email:

  • SMTP — host, θύρα (465/SSL ή 587/TLS), όνομα χρήστη και κωδικός του email σας·
  • Resend — σύγχρονο API: δηλώστε το κλειδί API (re_...) και επιβεβαιωμένο domain αποστολέα.
Το κουμπί «Δοκιμαστική αποστολή» ελέγχει άμεσα το κανάλι. Ο προγραμματισμός της αυτόματης αναφοράς γίνεται μέσω cron (ενότητα «Όλες οι εργασίες cron»): αυτός ενεργοποιεί την αποστολή, ενώ τα κανάλια λαμβάνονται από τις ρυθμίσεις.

Κατάσταση αναφοράς: «ΠΡΟΣΟΧΗ» ή «ΟΚ». Ο τίτλος γίνεται «ΠΡΟΣΟΧΗ» μόνο σε πραγματικό πρόβλημα ή εκκρεμή ενέργεια: εντοπίστηκε απειλή ClamAV, αλλαγές αρχείων στο AIDE, κρίσιμα συμβάντα Falco (Emergency/Alert/Critical τις τελευταίες 24 ώρες), σταματημένη υπηρεσία στο Monit, απαιτείται επανεκκίνηση, λήγει SSL (≤14 ημέρες) ή εκκρεμούν ενημερώσεις ασφαλείας. Ο θόρυβος παρασκηνίου — δοκιμές SSH από bots, IP που έχουν μπλοκαριστεί από fail2ban, ειδοποιήσεις Suricata, προειδοποιήσεις Lynis και ήδη αποκρουσμένα αιτήματα ModSecurity — δεν ανεβάζει την κατάσταση, οπότε τέτοιοι αριθμοί στην αναφορά δεν σημαίνουν «ΠΡΟΣΟΧΗ» από μόνοι τους.

07. Άδεια χρήσης — εισαγωγή και ενεργοποίηση

Οι αναλυτικές μονάδες παρακολούθησης (Lynis, UFW, ModSecurity, χάρτης επιθέσεων, AIDE, ClamAV κ.ά.) ξεκλειδώνουν εφόσον υπάρχει έγκυρη άδεια χρήσης. Χωρίς αυτήν, το dashboard, οι ρυθμίσεις και ο λογαριασμός λειτουργούν, ενώ οι μονάδες εμφανίζουν την κάρτα «Απαιτείται άδεια χρήσης».

Μετά την αγορά, στον λογαριασμό σας έχετε έναν κωδικό ενεργοποίησης της μορφής ARCIVEO-XXXX-XXXX-XXXX-XXXX. Πρέπει να τον «ενεργοποιήσετε» στον τομέα του panel σας — αυτό μετατρέπει τον κωδικό σε υπογεγραμμένο αρχείο άδειας (μπλοκ [license]), που εισάγετε στο panel.

Πώς γίνεται η ενεργοποίηση (3 βήματα):

  1. Πάρτε τον κωδικό ενεργοποίησης. Λογαριασμός my.arciveo.com → ενότητα «Άδειες» / «Ενεργοποίηση άδειας» — αντιγράψτε τον κωδικό ARCIVEO-….
  2. Ενεργοποιήστε τον κωδικό στον τομέα σας. Στον ίδιο λογαριασμό ανοίξτε την «Ενεργοποίηση άδειας», εισαγάγετε: κωδικό ενεργοποίησης, το email σας και τον τομέα του panel (τη διεύθυνση όπου ανοίγει ο monitor, π.χ. monitor.example.com). Πατήστε ενεργοποίηση — το σύστημα δημιουργεί αρχείο άδειας συνδεδεμένο με αυτόν τον τομέα και το εμφανίζει σε πεδίο με κουμπί «Αντιγραφή».
  3. Εισαγάγετε το κλειδί στο panel. Αντιγράψτε ολόκληρο το κείμενο της άδειας → στο panel ανοίξτε «Ρυθμίσεις» → μπλοκ «Άδεια χρήσης», επικολλήστε και πατήστε «Αποθήκευση». Οι μονάδες ξεκλειδώνουν αμέσως.

Το panel ελέγχει το κλειδί κρυπτογραφικά: υπογραφή, σύνδεση με τον τομέα και διάρκεια ισχύος.

Ο τομέας κατά την ενεργοποίηση πρέπει να ταυτίζεται ακριβώς με τη διεύθυνση του panel. Πάρτε τον από τη σταθερά APP_URL στο config.php και εισαγάγετε μόνο το όνομα του host — χωρίς https:// και χωρίς πρόθεμα www. Η ενεργοποίηση είναι μία φορά: ο κωδικός μετατρέπεται σε άδεια για τον τομέα που δώσατε και δεν ενεργοποιείται ξανά — σε λάθος τομέα το κλειδί δεν θα ταιριάζει στο panel σας και ο κωδικός θα έχει αναλωθεί. Γι' αυτό εισαγάγετε τον τομέα προσεκτικά.
Αν λήξει η ισχύς ή αλλάξει ο τομέας — στην κεφαλίδα του panel θα εμφανιστεί προειδοποίηση. Η άδεια συνδέεται μόνιμα με τον τομέα και δεν μεταφέρεται σε άλλον: για νέα διάρκεια ή νέο τομέα χρειάζεται νέο κλειδί (αγοράζεται στον λογαριασμό και ενεργοποιείται μία φορά).

08. Το αρχείο config.php — όλες οι ρυθμίσεις του πίνακα

Όλες οι βασικές παράμετροι του πίνακα ορίζονται σε ένα αρχείο config.php στη ρίζα (δίπλα στον φάκελο public/) με απλές σταθερές define(). Το αρχείο δημιουργείται κατά την εγκατάσταση· χρειάζεται σπάνια χειροκίνητη επεξεργασία — κυρίως όταν αλλάζετε domain, κατά τη μεταφορά ή τη σύνδεση σε άλλη βάση. Μετά από κάθε αλλαγή επανεκκινήστε το PHP-FPM (αλλιώς, λόγω του OPcache, οι αλλαγές δεν θα εφαρμοστούν).

Συμπληρώστε τις δικές σας τιμές στα επισημασμένα σημεία· τα υπόλοιπα αφήστε τα ως έχουν:

// --- Βάση δεδομένων --- define('DB_HOST', 'localhost'); // αφήστε το define('DB_NAME', 'db_name'); // ό,τι ορίσατε κατά τη δημιουργία της βάσης define('DB_USER', 'user'); // ό,τι ορίσατε κατά τη δημιουργία της βάσης define('DB_PASS', 'db_password'); // ό,τι ορίσατε κατά τη δημιουργία της βάσης define('DB_CHARSET', 'utf8mb4'); // αφήστε το // --- Εφαρμογή --- define('APP_URL', 'https://monitor.example.com'); // διεύθυνση του πίνακα, χωρίς κάθετο στο τέλος define('TIMEZONE', 'Europe/Athens'); // η ζώνη ώρας σας // --- Διάρκεια συνεδρίας --- define('SESSION_LIFETIME', 28800); // αδράνεια μέχρι νέα σύνδεση, δευτ. (28800 = 8 ώ)

Βάση δεδομένων. Στοιχεία σύνδεσης στη MySQL/MariaDB:

  • DB_HOST — ο host της βάσης, σχεδόν πάντα localhost·
  • DB_NAME — το όνομα της βάσης δεδομένων του πίνακα·
  • DB_USER — ο χρήστης της βάσης (πρόσβαση μόνο στη δική του βάση)·
  • DB_PASS — ο κωδικός αυτού του χρήστη·
  • DB_CHARSET — η κωδικοποίηση της σύνδεσης, αφήστε utf8mb4.

Εφαρμογή.

  • APP_URL — η πλήρης διεύθυνση του πίνακα (π.χ. https://monitor.example.com). Πρέπει να συμπίπτει με το domain για το οποίο ενεργοποιήθηκε η άδεια — αλλιώς το κλειδί θα απορριφθεί (δείτε την ενότητα «Άδεια»)·
  • TIMEZONE — η ζώνη ώρας του PHP: επηρεάζει μόνο τον τρόπο που ο πίνακας εμφανίζει ημερομηνίες και ώρα. Στην ώρα εκτέλεσης των εργασιών cron δεν επηρεάζει — εκεί ισχύει η ζώνη του συστήματος (δείτε «Όλες οι εργασίες cron»).

Διάρκεια συνεδρίας. SESSION_LIFETIME — το χρονικό όριο αδράνειας της συνεδρίας σε δευτερόλεπτα (κυλιόμενο: ανανεώνεται με τη δραστηριότητα). Προεπιλογή 28800 = 8 ώρες· μετά από αυτό το διάστημα αδράνειας ο πίνακας θα ζητήσει νέα σύνδεση. Για παράδειγμα, 3600 = 1 ώρα, 86400 = μία ημέρα.

Καταγραφή σφαλμάτων. Τα σφάλματα δεν εμφανίζονται ποτέ στους επισκέπτες, αλλά γράφονται στο logs/php_errors.log — φαίνονται στη σελίδα «Αρχεία καταγραφής εφαρμογής». Αυτές οι γραμμές (display_errors=0, log_errors=1, η διαδρομή error_log) συνήθως δεν χρειάζονται αλλαγή — οι ρυθμίσεις ορίζονται απευθείας στο αρχείο και δεν εξαρτώνται από το php.ini.

config.php — μυστικό αρχείο. Περιέχει τον κωδικό της βάσης. Βρίσκεται στη ρίζα του πίνακα (δίπλα στο public/), ενώ η ρίζα ιστού (DocumentRoot) αυτού του πίνακα είναι ακριβώς η ρίζα του πίνακα, όχι το public/. Το ίδιο το αρχείο δεν «διαρρέει»: στο ριζικό .htaccess υπάρχει ρητή απαγόρευση γι' αυτό (Require all denied) — ο διακομιστής επιστρέφει 403. Ακόμη και χωρίς αυτόν τον κανόνα ο πηγαίος κώδικας δεν θα διέρρεε: είναι PHP — ο διακομιστής το εκτελεί, δεν το παραδίδει ως κείμενο. Για κάθε ενδεχόμενο: μην το ανεβάζετε σε δημόσια αποθετήρια και μην το στέλνετε στην υποστήριξη με πραγματικό κωδικό. Δικαιώματα στο αρχείο — 640.
Κατά τη μεταφορά ή την επαναφορά πρόσβασης, αυτό το αρχείο είναι η κύρια πηγή στοιχείων: το όνομα της βάσης, ο χρήστης και ο κωδικός λαμβάνονται ακριβώς από εδώ (δείτε τις ενότητες «Ενημέρωση και μεταφορά του πίνακα» και «Επαναφορά πρόσβασης»).

Εργαλεία ασφαλείας

09. Τείχος προστασίας UFW

Το UFW (Uncomplicated Firewall) είναι ένα απλό περιβάλλον για το nftables/iptables. Κλείνει όλες τις εισερχόμενες θύρες εκτός από τις ρητά επιτρεπόμενες. Η σελίδα «Τείχος προστασίας UFW» εμφανίζει την κατάσταση και τους κανόνες.

sudo apt install ufw # Επιτρέψτε το SSH (υποχρεωτικά ΠΡΙΝ την ενεργοποίηση!) και το web sudo ufw allow OpenSSH sudo ufw allow 80,443/tcp # Κλείστε τη ΒΔ προς τα έξω (πρόσβαση μόνο τοπικά) sudo ufw deny 3306 # Ενεργοποίηση και έλεγχος sudo ufw enable sudo ufw status verbose
Πριν από το ufw enable επιτρέψτε οπωσδήποτε το SSH (ufw allow OpenSSH), αλλιώς θα χάσετε την πρόσβαση στον διακομιστή.
Η «Εξωτερική έκθεση» στον πίνακα λαμβάνει υπόψη το UFW: μια θύρα που έχει κλείσει με κανόνα deny δεν θεωρείται προσβάσιμη από έξω.
Skipping adding existing rule — δεν είναι σφάλμα. Έτσι το UFW αναφέρει ότι ο ίδιος ακριβώς κανόνας υπάρχει ήδη και δεν τον προσθέτει ξανά. Κατά την επανάληψη της αυτόματης ρύθμισης (είναι ιδεμποτεντική) αυτό είναι κανονικό μήνυμα — δεν χρειάζεται καμία ενέργεια.

10. Εγκατάσταση Fail2ban

Μπλοκάρει αυτόματα IP μετά από υπέρβαση του αριθμού αποτυχημένων προσπαθειών σύνδεσης. Αναλύει τα αρχεία καταγραφής των SSH, nginx, Apache και άλλων υπηρεσιών.

sudo apt install fail2ban sudo systemctl enable --now fail2ban # Έλεγχος κατάστασης: sudo fail2ban-client status
Η λειτουργική διαμόρφωση (jail.local με δεκάδες jail και αυτόματο αποκλεισμό από το ipsum) βρίσκεται στην επόμενη ενότητα.

11. Λειτουργική διαμόρφωση Fail2ban + ipsum

Η βασική εγκατάσταση βρίσκεται παραπάνω. Εδώ είναι η λειτουργική διαμόρφωση που δίνει δεκάδες ενεργά jail και χιλιάδες αποκλεισμούς: γενικές ρυθμίσεις, βασικά jail και αυτόματο μπαν κακόβουλων IP από τη λίστα ipsum.

Το αρχείο /etc/fail2ban/jail.local — γενικές ρυθμίσεις και τα σημαντικότερα jail:

[DEFAULT] bantime = 1w findtime = 900 maxretry = 3 backend = systemd banaction = nftables-multiport ignoreip = 127.0.0.1/8 ::1 <YOUR_IP> <TRUSTED_NETS> # Προοδευτικό μπαν: κάθε επανάληψη διαρκεί περισσότερο bantime.increment = true bantime.factor = 2 bantime.maxtime = 5w bantime.rndtime = 300 [sshd] enabled = true maxretry = 5 bantime = -1 # μόνιμο μπαν για brute-force SSH findtime = 3600 # Υπότροποι: όποιος έφαγε πολλά μπαν, μπανάρεται μόνιμα [recidive] enabled = true logpath = /var/log/fail2ban.log banaction = %(banaction_allports)s bantime = -1 findtime = 86400 maxretry = 2 [http-get-dos] enabled = true maxretry = 100 findtime = 300 bantime = 1w # Υπηρεσίες web (apache-*, nginx-*, php-url-fopen, phpmyadmin-syslog): [nginx-http-auth] enabled = true port = http,https [apache-badbots] enabled = true port = http,https # … και τα υπόλοιπα jail ανά υπηρεσία (dovecot, exim, postfix-sasl, # mysqld-auth, vsftpd, portscan, pam-generic) — enabled = true
Στο ignoreip βάλτε οπωσδήποτε το δικό σας IP και τα έμπιστα δίκτυα, αλλιώς μπορεί να μπανάρετε τον εαυτό σας. Μετά τις αλλαγές: sudo fail2ban-client reload.

Αυτόματη φόρτωση της λίστας αποκλεισμού ipsum — στο cron του root (sudo crontab -e): το level 1 (100+ χιλιάδες IP) φορτώνεται στο σύνολο ipsum, που αποκόπτεται στο firewall (περισσότερα — στην ενότητα «Λίστα αποκλεισμού IPset»):

# 04:00 — ενημέρωση του ipset ipsum (level 1, μέγιστη κάλυψη): 0 4 * * * /usr/local/bin/load-ipsum.sh >> /path/to/monitor/logs/cron.log 2>&1
Το σύνολο πρέπει να ονομάζεται ipsum — αυτό ακριβώς διαβάζει ο πίνακας (κάρτα «IPset ipsum»). Επίπεδα: levels/1.txt — μέγιστη κάλυψη, levels/3.txt — πιο ακριβές (3+ πηγές).

Γιατί ο «Μόνιτορ ασφαλείας» χωρίζεται σε δύο ζώνες. Η προστασία λειτουργεί σε δύο επίπεδα, και ο πίνακας δεν τα ανακατεύει:

  • Πραγματικές επιθέσεις (αντιδραστικά) — ό,τι έπιασε το fail2ban: ζωντανές απόπειρες παραβίασης (jail sshd, apache-*, nginx-* κ.λπ.) και κακόβουλοι υπότροποι (jail recidive — αυτοί που έχουν ήδη μπαναριστεί πολλές φορές). Είναι IP που πραγματικά σας επιτέθηκαν — βρίσκονται στον χάρτη επιθέσεων και στη «Χρονογραμμή».
  • Προληπτικός αποκλεισμός (προδραστικά) — δημόσια λίστα αποκλεισμού γνωστών κακόβουλων IP ipset ipsum, που αποκόπτεται στο firewall με κανόνα DROP. Οι περισσότερες από αυτές τις διευθύνσεις ούτε καν άγγιξαν τον διακομιστή σας — αποκόπτονται εκ των προτέρων· ο μετρητής «IPset ipsum» δείχνει πόσες αποκόπηκαν προληπτικά.

Η διαφορά είναι απλή: αντιδραστικά — «αυτοί επιτέθηκαν και έφαγαν μπαν», προληπτικά — «αυτοί αποκλείστηκαν πριν καν την απόπειρα». Παλιότερα στο recidive φορτωνόταν τεχνητά η list-3 του ipsum (από εκεί ο παλιός διαχωρισμός «recidive λίστας»)· τώρα το recidive έχει μόνο πραγματικούς υπότροπους, ενώ το προληπτικό είναι εξ ολοκλήρου στο firewall.

12. Λίστα αποκλεισμού IPset (ipsum)

ipsum — δημόσια λίστα κακόβουλων IP που ενημερώνεται καθημερινά. Η μονάδα εμφανίζει τον αριθμό των φορτωμένων διευθύνσεων στον πίνακα και στον χάρτη επιθέσεων και τον συνυπολογίζει στη Βαθμολογία ασφάλειας (−10 αν το σύνολο δεν έχει φορτωθεί).

Η ελάχιστη επιλογή χωρίς fail2ban — ξεχωριστό σύνολο ipsum με αποκλεισμό μέσω iptables:

# Δημιουργία συνόλου (μία φορά): sudo ipset create ipsum hash:ip # Σκριπτ ενημέρωσης /usr/local/bin/update-ipsum.sh: #!/bin/bash ipset flush ipsum for ip in $(curl -s https://raw.githubusercontent.com/stamparm/ipsum/master/levels/3.txt); do ipset add ipsum "$ip" 2>/dev/null done iptables -C INPUT -m set --match-set ipsum src -j DROP 2>/dev/null \ || iptables -I INPUT -m set --match-set ipsum src -j DROP # Cron (sudo crontab -e, καθημερινά στις 4:00): 0 4 * * * /usr/local/bin/update-ipsum.sh
Η εκτεταμένη επιλογή με fail2ban-recidive βρίσκεται στην ενότητα «Λειτουργική διαμόρφωση Fail2ban + ipsum».
Το ipset ζει στη μνήμη και χάνεται στην επανεκκίνηση. Μόνο ένα καθημερινό cron θα αφήσει το σύνολο κενό από τη στιγμή της επανεκκίνησης έως την επόμενη εκτέλεση (ο πίνακας θα δείξει 0). Φορτώστε το σύνολο και κατά την εκκίνηση — μεταφέρετε τη φόρτωση σε σκριπτ και συνδέστε το στο @reboot. Παράλληλα η εντολή create … -exist ορίζει το όριο maxelem 300000 (η προεπιλογή 65536 — το level 1 δεν χωράει, θα βγει «Hash is full»):
# /usr/local/bin/load-ipsum.sh #!/bin/bash curl -s https://raw.githubusercontent.com/stamparm/ipsum/master/levels/1.txt \ | grep -v '^#' | sed 's/^/add ipsum /' \ | (echo "create ipsum hash:ip hashsize 131072 maxelem 300000 -exist"; echo "flush ipsum"; cat) \ | ipset restore -exist # sudo crontab -e — καθημερινά στις 04:00 ΚΑΙ σε κάθε εκκίνηση: 0 4 * * * /usr/local/bin/load-ipsum.sh @reboot sleep 60 && /usr/local/bin/load-ipsum.sh
Πώς λειτουργεί στην αυτόματη εγκατάσταση. Το σκριπτ φορτώνει την πλήρη λίστα level 1 (100+ χιλιάδες IP) στο σύνολο ipsum και, αν το τείχος προστασίας το διαχειρίζεται ο εγκαταστάτης (νέο VPS — προφίλ «Πλήρες»/«Ελαφρύ»), συνδέει το σύνολο στο UFW με κανόνα DROP — η κίνηση από αυτές τις IP όντως αποκλείεται. Ο κανόνας βρίσκεται μετά το ESTABLISHED,RELATED, γι' αυτό οι τρέχουσες συνδέσεις (μαζί με το SSH σας) δεν διακόπτονται — κόβονται μόνο οι νέες συνδέσεις από τη λίστα. Το σύνολο αποκαθίσταται κατά τη φόρτωση της υπηρεσίας ipsum-load.service πριν το τείχος προστασίας (αλλιώς το UFW δεν θα σηκωνόταν) και ενημερώνεται με cron στις 04:00. Σε έναν ήδη διαμορφωμένο διακομιστή (πίνακας, δικό σας τείχος προστασίας) ο εγκαταστάτης δεν αγγίζει το τείχος προστασίας — εκεί το ipsum παραμένει λίστα για τον πίνακα και τον χάρτη επιθέσεων, ενώ ο κανόνας DROP προστίθεται χειροκίνητα αν το επιθυμείτε (η ελάχιστη επιλογή με iptables … --match-set ipsum … -j DROP — παραπάνω). Στην αυτόματη εγκατάσταση δεν χρειάζεται να κάνετε τίποτα χειροκίνητα.

13. Εγκατάσταση CrowdSec

Σύγχρονη αντικατάσταση του Fail2ban με συλλογικό threat intelligence: αποκλεισμοί από την κοινότητα συν δικοί σας κανόνες. Απαιτεί ξεχωριστό bouncer για την εφαρμογή των αποκλεισμών στο firewall.

curl -s https://packagecloud.io/install/repositories/crowdsec/crowdsec/script.deb.sh | sudo bash sudo apt install crowdsec sudo systemctl enable --now crowdsec # Bouncer για iptables/nftables: sudo apt install crowdsec-firewall-bouncer-iptables # Έλεγχος κατάστασης: sudo systemctl status crowdsec sudo cscli decisions list sudo cscli bouncers list
Κατάσταση «Δεν εκτελείται» στον πίνακα = η υπηρεσία είναι εγκατεστημένη, αλλά δεν είναι ενεργή (η μονάδα την ελέγχει μέσω systemctl is-active crowdsec). Εκκίνηση: sudo systemctl enable --now crowdsec· σε αποτυχία δείτε sudo journalctl -u crowdsec -n 30. Ο ίδιος κανόνας ισχύει για κάθε υπηρεσία σε κατάσταση «Δεν εκτελείται» (Suricata, Falco, Monit, MySQL).
«0 σενάρια» ή «0 bouncers» στο dashboard. Το CrowdSec έρχεται σχεδόν άδειο — χωρίς συλλογές δεν εντοπίζει τίποτα, και χωρίς καταχωρημένο bouncer οι αποκλεισμοί δεν εφαρμόζονται στο firewall. Εγκαταστήστε τις βασικές συλλογές και βεβαιωθείτε ότι το bouncer είναι στη λίστα:
# Βασικές συλλογές (Linux + SSH + web server): sudo cscli collections install crowdsecurity/linux crowdsecurity/sshd crowdsecurity/base-http-scenarios sudo systemctl reload crowdsec # Το bouncer πρέπει να είναι στη λίστα και με κατάσταση ενεργής σύνδεσης: sudo cscli bouncers list
Στο log του bouncer stream halted / οι αποκλεισμοί δεν εφαρμόζονται. Πρόκειται για ορφανό api-key: το bouncer αφαιρέθηκε από το cscli bouncers list, αλλά το παλιό του κλειδί παρέμεινε στο /etc/crowdsec/bouncers/*.yaml. Καταχωρήστε ξανά το bouncer και ορίστε το νέο κλειδί:
sudo cscli bouncers add fw-bouncer # θα εμφανίσει νέο api_key # γράψτε αυτό το κλειδί στο api_key: στο /etc/crowdsec/bouncers/crowdsec-firewall-bouncer.yaml sudo systemctl restart crowdsec-firewall-bouncer
Η αυτόματη εγκατάσταση (προφίλ «Πλήρης προστασία») εγκαθιστά μόνη της τις συλλογές και καταχωρεί το firewall-bouncer — χειροκίνητα χρειάζεται μόνο σε χειροκίνητη εγκατάσταση ή μετά από χειροκίνητη παρέμβαση στο CrowdSec.

14. Εγκατάσταση AIDE

AIDE (Advanced Intrusion Detection Environment) δημιουργεί στιγμιότυπο του συστήματος αρχείων και σε κάθε έλεγχο αναφέρει τις αλλαγές σε /etc, /bin, /usr. Μετά την εγκατάσταση είναι υποχρεωτική η αρχικοποίηση της βάσης (aideinit).

sudo apt install aide # Αρχικοποίηση της βάσης (5–15 λεπτά): sudo aideinit sudo cp /var/lib/aide/aide.db.new /var/lib/aide/aide.db # Ubuntu 24.04: ο κατάλογος /var/lib/aide δημιουργείται σε λειτουργία 700 (κάτοχος _aide), # και ο πίνακας (www-data) δεν βλέπει τη βάση → εμφανίζει «Δεν αρχικοποιήθηκε». # Ανοίξτε τον κατάλογο για διέλευση (τα αρχεία της βάσης παραμένουν 600): sudo chmod 755 /var/lib/aide # Πρώτος έλεγχος ΜΕ ΕΓΓΡΑΦΗ στο αρχείο καταγραφής που διαβάζει το monitor. # Σε Ubuntu/Debian το aide απαιτεί ρητό --config (αλλιώς «missing configuration»· # το εκτελέσιμο aide.wrapper δεν διανέμεται στις νέες εκδόσεις): sudo bash -c 'aide --config /etc/aide/aide.conf --check > /var/log/aide/aide.log 2>&1'
Κατά το aideinit το τερματικό μένει 5–15 λεπτά στη γραμμή Running aide --init... — αυτό είναι φυσιολογικό (κατακερματισμός όλου του συστήματος αρχείων, φόρτος στον δίσκο). Μην το διακόπτετε με Ctrl+C. Αν η διεργασία «κολλάει» αλλά δεν γράφει τίποτα — ίσως περιμένει απάντηση σε ένα κρυφό ερώτημα Overwrite existing aide.db.new [Yn]? (πατήστε Y). Ελέγξτε τη δραστηριότητα από άλλη συνεδρία: pgrep -af aide.
Σφάλμα aideinit: «21_aide_spamassassin … printf: invalid number» (return code 20) — γνωστό bug του config-snippet του AIDE στο Ubuntu 22.04. Η βάση δεν δημιουργείται. Αφαιρέστε το ελαττωματικό snippet και επαναλάβετε:
sudo mv /etc/aide/aide.conf.d/21_aide_spamassassin /etc/aide/21_aide_spamassassin.disabled sudo aideinit sudo cp /var/lib/aide/aide.db.new /var/lib/aide/aide.db
Καταστάσεις στον πίνακα. «Δεν αρχικοποιήθηκε» = ο πίνακας δεν βλέπει το αρχείο της βάσης: είτε δεν εκτελέστηκε το aideinit, είτε (Ubuntu 24.04) ο κατάλογος /var/lib/aide δημιουργήθηκε σε λειτουργία 700 και δεν είναι προσβάσιμος από τον www-data — διορθώνεται με sudo chmod 755 /var/lib/aide (δείτε το μπλοκ παραπάνω). «Δεν έγιναν έλεγχοι» = η βάση υπάρχει, αλλά δεν έχει εκτελεστεί ακόμη έλεγχος — δεν είναι σφάλμα. Τα αποτελέσματα το monitor τα διαβάζει από το /var/log/aide/aide.log.
Τακτικός έλεγχος → αρχείο καταγραφής για τον πίνακα. Το τυπικό /etc/cron.daily/aide στα νέα Ubuntu/Debian μπορεί να μη γράφει το /var/log/aide/aide.log στη σωστή μορφή (και το aide.wrapper δεν υπάρχει πλέον σε αυτά). Πιο αξιόπιστο είναι να προσθέσετε δικό σας cron με ρητό --config — γράφει το αρχείο ως root σε λειτουργία 644, και το monitor το διαβάζει χωρίς επιπλέον ομάδες:
# sudo crontab -e — καθημερινός έλεγχος στις 02:00: 0 2 * * * /usr/bin/aide --config /etc/aide/aide.conf --check > /var/log/aide/aide.log 2>&1 # Εκτελέστε το τώρα, χωρίς να περιμένετε το πρόγραμμα: sudo bash -c 'aide --config /etc/aide/aide.conf --check > /var/log/aide/aide.log 2>&1'
Η αυτόματη εγκατάσταση κάνει ήδη όλα αυτά: chmod 755 /var/lib/aide και cron ελέγχου στις 02:00 — δεν χρειάζεται τίποτα χειροκίνητα.
Κάντε την πρώτη αρχικοποίηση σε καθαρό διακομιστή — πριν την εγκατάσταση των web εφαρμογών. Μετά από νόμιμες αλλαγές, αναδημιουργήστε τη βάση: sudo aideinit && sudo cp /var/lib/aide/aide.db.new /var/lib/aide/aide.db.

15. Εγκατάσταση του ClamAV

Σαρωτής antivirus για Linux. Ιδιαίτερα χρήσιμος για έλεγχο του /var/www για PHP-shells και κακόβουλο κώδικα.

sudo apt install clamav clamav-daemon sudo systemctl enable --now clamav-daemon # Ενημέρωση της βάσης υπογραφών: sudo freshclam # Χειροκίνητη σάρωση φακέλου: sudo clamscan -r /var/www --infected
Ο δαίμονας clamd δείχνει «Ανενεργός» μετά το enable --now; Τρεις συνηθισμένες αιτίες:

1. Στο config έχει μείνει η γραμμή Example — ο clamd αρνείται να ξεκινήσει όσο υπάρχει:

sudo sed -i '/^Example/d' /etc/clamav/clamd.conf sudo systemctl restart clamav-daemon

2. Δεν έχει κατέβει η βάση υπογραφών — ο clamd δεν ξεκινά χωρίς αυτήν:

sudo systemctl stop clamav-freshclam sudo freshclam sudo systemctl start clamav-freshclam sudo systemctl restart clamav-daemon

3. Απλώς φορτώνει — ο clamd φορτώνει ~8 εκατ. υπογραφές στη μνήμη σε 30–60 δευτ. Περιμένετε και ελέγξτε: systemctl is-active clamav-daemon (κατάσταση activating → φορτώνει ακόμη).

Διαγνωστικά: sudo journalctl -u clamav-daemon -n 30 --no-pager.
Στο dashboard «Ελεγμένα αρχεία: 0» / «Τελευταία σάρωση: —»; Ο δαίμονας clamd απλώς κρατά τις υπογραφές στη μνήμη, ο ίδιος δεν σαρώνει τίποτα βάσει προγράμματος. Ο πίνακας δείχνει τα αποτελέσματα προγραμματισμένης σάρωσης, οπότε χρειάζεται ένα cron που σαρώνει και γράφει log. Η αυτόματη εγκατάσταση τοποθετεί το wrapper /usr/local/bin/clamav-scan.sh και cron στη 01:30 — μετά την πρώτη εκτέλεση θα συμπληρωθούν τα «Ελεγμένα αρχεία» και «Τελευταία σάρωση». Εκτελέστε το αμέσως, χωρίς να περιμένετε το πρόγραμμα: sudo /usr/local/bin/clamav-scan.sh.

16. Εγκατάσταση του Linux Malware Detect (maldet)

Linux Malware Detect (LMD) — σαρωτής κακόβουλου λογισμικού για διαδικτυακές απειλές: PHP-shells, web backdoors, downloaders. Χρησιμοποιεί τη μηχανή του ClamAV και τη συμπληρώνει με τις δικές του υπογραφές.

wget https://www.rfxn.com/downloads/maldetect-current.tar.gz tar -xzf maldetect-current.tar.gz dir=$(ls -d maldetect-*/ | head -1) && cd "$dir" && sudo bash install.sh && cd ~ rm -rf maldetect-* maldetect-current.tar.gz # Ενημέρωση υπογραφών: sudo maldet -u # Σάρωση του /var/www: sudo maldet -a /var/www
Το LMD και το ClamAV λειτουργούν καλά μαζί. Τελευταία αναφορά: maldet --report.
Κατά την εγκατάσταση μπορεί να εμφανιστεί η γραμμή update-rc.d: error: unable to read /etc/init.d/maldet — είναι ακίνδυνη. Το maldet δεν χρησιμοποιεί init.d, η ενημέρωση υπογραφών και οι σαρώσεις εκτελούνται μέσω /etc/cron.daily/maldet. Αν παρακάτω βλέπετε installation completed — όλα εγκαταστάθηκαν.
Στη σελίδα το LMD αναφέρεται ως «Δεν έχει εγκατασταθεί», ενώ είναι εγκατεστημένο; Το maldet δεν εγκαθίσταται μέσω apt, αλλά στο /usr/local/maldetect, και όταν είναι ενεργό το open_basedir η ύπαρξή του ελέγχεται μέσω shell — δείτε την ενότητα «Η σελίδα είναι κενή, ενώ υπάρχουν δεδομένα στον διακομιστή».

17. Εγκατάσταση του Suricata

Δικτυακό σύστημα ανίχνευσης εισβολών: αναλύει την κίνηση σε επίπεδο πακέτων και γνωρίζει χιλιάδες υπογραφές επιθέσεων. Συμπληρώνει το ModSecurity (το οποίο λειτουργεί σε επίπεδο HTTP, ενώ το Suricata σε επίπεδο TCP/IP).

sudo add-apt-repository ppa:oisf/suricata-stable sudo apt update && sudo apt install suricata # Λήψη των τρεχόντων κανόνων: sudo suricata-update sudo systemctl enable --now suricata
Το Suricata είναι «Ενεργό», αλλά ο πίνακας δεν δείχνει ειδοποιήσεις / ο αριθμός συμβάντων είναι 0; Το Suricata γράφει το /var/log/suricata/eve.json ως root με δικαιώματα 750 στον κατάλογο, και ο διακομιστής web (www-data) δεν μπορεί να το διαβάσει. Ανοίξτε τον κατάλογο για διέλευση — τα αρχεία μέσα παραμένουν προστατευμένα:
sudo chmod o+rx /var/log/suricata
Η αυτόματη εγκατάσταση το κάνει μόνη της — δεν χρειάζεται χειροκίνητα.

18. Εγκατάσταση Falco

Παρεμβάλλεται στις κλήσεις συστήματος μέσω eBPF/kernel module και εντοπίζει ανωμαλίες σε πραγματικό χρόνο: shell από nginx, ανάγνωση του /etc/passwd από διεργασία web, εγγραφή στο /bin κ.λπ.

curl -fsSL https://falco.org/repo/falcosecurity-packages.asc > /tmp/falco.asc gpg --dearmor < /tmp/falco.asc | sudo tee /usr/share/keyrings/falco-archive-keyring.gpg > /dev/null sudo chmod 644 /usr/share/keyrings/falco-archive-keyring.gpg && rm /tmp/falco.asc echo "deb [signed-by=/usr/share/keyrings/falco-archive-keyring.gpg] https://download.falco.org/packages/deb stable main" \ | sudo tee /etc/apt/sources.list.d/falcosecurity.list sudo apt update && sudo apt install falco sudo systemctl enable --now falco
Η μονάδα διαβάζει τα συμβάντα του Falco μέσω journalctl -u falco (χωρίς sudo — μέσω της ομάδας systemd-journal). Βεβαιωθείτε ότι ο www-data ανήκει σε αυτή την ομάδα — δείτε «Ρύθμιση sudo» (σημ.2) στη σελίδα χειροκίνητης εγκατάστασης.
«0 συμβάντα σε 24 ώρες» — είναι φυσιολογικό, όχι σφάλμα. Το Falco είναι event-driven: σιωπά όσο όλα πάνε καλά και καταγράφει συμβάν μόνο σε ανωμαλία (shell από διεργασία web, ανάγνωση του /etc/passwd, εγγραφή σε καταλόγους συστήματος). Μηδέν κρίσιμα σε ένα εικοσιτετράωρο σε έναν ήσυχο διακομιστή είναι υγιής κατάσταση.
Για τον πίνακα είναι πιο αξιόπιστη η έξοδος σε αρχείο. Η ανάγνωση μέσω journalctl απαιτεί δικαιώματα στο journal· για να βλέπει ο πίνακας τα συμβάντα σταθερά, η αυτόματη εγκατάσταση ενεργοποιεί στο Falco το file_output/var/log/falco/falco.log και θέτει στην υπηρεσία UMask=0022 (το log διαβάζεται από τον web server). Σε νέα εγκατάσταση δεν χρειάζεται να το ρυθμίσετε χειροκίνητα.

19. Εγκατάσταση ModSecurity (WAF)

ModSecurity — τείχος προστασίας web (WAF) για Apache ή Nginx. Μπλοκάρει επιθέσεις σε επίπεδο εφαρμογής: SQL injection, XSS, path traversal, σαρωτές.

# Apache: sudo apt install libapache2-mod-security2 sudo a2enmod security2 # Σύνολο κανόνων OWASP Core Rule Set: sudo apt install modsecurity-crs # ΥΠΟΧΡΕΩΤΙΚΟ: χωρίς αυτό το αρχείο η μηχανή κανόνων είναι απενεργοποιημένη sudo cp /etc/modsecurity/modsecurity.conf-recommended /etc/modsecurity/modsecurity.conf sudo sed -i 's/^SecRuleEngine DetectionOnly/SecRuleEngine On/' /etc/modsecurity/modsecurity.conf sudo apache2ctl configtest && sudo systemctl reload apache2 # Έλεγχος: πρέπει να επιστρέψει 403 curl -s -o /dev/null -w '%{http_code}\n' "https://monitor.example.com/?id=1%20UNION%20SELECT%201,2--"
Η εγκατάσταση του πακέτου από μόνη της δεν προστατεύει τίποτα. Ο Apache φορτώνει τα configs με τη γραμμή IncludeOptional /etc/modsecurity/*.conf, ενώ το πακέτο τοποθετεί μόνο το modsecurity.conf-recommended — αυτό δεν ταιριάζει με τη μάσκα *.conf. Αν δεν το αντιγράψετε στο modsecurity.conf, το SecRuleEngine παραμένει Off: η μονάδα είναι φορτωμένη, οι κανόνες CRS είναι φορτωμένοι, αλλά η κίνηση δεν ελέγχεται και δεν δημιουργείται αρχείο ελέγχου. Η ενδιάμεση λειτουργία DetectionOnly απλώς καταγράφει συμβάντα χωρίς να μπλοκάρει τα αιτήματα — ο πίνακας τη δείχνει κίτρινη.

Πρόσβαση του πίνακα στο αρχείο ελέγχου. Το αρχείο /var/log/apache2/modsec_audit.log ανήκει στον root (δικαιώματα 640), ο web χρήστης δεν μπορεί να το διαβάσει. Ο πίνακας λαμβάνει τα δεδομένα μέσω ενός wrapper — δημιουργήστε το:

sudo tee /usr/local/bin/monitor-modsec >/dev/null <<'EOF' #!/bin/sh echo "ENGINE=$(grep -hE '^SecRuleEngine[[:space:]]+' /etc/modsecurity/*.conf 2>/dev/null | tail -1 | awk '{print $2}')" echo "---LOG---" tail -n 3000 /var/log/apache2/modsec_audit.log 2>/dev/null echo "---RULES---" for f in /etc/modsecurity/crs/rules/*.conf /usr/share/modsecurity-crs/rules/*.conf /etc/modsecurity/custom-rules.conf; do [ -f "$f" ] && { echo "===FILE:$(basename "$f")==="; cat "$f"; } done EOF sudo chown root:root /usr/local/bin/monitor-modsec sudo chmod 755 /usr/local/bin/monitor-modsec # στο /etc/sudoers.d/monitor (χρήστης = αυτός με τον οποίο τρέχει ο PHP-FPM): # www-data ALL=(ALL) NOPASSWD: /usr/local/bin/monitor-modsec
Το wrapper λαμβάνει την τελευταία οδηγία SecRuleEngine χωρίς εσοχή: οι γραμμές με εσοχή βρίσκονται μέσα σε μπλοκ <LocationMatch>/<Directory> (για παράδειγμα, απενεργοποίηση του WAF για το phpMyAdmin) και δεν καθορίζουν την καθολική λειτουργία.
Ο χρήστης στο sudoers πρέπει να συμπίπτει με τον χρήστη του FPM pool: σε συνηθισμένο Apache/Debian αυτός είναι ο www-data, στο HestiaCP το pool του ιστότοπου τρέχει από τον ιδιοκτήτη του ιστότοπου (για παράδειγμα, admin) — ελέγξτε με grep -E '^user' /etc/php/*/fpm/pool.d/monitor.example.com.conf.
Αν ο ιστότοπος βρίσκεται πίσω από proxy Nginx (HestiaCP), ο Apache βλέπει ως πελάτη το ίδιο το proxy — ο πίνακας λαμβάνει την πραγματική IP του επιτιθέμενου από την κεφαλίδα X-Forwarded-For. Στα στατιστικά καταλήγουν μόνο οι συναλλαγές με ενεργοποιημένο κανόνα: η οδηγία SecAuditLogRelevantStatus γράφει στο αρχείο ελέγχου οποιεσδήποτε αποκρίσεις 4xx/5xx, οπότε εκεί καταλήγουν και τα συνηθισμένα 403/500 — ο πίνακας δεν τα θεωρεί συμβάντα WAF.
Το μπλοκ ---RULES--- χρειάζεται για την ενότητα «Όλοι οι ενεργοί κανόνες» — ο πίνακας δεν δείχνει μόνο τους κανόνες που ενεργοποιήθηκαν, αλλά όλους τους φορτωμένους κανόνες CRS + τους προσαρμοσμένους. Οι τρεις διαδρομές στον βρόχο for f in … είναι τα τυπικά σημεία για κανόνες CRS και τοπικές προσθήκες· αν έχετε διαφορετική διάταξη (το πακέτο τοποθετεί τα αρχεία στον δικό του κατάλογο, ή οι προσαρμοσμένοι κανόνες δεν βρίσκονται στο /etc/modsecurity/custom-rules.conf), βρείτε τις πραγματικές διαδρομές με την εντολή sudo grep -rl 'IncludeOptional\|^Include ' /etc/apache2/mods-enabled/security2.conf /etc/apache2/conf-enabled/*.conf 2>/dev/null και τοποθετήστε τις στη λίστα. Αν το wrapper είναι παλιό (χωρίς αυτή την ενότητα) — η ενότητα απλώς θα δείξει την προειδοποίηση «μη διαθέσιμο», η υπόλοιπη σελίδα λειτουργεί όπως πριν.

20. Εγκατάσταση Auditd

Auditd (Linux Audit Daemon) καταγράφει τις κλήσεις συστήματος σε επίπεδο πυρήνα: συνδέσεις και αποσυνδέσεις, εντολές sudo, αποτυχημένες προσπάθειες ταυτοποίησης, αλλαγές αρχείων. Η μονάδα εμφανίζει τις συνδέσεις, τις αποτυχημένες προσπάθειες και τις εντολές sudo της σημερινής ημέρας.

sudo apt install auditd audispd-plugins sudo systemctl enable --now auditd # Έλεγχος κατάστασης και συμβάντων: sudo systemctl status auditd sudo ausearch -m USER_LOGIN -ts today
Η μονάδα διαβάζει τα συμβάντα μέσω ausearch (/usr/sbin/ausearch) και, όταν χρειάζεται, από το /var/log/audit/audit.log με την εντολή tail. Και τα δύο πρέπει να βρίσκονται στο sudoers.

21. Εγκατάσταση του Monit

Παρακολουθεί υπηρεσίες (nginx, php-fpm, mysql κ.λπ.) και τις επανεκκινεί όταν πέσουν. Μπορεί να στέλνει ειδοποιήσεις σε email.

sudo apt install monit sudo systemctl enable --now monit # Αρχεία ρυθμίσεων: sudo nano /etc/monit/monitrc ls /etc/monit/conf.d/
Ο μόνιτορ λαμβάνει τη λίστα υπηρεσιών μέσω monit status. Στο /etc/monit/monitrc πρέπει να είναι ενεργοποιημένο το HTTP interface (μπλοκ set httpd με allow localhost), αλλιώς το monit status θα επιστρέψει σφάλμα.
Στον πίνακα «0 υπηρεσίες υπό παρακολούθηση»; Δύο αιτίες. (1) Το HTTP interface είναι απενεργοποιημένο — στο monitrc η γραμμή set httpd είναι σε σχόλιο (από προεπιλογή είναι ως # set httpd port 2812 …). Αφαιρέστε το σχόλιο από το μπλοκ και επιτρέψτε το localhost. (2) Το ενεργοποιημένο httpd από μόνο του δεν παρακολουθεί τίποτα — το Monit μετράει μόνο ό,τι περιγράφεται με στάντζες check· χωρίς αυτές η λίστα είναι κενή ακόμη και με λειτουργικό interface. Ελάχιστη λειτουργική ρύθμιση:
# /etc/monit/conf.d/00-httpd — HTTP interface για localhost: set httpd port 2812 use address localhost allow localhost # παραδείγματα στάντζων check (τι να παρακολουθείται): check process sshd with pidfile /run/sshd.pid start program = "/usr/bin/systemctl start ssh" stop program = "/usr/bin/systemctl stop ssh" check filesystem rootfs with path / if space usage > 90% then alert
sudo monit -t # έλεγχος σύνταξης (Control file syntax OK) sudo systemctl reload monit sudo monit status
Η αυτόματη εγκατάσταση τοποθετεί έτοιμο conf.d με httpd στη 2812 και ένα σύνολο ελέγχων — σε νέα εγκατάσταση δεν χρειάζεται χειροκίνητη ρύθμιση.
Υπηρεσία σε κατάσταση «Με σφάλματα»; Ο μόνιτορ απλώς εμφανίζει την κατάσταση και σκόπιμα δεν επανεκκινεί υπηρεσίες από τον web πίνακα (αυτό θα ήταν απομακρυσμένη εκτέλεση εντολών root σε πίνακα ασφαλείας). Διάγνωση και επανεκκίνηση — μέσω SSH με το Monit:
sudo monit status <service> # αιτία του σφάλματος sudo monit restart <service> # επανεκκίνηση μέσω Monit # αν το Monit δεν σηκώνει την υπηρεσία — δείτε το δικό της unit: sudo systemctl status <unit> --no-pager sudo journalctl -u <unit> -n 50 --no-pager

22. Εγκατάσταση PSAD (ανίχνευση σάρωσης θυρών)

PSAD αναλύει το αρχείο καταγραφής του iptables και εντοπίζει σαρώσεις θυρών και δικτυακές επιθέσεις, αποδίδοντας σε κάθε πηγή ένα επίπεδο απειλής (1–5). Συμπληρώνει τα fail2ban και Suricata.

sudo apt install psad # Το PSAD διαβάζει το log του iptables — πρέπει να ενεργοποιηθεί η καταγραφή (το UFW το κάνει μόνο του). # Για καθαρό iptables προσθέστε κανόνες LOG στις αλυσίδες INPUT/FORWARD. sudo psad --sig-update sudo systemctl enable --now psad
Η μονάδα διαβάζει δεδομένα μέσω psad --Status (απαιτείται στο sudoers). Χωρίς καταγραφή του iptables η σελίδα θα είναι κενή — αυτό είναι φυσιολογικό όσο δεν έχουν γίνει σαρώσεις.

23. AppArmor / SELinux (έλεγχος πρόσβασης)

Mandatory Access Control περιορίζει σε ποια αρχεία και πόρους μπορεί να έχει πρόσβαση ένα πρόγραμμα, ακόμη κι αν παραβιαστεί. Στα Ubuntu/Debian χρησιμοποιείται από προεπιλογή το AppArmor (συνήθως ήδη εγκατεστημένο και ενεργό).

# AppArmor (Ubuntu/Debian): sudo apt install apparmor apparmor-utils sudo systemctl enable --now apparmor sudo aa-status # έλεγχος προφίλ
Η μονάδα διαβάζει την κατάσταση μέσω aa-status (απαιτείται στο sudoers). Δείχνει τον αριθμό των προφίλ σε λειτουργία enforce/complain και τις διεργασίες χωρίς προφίλ.

Τα «φορτωμένα προφίλ» είναι περισσότερα από enforce + complain — αυτό είναι φυσιολογικό. Στο AppArmor 4.x (Ubuntu 24.04 και νεότερα) προστέθηκε η λειτουργία unconfined: το προφίλ είναι φορτωμένο στον πυρήνα, αλλά δεν περιορίζει τίποτα. Το Ubuntu επισημαίνει έτσι δεκάδες προφίλ για προγράμματα που χρησιμοποιούν user namespaces (προγράμματα περιήγησης, πελάτες torrent και παρόμοια). Όταν υπάρχουν τέτοια προφίλ, η κάρτα «Φορτωμένα προφίλ» γίνεται πορτοκαλί και δείχνει τον αριθμό τους — για παράδειγμα unconfined: 90 με 120 φορτωμένα και 26 σε enforce. Πραγματική προστασία παρέχουν μόνο τα προφίλ σε enforce· στο Ubuntu 22.04 (AppArmor 3.x) δεν υπάρχει αυτή η λειτουργία και οι αριθμοί πάντα ταιριάζουν.

sudo aa-status | grep -E "profiles are" # ανάλυση ανά λειτουργία sudo aa-enforce /etc/apparmor.d/profile-name # μετάβαση προφίλ σε enforce
Η μετάβαση σε enforce των προφίλ που το Ubuntu άφησε σκόπιμα σε unconfined αξίζει μόνο συνειδητά: είναι απενεργοποιημένα όχι κατά λάθος, αλλά επειδή διαφορετικά χαλάει η λειτουργία των ίδιων των προγραμμάτων. Τα προφίλ σε complain είναι άλλη υπόθεση: εκεί οι κανόνες έχουν ήδη γραφτεί και απλώς δεν εφαρμόζονται.

24. Εγκατάσταση debsums (ακεραιότητα πακέτων)

Το debsums ελέγχει ότι τα αρχεία των εγκατεστημένων πακέτων ταιριάζουν με τα αθροίσματα ελέγχου του αποθετηρίου — εντοπίζει αλλοιωμένα εκτελέσιμα του συστήματος (συμπληρώνει το AIDE). Ο πλήρης έλεγχος διαρκεί 1–2 λεπτά, γι' αυτό εκτελείται μέσω cron, και ο πίνακας διαβάζει το αποτέλεσμα από το data/debsums/debsums.log και το κατηγοριοποιεί μόνος του (σημασία έχουν μόνο τα εκτελέσιμα και οι βιβλιοθήκες).

Η εργασία μπαίνει στο root-cron (sudo crontab -e). Το έτοιμο περιτύλιγμα debsums-scan.sh τοποθετείται στο /usr/local/bin/ (chmod +x· δείτε τη σύνοψη εργασιών cron) και γράφει μόνο του την αναφορά στο data/debsums/ του πίνακα.

sudo apt install debsums # Γραμμή cron (καθημερινά 4:30): 30 4 * * * /usr/local/bin/debsums-scan.sh >> /path/to/monitor/logs/cron.log 2>&1

Το περιτύλιγμα debsums-scan.sh βρίσκει μόνο του το data/ του πίνακα — δεν χρειάζεται να ορίσετε διαδρομή.

Οι αλλαγές στα /etc/ (ρυθμίσεις) και /usr/share/ (πόροι) στον διακομιστή είναι συνήθως φυσιολογικές — ο πίνακας τις επισημαίνει με ξεχωριστό χρώμα. Ανησυχητικές είναι οι αλλαγές σε εκτελέσιμα και βιβλιοθήκες (/bin, /sbin, /usr/lib κ.λπ.) — η κάρτα «Εκτελέσιμα / βιβλιοθήκες» δείχνει ακριβώς αυτές.

25. Ρύθμιση αναφορών Lynis

Το Lynis εκτελείται χειροκίνητα ή μέσω cron. Η αναφορά πρέπει να αποθηκεύεται στον φάκελο data/lynis/ του έργου — η μονάδα διαβάζει το αρχείο lynis-report.dat.

# Μεμονωμένη εκτέλεση (βάλτε τη δική σας διαδρομή προς τη ρίζα του πίνακα): sudo lynis audit system --report-file /path/to/monitor/data/lynis/lynis-report.dat # Καθημερινός έλεγχος — γραμμή cron (έτοιμο wrapper lynis-scan.sh στο /usr/local/bin/, δείτε τη σύνοψη): 0 3 * * * /usr/local/bin/lynis-scan.sh >> /path/to/monitor/logs/cron.log 2>&1
Μετά την πρώτη εκτέλεση, η σελίδα «Έλεγχος Lynis» θα εμφανίσει αμέσως το hardening index, τις προειδοποιήσεις και τις συστάσεις.
Το κουμπί «Εκτέλεση ελέγχου» στη σελίδα Lynis. Εκτελεί το lynis-scan.sh στο παρασκήνιο απευθείας από τον πίνακα (χωρίς αναμονή για το cron): εμφανίζει «Σάρωση…» και με την ολοκλήρωση ενημερώνει μόνο του την αναφορά. Για αυτό, ο χρήστης web χρειάζεται μια γραμμή sudoers για την εκτέλεση του script — ο εγκαταστάτης την προσθέτει αυτόματα στο /etc/sudoers.d/monitor. Αν ο πίνακας εγκαταστάθηκε χειροκίνητα/παλαιότερα, προσθέστε την με τον ίδιο χρήστη που αναγράφεται ήδη στο αρχείο:
u=$(sudo awk '/NOPASSWD/ && !/lynis-scan/ {print $1; exit}' /etc/sudoers.d/monitor) [ -n "$u" ] && echo "$u ALL=(ALL) NOPASSWD: /usr/local/bin/lynis-scan.sh" | sudo tee -a /etc/sudoers.d/monitor sudo visudo -c && sudo chmod 440 /etc/sudoers.d/monitor

26. Ρύθμιση αναφορών Logwatch

Το Logwatch πρέπει να αποθηκεύει τις καθημερινές αναφορές στον φάκελο data/logwatch/ του έργου σε μορφή .txt. Η μονάδα εμφανίζει την τελευταία αναφορά και το αρχείο.

# Καθημερινά (6:00) — γραμμή cron (έτοιμο wrapper logwatch_daily.sh στο /usr/local/bin/, βλ. σύνοψη): 0 6 * * * /usr/local/bin/logwatch_daily.sh >> /path/to/monitor/logs/cron.log 2>&1

Μονάδες πίνακα

27. Παρακολούθηση δικτύου (ενσωματωμένη)

Η παρακολούθηση δικτύου δεν απαιτεί εγκατάσταση — είναι μια ενσωματωμένη σελίδα του πίνακα. Εμφανίζει την κατάσταση δικτύου του διακομιστή από τοπικές πηγές:

  • διεπαφές και κίνηση — από /proc/net/dev·
  • κατάσταση συνδέσμων (UP/DOWN) και IP — μέσω ip·
  • συνδέσεις και θύρες σε ακρόαση — μέσω ss·
  • συμβάντα δικτύου του πυρήνα τελευταίων 24ω — μέσω journalctl -k.

Οι τρεις πρώτες πηγές λειτουργούν χωρίς sudo, οπότε οι διεπαφές, η κίνηση, οι συνδέσεις και οι θύρες φαίνονται αμέσως. Το τμήμα «Συμβάντα πυρήνα» χρησιμοποιεί journalctl -k — διαβάζεται μέσω της ομάδας systemd-journal («Ρύθμιση sudo», β.2), δεν χρειάζεται sudo. Ελέγξτε ότι όλα είναι προσβάσιμα από τον χρήστη web:

# Έλεγχος ως www-data (κάτω από αυτόν τρέχει η PHP): sudo -u www-data bash -c 'cat /proc/net/dev' sudo -u www-data bash -c 'ip -o link show' sudo -u www-data bash -c 'ss -s' sudo -u www-data journalctl -k --no-pager -n 5
Το τμήμα «Συμβάντα δικτύου πυρήνα» εμφανίζει συμβάντα της στοίβας δικτύου του πυρήνα (αλλαγή συνδέσμου up/down, σφάλματα φέροντος, «network unreachable»). Οι εγγραφές του τείχους UFW BLOCK δεν εμφανίζονται εδώ — βρίσκονται στις σελίδες «Τείχος προστασίας UFW» και «Χάρτης επιθέσεων». Κενό τμήμα με πράσινο τικ = μέσα στο 24ωρο δεν υπήρξαν αστοχίες δικτύου.

28. Δίσκος και SMART

Η ενσωματωμένη σελίδα εμφανίζει τρία πράγματα:

  • Συστήματα αρχείων — πληρότητα κατατμήσεων (df)· η μπάρα κοκκινίζει στο ≥90%·
  • Αποθηκευτικά μέσα — λίστα δίσκων (lsblk), μόνο πραγματικά (τα loop/snap αποκρύπτονται)·
  • Υγεία (SMART) — κατάσταση δίσκου και χαρακτηριστικά (smartctl).

Ο χώρος και η λίστα συσκευών λειτουργούν αμέσως, χωρίς ρύθμιση. Για το SMART απαιτείται το πακέτο smartmontools. Η διεργασία web δεν έχει άμεση πρόσβαση στις συσκευές δίσκων, γι' αυτό το SMART λαμβάνεται μέσω cron στο αρχείο data/disk/smart.txt, και ο πίνακας το διαβάζει.

Η εργασία μπαίνει στο root-cron (sudo crontab -e). Το έτοιμο wrapper smart-scan.sh τοποθετείται στο /usr/local/bin/ (chmod +x· δείτε τη σύνοψη εργασιών cron) και γράφει το ίδιο στο data/disk/ του πίνακα.

sudo apt install smartmontools # Γραμμή cron (κάθε 30 λεπτά): */30 * * * * /usr/local/bin/smart-scan.sh >> /path/to/monitor/logs/cron.log 2>&1

Το wrapper smart-scan.sh εντοπίζει μόνο του το data/ του πίνακα — δεν χρειάζεται να ορίσετε διαδρομή. Εσωτερικά το lsblk -e7,11 εξαιρεί τα loop/cdrom.

Σε εικονικούς δίσκους (QEMU/KVM και παρόμοιους) συνήθως διατίθεται μόνο η γενική κατάσταση «υγεία: OK», ενώ η θερμοκρασία, οι ώρες λειτουργίας και οι ανακατανεμημένοι τομείς μπορεί να είναι κενά — αυτό είναι φυσιολογικό. Σε φυσικό διακομιστή εμφανίζονται όλα τα χαρακτηριστικά.

29. Επιδόσεις (CPU/RAM/Δίκτυο/Δίσκος)

Η σελίδα εμφανίζει το ιστορικό φορτίου του διακομιστή για τις τελευταίες 24 ώρες — Load Average, χρήση CPU και αναμονή I/O, RAM/Swap, δικτυακή κίνηση (λήψη/αποστολή), I/O δίσκου (ανάγνωση/εγγραφή), πλήρωση δίσκου και inodes, ανοιχτούς περιγραφείς αρχείων και συνδέσεις MySQL, καθώς και τον τρέχοντα αριθμό συνδέσεων TCP και διεργασιών.

Τα δεδομένα συλλέγει το cron/collect_metrics.php — κάθε 5 λεπτά γράφει ένα «ακατέργαστο» στιγμιότυπο των μετρητών (/proc/loadavg, /proc/meminfo, /proc/stat, /proc/net/dev, /proc/diskstats, df/df -i, /proc/sys/fs/file-nr, SHOW GLOBAL STATUS LIKE 'Threads_connected') στον πίνακα ΒΔ system_metrics· τα ποσοστά και τις ταχύτητες τα υπολογίζει η ίδια η σελίδα από τη διαφορά μεταξύ γειτονικών στιγμιότυπων (πλήρωση δίσκου/inodes/περιγραφέων/συνδέσεων MySQL — στιγμιαίες τιμές, χωρίς επανυπολογισμό). Δεν απαιτείται sudo — οι πηγές διαβάζονται χωρίς δικαιώματα root. Τα σημεία παλαιότερα των 24 ωρών διαγράφονται αυτόματα σε κάθε εγγραφή.

# Γραμμή cron (κάθε 5 λεπτά): */5 * * * * /usr/local/bin/collect-metrics-all.sh >> /path/to/monitor/logs/cron.log 2>&1

Το wrapper collect-metrics-all.sh (δείτε τη σύνοψη εργασιών cron) εντοπίζει μόνο του όλα τα εγκατεστημένα instances του πίνακα στον διακομιστή και εκτελεί το cron/collect_metrics.php του καθενός με ταυτότητα του κατόχου του ιστότοπου.

Μέχρι ο συλλέκτης να τρέξει τουλάχιστον δύο φορές (τα πρώτα ~10 λεπτά μετά την εγκατάσταση), η σελίδα εμφανίζει «γίνεται συλλογή δεδομένων» — τα γραφήματα χρειάζονται τουλάχιστον ένα ζεύγος γειτονικών σημείων για να υπολογίσουν ταχύτητες και ποσοστά.

Ειδοποιήσεις φορτίου (ενότητα «Ρυθμίσεις» → «Ειδοποιήσεις φορτίου») — όταν ξεπεραστεί το όριο CPU/RAM/δίσκου/inodes, ο πίνακας στέλνει ειδοποίηση στο Telegram/Email (τα ίδια κανάλια με την ημερήσια αναφορά — δεν χρειάζεται να τα ενεργοποιήσετε ξεχωριστά για τις ειδοποιήσεις), και άλλη μία — όταν η μετρική επανέλθει στο φυσιολογικό. Δεν στέλνει spam όσο διαρκεί το ξεπέρασμα του ορίου: η επόμενη ειδοποίηση θα έρθει μόνο μετά τον κύκλο «επανήλθε → ξαναξεπεράστηκε».

Τα όρια ελέγχονται από το ίδιο το collect_metrics.php σε κάθε εκτέλεση (κάθε 5 λεπτά) — δεν χρειάζεται ξεχωριστό cron. Η κατάσταση «ήδη ειδοποιήσαμε / όχι ακόμη» αποθηκεύεται στο data/alerts_state.json, τα όρια — στις ρυθμίσεις του πίνακα.

30. Χάρτης επιθέσεων (GeoIP)

Η σελίδα «Χάρτης επιθέσεων» εντοπίζει τη χώρα από την IP με την εντολή geoiplookup. Χωρίς το πακέτο GeoIP δεν εντοπίζονται οι χώρες και δεν εμφανίζονται σημεία στον χάρτη:

sudo apt install geoip-bin geoip-database # Έλεγχος: geoiplookup 8.8.8.8
Δεν απαιτείται sudo — η βάση /usr/share/GeoIP/GeoIP.dat είναι αναγνώσιμη από όλους, τα αποτελέσματα αποθηκεύονται προσωρινά στο tmp/geoip_cache.json. Ο ίδιος ο χάρτης (Leaflet + πλακίδια OpenStreetMap) φορτώνεται στο πρόγραμμα περιήγησης — χρειάζεται σύνδεση στο διαδίκτυο στον υπολογιστή όπου είναι ανοιχτός ο πίνακας.

31. Εξωτερική έκθεση, ενημερώσεις και αυτόματες ενημερώσεις

Δύο ενσωματωμένες κάρτες του dashboard που δείχνουν όχι το «ενεργό/ανενεργό» ενός εργαλείου, αλλά την πραγματική προστασία του διακομιστή. Δεν χρειάζονται εγκατάσταση, διαβάζονται τοπικά χωρίς sudo.

Εξωτερική έκθεση — πόσες υπηρεσίες ακούν σε όλες τις διεπαφές (0.0.0.0/[::]) και είναι προσβάσιμες από έξω. Επισημαίνει με κόκκινο αν εκτίθενται προς τα έξω βάσεις δεδομένων ή cache (MySQL, PostgreSQL, Redis, MongoDB, Memcached, Elasticsearch) — είναι άμεση τρύπα (−10 στη Βαθμολογία ασφάλειας). Πηγή: ss -tuln.

Αν η κάρτα είναι κόκκινη — κλείστε τη βάση δεδομένων προς τον έξω κόσμο: δέστε την στο 127.0.0.1 (bind-address στη ρύθμιση του MySQL/PostgreSQL, bind 127.0.0.1 στο Redis) ή κλείστε τη θύρα στο UFW.
«Ανοιχτή θύρα» ≠ «προσβάσιμη από έξω». Μια υπηρεσία που ακούει στο 127.0.0.1 (loopback) είναι ορατή μόνο στον ίδιο τον διακομιστή — από έξω δεν την προσεγγίζεις, ακόμη κι αν η θύρα είναι «ανοιχτή». Γι' αυτό το Postfix στη θύρα 25, δεμένο στο loopback, είναι ασφαλές: η αυτόματη ρύθμιση ορίζει inet_interfaces = loopback-only (συν ουδέτερο smtpd_banner — κλείνει την παρατήρηση MAIL-8818 του Lynis για την αποκάλυψη έκδοσης). Η κάρτα «Εξωτερική έκθεση» θεωρεί εκτεθειμένο προς τα έξω μόνο ό,τι ακούει στο 0.0.0.0/[::]· οι υπηρεσίες loopback δεν συμπεριλαμβάνονται.
Lynis MAIL-8818 χειροκίνητα (αν στήσατε το mail μόνοι σας): στο /etc/postfix/main.cf ορίστε smtpd_banner = $myhostname ESMTP (χωρίς έκδοση και ΛΣ) και inet_interfaces = loopback-only, μετά sudo systemctl restart postfix.

Ενημερώσεις ασφαλείας — πόσα security patch περιμένουν εγκατάσταση και αν χρειάζεται επανεκκίνηση μετά την ενημέρωση του πυρήνα (−5 στη Βαθμολογία ασφάλειας όταν υπάρχουν patch). Πηγή: /usr/lib/update-notifier/apt-check, αρχείο /var/run/reboot-required. Αναλυτική λίστα — στη σελίδα «Ενημερώσεις ασφαλείας».

# Εγκατάσταση ενημερώσεων: sudo apt update && sudo apt upgrade # Έλεγχος τι ακούει προς τα έξω: ss -tuln | grep -E '0\.0\.0\.0|\[::\]'
Η κάρτα ενημερώσεων λειτουργεί σε Ubuntu/Debian (update-notifier-common). Αν λείπει το apt-check — η μονάδα μετρά τα patch μέσω apt-get -s upgrade.

Αυτόματες ενημερώσεις ασφαλείας (unattended-upgrades) — στη σελίδα «Ενημερώσεις ασφαλείας» μια ξεχωριστή κάρτα δείχνει αν είναι ενεργή η αυτόματη εγκατάσταση των security patch και πότε εκτελέστηκε τελευταία φορά. Δεν χρειάζεται sudo — η κατάσταση διαβάζεται μέσω apt-config dump.

sudo apt install unattended-upgrades sudo dpkg-reconfigure -plow unattended-upgrades # ενεργοποίηση # Έλεγχος τι είναι ενεργό: apt-config dump | grep Unattended-Upgrade

Συντήρηση

32. Αντίγραφα ασφαλείας

Το backup είναι η βασική ασφάλεια: η απώλεια δεδομένων είναι χειρότερη από κάθε παραβίαση. Χρειάζονται δύο πράγματα — backup του διακομιστή/των ιστότοπων και ξεχωριστά backup της ΒΔ του πίνακα (εκεί βρίσκονται χρήστες, κλειδιά WebAuthn, ρυθμίσεις, άδεια).

Επιλογή A — HestiaCP: καρτέλα Backup στον χρήστη → κουμπί δημιουργίας backup (ή προγραμματισμένα στις ρυθμίσεις του διακομιστή). Το backup περιλαμβάνει ιστότοπους και τις ΒΔ τους.

Επιλογή B — χειροκίνητα (cron): dump της ΒΔ + αρχειοθέτηση του καταλόγου data/ του πίνακα:

# root-cron (sudo crontab -e) — καθημερινό backup στις 2:30 (βάλτε τα δικά σας ονόματα/διαδρομές): 30 2 * * * mysqldump -u root MY_DB | gzip > /var/backups/monitor-db-$(date +\%F).sql.gz 40 2 * * * tar czf /var/backups/monitor-data-$(date +\%F).tar.gz -C /path/to/monitor data # Διαγραφή αρχείων παλαιότερων των 14 ημερών: 0 3 * * * find /var/backups -name 'monitor-*' -mtime +14 -delete
Το backup στον ίδιο διακομιστή σας σώζει από λάθη, αλλά όχι από απώλεια του διακομιστή. Αντιγράφετε τα αρχεία σε εξωτερικό χώρο αποθήκευσης (άλλος διακομιστής, S3, rclone στο cloud). Ελέγχετε ότι η επαναφορά πράγματι λειτουργεί.

33. Ενημέρωση και μεταφορά του πίνακα

Ενημέρωση σε νέα έκδοση. Πρώτα κάντε αντίγραφο ασφαλείας. Στη συνέχεια ανεβάστε ξανά τα αρχεία κώδικα, διατηρώντας τα δεδομένα σας:

  • αντικατάσταση (κώδικας): public/, includes/, assets/, cron/, database/, καθώς και τα βασικά .htaccess (front controller — η δρομολόγηση δεν πρέπει να παραμένει από την παλιά έκδοση), manifest.json, sw.js;
  • μην αγγίξετε: config.php (δεδομένα ΒΔ), data/ (αναφορές), logs/, tmp/ (συνεδρίες και προσωρινή μνήμη).
# Μετά το ανέβασμα — καθαρίστε την cache της PHP (αν είναι ενεργό το opcache): sudo systemctl reload php*-fpm
Το FileZilla αναφέρει SSH_FX_PERMISSION_DENIEDPermission denied. Τα αρχεία του πίνακα ανήκουν στον www-data (έτσι ορίστηκαν κατά την εγκατάσταση), ενώ ο πελάτης SFTP συνδέεται με τον δικό σας χρήστη, που δεν έχει δικαίωμα εγγραφής. Το να δώσετε στον www-data ολόκληρο τον πίνακα «για να δουλέψει» είναι ακριβώς αυτό που οδηγεί σε αυτό το σφάλμα· παρακάτω τρεις τρόποι, οποιοσδήποτε λύνει το πρόβλημα.
# Παραλλαγή A (συνιστάται) — διαχωρίστε τους ιδιοκτήτες: ο κώδικας δικός σας, οι φάκελοι εργασίας του διακομιστή web. # Ο διακομιστής web δεν αποκτά καθόλου δικαίωμα εγγραφής στον ΚΩΔΙΚΑ του πίνακα: sudo chown -R deploy:www-data /path/to/monitor sudo chown -R www-data:www-data /path/to/monitor/data /path/to/monitor/tmp /path/to/monitor/logs sudo find /path/to/monitor -type d -exec chmod 755 {} \; sudo find /path/to/monitor -type f -exec chmod 644 {} \; sudo chmod 750 /path/to/monitor/data /path/to/monitor/tmp /path/to/monitor/logs sudo chmod 640 /path/to/monitor/config.php # Παραλλαγή B — ACL πάνω από τους τρέχοντες ιδιοκτήτες (δεν μεταφέρουμε τίποτα): sudo apt install -y acl sudo setfacl -R -m u:deploy:rwX /path/to/monitor sudo setfacl -R -d -m u:deploy:rwX /path/to/monitor # Παραλλαγή C — μέσω της ομάδας www-data. Πιο απλή, αλλά δικαίωμα εγγραφής στα # αρχεία του πίνακα αποκτά και ο διακομιστής web (με ευπάθεια στην PHP ο κώδικας αντικαθίσταται): sudo usermod -aG www-data deploy sudo find /path/to/monitor -type d -exec chmod 2775 {} \; sudo find /path/to/monitor -type f -exec chmod 664 {} \; sudo chmod 640 /path/to/monitor/config.php sudo chmod 2750 /path/to/monitor/data /path/to/monitor/tmp /path/to/monitor/logs
Γιατί η παραλλαγή A είναι ασφαλής. Ο πίνακας γράφει μόνο σε τρεις καταλόγους — data/ (αναφορές), tmp/ (συνεδρίες και προσωρινή μνήμη), logs/· αυτοί παραμένουν στον www-data. Τα υπόλοιπα είναι κώδικας, και ο διακομιστής web τον χρειάζεται μόνο για ανάγνωση, την οποία δίνει η ομάδα www-data με δικαιώματα 644. Επιπλέον όφελος: με ευπάθεια στην PHP τα αρχεία του πίνακα δεν μπορούν πλέον να αντικατασταθούν. Στους πίνακες φιλοξενίας (HestiaCP και παρόμοιους) η παραλλαγή A δεν χρειάζεται: εκεί τα αρχεία του ιστότοπου ανήκουν έτσι κι αλλιώς στον λογαριασμό με τον οποίο συνδέεστε μέσω SFTP, ενώ ο διακομιστής web τα διαβάζει μέσω ομάδας.
Παγίδα της παραλλαγής B: κάθε επόμενο chmod στα αρχεία μηδενίζει τη μάσκα ACL, και η πρόσβαση χάνεται σιωπηλά. Αν μετά από «τακτοποίηση των δικαιωμάτων» το ανέβασμα σκοντάφτει ξανά σε Permission denied — επαναλάβετε και τις δύο εντολές setfacl.
Το bit 2 στην παραλλαγή C είναι το setgid: τα αρχεία που ανεβαίνουν μέσω SFTP παραμένουν στην ομάδα www-data, αλλιώς ο πίνακας δεν μπορεί να τα αντικαταστήσει. Μετά την παραλλαγή C συνδεθείτε ξανά στο FileZilla — η νέα ομάδα ισχύει μόνο σε νέα σύνδεση. Έλεγχος: id deploy (πρέπει να εμφανιστεί η ομάδα www-data) και ls -ld /path/to/monitor (drwxrwsr-x — το γράμμα s σημαίνει ότι το setgid είναι ενεργό).

Μεταφορά σε άλλον διακομιστή:

  1. Στον νέο διακομιστή στήστε τον ιστότοπο + HTTPS (δείτε τη σελίδα χειροκίνητης εγκατάστασης).
  2. Αντιγράψτε όλα τα αρχεία του πίνακα μαζί με τα config.php, data/.
  3. Μεταφέρετε τη ΒΔ: mysqldump στον παλιό → εισαγωγή στον νέο· διορθώστε τα δεδομένα ΒΔ στο config.php.
  4. Επαναλάβετε στον νέο διακομιστή: sudoers, συμμετοχή στην ομάδα adm, εργασίες cron.
  5. Η άδεια είναι συνδεδεμένη με τον τομέα — αν ο τομέας είναι ο ίδιος, το κλειδί θα συνεχίσει να λειτουργεί.

34. Επαναφορά πρόσβασης (χαμένο κλειδί, κωδικός, μπλοκάρισμα IP)

Αν δεν μπορείτε να συνδεθείτε — όλα διορθώνονται απευθείας στη ΒΔ από τον διακομιστή. Ανοίξτε τη ΒΔ (το όνομα από το config.php):

sudo mysql MY_DB

Χάθηκε το κλειδί WebAuthn (δεν περνά ο δεύτερος παράγοντας) — απενεργοποιήστε το 2FA, συνδεθείτε με κωδικό και καταχωρίστε νέο κλειδί:

UPDATE users SET webauthn_enabled = 0;

Ξεχάσατε τον κωδικό — ορίστε νέο hash (δημιουργήστε τον στον διακομιστή και βάλτε τον):

# Δημιουργία hash νέου κωδικού: php -r "echo password_hash('NEW_PASSWORD', PASSWORD_BCRYPT), \"\n\";" # Στη ΒΔ (βάλτε το hash που πήρατε): # UPDATE users SET password = '$2y$10$...' WHERE username = 'admin';

Κλειδωθήκατε έξω με το φίλτρο IP — απενεργοποιήστε τον περιορισμό:

UPDATE settings SET value = '0' WHERE name = 'ip_restriction_enabled';
Πρόσβαση στη ΒΔ υπάρχει πάντα: sudo mysql στον διακομιστή, ή phpMyAdmin / η ενότητα ΒΔ στον πίνακα του hosting. Μετά την επαναφορά, ενεργοποιήστε ξανά το WebAuthn και το φίλτρο IP.

35. Όλες οι εργασίες cron σε ένα μέρος

Η σύνοψη των εργασιών βρίσκεται στο root-cron του διακομιστή (προστίθενται μέσω sudo crontab -e). Αφήστε μόνο τις γραμμές των εργαλείων που χρησιμοποιείτε· προσαρμόστε τις διαδρομές στον διακομιστή σας.

# Cron διακομιστή της μονάδας (root) — προσθέστε μέσω: sudo crontab -e # 01:30 — σάρωση ClamAV σε επικίνδυνες διαδρομές (web, home, temp) → κάρτες «Αρχεία που ελέγχθηκαν» και «Τελευταία σάρωση» 30 1 * * * /usr/local/bin/clamav-scan.sh >> /path/to/monitor/logs/cron.log 2>&1 # 02:00 — έλεγχος ακεραιότητας αρχείων AIDE (απαιτείται ρητό --config) 0 2 * * * /usr/bin/aide --config /etc/aide/aide.conf --check > /var/log/aide/aide.log 2>&1 # κατά την εκκίνηση — επαναφορά δικαιωμάτων /var/lib/aide (το αρχείο tmpfiles του πακέτου # aide-common.conf τα επαναφέρει σε 0700 και το panel δεν βλέπει πλέον τη βάση) @reboot chmod 755 /var/lib/aide # 03:00 — έλεγχος ασφαλείας Lynis 0 3 * * * /usr/local/bin/lynis-scan.sh >> /path/to/monitor/logs/cron.log 2>&1 # 04:00 — ενημέρωση λίστας αποκλεισμού ipsum (level 1) 0 4 * * * /usr/local/bin/load-ipsum.sh >> /path/to/monitor/logs/cron.log 2>&1 # το set ipsum κατά την εκκίνηση το φορτώνει η υπηρεσία ipsum-load.service (ΠΡΙΝ το firewall, αλλιώς # το UFW δεν θα δει το set στο before.rules) — δεν είναι cron. Εδώ μόνο η καθημερινή ανανέωση παραπάνω. # 06:00 — αναφορά Logwatch 0 6 * * * /usr/local/bin/logwatch_daily.sh >> /path/to/monitor/logs/cron.log 2>&1 # κάθε 30 λεπτά — έλεγχος δίσκων SMART */30 * * * * /usr/local/bin/smart-scan.sh >> /path/to/monitor/logs/cron.log 2>&1 # 04:30 — ακεραιότητα πακέτων debsums 30 4 * * * /usr/local/bin/debsums-scan.sh >> /path/to/monitor/logs/cron.log 2>&1 # 08:00 — προγραμματισμένη αναφορά σε Email και Telegram 0 8 * * * /usr/local/bin/daily-report-all.sh >> /path/to/monitor/logs/cron.log 2>&1 # κάθε ώρα — ανανέωση των λιστών πακέτων (για την κάρτα «Ενημερώσεις ασφαλείας») 0 * * * * /usr/bin/apt-get update -qq >/dev/null 2>&1 # κάθε 5 λεπτά — στιγμιότυπο πόρων (CPU/RAM/δίκτυο/δίσκος) για τη σελίδα «Απόδοση» */5 * * * * /usr/local/bin/collect-metrics-all.sh >> /path/to/monitor/logs/cron.log 2>&1
Λεπτομέρειες για το καθένα — στις αντίστοιχες ενότητες. Οι εργασίες αντιγράφων ασφαλείας (προηγούμενη ενότητα) προστίθενται στο ίδιο cron. Μετά τις αλλαγές ελέγξτε: sudo crontab -l και ότι η υπηρεσία cron είναι ενεργή.
Η ώρα cron = ζώνη ώρας του διακομιστή, όχι το TIMEZONE από το config.php. Η σταθερά TIMEZONE επηρεάζει μόνο την PHP (πώς το panel εμφανίζει τις ημερομηνίες), αλλά ο δαίμονας cron εκτελεί τις εργασίες με βάση την ώρα του συστήματος του λειτουργικού. Αν η ζώνη του διακομιστή δεν συμπίπτει με τη δική σας, η αναφορά «08:00» θα φτάσει σε λάθος ώρα. Παράδειγμα: ο διακομιστής βρίσκεται σε άλλη ζώνη (Europe/Berlin, UTC+2) και εσείς στην Αθήνα (UTC+3) → η αναφορά «08:00» θα φτάσει στις 09:00 για εσάς. Ελέγξτε και, αν χρειάζεται, ρυθμίστε τη ζώνη του συστήματος στη δική σας:
# Έλεγχος τρέχουσας ζώνης διακομιστή: timedatectl # Ορισμός δικής σας ζώνης (παράδειγμα) και επανεκκίνηση του cron: sudo timedatectl set-timezone Europe/Athens sudo systemctl restart cron
Μετά από αυτό η γραμμή 0 8 * * * θα εκτελεστεί στις 08:00 τοπική ώρα. Διαφορετικά θα έπρεπε να μετατοπίζετε το ίδιο το cron, αλλά με τη μετάβαση σε χειμερινή/θερινή ώρα η μετατόπιση θα ξαναχαλάσει — γι' αυτό είναι σωστότερο να ρυθμίσετε τη ζώνη του συστήματος.
Έτοιμα scripts-περιτυλίγματα. Τα λειτουργικά τους αντίγραφα και ένα δείγμα crontab (crontab.txt) βρίσκονται στον φάκελο system/ δίπλα στο έργο, εκτός του public_html. Αυτό δεν είναι μέρος του ιστότοπου — δεν χρειάζεται να τα ανεβάσετε στο web-root· τοποθετήστε τα στον διακομιστή στις διαδρομές του συστήματος (όπως στο crontab παραπάνω):
  • lynis-scan.sh/usr/local/bin/ (chmod +x) — εκτελεί lynis audit system, κατά τη σάρωση θέτει το flag /tmp/lynis-running και αντιγράφει το lynis-report.dat στο data/lynis/ του panel·
  • logwatch_daily.sh/usr/local/bin/ (chmod +x) — δημιουργεί την καθημερινή αναφορά Logwatch (sshd, fail2ban, sudo, postfix) στο data/logwatch/·
  • smart-scan.sh/usr/local/bin/ (chmod +x) — καταγράφει την κατάσταση των δίσκων (smartctl) στο data/disk/·
  • debsums-scan.sh/usr/local/bin/ (chmod +x) — ελέγχει την ακεραιότητα των πακέτων (debsums) στο data/debsums/·
  • clamav-scan.sh/usr/local/bin/ (chmod +x) — σάρωση antivirus ClamAV σε επικίνδυνες διαδρομές (web, home, temp)· γράφει τη σύνοψη στο /var/log/clamav/scan.log, από όπου τη διαβάζει η σελίδα ClamAV (γραμμή 01:30 στο crontab παραπάνω)·
  • load-ipsum.sh/usr/local/bin/ (chmod +x) — ενημερώνει το σύνολο ipset ipsum (level 1) επιτόπου, χωρίς να σπάει τους ενεργούς κανόνες του firewall (γραμμή 04:00 στο crontab παραπάνω)·
  • daily-report-all.sh/usr/local/bin/ (chmod +x) — εκτελεί την αναφορά cron/daily_report.php του panel (γραμμή 08:00 στο crontab παραπάνω)·
  • daily_report.php — περιλαμβάνεται ήδη στο panel (cron/daily_report.php), εκτελείται μέσω daily-report-all.sh, δεν χρειάζεται ξεχωριστή εγκατάσταση·
  • collect-metrics-all.sh/usr/local/bin/ (chmod +x) — εκτελεί το cron/collect_metrics.php του panel (σελίδα «Απόδοση», γραμμή */5 στο crontab παραπάνω)· το collect_metrics.php περιλαμβάνεται ήδη στο panel, δεν χρειάζεται ξεχωριστή εγκατάσταση·
  • crontab.txt (system/cron/) — δείγμα εργασιών· προσθέστε τις γραμμές που χρειάζεστε μέσω sudo crontab -e.
Η διαδρομή προς το script στο crontab πρέπει να συμπίπτει με αυτή όπου το τοποθετήσατε.
Πώς να τοποθετήσετε ένα script στο /usr/local/bin/. Απευθείας από το FileZilla δεν μπορείτε να γράψετε εκεί — ο κατάλογος ανήκει στον root και ο SFTP-client θα λάβει SSH_FX_PERMISSION_DENIED. Η σειρά είναι η εξής: πρώτα ανεβάστε το αρχείο στο /tmp (εκεί γράφουν όλοι), μετά μεταφέρετέ το στη θέση του με μία εντολή:
# στο FileZilla: στο πεδίο «Απομακρυσμένος ιστότοπος» εισαγάγετε /tmp και ανεβάστε εκεί το script, # μετά μέσω SSH (το install ορίζει αμέσως ιδιοκτήτη και δικαιώματα, δεν χρειάζονται chown/chmod): sudo install -o root -g root -m 755 /tmp/lynis-scan.sh /usr/local/bin/lynis-scan.sh rm -f /tmp/lynis-scan.sh # έλεγχος: το αρχείο στη θέση του, δικαιώματα rwxr-xr-x, σύνταξη ακέραιη bash -n /usr/local/bin/lynis-scan.sh && ls -l /usr/local/bin/lynis-scan.sh
Μην μπερδέψετε τους καταλόγους: χρειάζεστε το /tmp στη ρίζα του διακομιστή — όχι το /var/tmp ούτε το tmp/ μέσα στο ίδιο το panel (το τελευταίο ανήκει στον www-data και είναι κλειστό για τον χρήστη σας). Στο δέντρο του FileZilla το /tmp είναι κλάδος ανώτατου επιπέδου, δίπλα στο var, όχι μέσα σε αυτό.
Στήσατε τον διακομιστή με αυτόματη ρύθμιση; Αυτά τα περιτυλίγματα και οι εργασίες cron τους είναι ήδη εγκατεστημένα από το script (στο /usr/local/bin/, log — /var/log/arciveo-cron.log) — δεν χρειάζεται να κάνετε τίποτα χειροκίνητα.
Πού ψάχνουν τα scripts το panel. Τα περιτυλίγματα είναι ανεξάρτητα από domain: εντοπίζουν τις εγκαταστάσεις του panel σαρώνοντας τα /home/*/web/*/public_html και /var/www/*, και τοποθετούν τις αναφορές στο data/ τους. Αν το panel βρίσκεται σε άλλη διαδρομή — προσθέστε τη στη γραμμή for app in … μέσα στα scripts, αλλιώς οι αναφορές Lynis/SMART/debsums/Logwatch δεν θα φτάσουν στο panel.
cron.log και δικαιώματα πρόσβασης. Το αρχείο logs/cron.log το δημιουργεί πρώτο το root-cron — θα ανήκει στον root, και η καρτέλα «Αρχείο καταγραφής cron» στο panel δεν θα μπορεί ούτε να το διαβάσει ούτε να το καθαρίσει. Δημιουργήστε το αρχείο εκ των προτέρων ως χρήστης web (ιδιοκτήτης του καταλόγου του ιστότοπου· στο HestiaCP είναι ο λογαριασμός, π.χ. admin) — τότε το root-cron θα προσθέτει μόνο εγγραφές, χωρίς να αλλάζει τον ιδιοκτήτη:
# δημιουργία εκ των προτέρων ως χρήστης web (πριν την προσθήκη των γραμμών cron): sudo -u OWNER touch /path/to/monitor/logs/cron.log # αν το cron.log έχει ήδη δημιουργηθεί από το root-cron — αναθέστε το στον χρήστη web: sudo chown OWNER:OWNER /path/to/monitor/logs/cron.log sudo chmod 644 /path/to/monitor/logs/cron.log
Δείτε τον ιδιοκτήτη του καταλόγου: stat -c %U /path/to/monitor.
Διαχείριση από το panel. Στην ενότητα «Σύστημα» υπάρχει η σελίδα «Crontab» — μπορείτε να δείτε και να προσθέσετε εργασίες χωρίς SSH. Το panel επεξεργάζεται μόνο τις εργασίες που προστέθηκαν μέσω αυτού (ξεχωριστό μπλοκ στο root-crontab, σημειωμένο με ειδικά σχόλια)· ό,τι υπάρχει ήδη στο crontab (λίστα παραπάνω) εμφανίζεται εκεί ως λίστα read-only «Λοιπές εργασίες διακομιστή» με το κουμπί «Αντιγραφή στον επεξεργαστή» — αυτό απλώς μεταφέρει το πρόγραμμα/εντολή στη φόρμα προσθήκης, χωρίς να αγγίζει την αρχική γραμμή. Για να «περάσετε» μια υπάρχουσα εργασία υπό τη διαχείριση του panel — αντιγράψτε τη στον επεξεργαστή, αποθηκεύστε, μετά διαγράψτε χειροκίνητα την παλιά γραμμή (sudo crontab -e), αλλιώς θα εκτελείται δύο φορές.
Εφάπαξ ρύθμιση στον διακομιστή. Η σελίδα χρειάζεται ένα προνομιακό script-περιτύλιγμα — όχι σκέτο sudo crontab (αυτό θα ήταν άμεση κλιμάκωση σε root από οποιονδήποτε αποκτούσε πρόσβαση στη συνεδρία του panel), αλλά ένα στενό script με δύο εντολές (list/set), που αγγίζει μόνο το δικό του μπλοκ ανάμεσα στα ειδικά σχόλια. Εγκαταστήστε το μία φορά:
sudo install -m 0755 -o root -g root /dev/stdin /usr/local/sbin/arciveo-cron <<'ARCIVEO_CRON_EOF' #!/bin/bash set -euo pipefail BEGIN='# >>> ARCIVEO-CRON-MANAGED (edited from the panel; do not edit by hand) >>>' END='# <<< ARCIVEO-CRON-MANAGED <<<' cmd=${1:-} case "$cmd" in list) [ "$#" -eq 1 ] || { echo "usage: ${0##*/} list" >&2; exit 2; } crontab -l -u root 2>/dev/null || true ;; set) [ "$#" -eq 1 ] || { echo "usage: ${0##*/} set (body on stdin)" >&2; exit 2; } body=$(cat) if grep -qF "$BEGIN" <<<"$body" || grep -qF "$END" <<<"$body"; then echo "invalid body: markers not allowed" >&2; exit 2 fi current=$(crontab -l -u root 2>/dev/null || true) tmp=$(mktemp); trap 'rm -f "$tmp"' EXIT { if grep -qF "$BEGIN" <<<"$current"; then awk -v b="$BEGIN" '{print} $0==b{exit}' <<<"$current" else [ -n "$current" ] && printf '%s\n' "$current" echo "$BEGIN" fi printf '%s\n' "$body" echo "$END" if grep -qF "$END" <<<"$current"; then awk -v e="$END" 'f{print} $0==e{f=1}' <<<"$current" fi } > "$tmp" crontab -u root "$tmp" ;; *) echo "usage: ${0##*/} <list|set>" >&2; exit 2 ;; esac ARCIVEO_CRON_EOF echo "www-data ALL=(ALL) NOPASSWD: /usr/local/sbin/arciveo-cron" | sudo tee -a /etc/sudoers.d/monitor sudo visudo -c
Ο χρήστης web μπορεί να διαφέρει από τον www-data — ελέγξτε υπό ποιον τρέχει το pool PHP-FPM του ιστότοπου (ps -o user= -C php-fpm) και βάλτε τον στη γραμμή sudoers.
Το νέο αρχείο ανέβηκε με λάθος ιδιοκτήτη — η σελίδα απαντά «Access denied.». Αν το αρχείο public/crontab_monitor.php ανέβηκε μέσω FTP/SFTP υπό διαφορετικό χρήστη συστήματος (π.χ. root) από τα υπόλοιπα αρχεία του ιστότοπου, ο web server δεν θα μπορεί να το διαβάσει. Συγκρίνετε τον ιδιοκτήτη και τα δικαιώματα με ένα διπλανό αρχείο και προσαρμόστε τα:
ls -la public/crontab_monitor.php public/ssl_monitor.php sudo chown OWNER:OWNER public/crontab_monitor.php sudo chmod 644 public/crontab_monitor.php

Διαγνωστικά

36. Το εργαλείο είναι εγκατεστημένο, αλλά εμφανίζεται «Μη εγκατεστημένο»

Η μονάδα εντοπίζει τα εργαλεία μέσω του dpkg-query — της βάσης πακέτων APT. Αν το εργαλείο δεν εγκαταστάθηκε μέσω apt (χειροκίνητα, από snap ή από πηγαίο κώδικα), το dpkg δεν το βλέπει.

# Έλεγχος μέσω dpkg: dpkg -l fail2ban | grep '^ii' dpkg -l auditd | grep '^ii' # Εύρεση διαδρομής του εκτελέσιμου: which ufw fail2ban-client auditctl # Δοκιμή sudo ως www-data: sudo -u www-data sudo fail2ban-client status sudo -u www-data sudo ufw status verbose

37. Επίλυση προβλημάτων (500, χωρίς δεδομένα)

Σφάλμα 500 — ελέγξτε τα αρχεία καταγραφής της PHP, του nginx και του ίδιου του monitor:

tail -50 /var/log/nginx/error.log tail -50 /var/log/php*-fpm.log # Αρχεία καταγραφής του monitor: tail -50 logs/monitor_$(date +%Y-%m-%d).log # Δικαιώματα φακέλων: ls -la data/ tmp/ logs/
Ο πίνακας σε πάνελ φιλοξενίας (HestiaCP, ISPmanager, cPanel); Εκεί η PHP δεν τρέχει ως www-data, αλλά ως λογαριασμός χρήστη (π.χ. admin — ιδιοκτήτης του καταλόγου του ιστότοπου). Όλοι οι κανόνες sudo και η συμμετοχή σε ομάδες (adm, systemd-journal) πρέπει να οριστούν σε αυτόν τον χρήστη, αλλιώς οι μονάδες θα δείξουν «Ανενεργό / 0» ενώ οι υπηρεσίες λειτουργούν. Για να βρείτε τον πραγματικό χρήστη της PHP: ps -o user= -C php-fpm | sort -u ή τον ιδιοκτήτη του καταλόγου του ιστότοπου stat -c '%U' /path/to/monitor. Στη συνέχεια σε όλες τις παρακάτω εντολές βάλτε αυτόν αντί για www-data. Η αυτόματη εγκατάσταση εντοπίζει μόνη της τον χρήστη web και ορίζει τα sudoers σε αυτόν.

Δεν εμφανίζονται δεδομένα — σχεδόν πάντα φταίνε τα μη ορισμένα δικαιώματα sudo. Ελέγξτε τη συγκεκριμένη εντολή ως χρήστης web (αντικαταστήστε το www-data με τον δικό σας). Η σημαία -n = χωρίς κωδικό, όπως στην PHP — αν ζητά κωδικό, τότε δεν υπάρχει κανόνας στο sudoers:

sudo -u www-data sudo -n fail2ban-client status sudo -u www-data sudo -n ufw status verbose sudo -u www-data sudo -n ipset list -t ipsum sudo -u www-data sudo -n /usr/sbin/ausearch -m USER_LOGIN -ts today sudo -u www-data sudo -n /usr/sbin/aa-status sudo -u www-data sudo -n /usr/sbin/psad --Status sudo -u www-data journalctl -u falco --no-pager -n 5
Η μονάδα γράφει «Ανενεργό» / «0», ενώ το εργαλείο λειτουργεί (π.χ. το sudo aa-status στο τερματικό δείχνει προφίλ, αλλά η σελίδα «AppArmor» δείχνει «Ανενεργό»). Αιτία: ο χρήστης web δεν έχει δικαίωμα sudo για την εντολή αυτής της μονάδας. Ελέγξτε την από την παραπάνω λίστα: αν ζητά κωδικό — προσθέστε τη γραμμή που λείπει στο /etc/sudoers.d/monitor («Ρύθμιση sudo»). Συχνές «νέες» εντολές: /usr/sbin/aa-status (MAC), /usr/sbin/psad --Status (PSAD).
Αν μια συγκεκριμένη σελίδα (Falco, ModSecurity, Auditd, ανοιχτές θύρες UFW) είναι κενή — αντιπαραβάλετε με τη λίστα στην ενότητα για το sudo: πιθανώς δεν επιτρέπεται το apache2ctl, ausearch, aa-status ή ss, ή ο χρήστης web δεν είναι στις ομάδες adm/systemd-journal (από εκεί διαβάζονται τα αρχεία καταγραφής fail2ban/auth/modsec και το journalctl — Falco και συμβάντα πυρήνα).

38. Η σελίδα είναι κενή, αν και υπάρχουν δεδομένα στον διακομιστή

Σύμπτωμα: στον διακομιστή υπάρχουν δεδομένα (φαίνονται μέσω shell), αλλά η σελίδα δείχνει «δεν υπάρχουν δεδομένα» ή λανθασμένη κατάσταση — για παράδειγμα το AIDE γράφει «Μη αρχικοποιημένη», αν και η βάση έχει δημιουργηθεί.

Η αιτία είναι το open_basedir: πολλά panel και hosting περιορίζουν το pool του PHP-FPM στον κατάλογο του domain, γι' αυτό οι συναρτήσεις PHP file_exists(), file_get_contents(), filemtime() σε συστημικές διαδρομές (/var/lib/aide, /var/log, /proc…) μπλοκάρονται. Η μονάδα το παρακάμπτει διαβάζοντας τέτοιες διαδρομές με τυπικές συστημικές εντολές (cat, test, stat).

# Φαίνεται το αρχείο μέσω shell (έτσι το διαβάζει η μονάδα): sudo -u www-data bash -lc 'test -e /var/lib/aide/aide.db && echo VISIBLE || echo NO' # Τρέχουσα τιμή open_basedir για το pool του domain: grep -ri open_basedir /etc/php/*/fpm/pool.d/ 2>/dev/null
Αν το shell «βλέπει» το αρχείο (VISIBLE), αλλά η σελίδα όχι — πρόκειται για open_basedir. Η σωστή λύση είναι η ανάγνωση με συστημικές εντολές (έχει ήδη γίνει για το AIDE και τη Μονάδα δικτύου). Δεν χρειάζεται να επεκτείνετε το open_basedir στα /var, /proc και είναι λιγότερο ασφαλές.

39. Η σελίδα SSL δεν λειτουργεί

Η μονάδα ελέγχει τα πιστοποιητικά συνδεόμενη απευθείας στους τομείς μέσω της θύρας 443. Αν ο τομέας δεν είναι προσβάσιμος από τον ίδιο τον διακομιστή ή η θύρα είναι κλειστή από το τείχος προστασίας, ο έλεγχος θα αποτύχει.

# Χειροκίνητος έλεγχος πιστοποιητικού: echo | openssl s_client -connect monitor.example.com:443 2>/dev/null \ | openssl x509 -noout -dates # Έλεγχος προσβασιμότητας: curl -I https://monitor.example.com
Τους τομείς η μονάδα τους λαμβάνει αυτόματα από τα configs του nginx (/etc/nginx/sites-enabled/, /etc/nginx/conf.d/) και του Apache (/etc/apache2/sites-enabled/), καθώς και τον τρέχοντα host από το HTTP_HOST.
Αυτόματος εντοπισμός υποτομέων. Οι υποτομείς εντοπίζονται αυτόματα από τα δημόσια αρχεία καταγραφής Certificate Transparency και ελέγχονται μέσω δικτύου — ακόμη κι αν φιλοξενούνται σε άλλους διακομιστές. Δεν χρειάζεται να προσθέσετε τίποτα χειροκίνητα.

40. Φαίνεται μόνο μία ΒΔ από τις πολλές

Ο monitor συνδέεται στη MySQL με τον χρήστη από το config.php, ο οποίος έχει πρόσβαση μόνο στη δική του βάση. Η MySQL εμφανίζει στο information_schema μόνο τις βάσεις με δικαιώματα — γι' αυτό οι υπόλοιπες δεν φαίνονται.

Για να βλέπει ο monitor όλες τις ΒΔ, δώστε σε αυτόν τον χρήστη μόνο δικαίωμα ανάγνωσης (μία φορά ως root· βάλτε το όνομα χρήστη από το config.php):

sudo mysql -u root GRANT SELECT, PROCESS, SHOW DATABASES ON *.* TO 'DB_USER'@'localhost'; FLUSH PRIVILEGES; EXIT;
SELECT ON *.* δίνει μόνο δικαίωμα ανάγνωσης — δεν είναι δυνατή η τροποποίηση, διαγραφή ή δημιουργία οτιδήποτε· είναι ασφαλές για την παρακολούθηση.
Χωρίς αυτό το GRANT ο πίνακας βλέπει μόνο τη δική του βάση — δεν είναι σφάλμα, αλλά περιορισμός δικαιωμάτων. Κανένα sudo mysql δεν χρησιμοποιεί ο πίνακας: η λίστα των βάσεων λαμβάνεται μέσω της δικής του σύνδεσης PDO.

41. Η PostgreSQL δεν εμφανίζεται στη σελίδα «Βάση δεδομένων»

Η PostgreSQL απαιτεί πρόσβαση επιπέδου χρήστη postgres, την οποία ο διαδικτυακός χρήστης του πίνακα δεν διαθέτει. Το άνοιγμα ενός ευρέος sudo psql από την PHP είναι επισφαλές — αντ' αυτού ο πίνακας καλεί ένα στενό wrapper χωρίς παραμέτρους, που τυπώνει μόνο την έκδοση, το πλήθος συνδέσεων και τη λίστα βάσεων με τα μεγέθη τους. Δημιουργήστε το:

sudo tee /usr/local/bin/monitor-pgstat >/dev/null <<'EOF' #!/bin/sh # Arciveo Monitor - read-only PostgreSQL version, connections and per-database size sudo -u postgres psql -tAc "SELECT version();" | grep -oE 'PostgreSQL [0-9.]+' echo "---" sudo -u postgres psql -tAc "SELECT count(*) FROM pg_stat_activity;" echo "---" sudo -u postgres psql -tAc "SELECT datname || '|' || pg_size_pretty(pg_database_size(datname)) FROM pg_database WHERE datistemplate = false;" EOF sudo chown root:root /usr/local/bin/monitor-pgstat sudo chmod 755 /usr/local/bin/monitor-pgstat # στο /etc/sudoers.d/monitor (χρήστης = αυτός με τον οποίο τρέχει το PHP-FPM): # www-data ALL=(ALL) NOPASSWD: /usr/local/bin/monitor-pgstat
Αν δεν χρησιμοποιείτε την PostgreSQL — αφαιρέστε τη γραμμή monitor-pgstat από το sudoers (βήμα 13 της χειροκίνητης εγκατάστασης) και μη δημιουργήσετε το script: η κάρτα της PostgreSQL απλώς θα παραμείνει ανενεργή.

42. Ενεργοποιήθηκε ειδοποίηση — τι να κάνετε

Ο πίνακας δείχνει τι συμβαίνει· παρακάτω θα βρείτε τι να κάνετε σε τυπικές περιπτώσεις. Γενική αρχή: μην πανικοβάλλεστε, αντιπαραβάλετε με τη νόμιμη δραστηριότητα (οι ενέργειές σας, ενημερώσεις, αντίγραφα ασφαλείας) και αντιδράστε ανάλογα με τη σοβαρότητα.

  • Χάρτης επιθέσεων / πολλά μπλοκαρίσματα fail2ban — είναι κάτι φυσιολογικό για κάθε διακομιστή στο διαδίκτυο (τα bots δοκιμάζουν συνεχώς SSH/web). Το σημαντικό είναι τα μπλοκαρίσματα να λειτουργούν. Βεβαιωθείτε ότι η σύνδεση μέσω SSH γίνεται μόνο με κλειδί (ο κωδικός είναι απενεργοποιημένος) και ότι η IP σας βρίσκεται στο ignoreip.
  • Το ModSecurity μπλόκαρε αιτήματα — το WAF αποκρούει επιθέσεις στον ιστότοπο, αυτή είναι η δουλειά του. Αν μπλοκάρεται η νόμιμη κίνησή σας (ψευδής ενεργοποίηση) — βρείτε το rule id στις λεπτομέρειες και προσθέστε εξαίρεση στη διαμόρφωση CRS.
  • AIDE: τροποποιήθηκαν αρχεία — αντιπαραβάλετε τη λίστα με ό,τι κάνατε εσείς (ενημέρωση πακέτων, επεξεργασία διαμορφώσεων — φυσιολογικά). Αλλαγές σε δυαδικά αρχεία του συστήματος που δεν αγγίξατε αποτελούν λόγο ανησυχίας. Μετά από νόμιμες αλλαγές, ενημερώστε τη βάση AIDE.
  • debsums: τροποποιήθηκαν δυαδικά/βιβλιοθήκες (εκτός /etc, εκτός /usr/share) — πιθανή αντικατάσταση. Ελέγξτε το πακέτο: debsums PACKAGE_NAME, και αν έχετε αμφιβολίες επανεγκαταστήστε το (apt install --reinstall).
  • ClamAV / maldet: εντοπίστηκε απειλή — ελέγξτε το αρχείο στην καραντίνα, μην το ανοίγετε. Αν πρόκειται για web-shell στον κατάλογο του ιστότοπου — απομονώστε τον διακομιστή και αναζητήστε το σημείο εισόδου (ευάλωτο plugin, διαρροή διαπιστευτηρίων).
  • Falco: κρίσιμα συμβάντα (εκτέλεση shell σε container, πρόσβαση σε ευαίσθητα αρχεία) — αναλύστε το συμβάν: ποιανού είναι η διεργασία, τι την εκκίνησε. Συχνά είναι νόμιμη δραστηριότητα διαχείρισης.
  • Εξωτερική έκθεση: με κόκκινο η ΒΔ/cache — κλείστε το αμέσως: δέστε την υπηρεσία στο 127.0.0.1 ή κλείστε τη θύρα στο UFW. Είναι πραγματικό κενό ασφαλείας.
  • Το SSL λήγει / έληξε — ανανεώστε το πιστοποιητικό (το Let's Encrypt ανανεώνεται μόνο του· αν όχι — ελέγξτε το certbot renew ή τις ρυθμίσεις στον πίνακα).
  • Εκκρεμούν ενημερώσεις ασφαλείας — εγκαταστήστε τες: sudo apt update && sudo apt upgrade· μετά από ενημέρωση του πυρήνα επανεκκινήστε τον διακομιστή.
Ενδείξεις πραγματικής παραβίασης (άγνωστες διεργασίες/χρήστες, τροποποιημένα δυαδικά, εξερχόμενο spam, άγνωστες εργασίες cron): αποσυνδέστε τον διακομιστή από την εξωτερική πρόσβαση, κρατήστε ένα αντίγραφο ασφαλείας για ανάλυση και, αν τα δεδομένα είναι κρίσιμα, στήστε καθαρό διακομιστή από ένα αξιόπιστο αντίγραφο ασφαλείας — η αξιόπιστη εκκαθάριση ενός rootkit είναι δύσκολη.
Arcivéo - Security Monitor © 2026