# Εύρεση και αφαίρεση άγνωστων κλειδιών SSH

> Έλεγχος authorized_keys: πού βρίσκονται τα κλειδιά SSH στον διακομιστή, πώς αναγνωρίζετε ξένες εγγραφές, πώς τις αφαιρείτε με ασφάλεια και πώς θωρακίζετε το SSH μετά.

Πηγή: https://phpsos.de/el/blog/ssh-schluessel-pruefen/  
Ημερομηνία: 25/10/2026  
Πάροχος: PHP SOS, Επείγουσα βοήθεια PHP και ασφάλεια διακομιστών. Άμεση βοήθεια μέσω WhatsApp: https://wa.me/491736494914?text=%CE%93%CE%B5%CE%B9%CE%B1%20%CF%83%CE%B1%CF%82%2C%20PHP%20SOS%2C%20%CF%87%CF%81%CE%B5%CE%B9%CE%B1%CE%B6%CF%8C%CE%BC%CE%B1%CF%83%CF%84%CE%B5%20%CE%B2%CE%BF%CE%AE%CE%B8%CE%B5%CE%B9%CE%B1%20%CE%BC%CE%B5%20%CF%84%CE%BF%CE%BD%20%CE%B4%CE%B9%CE%B1%CE%BA%CE%BF%CE%BC%CE%B9%CF%83%CF%84%CE%AE%20PHP%20%CE%BC%CE%B1%CF%82.%20%CE%95%CF%84%CE%B1%CE%B9%CF%81%CE%B5%CE%AF%CE%B1%3A%20%E2%80%A6%20%CE%99%CF%83%CF%84%CF%8C%CF%84%CE%BF%CF%80%CE%BF%CF%82%3A%20%E2%80%A6

**Εν ολίγοις:** Για να βρείτε άγνωστα κλειδιά SSH, πρέπει να ελέγξετε όλα τα αρχεία authorized_keys στον διακομιστή, όχι μόνο του root. Προσδιορίστε με `sshd -T` ποια αρχεία διαβάζει η υπηρεσία SSH σας, απαριθμήστε τα δακτυλικά αποτυπώματα κάθε κλειδιού και αντιπαραβάλετέ τα με τα γνωστά κλειδιά. Διασφαλίστε πρώτα τις ξένες εγγραφές, αφαιρέστε τες και θωρακίστε μετά την πρόσβαση.

## Το κλειδί που επιβιώνει σε κάθε αλλαγή κωδικού

Μετά από ένα περιστατικό πολλοί διαχειριστές αλλάζουν πρώτα όλους τους κωδικούς. Απέναντι σε μία από τις πιο διακριτικές κερκόπορτες αυτό δεν βοηθά: ένα πρόσθετο δημόσιο κλειδί σε ένα αρχείο `authorized_keys`. Όποιος διαθέτει το αντίστοιχο ιδιωτικό κλειδί συνδέεται χωρίς κωδικό, όσο δεν βρίσκει κάποιος τη γραμμή.

Τα άγνωστα κλειδιά SSH ανήκουν γι' αυτό στις ενδείξεις που πρέπει πάντα να ελέγχονται μετά από εκτέλεση κώδικα. Για το PHP2Shell δεν υπάρχουν δημοσιευμένοι, επιβεβαιωμένοι Indicators of Compromise· η αναγνώριση βασίζεται σε ανάλυση συμπεριφοράς. Ένα ξένο κλειδί δεν είναι ειδική απόδειξη PHP2Shell, αλλά σαφής ένδειξη ότι κάποιος ήθελε μόνιμη πρόσβαση. Περαιτέρω ενδείξεις περιγράφει το [Έχω ήδη παραβιαστεί;](https://phpsos.de/el/php2shell/bin-ich-gehackt-anzeichen/).

## Πού βρίσκονται τα κλειδιά SSH στον διακομιστή

Το OpenSSH διαβάζει, σύμφωνα με την τεκμηρίωση, από προεπιλογή δύο αρχεία στον αρχικό κατάλογο κάθε χρήστη: `.ssh/authorized_keys` και `.ssh/authorized_keys2`. Το δεύτερο ξεχνιέται συχνά. Η ρύθμιση μπορεί να αλλάξει και με το `AuthorizedKeysCommand` ο διακομιστής μπορεί ακόμη και να αντλεί κλειδιά από εξωτερικό πρόγραμμα. Ελέγξτε γι' αυτό πρώτα τι ισχύει πραγματικά στον διακομιστή σας:

```bash
# Εμφάνιση της ισχύουσας διαμόρφωσης SSH (μόνο ανάγνωση)
sudo sshd -T | grep -iE '^(authorizedkeysfile|authorizedkeyscommand|permitrootlogin|passwordauthentication|pubkeyauthentication)'

# Πρόσθετα αρχεία διαμόρφωσης και μπλοκ Match
ls -la /etc/ssh/sshd_config.d/ 2>/dev/null
sudo grep -rn -iE '^\s*(Match|AuthorizedKeys)' /etc/ssh/
```

Ένα ιδιαίτερο σημείο είναι ο αρχικός κατάλογος του χρήστη του διακομιστή ιστού. Σε Debian και Ubuntu αυτός είναι για το `www-data` συχνά το `/var/www`. Αν ο κατάλογος αυτός είναι εγγράψιμος για την PHP, ο παρεισφρήσας κώδικας μπορεί να δημιουργήσει εκεί ένα `.ssh/authorized_keys`. Το αν η σύνδεση θα πετύχει τότε εξαρτάται από το shell σύνδεσης και τις ρυθμίσεις SSH, το ίδιο το αρχείο όμως είναι ήδη προειδοποιητικό σημάδι.

Δεν είναι κακόβουλη κάθε άγνωστη εγγραφή. Εργαλεία deployment, υπηρεσίες αντιγράφων ασφαλείας ή πρώην πάροχοι υπηρεσιών καταχωρίζουν δικά τους κλειδιά. Τέτοιες εγγραφές πρέπει όμως να έχουν γνωστό κάτοχο και σκοπό.

## Έλεγχος authorized_keys βήμα προς βήμα

Οι παρακάτω εντολές δεν αλλάζουν τίποτα. Απαριθμούν όλα τα αρχεία κλειδιών των χρηστών και δείχνουν για κάθε κλειδί το δακτυλικό αποτύπωμα:

```bash
# Όλα τα αρχεία authorized_keys στους αρχικούς καταλόγους όλων των χρηστών
getent passwd | cut -d: -f1,6 | while IFS=: read -r user home; do
  for f in "$home/.ssh/authorized_keys" "$home/.ssh/authorized_keys2"; do
    [ -f "$f" ] && echo "== $user: $f" && sudo ls -la --time-style=full-iso "$f"
  done
done

# Εμφάνιση δακτυλικών αποτυπωμάτων και σχολίων ενός αρχείου
sudo ssh-keygen -lf /root/.ssh/authorized_keys

# Πρόσθετα αρχεία κλειδιών εκτός των συνήθων θέσεων
sudo find / -xdev -name 'authorized_keys*' 2>/dev/null
```

Διατρέξτε το αποτέλεσμα με αυτή τη λίστα ελέγχου:

1. **Ανήκει κάθε κλειδί σε γνωστό πρόσωπο ή γνωστή υπηρεσία;** Αντιπαραβάλετε τα δακτυλικά αποτυπώματα, όχι μόνο το σχόλιο.
2. **Έχει κάποιος χρήστης κλειδιά ενώ δεν θα έπρεπε να έχει καθόλου;** Για παράδειγμα ο χρήστης του διακομιστή ιστού, της βάσης δεδομένων ή λογαριασμοί υπηρεσιών.
3. **Υπάρχουν επιλογές πριν από το κλειδί;** Οι εγγραφές με `command=` εκτελούν σε κάθε σύνδεση μια σταθερή εντολή. Αυτό είναι θεμιτό για αντίγραφα ασφαλείας, αλλά και κρυψώνα.
4. **Πότε άλλαξε τελευταία φορά το αρχείο;** Μια ημερομηνία αλλαγής μετά τις 17.10.2026, την ημέρα της πρώτης παρατηρηθείσας απόπειρας επίθεσης PHP2Shell σύμφωνα με δημοσιεύματα, αξίζει ιδιαίτερη προσοχή. Οι χρονοσημάνσεις όμως μπορούν να πλαστογραφηθούν.
5. **Ταιριάζουν ιδιοκτήτης και δικαιώματα;** Ένα αρχείο που ανήκει σε άλλον χρήστη από τον αρχικό κατάλογο προκαλεί προσοχή.

## Ασφαλής αφαίρεση ξένων κλειδιών

Πριν διαγράψετε μια γραμμή, διασφαλίστε το αρχείο με χρονοσήμανση και άθροισμα ελέγχου εκτός του διακομιστή. Σημειώστε το δακτυλικό αποτύπωμα του ξένου κλειδιού. Βοηθά αργότερα στο ερώτημα αν το ίδιο κλειδί εμφανίζεται και σε άλλους διακομιστές, για παράδειγμα σε ένα γραφείο με πολλά συστήματα πελατών.

Ελέγξτε επιπλέον τα πρωτόκολλα σύνδεσης. Στο `/var/log/auth.log` (Debian, Ubuntu) ή στο `/var/log/secure` (οικογένεια RHEL) η υπηρεσία SSH καταγράφει τις επιτυχημένες συνδέσεις με το δακτυλικό αποτύπωμα του κλειδιού που χρησιμοποιήθηκε. Έτσι βλέπετε αν το ξένο κλειδί έχει ήδη χρησιμοποιηθεί και από ποια διεύθυνση.

Σκεφτείτε και την αντίστροφη κατεύθυνση. Αν στον διακομιστή βρίσκονται ιδιωτικά κλειδιά, για παράδειγμα κάτω από `~/.ssh/id_*` για deployments ή αντίγραφα ασφαλείας, ο επιτιθέμενος μπορούσε να τα αντιγράψει. Με αυτά φτάνει ενδεχομένως σε άλλους διακομιστές, αποθετήρια Git ή προορισμούς αντιγράφων ασφαλείας. Τέτοια κλειδιά θεωρούνται μετά από εισβολή εξαντλημένα: δημιουργήστε νέα κλειδιά και αφαιρέστε τα παλιά από όλα τα συστήματα προορισμού.

Ένα ξένο κλειδί είναι σπάνια το μοναδικό ίχνος. Όποιος το κατέθεσε, είχε δικαιώματα εγγραφής και ίσως έχει ρυθμίσει περαιτέρω δρόμους, όπως cronjobs ή πρόσθετους λογαριασμούς. Ελέγξτε γι' αυτό και τα [κρυφά cronjobs](https://phpsos.de/el/blog/cronjobs-als-hintertuer/) και τους [ξένους λογαριασμούς διαχειριστή](https://phpsos.de/el/blog/fremde-admin-konten-finden/). Αν ο επιτιθέμενος είχε δικαιώματα root, μια αναδόμηση του διακομιστή είναι συχνά πιο αξιόπιστη από έναν καθαρισμό.

> **Σημαντικό:**
> Αφαιρέστε ξένα κλειδιά μόνο όταν η PHP βρίσκεται σε διορθωμένο επίπεδο (8.5.12, 8.4.27, 8.3.36, 8.2.35 ή επιβεβαιωμένο backport) και όλοι οι workers έχουν επανεκκινηθεί. Αλλιώς ο επιτιθέμενος μπορεί να καταχωρίσει το κλειδί αμέσως ξανά μέσω της ίδιας ευπάθειας.

## Θωράκιση της πρόσβασης SSH μετά

Μετά τον καθαρισμό αξίζει μια σύντομη θωράκιση. Τα περισσότερα σημεία υλοποιούνται γρήγορα, πρέπει όμως να δοκιμάζονται πάντα με μια δεύτερη, ανοιχτή συνεδρία, ώστε να μην κλειδωθείτε έξω.

| Μέτρο | Ρύθμιση ή διαδικασία |
|---|---|
| Σύνδεση μόνο με κλειδί | `PasswordAuthentication no` |
| Να μη συνδέεται απευθείας το root | `PermitRootLogin no`, εργασία μέσω προσωπικών λογαριασμών με sudo |
| Απενεργοποίηση του δεύτερου αρχείου κλειδιών | `AuthorizedKeysFile .ssh/authorized_keys` |
| Περιορισμός κλειδιού ως προς την προέλευση | επιλογή `from=` πριν από το κλειδί, για παράδειγμα για διακομιστή αντιγράφων ασφαλείας |
| Περιορισμός κλειδιών υπηρεσιών | επιλογή `restrict` και σταθερό `command=` για αυτοματισμό |
| Χρήστης διακομιστή ιστού χωρίς σύνδεση | shell σύνδεσης `nologin`, κανένα `.ssh` στον αρχικό κατάλογο |

Τηρείτε επιπλέον μια λίστα όλων των εξουσιοδοτημένων κλειδιών με κάτοχο και σκοπό. Όταν αποχωρεί ένας συνεργάτης ή πάροχος υπηρεσιών, το κλειδί του αφαιρείται από όλους τους διακομιστές. Χωρίς αυτή τη λίστα ο επόμενος έλεγχος είναι πάλι έργο ντετέκτιβ. Αναγνωρισμένες προδιαγραφές θωράκισης για το SSH περιέχουν και τα CIS Benchmarks.

## Πώς βοηθά συγκεκριμένα η PHP SOS;

- Εντοπίζουμε ποια αρχεία κλειδιών διαβάζει πραγματικά η υπηρεσία SSH σας και ελέγχουμε κάθε εγγραφή σε σχέση με τους γνωστούς κατόχους.
- Διασφαλίζουμε τα ευρήματα και αξιολογούμε τα πρωτόκολλα σύνδεσης, για να διευκρινίσουμε αν χρησιμοποιήθηκε ένα ξένο κλειδί.
- Καθαρίζουμε κλειδιά, λογαριασμούς και cronjobs με τη σωστή σειρά και κλείνουμε προηγουμένως την ευπάθεια.
- Στο πλαίσιο της [θωράκισης διακομιστή](https://phpsos.de/el/leistungen/server-haertung/) υλοποιούμε τις ρυθμίσεις SSH και ρυθμίζουμε μια διαχείριση κλειδιών με λίστα κατόχων.


## Συχνές ερωτήσεις

**Πώς καταλαβαίνω αν ένα κλειδί SSH είναι ξένο;**  
Κάθε κλειδί έχει δακτυλικό αποτύπωμα και συνήθως ένα σχόλιο στο τέλος της γραμμής. Αντιπαραβάλετε τα δακτυλικά αποτυπώματα με τα κλειδιά των συνεργατών και των παρόχων υπηρεσιών σας. Το σχόλιο μόνο του δεν αποδεικνύει τίποτα, γιατί επιλέγεται ελεύθερα και μπορεί να πλαστογραφηθεί.

**Βοηθά να αλλάξω τον κωδικό του root;**  
Όχι απέναντι σε κλειδί που παρεισέφρησε. Η σύνδεση με κλειδί δεν χρειάζεται κωδικό. Γι' αυτό τα ίδια τα αρχεία authorized_keys πρέπει να ελεγχθούν και να καθαριστούν.

**Γιατί μπορεί ο χρήστης του διακομιστή ιστού να έχει κλειδί SSH;**  
Ο χρήστης του διακομιστή ιστού έχει δικό του αρχικό κατάλογο, σε Debian και Ubuntu συχνά /var/www. Αν υπάρχει εκεί ένα .ssh/authorized_keys και ο λογαριασμός έχει shell σύνδεσης, είναι δυνατή η σύνδεση ως αυτός ο χρήστης. Αν ο κατάλογος ιστού είναι εγγράψιμος, ο παρεισφρήσας κώδικας PHP μπορεί να δημιουργήσει ένα τέτοιο αρχείο.

**Τι είναι το authorized_keys2;**  
Ένα παλαιότερο δεύτερο αρχείο που το OpenSSH διαβάζει σύμφωνα με την προεπιλεγμένη ρύθμιση επίσης. Πολλοί οδηγοί ελέγχου το παραβλέπουν. Ελέγξτε με sshd -T ποια αρχεία αξιολογεί πραγματικά ο διακομιστής σας.

## Πηγές

- [BSI: υποδείξεις για περιστατικά ασφαλείας πληροφορικής](https://www.bsi.bund.de/)
- [php.net: ανακοινώσεις ασφαλείας](https://www.php.net/)
- [CIS Benchmarks](https://www.cisecurity.org/cis-benchmarks)
