Στον χάρτη επιθέσεων υπάρχει μια πυκνή κηλίδα πάνω από μία χώρα, και από μόνος του προτείνεται ο κανόνας «να απαγορευτεί ολόκληρη». Δεν θα δώσει σχεδόν τίποτα: η αλλαγή της χώρας εξόδου κοστίζει στον επιτιθέμενο λίγα λεπτά, ενώ κάτω από την απαγόρευση θα πέσουν οι δικοί σας επισκέπτες και εσείς οι ίδιοι όταν ταξιδεύετε. Χειρότερα ακόμη: ένας ορατός ανιχνευτής που έρχεται από ένα μόνο νέφος, μετά τον αποκλεισμό θα μετακομίσει σε οικιακές διευθύνσεις και θα γίνει αδιάκριτος από τους ανθρώπους.
Παρακάτω υπάρχουν πέντε βήματα που στον ίδιο διακομιστή δίνουν πράγματι αποτέλεσμα: να κοπούν οι σαρωτές, να περιοριστεί ο ρυθμός, να μην κοπεί το απαραίτητο και, αν τελικά χρειάζεται, να γίνει σωστός αποκλεισμός. Όλα ελέγχονται και ρυθμίζονται σε ένα κάθισμα.
Βήμα 1. Δείτε ποιος δημιουργεί πραγματικά την κηλίδα
Πρώτα βρείτε το αρχείο καταγραφής αιτημάτων. Σε διακομιστή με πολλούς ιστότοπους το access.log συχνά είναι άδειο, ενώ οι εγγραφές πηγαίνουν στο αρχείο καταγραφής του κάθε εικονικού κόμβου:
sudo ls -lS /var/log/apache2/*access*.log /var/log/apache2/*requests*.log 2>/dev/null
Σε όλες τις επόμενες εντολές μπαίνει το αρχείο που βρέθηκε στην κορυφή αυτού του καταλόγου. Πρώτα οι κορυφαίες διευθύνσεις του εικοσιτετραώρου, έπειτα τι ακριβώς ζητά εκείνη που βρίσκεται στην κορυφή:
sudo awk '{print $1}' /var/log/apache2/access.log | sort | uniq -c | sort -rn | head -20
sudo grep '^203\.0\.113\.' /var/log/apache2/access.log | awk '{print $7}' | sort | uniq -c | sort -rn | head -20
Η δεύτερη εντολή απαντά στο κύριο ερώτημα. Αν στην έξοδο υπάρχουν δεκάδες διαφορετικές σελίδες του ιστοτόπου σας, πρόκειται για συλλέκτη περιεχομένου: είναι αβλαβής και αρκεί να μην τον μετράτε ως επισκέπτη. Αν εκεί βρίσκονται /wp-login.php, /.env, /phpmyadmin και άλλα που δεν τα έχετε, πρόκειται για σαρωτή, και με αυτόν ασχολείται το βήμα 2. Στον nginx τα αρχεία καταγραφής βρίσκονται στο /var/log/nginx/, τα πεδία είναι τα ίδια.
Βήμα 2. Ένα jail για αιτήματα προς ό,τι δεν έχετε
Η διαδρομή του αιτήματος δεν πλαστογραφείται — αυτή είναι η ίδια η πρόθεση, σε αντίθεση με τη διεύθυνση και τον User-Agent. Το φίλτρο /etc/fail2ban/filter.d/web-probes.local:
[Definition]
failregex = ^<HOST> .* "(GET|POST|HEAD) /(wp-login\.php|wp-admin|xmlrpc\.php|\.env|\.git/|phpmyadmin|administrator/)
ignoreregex =
Το jail /etc/fail2ban/jail.d/web-probes.local:
[web-probes]
enabled = true
port = http,https
filter = web-probes
logpath = /var/log/apache2/*access.log
maxretry = 1
findtime = 1h
bantime = 1d
Εδώ το maxretry = 1 δικαιολογείται: τυχαίες προσβάσεις σε ξένο πίνακα διαχείρισης δεν υπάρχουν. Εφαρμόστε το και βεβαιωθείτε ότι το φίλτρο πιάνει γραμμές στο δικό σας αρχείο καταγραφής:
sudo fail2ban-regex /var/log/apache2/access.log /etc/fail2ban/filter.d/web-probes.local
sudo systemctl reload fail2ban && sudo fail2ban-client status web-probes
Βήμα 3. Περιορίστε τον ρυθμό
Ο σαρωτής και ο ανιχνευτής προδίδονται από την ταχύτητα, ανεξάρτητα από τη χώρα προέλευσης. Τριάντα σελίδες το λεπτό από μία διεύθυνση είναι ένα κατώφλι που δεν αγγίζει άνθρωπο ο οποίος ξεφυλλίζει έναν κατάλογο:
[http-flood]
enabled = true
port = http,https
filter = apache-overflows
logpath = /var/log/apache2/site_access.log
maxretry = 30
findtime = 60
bantime = 1h
Η καθοριστική λεπτομέρεια είναι ποιο αρχείο καταγραφής αναγράφεται στο logpath. Αν κάτω από το μοτίβο πέσει το αρχείο καταγραφής του ίδιου του πίνακα διαχείρισης ή της περιοχής διαχείρισης, θα αποκλείσετε τον εαυτό σας: μία μόνο σελίδα του τραβά μαζί της καμιά δεκαριά αιτήματα για στυλ και σενάρια, και τα τριάντα συμπληρώνονται με δύο κλικ. Γι' αυτό στον πίνακα δίνεται ξεχωριστό αρχείο καταγραφής, που δεν ταιριάζει με το μοτίβο του jail, και στα στατικά αρχεία μεγάλη διάρκεια προσωρινής αποθήκευσης, ώστε ο περιηγητής να μην τα ζητά ξανά σε κάθε μετάβαση. Το σύμπτωμα, αν τελικά συμβεί: το HTML φτάνει, η εμφάνιση όχι, η σελίδα κρέμεται. Άρση του αποκλεισμού:
sudo fail2ban-client set http-flood unbanip 203.0.113.10
Βήμα 4. Προστατέψτε ό,τι δεν πρέπει να κοπεί
Πριν ενεργοποιήσετε τους αποκλεισμούς, γράψτε τις εξαιρέσεις — αλλιώς το πρώτο που θα πέσει κάτω από αυτούς θα είναι το απαραίτητο:
[DEFAULT]
ignoreip = 127.0.0.1/8 ::1 203.0.113.0/24 66.249.64.0/19
Τι πρέπει οπωσδήποτε να υπάρχει σε αυτή τη γραμμή και γιατί:
- Η δική σας διεύθυνση ή το υποδίκτυο του γραφείου. Η συχνότερη αιτία απώλειας πρόσβασης στον διακομιστή είναι ο δικός σας κανόνας, όχι κάποια επίθεση·
- Το εύρος
66.249.64.0/19. Το ρομπότ αναζήτησης της Google αναγνωρίζεται από τον User-Agent, όμως εκείνο το μέρος του που εκτελεί JavaScript έρχεται ως συνηθισμένοςChrome/Linuxκαι δεν συστήνεται. Κάθε κανόνας του τύπου «να αποκλειστεί η κίνηση από κέντρα δεδομένων» χτυπά ακριβώς αυτό, και έπειτα οι σελίδες βγαίνουν σιωπηλά από το ευρετήριο. Μια ύποπτη διεύθυνση ελέγχεται με αντίστροφο ερώτημα: η εντολήdig -x 66.249.66.1 +shortπρέπει να επιστρέψει όνομα στη ζώνηgooglebot.com· - Οι διευθύνσεις των ειδοποιήσεων πληρωμής. Τα webhook των συστημάτων πληρωμών έρχονται από διακομιστές AWS και Azure. Αν κλείσετε αυτά τα νέφη ολόκληρα, οι επιβεβαιώσεις πληρωμών θα πάψουν να φτάνουν, και θα το μάθετε όταν κάποιος πελάτης γράψει ότι τα χρήματα χρεώθηκαν αλλά πρόσβαση δεν υπάρχει. Τα εύρη λαμβάνονται από την τεκμηρίωση του παρόχου πληρωμών σας.
Βήμα 5. Αν ο αποκλεισμός τελικά χρειάζεται — αποκλείστε υποδίκτυο, όχι χώρα
Μια σταθερή πύκνωση από ένα μόνο δίκτυο, που κρατά μέρες και συνοδεύεται από ομοιόμορφα αιτήματα, είναι ένας μόνο εκτελεστής που πηγαίνει βάσει καταλόγου. Αυτή η περίπτωση αποκλείεται σημειακά και για ορισμένο χρόνο:
sudo ufw deny from 198.51.100.0/22 to any
sudo ufw status numbered
Με τη δεύτερη εντολή σημειώστε τον αριθμό του κανόνα: η άρση του αποκλεισμού θα γίνει ακριβώς μέσω αυτού, sudo ufw delete <αριθμός>. Συμφωνήστε με τον εαυτό σας μια προθεσμία — λόγου χάρη έναν μήνα — και γράψτε την άρση στο ημερολόγιο. Οι κανόνες που μπαίνουν «για πάντα» μετά από έναν χρόνο μετατρέπονται σε κατάλογο που κανείς δεν τολμά να αγγίξει, επειδή κανείς δεν θυμάται για ποιον λόγο βρέθηκαν εκεί αυτές οι διευθύνσεις.
Ποιο υποδίκτυο να αποκλείσετε μπορείτε να το βρείτε από τη διεύθυνση του πρώτου βήματος: whois 198.51.100.17 | grep -iE 'route|cidr|netname'.
Τι αλλάζει μετά από αυτά τα πέντε βήματα
Οι σαρωτές κόβονται με βάση την πρόθεση και όχι την προέλευση, και πιάνονται από το πρώτο αίτημα. Οι ανιχνευτές προσκρούουν στο όριο ρυθμού. Το ρομπότ αναζήτησης και οι ειδοποιήσεις πληρωμών συνεχίζουν να περνούν. Ο μόνος αποκλεισμός που έμεινε ευρύς είναι σημειακός, με γνωστή προθεσμία και κατανοητή αιτία.
Ο χάρτης δεν εξαφανίζεται, αλλά ο ρόλος του αλλάζει: δεν χρειάζεται για να κλείνει χώρες, αλλά για να εντοπίσετε την ίδια την πύκνωση και να τη συγκρίνετε με εκείνη πριν από μια εβδομάδα. Γι' αυτό χρειάζεται ιστορικό και όχι στιγμιότυπο του τρέχοντος εικοσιτετραώρου. Πώς δείχνει ένας τέτοιος χάρτης μαζί με το αρχείο αποκλεισμών και τον κατάλογο ανοιχτών θυρών, το δείχνουν οι σελίδες επίδειξης παρακάτω.