Πλήρως χειροκίνητη εγκατάσταση: από ένα μόλις αγορασμένο VPS έως έναν λειτουργικό πίνακα, βήμα προς βήμα.
Η προετοιμασία του διακομιστή, η δημιουργία του ιστότοπου, η βάση δεδομένων, το config.php και το SSL περιγράφονται εδώ.
Οι εντολές για κάθε εργαλείο ασφάλειας και για το cron βρίσκονται στον
οδηγό FAQ, με συνδέσμους στην πορεία.
Βασικός κανόνας: όταν αλλάζετε SSH ή τείχος προστασίας, μην κλείνετε την τρέχουσα σύνδεση προτού δοκιμάσετε τη νέα σε ξεχωριστό παράθυρο. Αν παρ' όλα αυτά χάσετε την πρόσβαση, σχεδόν όλοι οι πάροχοι φιλοξενίας προσφέρουν κονσόλα έκτακτης ανάγκης (VNC/Recovery) στον πίνακα διαχείρισης.
01. Αγόρασα VPS με Ubuntu/Debian — από πού να ξεκινήσω
Μετά την αγορά, ο πάροχος στέλνει: διεύθυνση IP, όνομα χρήστη (συνήθως root) και κωδικό (ή κλειδί SSH). Αυτά αρκούν για τη σύνδεση. Σειρά ενεργειών (κάθε βήμα είναι ενότητα παρακάτω):
Σύνδεση στον διακομιστή μέσω SSH·
Ενημέρωση του συστήματος, ορισμός ονόματος κεντρικού υπολογιστή και ζώνης ώρας·
Δημιουργία απλού χρήστη με δικαιώματα sudo (να μην εργάζεστε ως root)·
Ρύθμιση σύνδεσης με κλειδί SSH και απενεργοποίηση σύνδεσης με κωδικό·
Ενεργοποίηση του τείχους προστασίας και της αυτόματης προστασίας·
(προαιρετικά) εγκατάσταση του πίνακα διαχείρισης HestiaCP — διακομιστής web, βάση δεδομένων, email «έτοιμα προς χρήση».
02. Πρώτη σύνδεση μέσω SSH
Το SSH είναι ένα ασφαλές τερματικό προς τον διακομιστή. Βάλτε τη δική σας IP στη θέση του 203.0.113.10.
Το 203.0.113.10 είναι παράδειγμα, ανύπαρκτη διεύθυνση (δεσμευμένη για τεκμηρίωση). Μην το βάλετε ως έχει — αντικαταστήστε το με την πραγματική IP του διακομιστή σας από το email του παρόχου. Αλλιώς δεν θα υπάρξει σύνδεση.
Windows 10/11: ανοίξτε το PowerShell ή το «Τερματικό» και χρησιμοποιήστε το ενσωματωμένο ssh (ή τους πελάτες PuTTY / MobaXterm). macOS / Linux: ανοίξτε το «Τερματικό».
# Είσοδος ως root (ο κωδικός ήρθε από τον πάροχο):
ssh root@203.0.113.10
# Αν ο πάροχος έδωσε αρχείο-κλειδί αντί για κωδικό:
ssh -i διαδρομή/προς/κλειδί root@203.0.113.10
Κατά την πρώτη σύνδεση το SSH θα ρωτήσει για το «authenticity of host» — πληκτρολογήστε yes. Ο κωδικός δεν εμφανίζεται καθώς τον πληκτρολογείτε (αυτό είναι φυσιολογικό). Αν ο πάροχος έδωσε προσωρινό κωδικό — αλλάξτε τον με την εντολή passwd.
03. Ενημέρωση συστήματος και βασική διαμόρφωση
Πρώτο βήμα — ενημερώστε όλα τα πακέτα και ορίστε το όνομα κεντρικού υπολογιστή και τη ζώνη ώρας.
Λίστα ζωνών ώρας — timedatectl list-timezones. Αν στο τέλος της ενημέρωσης εμφανιστεί το μπλε παράθυρο «Daemons using outdated libraries» — επιλέξτε όλες τις υπηρεσίες (Space) και πατήστε OK, είναι ασφαλές.
04. Δημιουργία χρήστη με sudo
Η μόνιμη εργασία ως root είναι επισφαλής. Δημιουργήστε έναν κανονικό χρήστη και δώστε του δικαιώματα sudo (εκτέλεση εντολών ως διαχειριστής όταν χρειάζεται). Αντικαταστήστε το deploy με όποιο όνομα θέλετε.
# Δημιουργία χρήστη (θα ζητήσει κωδικό και στοιχεία — μπορείτε Enter):
adduser deploy
# Προσθήκη στην ομάδα sudo:
usermod -aG sudo deploy
# Έλεγχος (ως root):
su - deploy
sudo whoami # πρέπει να εμφανίσει: root
exit
Στη συνέχεια συνδέεστε στον διακομιστή με αυτόν τον χρήστη: ssh deploy@203.0.113.10, και τις εντολές διαχειριστή τις εκτελείτε με το πρόθεμα sudo.
05. Κλειδιά SSH και απενεργοποίηση σύνδεσης με κωδικό
Η σύνδεση με κλειδί είναι ασφαλέστερη από τον κωδικό: ο κωδικός μπορεί να μαντευτεί, το κλειδί σχεδόν ποτέ. Πρώτα δημιουργούμε το κλειδί στον υπολογιστή μας, το αντιγράφουμε στον διακομιστή, ελέγχουμε τη σύνδεση — και μόνο μετά απενεργοποιούμε τον κωδικό.
Βήμα 3. Ελέγξτε τη σύνδεση με κλειδί σε νέο παράθυρο — πρέπει να συνδέεστε χωρίς κωδικό:
ssh deploy@203.0.113.10
Μην εκτελέσετε την Επιλογή B προτού η σύνδεση με κλειδί ελεγχθεί και λειτουργεί (Βήματα 1–3), και μην κλείσετε την ενεργή σύνδεση. Απενεργοποιεί τη σύνδεση με κωδικό για όλους τους χρήστες, συμπεριλαμβανομένου του root. Χωρίς λειτουργικό κλειδί θα χάσετε εντελώς την πρόσβαση στον διακομιστή — θα μπορείτε να την ανακτήσετε μόνο μέσω της κονσόλας του παρόχου. Δεν έχετε κλειδί — επιλέξτε την Επιλογή A.
Βήμα 4. Ενισχύστε την πρόσβαση μέσω SSH. Τις ρυθμίσεις τις βάζουμε σε ξεχωριστό αρχείο, το κύριο config δεν το πειράζουμε. Επιλέξτε τον τρόπο ανάλογα με την περίπτωση:
Επιλογή A — μόνο κλείσιμο του root, ο κωδικός παραμένει. Δεν χρειάζεται κλειδί, δεν θα χάσετε την πρόσβαση:
Επιλογή B — πλήρες hardening. Απενεργοποιήστε τη σύνδεση με κωδικό και αφήστε τον root μόνο με κλειδί. Εκτελέστε την μόνο αφού βεβαιωθείτε ότι η σύνδεση με κλειδί λειτουργεί:
sudo tee /etc/ssh/sshd_config.d/00-hardening.conf >/dev/null <<'EOF'
PubkeyAuthentication yes
PasswordAuthentication no
PermitRootLogin prohibit-password
KbdInteractiveAuthentication no
EOF
sudo systemctl restart ssh
Και στους δύο τρόπους ο root με κωδικό είναι κλειστός. Το PermitRootLogin no απαγορεύει εντελώς τον root, το prohibit-password — αφήνει τη σύνδεση μόνο με κλειδί (για διαχείριση συνδέεστε ως deploy και χρησιμοποιείτε sudo). Αν θέλετε να αλλάξετε τη θύρα SSH — προσθέστε τη γραμμή Port 2222, αλλά πρώτα ανοίξτε τη νέα θύρα στο τείχος προστασίας (επόμενη ενότητα) και ελέγξτε τη σύνδεση, αλλιώς θα αποκλείσετε την πρόσβασή σας.
06. Βασικό firewall και αυτόματη προστασία
Κλείστε ό,τι περιττό με το firewall και ενεργοποιήστε το fail2ban (μπλοκάρει τις απόπειρες εύρεσης κωδικού μέσω SSH). Πρώτα επιτρέψτε το SSH, αλλιώς μετά την ενεργοποίηση του UFW θα χάσετε την πρόσβαση.
# Επιτρέψτε το SSH (ή τη θύρα σας, αν την αλλάξατε) και το web:
sudo ufw allow OpenSSH
sudo ufw allow 80,443/tcp
# Ενεργοποιήστε το firewall:
sudo ufw enable
sudo ufw status verbose
# fail2ban — προστασία SSH από brute-force (το βασικό προφίλ ενεργοποιείται αμέσως):
sudo systemctl enable --now fail2ban
sudo fail2ban-client status sshd
Αυτό είναι το ελάχιστο. Λειτουργικές ρυθμίσεις fail2ban, λίστα αποκλεισμού ipsum, εκτεταμένο UFW και τα υπόλοιπα εργαλεία — στην ομάδα «Εργαλεία ασφάλειας» του οδηγού. Ο ίδιος ο πίνακας του Arcivéo Monitor εμφανίζει παραστατικά την κατάσταση όλων αυτών.
07. Εγκατάσταση του πίνακα HestiaCP (προαιρετικά)
HestiaCP — δωρεάν πίνακας διαχείρισης hosting: εγκαθιστά και ρυθμίζει διακομιστή web (nginx + apache), PHP, βάση δεδομένων (MariaDB), email, DNS και πιστοποιητικά SSL, προσφέρει διεπαφή web για ιστότοπους. Βολικός αν δεν θέλετε να ρυθμίσετε τα πάντα χειροκίνητα και σκοπεύετε να φιλοξενήσετε ιστότοπους (μαζί και τον ίδιο τον πίνακα Arcivéo Monitor).
Εγκαταστήστε το HestiaCP σε καθαρό διακομιστή (πρόσφατη υποστηριζόμενη Ubuntu/Debian, τουλάχιστον ~1–2 GB RAM), πριν εγκαταστήσετε άλλους διακομιστές web και βάσεις δεδομένων — αλλιώς θα προκύψουν συγκρούσεις. Η εγκατάσταση διαρκεί 10–20 λεπτά και θα επανεκκινήσει τον διακομιστή.
# Λήψη του προγράμματος εγκατάστασης και εκτέλεση:
wget https://raw.githubusercontent.com/hestiacp/hestiacp/release/install/hst-install.sh
sudo bash hst-install.sh
Το πρόγραμμα εγκατάστασης θα ζητήσει email και όνομα κεντρικού υπολογιστή, έπειτα θα εγκαταστήσει όλη τη στοίβα. Μετά την επανεκκίνηση, ο πίνακας είναι διαθέσιμος στη διεύθυνση https://YOUR_IP:8083 (το όνομα χρήστη και ο κωδικός θα εμφανιστούν από το πρόγραμμα εγκατάστασης στο τέλος).
Το HestiaCP διαχειρίζεται μόνο του τα UFW και fail2ban — δεν χρειάζεται να τα ρυθμίσετε ξεχωριστά, θα τα εντοπίσει. Τα κλειδιά SSH και την απενεργοποίηση κωδικού (προηγούμενη ενότητα) κάντε τα ούτως ή άλλως.
08. Απαιτήσεις συστήματος και ionCube
Το dashboard είναι μια εφαρμογή PHP σε τυπικό stack LAMP/LEMP:
ΛΣ: Linux (συνιστώνται Ubuntu/Debian)·
Διακομιστής web: nginx ή Apache με PHP-FPM·
PHP 8.0+ με επεκτάσεις: pdo_mysql, openssl, curl, json, mbstring·
ionCube Loader — επέκταση PHP απαραίτητη για τη λειτουργία του dashboard·
ΒΔ: MySQL 5.7+ ή MariaDB 10.3+·
HTTPS — υποχρεωτικό (η σύνδεση και το WebAuthn λειτουργούν μόνο μέσω https)·
sudo για τον χρήστη του διακομιστή web (περιορισμένο σύνολο — βήμα 13).
Εγκατάσταση ionCube Loader (αν δεν υπάρχει ήδη). Σε hosting με πάνελ (HestiaCP, cPanel) το ionCube ενεργοποιείται με ένα τικ στις ρυθμίσεις PHP. Χειροκίνητα σε Ubuntu/Debian:
# Βρείτε την έκδοση PHP και τον κατάλογο επεκτάσεων:
php -v
EXTDIR=$(php -r 'echo ini_get("extension_dir");'); PHPVER=$(php -r 'echo PHP_MAJOR_VERSION.".".PHP_MINOR_VERSION;')
# Κατεβάστε και αποσυμπιέστε τους loaders (64-bit):
cd /tmp
wget -q https://downloads.ioncube.com/loader_downloads/ioncube_loaders_lin_x86-64.tar.gz
tar xzf ioncube_loaders_lin_x86-64.tar.gz
# Αντιγράψτε τον loader για την έκδοση PHP σας στον κατάλογο επεκτάσεων:
sudo cp ioncube/ioncube_loader_lin_${PHPVER}.so "$EXTDIR"/
# Ενεργοποιήστε (CLI + PHP-FPM) και επανεκκινήστε:
echo "zend_extension=ioncube_loader_lin_${PHPVER}.so" | sudo tee /etc/php/${PHPVER}/mods-available/ioncube.ini
sudo phpenmod ioncube
sudo systemctl restart php${PHPVER}-fpm
# Έλεγχος — στην έξοδο θα εμφανιστεί η γραμμή "with the ionCube PHP Loader":
php -v
Η έκδοση του loader πρέπει να ταιριάζει με την έκδοση PHP (για παράδειγμα ioncube_loader_lin_8.1.so για PHP 8.1). Αν χρησιμοποιείτε πολλές εκδόσεις PHP — ενεργοποιήστε τον loader για την καθεμία.
09. Τομέας και DNS
Για να ανοίγετε τον πίνακα σε διεύθυνση όπως monitor.example.com και να αποκτήσετε δωρεάν SSL, χρειάζεστε έναν τομέα που δείχνει στον διακομιστή σας. Στον πίνακα διαχείρισης DNS δημιουργήστε μια εγγραφή A:
Τύπος: A
Όνομα: monitor (υποτομέας → monitor.example.com)
ή @ (ρίζα τομέα → example.com)
Τιμή: 203.0.113.10 ← η IP του διακομιστή σας
TTL: 3600
Μετά από λίγα λεπτά ελέγξτε ότι ο τομέας δείχνει στον διακομιστή:
dig +short monitor.example.com # πρέπει να επιστρέψει την IP σας
# ή, αν δεν υπάρχει dig:
getent hosts monitor.example.com
Το πιστοποιητικό SSL Let's Encrypt εκδίδεται μόνο για τομέα — το DNS πρέπει να δείχνει στον διακομιστή πριν από την έκδοση του πιστοποιητικού.
10. Δημιουργία ιστότοπου και μεταφόρτωση αρχείων του πίνακα
Apache: το DocumentRoot στη ρίζα του πίνακα, ΟΧΙ στο public/. Τα στυλ (CSS/JS), το sw.js και το manifest.json βρίσκονται στο assets/ δίπλα στο public/ και ζητούνται από τη ρίζα του ιστότοπου. Το ριζικό .htaccess είναι ο front-controller. Αν στο Apache ορίσετε το DocumentRoot στο public/, ο πίνακας θα ανοίξει χωρίς στυλ. Στον καθαρό nginx ισχύει το αντίθετο: ως ρίζα ορίζεται το public/, ενώ το assets/ εξυπηρετείται με ξεχωριστό κανόνα (δείτε το μπλοκ nginx παρακάτω).
Τα αρχεία του πίνακα (το αρχείο διανομής) κατεβαίνουν μετά την αγορά από τον λογαριασμό στο my.arciveo.com → «Λήψεις». Αποσυμπιέστε το αρχείο πριν τη μεταφόρτωση.
1) Δημιουργήστε τον κατάλογο του πίνακα και ανεβάστε σε αυτόν το περιεχόμενο της διανομής (ώστε μέσα να βρίσκονται τα public/, assets/, config.php κ.λπ.):
sudo mkdir -p /var/www/monitor
# έπειτα ανεβάστε τα αρχεία διανομής στο /var/www/monitor (FileZilla / WinSCP / scp)
2) Ρυθμίστε τον web server.Apache: DocumentRoot στη ρίζα του πίνακα (ΟΧΙ στο /public)· το AllowOverride All είναι υποχρεωτικό. Η διαδρομή προς το socket του PHP-FPM εντοπίζεται αυτόματα. Το μπλοκ επικολλάται στο τερματικό ολόκληρο:
PHPSOCK=$(ls -1 /run/php/php*-fpm.sock 2>/dev/null | head -1) # αυτόματος εντοπισμός του socket PHP-FPM
sudo tee /etc/apache2/sites-available/monitor.conf > /dev/null <<'EOF'
<VirtualHost *:80>
ServerName monitor.example.com
DocumentRoot /var/www/monitor
<Directory /var/www/monitor>
AllowOverride All
Require all granted
</Directory>
<FilesMatch \.php$>
SetHandler "proxy:unix:__PHPSOCK__|fcgi://localhost"
</FilesMatch>
</VirtualHost>
EOF
sudo sed -i "s#__PHPSOCK__#${PHPSOCK}#" /etc/apache2/sites-available/monitor.conf
sudo a2dissite 000-default.conf
sudo a2ensite monitor.conf
sudo apache2ctl configtest
sudo systemctl reload apache2
nginx: ο nginx δεν έχει .htaccess, γι' αυτό ως ρίζα παίρνουμε το public/, ενώ τα assets/, sw.js, manifest.json (ένα επίπεδο πιο πάνω) τα εξυπηρετούμε με ξεχωριστό κανόνα:
PHPSOCK=$(ls -1 /run/php/php*-fpm.sock 2>/dev/null | head -1) # αυτόματος εντοπισμός του socket PHP-FPM
sudo tee /etc/nginx/sites-available/monitor.conf > /dev/null <<'EOF'
server {
listen 80;
server_name monitor.example.com;
root /var/www/monitor/public;
index index.php;
# τα assets, ο service worker και το manifest βρίσκονται ένα επίπεδο πάνω από το public/
location ~ ^/(assets/|sw\.js|manifest\.json) { root /var/www/monitor; }
location / { try_files $uri $uri/ /index.php?$query_string; }
location ~ \.php$ {
include snippets/fastcgi-php.conf;
fastcgi_pass unix:__PHPSOCK__;
}
}
EOF
sudo sed -i "s#__PHPSOCK__#${PHPSOCK}#" /etc/nginx/sites-available/monitor.conf
sudo ln -s /etc/nginx/sites-available/monitor.conf /etc/nginx/sites-enabled/
sudo nginx -t && sudo systemctl reload nginx
Μεταφόρτωση αρχείων — SFTP/SCP (FileZilla, WinSCP) ή scp:
# Παράδειγμα μέσω scp από τον τοπικό υπολογιστή:
scp -r ./monitor/* deploy@203.0.113.10:/var/www/monitor/
Ορίστε τα δικαιώματα των αρχείων — είναι υποχρεωτικό βήμα. Αν ανεβάσατε ως root ή μέσω SFTP, τα αρχεία ανήκουν στον root και ο web server (www-data) δεν θα μπορεί να τα διαβάσει — ο πίνακας θα ανοίξει κενός ή με σφάλμα 403 (στο log: .htaccess unreadable / directory not executable). Η παρακάτω εντολή το διορθώνει:
# Κανονικοποιούμε τα δικαιώματα όλου του webroot: ο κατάλογος που δημιουργήθηκε από τον root δεν είναι προσβάσιμος
# από τον web server (www-data) — χωρίς αυτό ο πίνακας επιστρέφει κενή σελίδα ή 403.
# Ο Apache τρέχει ως www-data· αν έχετε άλλον χρήστη web — αντικαταστήστε τον.
cd /var/www/monitor
# Δημιουργούμε τους φακέλους εργασίας ΠΡΙΝ το chown — αλλιώς οι νέοι κατάλογοι θα μείνουν root:root
# και με chmod 750 ο web server (www-data) δεν θα μπορεί να γράψει σε αυτούς.
sudo mkdir -p data/lynis data/logwatch tmp logs
sudo chown -R www-data:www-data /var/www/monitor
sudo find /var/www/monitor -type d -exec chmod 755 {} \;
sudo find /var/www/monitor -type f -exec chmod 644 {} \;
sudo chmod 640 /var/www/monitor/config.php
sudo chmod 750 data tmp logs
3) Ανοίξτε για τον εαυτό σας το ανέβασμα αρχείων μέσω SFTP. Μετά την παραπάνω εντολή όλα τα αρχεία ανήκουν στον www-data, ενώ το FileZilla / WinSCP συνδέονται με τον δικό σας χρήστη — το ανέβασμα τότε αποτυγχάνει με SSH_FX_PERMISSION_DENIED (Permission denied). Η σύνδεση ως root για ανέβασμα δεν είναι επιλογή — η είσοδος root απενεργοποιήθηκε στο βήμα 05. Επιλέξτε μία από τις δύο παραλλαγές.
Παραλλαγή A — μια ACL μόνο για τον χρήστη σας (συνιστάται). Δικαίωμα εγγραφής παίρνετε μόνο εσείς· ο διακομιστής web εξακολουθεί να μην μπορεί να αντικαταστήσει τον κώδικα του πίνακα:
sudo apt install -y acl
# Δικαίωμα εγγραφής για τον χρήστη σας σε ολόκληρο τον κατάλογο του πίνακα:
sudo setfacl -R -m u:deploy:rwX /var/www/monitor
# Ο ίδιος κανόνας ως προεπιλογή — για αρχεία και φακέλους που θα δημιουργηθούν αργότερα:
sudo setfacl -R -d -m u:deploy:rwX /var/www/monitor
Παραλλαγή B — μέσω της ομάδας www-data. Πιο απλή, αλλά δικαίωμα εγγραφής στα αρχεία του πίνακα αποκτά και ο διακομιστής web: με μια ευπάθεια στην PHP ο κώδικας θα μπορούσε να αντικατασταθεί. Η σειρά των εντολών έχει σημασία — το config.php και οι φάκελοι εργασίας κλείνουν τελευταίοι:
sudo usermod -aG www-data deploy
# Εγγραφή για την ομάδα + setgid (το bit 2): τα αρχεία που ανεβαίνουν μέσω SFTP
# παραμένουν στην ομάδα www-data — αλλιώς ο πίνακας δεν μπορεί να τα αντικαταστήσει.
sudo find /var/www/monitor -type d -exec chmod 2775 {} \;
sudo find /var/www/monitor -type f -exec chmod 664 {} \;
sudo chmod 640 /var/www/monitor/config.php
sudo chmod 2750 /var/www/monitor/data /var/www/monitor/tmp /var/www/monitor/logs
Μετά την παραλλαγή B συνδεθείτε ξανά στο FileZilla (Διακομιστής → Αποσύνδεση και έπειτα νέα είσοδος) — η νέα ομάδα ισχύει μόνο σε νέα σύνδεση, ως τότε δικαιώματα πάλι δεν θα έχετε. Έλεγχος: id deploy — στη λίστα ομάδων πρέπει να εμφανιστεί το www-data· ls -ld /var/www/monitor — δικαιώματα drwxrwsr-x, το γράμμα s στη θέση του x σημαίνει ότι το setgid είναι ενεργό.
11. Βάση δεδομένων
Δημιουργήστε τη βάση και τον χρήστη, μετά εισαγάγετε το σχήμα. Το μπλοκ επικολλάται στο τερματικό ολόκληρο. Τα monitor_db και monitor_user είναι ενδεικτικά ονόματα, μπορείτε να ορίσετε δικά σας· να θυμάστε το όνομα της βάσης, τον χρήστη και τον κωδικό — θα τα καταχωρίσετε στο config.php στο επόμενο βήμα:
# 1. Βάση δεδομένων. Ο κωδικός ορίζεται ΜΙΑ φορά στο DBPASS και μπαίνει σε όλες τις γραμμές.
# Το μπλοκ επικολλάται στο τερματικό ΟΛΟΚΛΗΡΟ· το sudo mysql συνδέει τον root μέσω unix-socket
# (δεν χρειάζεται κωδικός root). ΜΗΝ χρησιμοποιείτε το διαδραστικό `sudo mysql -u root -p`
# με copy-paste — κατά την επικόλληση οι γραμμές SQL θα πάνε στο ερώτημα κωδικού και θα χαθούν.
DBPASS='CHOOSE_A_PASSWORD' # ← αλλάξτε μόνο αυτή τη γραμμή
sudo mysql <<SQL
CREATE DATABASE IF NOT EXISTS monitor_db CHARACTER SET utf8mb4;
CREATE USER IF NOT EXISTS 'monitor_user'@'localhost' IDENTIFIED BY '$DBPASS';
GRANT ALL ON monitor_db.* TO 'monitor_user'@'localhost';
FLUSH PRIVILEGES;
SQL
# Έλεγχος (πρέπει να εμφανίσει το monitor_db):
mysql -u monitor_user -p"$DBPASS" -e "SHOW DATABASES;"
# Τον ίδιο κωδικό καταχωρίστε στο config.php → DB_PASS.
Δεν χρειάζεται εισαγωγή του σχήματος — ο πίνακας δημιουργεί μόνος του τους πίνακες και τον λογαριασμό admin στην πρώτη είσοδο από τον browser (από το database/db.sql), αν η βάση είναι κενή. Η χειροκίνητη εισαγωγή του σχήματος χρειάζεται μόνο αν δεν λειτούργησε η αυτόματη αρχικοποίηση.
Αν χρησιμοποιήσατε τον εγκαταστάτη μέσω browser public/start_db.php — διαγράψτε τον αμέσως μετά την εγκατάσταση: επιτρέπει την εκ νέου δημιουργία της βάσης χωρίς πιστοποίηση. Όσο το αρχείο βρίσκεται στη ρίζα του πίνακα ή στο public/, ο πίνακας εμφανίζει κόκκινη προειδοποίηση.
12. Ρύθμιση του config.php
Το config.php στη ρίζα του πίνακα (/var/www/monitor/config.php) είναι το μοναδικό αρχείο που πρέπει να επεξεργαστείτε χειροκίνητα. Όλες οι ρυθμίσεις του πίνακα ορίζονται σε αυτό με σταθερές define(). Ανοίξτε το σε έναν επεξεργαστή:
sudo nano /var/www/monitor/config.php
Βάλτε τις δικές σας τιμές στα επισημασμένα σημεία· τα υπόλοιπα αφήστε τα ως έχουν:
// --- Βάση δεδομένων (από το βήμα 11) ---
define('DB_HOST', 'localhost'); // αφήστε το
define('DB_NAME', 'db_name'); // ό,τι δημιουργήσατε στο βήμα 11
define('DB_USER', 'user'); // ό,τι δημιουργήσατε στο βήμα 11
define('DB_PASS', 'db_password'); // ό,τι ορίσατε στο βήμα 11
define('DB_CHARSET', 'utf8mb4'); // αφήστε το
// --- Εφαρμογή ---
define('APP_URL', 'https://monitor.example.com'); // διεύθυνση του πίνακα, χωρίς κάθετο στο τέλος
define('TIMEZONE', 'Europe/Athens'); // η ζώνη ώρας σας
// --- Διάρκεια συνεδρίας ---
define('SESSION_LIFETIME', 28800); // αδράνεια έως νέα σύνδεση, δευτ. (28800 = 8 ώ)
Τι να αλλάξετε:
DB_NAME, DB_USER, DB_PASS — ακριβώς το ίδιο όνομα βάσης, χρήστη και κωδικό που ορίσατε κατά τη δημιουργία της ΒΔ στο βήμα 11 (αν αφήσατε τα παραδείγματα — monitor_db / monitor_user). Τα DB_HOST και DB_CHARSET μην τα πειράξετε.
APP_URL — η πλήρης διεύθυνση του πίνακα με https://, χωρίς κάθετο στο τέλος και χωρίς www. Πρέπει να ταιριάζει με τον τομέα στον οποίο ενεργοποιείτε την άδεια (βήμα 16), αλλιώς το κλειδί θα απορριφθεί.
TIMEZONE — η ζώνη ώρας σας (λίστα — timedatectl list-timezones). Επηρεάζει μόνο τον τρόπο που ο πίνακας εμφανίζει τις ημερομηνίες· στην ώρα εκτέλεσης των εργασιών cron δεν επηρεάζει (εκεί ισχύει η ζώνη του συστήματος).
SESSION_LIFETIME — μετά από πόσα δευτερόλεπτα αδράνειας ο πίνακας θα ζητήσει νέα σύνδεση (προεπιλογή 8 ώρες). Π.χ. 3600 = 1 ώρα, 86400 = μία μέρα.
Το μπλοκ καταγραφής σφαλμάτων (display_errors, log_errors, error_log) — αφήστε το στην προεπιλογή.
Αποθηκεύστε το αρχείο (Ctrl+O, Enter, μετά Ctrl+X) και επανεκκινήστε το PHP-FPM — αλλιώς λόγω του OPcache οι αλλαγές δεν θα εφαρμοστούν:
sudo systemctl restart php*-fpm
Το config.php είναι μυστικό αρχείο (περιέχει τον κωδικό της ΒΔ). Βρίσκεται στη ρίζα του πίνακα, που είναι και η ρίζα του web, αλλά είναι κλειδωμένο: δικαιώματα 640 (ορίστηκαν στο βήμα 10) και ρητή απαγόρευση στο ριζικό .htaccess. Μην το ανεβάζετε σε δημόσια αποθετήρια και μην το στέλνετε στην υποστήριξη με πραγματικό κωδικό.
Η PHP εκτελείται από τον χρήστη του διακομιστή web, ο οποίος δεν έχει δικαιώματα σε εντολές συστήματος. Η πρόσβαση δίνεται περιορισμένα: στοχευμένο sudo σε συγκεκριμένα εργαλεία και ανάγνωση των logs μέσω ομάδων (χωρίς sudo). Η παραβίαση του επιπέδου web δεν δίνει root.
Στα παραδείγματα το www-data είναι ο τυπικός χρήστης του Apache. Αν εσείς έχετε άλλον (σε ορισμένους πίνακες η PHP τρέχει με ξεχωριστό χρήστη) — αντικαταστήστε τον παντού. Δείτε τον με: ps -o user= -C php-fpm | sort -u.
1. Δημιουργήστε το /etc/sudoers.d/monitor με sudo visudo -f /etc/sudoers.d/monitor και επικολλήστε (αφαιρέστε τις γραμμές των μονάδων που δεν χρησιμοποιείτε):
# UFW — κατάσταση και κανόνες (σελίδα «Τείχος προστασίας»)
www-data ALL=(ALL) NOPASSWD: /usr/sbin/ufw status, /usr/sbin/ufw status verbose, /usr/sbin/ufw status numbered
www-data ALL=(ALL) NOPASSWD: /usr/sbin/ufw allow [0-9]*, /usr/sbin/ufw deny [0-9]*, /usr/sbin/ufw --force delete [0-9]*
# Fail2ban — κατάσταση, ban και unban (το banned επιστρέφει τα ban όλων των jail με μία εντολή·
# τα ban/unban χρειάζονται τα κουμπιά του dashboard)
www-data ALL=(ALL) NOPASSWD: /usr/bin/fail2ban-client status, /usr/bin/fail2ban-client status *, /usr/bin/fail2ban-client banned, /usr/bin/fail2ban-client set * banip *, /usr/bin/fail2ban-client set * unbanip *
# Ενημερώσεις ασφαλείας (κάρτα «Ενημερώσεις»). Μόνο ανάγνωση, αλλά ακριβώς ως root:
# η cache του apt (~70 MB) είναι προσβάσιμη μόνο στον root, ο μη-root την ξαναχτίζει σε κάθε κλήση
# (4.2 s CPU έναντι 0.01 s). Χωρίς wildcard — ακριβώς αυτή η μία εντολή, δεν εγκαθιστά τίποτα.
www-data ALL=(ALL) NOPASSWD: /usr/bin/apt list --upgradable
# IPset (χάρτης επιθέσεων, dashboard)
www-data ALL=(ALL) NOPASSWD: /usr/sbin/ipset list -t ipsum
# CrowdSec
www-data ALL=(ALL) NOPASSWD: /usr/bin/cscli decisions list *, /usr/bin/cscli alerts list *, /usr/bin/cscli bouncers list *, /usr/bin/cscli scenarios list *
# Auditd — αναζήτηση συμβάντων + ανάγνωση των τελευταίων γραμμών του journal (ακριβής διαδρομή)
www-data ALL=(ALL) NOPASSWD: /usr/sbin/ausearch -m *
www-data ALL=(ALL) NOPASSWD: /usr/bin/tail -n 300 /var/log/audit/audit.log
# Monit / ModSecurity / AppArmor / PSAD
www-data ALL=(ALL) NOPASSWD: /usr/bin/monit status
www-data ALL=(ALL) NOPASSWD: /usr/sbin/apache2ctl -M
www-data ALL=(ALL) NOPASSWD: /usr/local/bin/monitor-modsec
www-data ALL=(ALL) NOPASSWD: /usr/sbin/aa-status
www-data ALL=(ALL) NOPASSWD: /usr/sbin/psad --Status
# Ανοιχτές θύρες (τα logs του πυρήνα/SSH/Falco διαβάζονται ΧΩΡΙΣ sudo — μέσω της ομάδας
# systemd-journal, βλ. σημείο 2· ΔΕΝ χρειάζεται και είναι επισφαλές να δώσετε sudo στο journalctl)
www-data ALL=(ALL) NOPASSWD: /usr/bin/ss -tuln, /usr/sbin/ss -tuln, /bin/ss -tuln
# PostgreSQL (μόνο αν το χρησιμοποιείτε) — σταθερό read-only script,
# δημιουργήστε το κατά το FAQ «Η PostgreSQL δεν εμφανίζεται»· χωρίς αυτό διαγράψτε τη γραμμή
www-data ALL=(ALL) NOPASSWD: /usr/local/bin/monitor-pgstat
sudo chmod 440 /etc/sudoers.d/monitor
sudo visudo -c # πρέπει να βγει "parsed OK"
2. Πρόσβαση στα logs και στο journal του systemd. Οι μονάδες διαβάζουν τα /var/log/fail2ban.log, auth.log, ufw.log, apache2/*, aide απευθείας (σε Debian/Ubuntu αυτά τα logs ανήκουν στην ομάδα adm). Τα συμβάντα του πυρήνα, του SSH και του Falco λαμβάνονται από το journald με την εντολή journalctlχωρίς sudo, μέσω της ομάδας systemd-journal. Προσθέστε τον χρήστη web και στις δύο ομάδες και επανεκκινήστε το PHP-FPM:
sudo usermod -aG adm,systemd-journal www-data
sudo systemctl restart php*-fpm # υποχρεωτικό, αλλιώς οι ομάδες δεν θα εφαρμοστούν
3. Αν το ClamAV ή το Suricata γράφουν logs όχι στην ομάδα adm (συμβαίνει να είναι root:root) — δώστε πρόσβαση μέσω ACL:
4. Wrapper του ModSecurity. Το audit-log του WAF (/var/log/apache2/modsec_audit.log) ανήκει στον root με δικαιώματα 640, και ο χρήστης web δεν μπορεί να το διαβάσει απευθείας. Η σελίδα ModSecurity λαμβάνει τη λειτουργία της μηχανής, τα συμβάντα και τη λίστα των ενεργών κανόνων μέσω ενός σταθερού read-only script — αυτό ακριβώς επιτρέπεται στο sudoers με τη γραμμή παραπάνω:
Χωρίς το αρχείο /etc/modsecurity/modsecurity.conf το ίδιο το WAF δεν λειτουργεί: το πακέτο τοποθετεί μόνο το modsecurity.conf-recommended και η μηχανή κανόνων παραμένει απενεργοποιημένη — για το πώς ενεργοποιείται, βλ. FAQ → «Εγκατάσταση ModSecurity».
Ο χρήστης σε όλες τις γραμμές του sudoers πρέπει να ταυτίζεται με τον χρήστη του FPM-pool: σε τυπικό Apache/Debian είναι το www-data, στο HestiaCP το pool του ιστότοπου τρέχει από τον κάτοχο του ιστότοπου (π.χ. admin) — ελέγξτε με grep -E '^user' /etc/php/*/fpm/pool.d/monitor.example.com.conf.
5. Αν μπροστά από τον Apache βρίσκεται ο Nginx (HestiaCP, ISPmanager και άλλοι πίνακες — εκεί ο Nginx κάνει proxy την PHP στον Apache και σερβίρει μόνος του το στατικό περιεχόμενο). Οι υπηρεσιακοί κατάλογοι κλείνουν με αρχεία .htaccess, αλλά ο Nginx δεν τα διαβάζει: κάθε στατικό αρχείο (.json, .txt, .log, .dat) το σερβίρει απευθείας, παρακάμπτοντας τον Apache. Θα διαρρεύσουν προς τα έξω οι caches του πίνακα και δεδομένα — για παράδειγμα το tmp/modsec_cache.json με συμβάντα WAF και IP επιτιθέμενων. Προσθέστε την απαγόρευση στο config του ιστότοπου Nginx:
Το πρόθεμα ^~ είναι υποχρεωτικό: επιλέγεται πριν από τον κανόνα regex για το στατικό περιεχόμενο μέσα στο location /, αλλιώς η απαγόρευση δεν θα ισχύσει.
Στο HestiaCP τοποθετήστε το ως ξεχωριστό αρχείο /home/<user>/conf/web/<domain>/nginx.ssl.conf_deny (και nginx.conf_deny για HTTP) — το config του ιστότοπου συμπεριλαμβάνει τα nginx.ssl.conf_* και κατά την ανακατασκευή δεν σβήνει τέτοια αρχεία. Εφαρμογή: sudo nginx -t && sudo systemctl reload nginx.
Έλεγχος: curl -s -o /dev/null -w '%{http_code}\n' https://monitor.example.com/tmp/modsec_cache.json — πρέπει να είναι 403. Αν ο Apache λειτουργεί χωρίς Nginx (ακούει μόνος του στις 80/443), δεν χρειάζεται να προσθέσετε τίποτα — το .htaccess αρκεί.
Ελέγξτε τις διαδρομές των binaries με το which (π.χ. which ufw cscli ausearch ss). Επεξεργαστείτε το sudoers μόνο μέσω visudo. Η λίστα όλων των βάσεων MySQL ενεργοποιείται με ξεχωριστό GRANT (FAQ → «Εμφανίζεται μόνο μία ΒΔ»).
14. Περιορισμός πρόσβασης βάσει IP
Περιορίστε την πρόσβαση στον μόνιτορ βάσει διεύθυνσης IP — ακόμη κι αν γίνει γνωστό το URL, η σελίδα σύνδεσης δεν θα ανοίξει. Μπορεί να γίνει σε επίπεδο διακομιστή web (παράδειγμα για nginx παρακάτω) ή μέσα από τον ίδιο τον πίνακα («Ρυθμίσεις» → «Περιορισμός πρόσβασης βάσει IP»). Αν έχετε Apache, χρησιμοποιήστε τον περιορισμό στον πίνακα.
Αν ο ιστότοπος nginx έχει ήδη ρυθμιστεί κατά το βήμα 10, μην προσθέσετε δεύτεροlocation / — γράψτε τις γραμμές allow/deny στο ήδη υπάρχον μπλοκ. Δύο ίδια location / μέσα σε ένα server { } είναι σφάλμα διαμόρφωσης, ο nginx δεν θα επανεκκινήσει.
# Στη διαμόρφωση nginx (μέσα στο server { }):
# Το μονοπάτι ACME του Let's Encrypt το κρατάμε ανοιχτό παρακάμπτοντας τον περιορισμό IP —
# ώστε η έκδοση και η αυτόματη ανανέωση SSL (βήμα 15) να μην εξαρτώνται από το φίλτρο IP.
location ^~ /.well-known/acme-challenge/ { allow all; }
location / {
allow 203.0.113.10; # ← γράψτε τη δική σας IP
allow 10.0.0.0/8; # τοπικό δίκτυο (αν χρειάζεται)
deny all;
try_files $uri $uri/ /index.php?$query_string;
}
# Επανεκκίνηση του nginx:
sudo nginx -t && sudo systemctl reload nginx
15. Έκδοση SSL (HTTPS)
Ο πίνακας λειτουργεί μόνο μέσω HTTPS. Η συνεδρία εισόδου χρησιμοποιεί ασφαλές cookie, ενώ το WebAuthn (2FA) λειτουργεί μόνο σε HTTPS. Μέσω http:// δεν μπορείτε να συνδεθείτε.
Το πιστοποιητικό είναι δωρεάν (Let's Encrypt). Το DNS του τομέα πρέπει ήδη να δείχνει στον διακομιστή. Η εντολή εξαρτάται από τον web server:
# Apache:
sudo certbot --apache -d monitor.example.com
# nginx — ΜΟΝΟ αν έχετε ακριβώς nginx. Σε Apache ΜΗΝ το εκτελείτε:
# το apt θα τραβήξει το nginx και θα καταλάβει τη θύρα 80, σύγκρουση με Apache.
# sudo apt install python3-certbot-nginx
# sudo certbot --nginx -d monitor.example.com
# το certbot γράφει μόνο του το HTTPS στη ρύθμιση και ρυθμίζει την αυτόματη ανανέωση
Τι θα ρωτήσει το certbot: e-mail → αποδοχή των Terms (Y) → κοινοποίηση e-mail στο EFF (κατά την κρίση σας). Έπειτα εκδίδει μόνο του το πιστοποιητικό, γράφει το <VirtualHost *:443>, ρυθμίζει την ανακατεύθυνση http→https και την αυτόματη ανανέωση.
Το DNS πρέπει να δείχνει στον διακομιστή ΠΡΙΝ την εκτέλεση του certbot (έλεγχος κυριότητας μέσω της θύρας 80). Έλεγχος: dig +short monitor.example.com → IP του διακομιστή. Οι θύρες 80/443 ανοιχτές: sudo ufw allow 80,443/tcp.
Μετά την έκδοση: το https://monitor.example.com ανοίγει με λουκέτο, το http:// ανακατευθύνει στο https:// (το APP_URL στο config.php έχει ήδη οριστεί στο βήμα 12).
16. Είσοδος και αρχική ρύθμιση
Ανοίξτε το https://monitor.example.com, συνδεθείτε με admin / useradmin και ακολουθήστε τη λίστα ελέγχου:
Αλλάξτε τον κωδικό του admin — ενότητα «Χρήστες» στο μενού.
Ενεργοποιήστε το WebAuthn (2FA) — «Κλειδιά WebAuthn» → καταχωρίστε κλειδί/passkey (απαιτεί HTTPS). Καταχωρίστε αμέσως δύο: αν χάσετε το μοναδικό κλειδί, η είσοδος με αυτό θα είναι αδύνατη. Περισσότερα.
Περιορίστε την πρόσβαση ανά IP — «Ρυθμίσεις» → «Περιορισμός πρόσβασης ανά IP» (καταχωρίστε την IP σας πριν την ενεργοποίηση, αλλιώς θα κλείσετε την πρόσβασή σας).
Καταχωρίστε την άδεια — ενεργοποιήστε τον κωδικό ARCIVEO-… από τον λογαριασμό στο domain σας και επικολλήστε το κλειδί στις «Ρυθμίσεις» → «Άδεια». Περισσότερα.
Ρυθμίστε τις ειδοποιήσεις — Telegram ή/και Email στις «Ρυθμίσεις». Περισσότερα.
Διαγράψτε τον εγκαταστάτηpublic/start_db.php, αν παρέμεινε (βήμα 11).
17. Εργαλεία ασφάλειας (προαιρετικά)
Ο πίνακας λειτουργεί ήδη. Τα εργαλεία εγκαθίστανται κατ' επιλογήν — εγκαθιστάτε ό,τι χρειάζεστε και ο πίνακας εμφανίζει αμέσως την κατάσταση. Οι εντολές εγκατάστασης του καθενός βρίσκονται στον οδηγό (ξεχωριστές ενότητες ανά εργαλείο):
Πρόκειται για επίδειξη του Arcivéo Security Monitor μόνο για προβολή — κάθε αλλαγή είναι απενεργοποιημένη. Αναπτύξτε το στον δικό σας διακομιστή για να διαχειριστείτε πραγματικά δεδομένα ασφαλείας.