Εισαγωγή και Περιγραφή

Τα παρακάτω ζητούμενα υλοποιούνται σε Ubuntu 20.04.1 LTS Virtual Machine. Τα λογισμικά που απαιτήθηκαν για το περιβάλλον εργασίας είναι Docker και το swarmlab-sec για την δημιουργία ενός swarm cluster.

Docker

Το Docker είναι λογισμικό ανοιχτό κώδικα που επιτρέπει εικονικοποίηση σε επίπεδο λειτουργικού συστήματος, ώστε να μπορεί να γίνει ανάπτυξη και δοκιμή εφαρμογών σε απομονωμένες περιοχές χρήστη που ονομάζονται docker containers. Μέσω χρήσης τεχνολογιών του πυρήνα των Linux αποφεύγεται η χρήση επιπλέον υπολογιστικών πόρων που θα απαιτούσε μια κανονική εικονική μηχανή (Virtual Machine).

Swarm mode

Η χρήση του Docker σε swarm mode επιτρέπει την δημιουργία ενός cluster από μηχανές Docker που ονομάζονται κόμβοι (nodes) οι οποίοι μπορούν να είναι είτε masters είτε workers. Ένας κόμβος μπορεί να έχει και τους δυο ρόλους. Οι workers λαμβάνουν και εκτελούν εργασίες που τους αναθέτουν οι masters. Αυτό δεν εμποδίζει και τους masters από το να εκτελούν οι ίδιοι εργασίες. Πέρα από αυτό, η σημαντικότερη εργασία των master είναι η διαχείριση και ο συντονισμός ολόκληρου του cluster έτσι ώστε να εμφανίζεται ομαλή λειτουργία.

Swarmlab-sec

Tip
Με την χρήση του swarmlab-sec μπορούμε να δημιουργήσουμε με μεγαλύτερη ευκολία Docker swarm clusters και προσφέρει επιπλέον δυνατότητες διαχείρισης του cluster. Εδώ υπάρχουν οδηγίες σχετικά με την εγκατάσταση.

Προσομοίωση DoS/DDoS Attack

Σε αυτό το ζητούμενο θα γίνει μια προσομοίωση μιας επίθεσης DoS/DDoS σε έναν από τους κόμβους του cluster που θα δημιουργήσουμε. Πραγματοποιείτε συνήθως σε servers οι οποίοι υπερφορτώνονται με συνδέσεις από ένα δίκτυο υπολογιστών το οποίο μπορεί να είναι από ένας έως και εκατομμύριοι υπολογιστές και ονομάζεται botnet.

Ο επιτιθέμενος μπορεί να χρησιμοποιήσει περισσότερες τεχνικές για να αποκτήσει πρόσβαση σε πολλούς υπολογιστές και να έχει τον έλεγχο τελικά ενός botnet που στην συνέχεια θα χρησιμοποιήσει για την επίθεση του βάζοντας όλους τους υπολογιστές που έχει υπό τον έλεγχο του να κάνουν ταυτόχρονες συνδέσεις σε έναν server με αποτέλεσμα να μην αντέξει ο server το σύνολο των συνδέσεων και να βγει εκτός λειτουργίας και να μην μπορέσει να παρέχει υπηρεσίες. Μια επίθεση χαρακτηρίζεται ως DoS όταν χρησιμοποιείται ένας υπολογιστής ενώ DDoS όταν χρησιμοποιείται ένα δίκτυο υπολογιστών.

Χρήση του hping3 για πραγματοποίηση της επίθεσης

Το εργαλείο hping3 μπορεί να χρησιμοποιηθεί για την διεξαγωγή της επίθεσης.

Εγκατάσταση του hping3.

sudo apt update
sudo apt install hping3

Εφόσον είμαστε μέσα στον master μέσα στο swarm, μπορούμε βρίσκοντας την IP του, με την χρήση του nmap να δούμε και τις IP διευθύνσεις των υπόλοιπων κόμβων του cluster με τις παρακάτω εντολές:

ifconfig 				# Διέυθυνση IP του master node
nmap -sP 172.19.0.* 	# Εμφάνιση των IP διευθύσεων των υπόλοιπων κόμβων

Για να επιτεθούμε χρειαζόμαστε μια ανοιχτή πόρτα (port). Ανοιχνέυουμε τις ανοιχτές πόρτες με την εντολή:

nmap -p 1-100 <ip-addr>
Note
H εντολή ελέγχει ποιές πόρτες από την πόρτα 1 εώς την πόρτα 100 είναι ανοιχτές για την διεύθυνση που θέλουμε να χτυπήσουμε. Περισσότερες πληροφορίες για την χρήση του nmap για ανίχνευση ανοιχτών ports υπάρχουν εδώ.

Αφού βρούμε ποιά πόρτα είναι ανοιχτή, μπορούμε να μπούμε σε όσους workers θέλουμε να χρησιμοποιήσουμε για την επίθεση με την εντολη:

ssh docker@<worker-IP>

Σε κάθε worker πρέπει να γίνει εγκατάσταση του hping3. Αφού γίνει η εγκατάσταση, ο worker είναι έτοιμος να αρχίσει την επίθεση. Έαν η επίθεση γίνει από έναν worker τότε έχουμε DoS επίθεση, αν γίνει από περισσότερους, έχουμε DDoS επίθεση. Παρακάτω θα γίνει σύντομη περιγραφή για το πώς μπορεί να γίνει μια SYN flood επίθεση.

Tip
H SYN flood DDoS επίθεση εκμεταλλεύεται το 3-way handshake του πρωτοκόλλου TCP για την έναρξη μιας σύνδεσης μεταξύ client-server. Στην περίπτωση μιας SYN flood DDoS επίθεση, ο επιτιθέμενος στέλνει επαναλμβανόμενα πάρα πολλά SYN πακέτα, χωρίς να περιμένει για SYN-ACK από την μεριά του θύματος ώστε να γίνει η σύνδεση και τα SYN-ACK πακέτα που στέλνει το θύμα δεν φτάνουν ποτέ στον επιτιθέμενο.

Αφού έχουμε έτοιμο το hping3 στους workers που θα χρησιμοποιήσουμε, μπορεί να αρχίσει η επίθεση, με την παρακάτω εντολή:

sudo hping3 <target-IP> -p <target-port> -S --flood

Όπου αναλυτικά:

<target-IP>

Η IP διεύθυνση του θύματος.

-p <target-port>

Η ανοιχτή πόρτα που θα χρησιμοποιηθεί.

-S

Ορισμός τύπου πακέτου SYN.

--flood

Flood mode, στέλνουμε επαναλαμβανόμενα χωρίς να περιμένουμε απάντηση.

Με την εκτέλεση της παραπάνω εντολής σε πολλούς κόμβους κατά ενός κόμβου μπορεί να αρχίσει η DDoS επίθεση και το θύμα λαμβάνει μεγάλο όγκο SYN πακέτων.

Tip
Μπορούν να χρησιμοποιηθούν περισσότεροι παράμετροι στην εντολή για να κάνουν την ανίχνευση και την αντιμετώπιση από το θύμα πιο δύσκολη, όπως για παράδειγμα της παραμέτρου --rand-source που θα άλλαζε την source-IP διεύθυνση των πακέτων για κάθε πακέτο. Περισσότερα στο hping3-man.

Εντωπισμός και παρουσίαση επίθεσης με tcpdump, netstat

Για να εντωπίσουμε μια επίθεση DDoS υπάρχουν πολλά χρήσιμα εργαλεία με τα βασικά να είναι το tcpdump και το netstat.

Tip
Το tcpdump είναι command-line packet analyser, το οποίο εμφανίζει όλα τα πακέτα που στέλνονται και λαμβάνονται σε ένα δίκτυο ή σε μια διεπαφή. Το netstat είναι ένα command-line εργαλείο το οποίο εμφανίζει συνδέσεις δικτύου, πίνακες δρομολόγησεις, στατιστικά κ.α. Μπορούν να χρησιμοποιήθουν μαζί για ανάλυση και εντωπισμό DDoS επιθέσεων.

Για την παρουσίαση όλων των πακέτων που λαμβάνουμε μπορούμε να χρησιμοποιήσουμε την εντολη:

sudo tcpdump -i eth0 -n

Η οποία εμφανίζει όλα τα πακέτα που στέλνονται και λαμβάνονται στην διεπαφή eth0 με τις IP διευθύνσεις αυτών που στέλνουν και λαμβάνουν. Μπορεί να παρατηρηθεί να παρατηρηθεί για παράδειγμα ότι από ορισμένες διευθύνσεις ο host δέχεται υπερβολικά πολλά πακέτα SYN σε λίγο χρόνο από τις διευθύνσεις των worker nodes που χρησιμοποιούμε για την επίθεση. Μπορεί να αναλυθεί η κίνηση μάλιστα που υπάρχει σε συγκεκριμένες θύρες μέσω της εντολής:

sudo tcpdump port <port-no> -n
Note
Εάν τρέξουμε την εντολή netstat δεν παρατήρουμε κάτι το ιδιαίτερο αν δεν έχει γίνει σύνδεση μεταξύ του επιτιθέμενου και του θύματος και στην περίπτωση ενός SYN flood δεν γίνεται ποτέ σύνδεση παρά μόνο προσπάθεια σύνδεσης!

Εάν καταλαβαίνουμε ότι πρόκειται για SYN flood επίθεση, τότε μπορούμε να εμφανίσουμε μόνο τα SYN πακέτα μέσω τις εντολής:

sudo tcpdump 'tcp[tcpflags] == tcp-syn' -n
Tip
Με μια τέτοια απλή ανάλυση μπορούμε να καταλάβουμε τον τύπο της επίθεσης και την πήγη από την οποία προέρχεται. Φυσικά η διαδικασία μπορεί να γίνει πιο δύσκολη όταν έχουμε χιλιάδες άλλα πακέτα να στέλνονται και να λαμβάνονται, όπως επίσης και αν ο επιτιθέμενος κάνει την επίθεση με τύχαιες source IP διευθύνσεις καθε φορα.

Χρήση iptables rules για αντιμετώπιση μιας επίθεσης

Η αντιμετώπιση μιας DDoS επίθεσης μπορεί να γίνει μέσω iptables rules.

Tip
To ip tables είναι ένα command-line πρόγραμμα το οποίο επιτρέπει την διαχείρηση του firewall του πυρίνα των linux, με το οποίο μπορούμε να φιλτράρουμε και να εμποδίσουμε ή να στείλουμε σε άλλον δρομολογητή πακέτα απο συγκεκριμένες διευθύνσεις ή συγκεκριμένου τύπου, το οποίο το κάνει το τέλειο εργαλείο για την αντιμετώπιση μιας DDoS επίθεσης!

Στην περίπτωση της επίθεσης SYN flood που περιγράφουμε, μπορούμε να πάρουμε κάποια βασικά αντίμετρα. Εφόσον η επίθεση γίνεται με την πραγματική διεύθυνση του επιτιθέμενου, η επίθεση μπορεί να σταματήσει πολύ εύκολα, με έναν απλό κανόνα, τον οποίο μπορούμε να ορίσουμε με την εντολή:

sudo iptables -A INPUT -s <source-IP> -j DROP
Note
Η παραπάνω εντολή κάνει alter, αλλάζει δηλαδή τον πίνακα για τα πακέτα που δεχόμαστε (-Α INPUT) και τα πακέτα που δεχόμαστε από την διεύθυνση IP (-s <source-IP>) τα πετάει και δεν τα δέχεται (-j DROP). Αν γίνει αυτό για όλες τις διευθύνσεις IP που στέλνουν επαναλαμβανόμενα πολλά πακέτα SYN, τότε η επίθεση σταματάει!

Οι πίνακες INPUT, FOWARD και OUTPUT μπορούν να εμφανιστούν με την χρήση της εντολής:

sudo iptables -L

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

sudo iptables -nvL
Tip
Στην περίπτωση που αναλύουμε, οι κάνονες που ορίσαμε δούλεψαν και η επίθεση σταματάει διότι ηταν πολύ απλή προσωμοίωση. Φυσικά σε περίπτωση που ο επιτιθέμενος χρησιμοποιεί πάρα πολλούς κόμβους για την επίθεση, με κάθε πακέτο να έχει ψεύτικη διαφορετική διεύθυνση, τα πράγματα είνα διαφορετικά, καθώς θα ήταν δύσκολο να φτίαξουμε έναν κανόνα για κάθε μια από τις εκατοντάδες ή και χιλιάδες διευθύνσεις του επιτιθέμενου. Θα μπορούσαμε όμως να φιλτράρουμε τον αριθμό των SYN πακέτων που μπορούν να σταλούν για παράδειγμα που θα ήταν πολύ πιο αποτελεσματικό.

Στιγμιότυπα οθόνης από προσομοίωση της επίθεσης

Παρακάτω εμφανίζονται στιγμιότυπα οθόνης από προσομοίωση μιας SYN flood DDoS επίθεσης με τον τρόπου που περιγράψαμε. Η επίθεση γίνεται από δυο workers, τον worker 2 (172.19.0.4) και τον worker 3 (172.19.0.5) κατά του worker 1 (172.19.0.3).

ifconfig
nmap
nmap showopenport
gettinginworker1
worker1 hping
worker2 hping
tcpdump
tcpdump p22
tcpdumpSYN
iptablesblocked
iptablesblocked packets

SSH Brute Force

Σε αυτό το ζητούμενο θα γίνει προσομοίωση και ανάλυση μιας επίθεσης SSH Brute Force. To SSH είναι δικτυακό πρωτόκολλο που προσφέρει μεταφορά δεδομένων μεταξύ υπολογιστών. Προσφέρει ασφαλής μεταφορά δεδομένων καθώς και κρυπτογράφήση τους. Δουλεύει σε μοντέλο client-server, με τον client να ζητάει την σύνδεση και να την επαληθεύει με κωδικό η ιδιωτικό κλειδί Μια επίθεση SSH brute force έχει ως σκοπό την απόκτηση πρόσβασης σε τέτοιους SSH servers. Ο επιτιθέμενος κάνει συνεχόμενες απόπειρες σύνδεσης με χρήση πολλών συνδυασμών πιθανών κωδικών μέχρι να μπορέσει να αποκτήσει πρόσβαση.

Χρήση του Hydra για την επίθεση

Για την προσομοίωση της επίθεσης, θα γίνει χρήση του εργαλείου Hydra. Ένας worker θα είναι ο SSH client που προσπαθεί να αποκτήσει πρόσβαση και ένας άλλος θα είναι ο SSH server. Για την επίθεση μπορούν να χρησιμοποιήθουν παράλληλα περισσότεροι clients (workers).

Tip
Το Hydra είναι εργαλείο με δυνατότητες παράλληλου υπολογισμού το οποίο προσεγγίζει πολλούς τρόπους για την πραγματοποίηση brute force επιθέσεων. Περισσότερα για το Hydra εδώ.

Η εγκατάσταση του Hydra 7.5 γίνεται με την παρακάτω εντολή:

sudo apt-get install hydra hydra-gtk

Το Hydra μπορεί να λειτουργήσει παράλληλα με άλλα προγράμματα τα οποία κάνουν generate συνδυασμούς ονομάτων χρήστη και κωδικών εισόδου. Στις οδηγίες της προσομοίωσης που θα κάνουμε για λόγους απλότητας θα χρησιμοποιήσουμε δύο αρχεία, users.txt και pass.txt τα οποία περιέχουν τυχαία συχνά ονόματα και τυχαίους συχνούς κωδικούς πρόσβασης. Έτσι η επίθεση θα γίνει πολύ γρήγορα καθώς δεν θα χρειαστεί να γίνουν υπερβολικά πολλές δοκιμές. Σε μια πραγματική επίθεση, το πρόγραμμα μπορει να δοκιμάζει κωδικούς για πολύ μεγαλύτερο χρονικό διάστημα μέχρι να μπορεί να τους πετύχει και να αποκτήσουμε πρόσβαση.

Πριν αρχίσει η επίθεση, αρκεί να γνωρίζουμε την IP του server που θέλουμε να χτυπήσουμε. Ελέγχουμε αρχικά αν τρέχει SSH service και αν έχει την default SSH πόρτα ανοιχτή με την εντολή:

nmap -p 22 <target-IP>
Note
Η πόρτα (port) μπορεί να είναι διαφορετική, σε αυτή την περίπτωση, θα κάναμε έλεγχο να δούμε ποιές πόρτες είναι ανοιχτές. Η default port του SSH όμως, την οποία και θα χρησιμοποιήσουμε για την επίθεση είναι η 22.

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

hydra -L <user-file-path> -P <password-file-path> ssh://<target-ip> -t 6

Όπου αναλυτικά:

-L <user-file-path>

Παράμετρος για path αρχείου με όνοματα χρήστη που θα δοκιμαστούν.

-P <password-file-path>

Παράμετρος για path αρχείου με κωδικούς χρήστη που θα δοκιμαστούν.

ssh://<target-ip>

Πρωτόκολλο (SSH) και IP διεύθυνση του server που προσπαθούμε να αποκτήσουμε πρόσβαση.

-t 6

Ο αριθμός διεργασιών που θα χρησιμοποιήθουν (όσο πιο πολλές, τόσο πιο γρήγορο το αποτέλεσμα).

Με την εκτέλεση της παραπάνω εντολής μπορεί να αρχίσει η επίθεση. Για σχετικά μικρό αριθμό ονομάτων και κωδικών που θα δοκιμαστούν, όπως στα στιγμιότυπα οθόνης στο παράδειγμα που υπάρχει παρακάτων η διαδικασία δεν παίρνει πάνω από λίγα λεπτά και άν έχουμε το σωστό όνομα και το σωστό κωδικό στα αρχεία μας, η επίθεση θα είναι επιτυχής!

Εύρεση και αντιμετώπιση της επίθεσης με Fail2Ban

Οι brute force επιθέσεις μπορούν να είναι καταστροφικές αν γίνουν με επιτυχία, για αυτό έχει μεγάλη σημασία η πρόληψη και η γρήγορη ανίχνευση και αντιμετώπιση των επιθέσεψω ώστε να είναι ασφαλής ο server μας. Ένα εργαλείο που μπορούμε να χρησιμοποιήσουμε για να το καταφέρουμε αυτό είναι το Fail2Ban.

Tip
Το Fail2Ban είναι framework που βοηθάει στην πρόληψη και την αντιμετώπιση brute force επιθέσεψων βάζοντας, για παράδειγμα σε SSH επιθέσεις, κανόνες σε iptables κάνοντας ban δίευθύνσεις που κάνουν πολλές απόπειρες σύνδεσης.

Η εγκατάσταση του Fail2Ban γίνεται με την παρακάτω εντολή:

sudo apt-get install fail2ban

Δοκιμάζουμε σε έναν από τους workers, στον οποίο θα το εγκαταστήσουμε και θα χρησιμοποιήσουμε ως server που θα δέχεται την επίθεση να εκκινήσουμε το Fail2Ban service ως εξής:

sudo service fail2ban start

Θα δεχτούμε ένα error τύπου:

* Starting authentication failure monitor fail2ban                                                                                                                                                         No file(s) found for glob /var/log/auth.log
 Failed during configuration: Have not found any log file for sshd jail

Αυτό διότι δεν υπάρχει auth.log αρχείο που να καταγράφει όλες τις απόπειρες σύνδεσης στον server μας μέσω SSH. Θα χρειαστούμε πρόγραμμα που κάνει ακριβώς αυτή τη δουλειά, στην περίπτωση μας θα εγκαταστήσουμε το rsyslog και θα το εκτελέσουμε με τις παρακάτω εντολές:

sudo apt-get install rsyslog
sudo rsyslogd

Πλέον μπορούμε να εκκινήσουμε κανονικά το Fail2Ban service κανονικά!

Tip
'Εαν θέλουμε να δούμε ότι το logging των μη επιτυχημένων εισόδων γίνεται κανονικά μπορούμε να το δούμε με την εντολή: sudo grep "Failed password" /var/log/auth.log.
Note
Οι ρυθμίσεις για το πως δουλεύει το Fail2Ban βρίσκονται στο αρχείο /etc/fail2ban/jail.conf, είναι προτεινόμενο όμως να βάζουμε τις ρυθμίσεις σε άλλο αρχείο /etc/fail2ban/jail.local.

Δημιουργούμε το jail.local.

sudo vim /etc/fail2ban/jail.local

Ανοίγουμε το jail.local και προσθέτουμε τις παρακάτω γραμμές:

[sshd]
# Ενεργοποίηση του jail
enabled  = true
# SSH πόρτα
port     = 22
# SSHD Fail2Ban φίλτρο
filter   = sshd
# Path του αρχείου auth.log
logpath  = /var/log/auth.log
# Αριθμός επιτρέπόμενων απόπειρων σύνδεσης
maxretry = 4
# Χρόνος του ban (seconds)
bantime = 7200

Αφού αποθηκεύσουμε το αρχείο, κάνουμε επανεκκίνηση το fail2ban service ώστε να δουλέψει με το configuration μας ως εξής:

sudo service fail2ban restart

Πλέον θα πρέπει να λειτουργεί σωστά με το configuration μας. Δοκιμάζουμε επίθεση με Hydra από οποιονδήποτε worker θέλουμε να χρησιμοποήσουμε. Μπορούμε να δούμε αν το fail2ban έχει ενεργό το sshd jail και αν ανίχνευσε και σταμάτησε την brute force επίθεση με ban στην IP με την εντολή:

sudo fail2ban-client status
sudo fail2ban-client status sshd

Στις πληροφορίες που θα εμφανιστούν θα πρέπει να φαίνεται η IP του worker που έκανε την επιθέση στις banned IPs. Μπορούμε να δούμε και των κανόνα για REJECT που δημιούργησε το fail2ban με την χρήση των iptables με την εντολή:

sudo iptables -L -n

Εάν η IP του επιτιθέμενου είναι banned και υπάρχει και ο κανόνας σε iptables τότε σε απόπειρα σύνδεσεις ο επιτιθέμενος θα πρέπει να λαμβάνει μήνυμα Connection Refused και για το χρονικό διάστημα που είναι banned, δεν θα μπορεί να συνδεθεί. Για να μπορεί να έχει πρόσβαση πάλι κάποιος από την συγκεκριμένη IP πρέπει να γίνει unban με την εντολή:

sudo fail2ban-client unban <IP-address>

Eίσοδος αποκλειστικά με key

Ένας δυνατός κωδικός θα μπορούσε να προστατέψει τον server μας αρκετά από brute force επιθέσεις, όμως μπορεί να γίνει χρήση και της εισόδου με κλειδί (public key authentication), που προσφέρει και πολλά άλλα πλεονεκτήματα

Note
Τα RSA κλειδία έρχονται σε ζευγάρια, ένα δημόσιο κλειδί και ένα ιδιωτικό κλειδί. Το δημόσιο κλειδί είναι γνωστό σε όλους ενώ το ιδιωτικό είναι γνωστό μόνο στον κάτοχο του. Για την σύνδεση αρκεί να αποδείξει ο client ότι κατέχει το ιδιωτικό κλειδί που αντιστοιχεί στο δημόσιο κλειδί, το οποίο γίνεται χωρίς να χρειαστεί να εμφανίσει το ιδιωτικό του κλειδί. Μάλιστα στο SFTP (SSH FILE TRANSFER PROTOCOL) δημόσια κλειδία χρησιμοποιούνται για την κρύπτογράφηση αρχείων τα οποία μπορούν να αποκρυπτογραφηθούν μόνο με το ιδιωτικό κλειδί.

Για αρχή θα πρέπει να γίνει το key generation στον client, το οποίο γίνεται με την εντολή:

ssh-keygen

Θα ακολουθήσει η επιλογή του path όπου θα αποθηκεύονται τα κλειδιά και επιλογή κωδικού για την χρήση του ιδιωτικού κλειδιού, το οποίο αυξάνει ακόμα περισσότερο την ασφάλεια. Αφού γίνουν οι επιλογές, θα δημιουργηθούν δύο κλειδία σε 2 αρχεία, το id_rsa που είναι το ιδιωτικό κλειδί και το id_rsa.pub που είναι το δημόσιο κλειδί. Τώρα έχει δημιουργηθεί το ζεύγος των κλειδιών μας.

Για να λειτουργήσει το public key authentication πρέπει ο server να έχει το δημόσιο κλειδί. Η αντιγραφή του δημόσιου κλειδιού στον server (ένας worker του swarm μας) γίνετε με την παρακάτω εντολή:

ssh-copy-id docker@<worker-IP>

Τώρα ο worker που έχει το δημόσιο κλειδί, μπορεί να γίνει η σύνδεση μέσω public key authentication. Μένει να τροποποιήσουμε τον server ώστε να δέχεται μόνο εισόδους μέσω κλειδιού και όχι μέσω κωδικού πρόσβασης. Θα πρέπει να γίνουν οι παρακάτω τροποποιήσεις στο αρχείο του server /etc/ssh/sshd_config:

# Authentication:

#LoginGraceTime 2m
PermitRootLogin without-password
#StrictModes yes
#MaxAuthTries 6
#MaxSessions 10

#PubkeyAuthentication yes
# To disable tunneled clear text passwords, change to no here!
PasswordAuthentication no
#PermitEmptyPasswords no

Κάνουμε επανεκκίνηση του ssh με την εντολή:

sudo service ssh restart

Πλέον η είσοδος γίνεται μόνο με public key authentication. Σε περίπτωση που δοκιμάσουμε σύνδεση από worker για οποίο ο server δεν έχει public key θα εμφανιστεί μήνυμα της παρακάτω μορφής:

docker@<IP-address>: Permission denied (publickey).
Tip
Όλα τα δημόσια κλειδιά είναι αποθηκευμένα στον SSH server στο αρχείο ~/.ssh/authorized_keys όπου μπορούν να προστεθούν manually κλειδιά.

Στιγμιότυπα οθόνης από προσομοίωση επίθεσης SSH Brute Force

Παρακάτω εμφανίζονται στιγμιότυπα οθόνης απο μια προσομοίωση επίθεσης με βάση την παραπάνω ανάλυση. Ο worker 1 (172.19.0.3) λειτουργεί ως server, ενώ άλλοι workers χρήσιμοποιούνται ως clients.

check ssh port
user
pass
hydra brute force
auth.logERROR
Fail2Ban works
failed pass auth
jailLocalFile
fail2ban client status before
fail2ban client status
fail2ban client status after
iptables rule fail2ban
ssh attacker connection refused
unban worker
ssh keygen
ssh copy id
new config file
keyauthworking
permission denied pk
authorized keys

Local/Remote SSH Fowarding

Σε αυτό το ερώτημα θα γίνει Local και Remote SSH Fowarding για την επίτευξη SSH Tunneling. Το Tunneling δημιουργεί μια σύνδεση που προσφέρει ασφαλή και κρυπτογραφημένη επικοινωνία μεταξύ του client και server. Μπορεί να χρησιμοποιήθει για πολλούς σκοπούς, μιας και με το tunneling γίνεται ασφαλής ανταλλαγή δεδομένων μεταξύ δύο αποκρυνσμένων υπολογιστών/δικτύων.

Στην παρακάτω ανάλυση θα μετατρέψουμε το μηχάνημα μας σε SSH Server που θα προσφέρει υπηρεσίες στο swarm. Θα πρέπει να γίνει εγκατάσταση του openssh-server με την παρακάτω εντολή, ώστε να μπορούν οι workers του swarm να συνδέονται μέσω του SSH.

sudo apt-get install openssh-server

'Επειτα θα εγκαταστήσουμε τον Apache Web Server. Το μηχάνημα μας θα δουλεύει ως Web Server. Η εγκατάστση γίνεται με την εντολή:

sudo apt install apache2
Tip
Το Apache HTTP Server Project είναι ένα από τα πιο γνωστά εργαλεία που χρησιμοποιούνται για το στήσιμο, την ανάπτυξη και την διατήρηση ενός HTTP Server. Με την χρήση του μπορούμε να φιλοξενήσουμε στο μηχάνημα μας μια ιστοσελίδα που θα είναι και η υπηρεσία που θα προσφέρουμε στο swarm μας.

Πλέον εάν χρησιμοποιήσουμε τον browser μας, και πάμε στο localhost:80 θα δούμε την default ιστοσελίδα του Apache. Θα κάνουμε μερικές αλλαγές ώστε να εμφανίζει δικό μας περιεχόμενο, εκτελούμε την εντολή:

sudo vim /var/www/html/index.html

Και μέσα στο αρχείο index.html βάζουμε δικό μας περιεχόμενο η μπορούμε να βάλουμε αρχεία δικιά μας ιστοσελίδας. Για το παράδειγμα θα χρησιμοποιήσουμε μια πολύ απλή ιστοσελίδα με το παρακάτω περιεχόμενο.

<!DOCTYPE html>
<html>
  <head>
    <title>Super Webpage</title>
  </head>
  <body>
    <center>
      <h>WELCOME</h>
      <p>If you see this, it works</p>
    </center>
  </body>
</html>

Για την προβολή του περιεχομένου μπορεί να χρησιμοποιήθει η εντολή curl ενώ για την προβολή μπορούμε να χρησιμοποιήσουμε και έναν command-line browser όπως τον lynx. Η εγκατάσταση του lynx γίνεται με την παρακάτω εντολή:

sudo apt-get install lynx
Tip
O lynx είναι command-line text based browser με πολλές δυνατότες που επιτρέπει την πλοήγηση στο διαδίκτυο από terminal.

Local SSH Port Fowarding

Local SSH Port Fowarding κάνουμε όταν θέλουμε να έχουμε πρόσβαση σε δεδομένα/υπηρεσίες που βρίσκονται σε έναν server και υπό κανονικές συνθήκες δεν θα είχα πρόσβαση. Σε αυτό το παράδειγμα θα κάνουμε Local SSH Port Fowarding, που θα επιτρέπει οποιοδήποτε μήχανημα του swarm που έχουμε στην διάθεση μας να επισκευτεί την ιστοσελίδα μας, σαν να τρέχει στο ίδιο το μηχάνημα του. Η εντολή που θα χρησιμοποιήσουμε, αφού συνδεθούμε στον worker που επιθυμούμε, είναι η παρακάτω:

ssh -nNT -L 8081:<IP-address>:80 user@<IP-address>

Με την παραπάνω εντολή ανοίγει ένα tunnel, ο worker μας ακούει στην πύλη 8081 για την υπηρεσία που τρέχει στον WebServer μας (<IP-address>:80) και θα αποκτήσω πρόσβαση μέσω του user@<IP-address> που έχει πρόσβαση. Αυτό έχει ως αποτέλεσμα να μπορέσουμε να πάρουμε η να προβάλουμε τα δεδομένα του index.html του WebServer μας για παράδειγμα με τις εντολές:

curl localhost:8081

ή αντίστοιχα:

lynx localhost:8081

Άρα πλέον είναι σαν η υπηρεσία του Apache να τρέχει στον worker της επιλογής μας στην πύλη της επιλογής μας, 8081 στο παράδειγμα μας.

Note
Έαν έχουμε IPv6 διεύθυνση στον server μας, μπορούμε να χρησιμοποιήσουμε την παράμετρο -4 στην ssh εντολή που δώσαμε ώστε να δουλέψει με την IPv4 διεύθυνση, αλλίως μπορεί να εμφανιστεί error bind: Cannot assign requested address.

Remote SSH Port Forwarding

Πρόκειται για την αντίστροφη ακριβώς διαδικασία. Κάνουμε Remote SSH Port Forwarding όταν έχουμε πρόσβαση σε δεδομένα/υπηρεσία και θέλουμε να την μοιράσουμε με άλλους. Στην περίπτωση μας θα πάμε στον Web Server μας και θα εκτελέσουμε την παρακάτω εντολή:

ssh -nNT -R 8081:localhost:80 user@<IP-address>

Με την παραπάνω εντολή λέμε ότι έχουμε πρόσβαση στην υπηρεσία (localhost:80) και όποιος επιθυμεί να έχει πρόσβαση να έρθει σε εμένα (user@<IP-address>) μέσω της πόρτας 8081. Αυτό επιτρέπει σε οποιονδήποτε να έχει πρόσβαση στην υπηρεσία μέσω της 8081 του Web Server μας, που σε αυτή την περίπτωση φιλοξενεί και την ιστοσελίδα.

Πρέπει όμως και να έχουμε ανοιχτή την πύλη 8081 για να μπορέσουμε να λάβουμε τα requests. Το SSH προσφέρει την δυνατότητα να ακούμε από έξω στις πύλες που ορίζουμε με το Remote SSH Port Forwarding. Για να μπορεί να λειτουργήσει σωστά το remote forwarding, πρέπει να ανοίξουμε το αρχείο sshd_config:

sudo vim /etc/ssh/sshd_config

Και να κάνουμε την παρακάτω αλλαγή:

GatewayPorts yes

Τώρα θα μπορούμε να λάβουμε συνδέσεις στην πύλη 8081. Σε κάθε worker του swarm μπορουμε να εκτελέσουμε τις εντολές:

curl <IP-address>:8081

ή

lynx <IP-address>:8081

Και τελικά με τις παραπάνω εντολές παίρνουμε το περιεχόμενο του index.html από τον Web Server μας.

Tip
Για μεγαλύτερη ασφάλεια μπορούμε να ορίσουμε GatewayPorts clientspecified ώστε να μπορούμε να δεχόμαστε συνδέσεις σε μια θύρα μόνο από συγκεκριμένες διευθύνσεις και βάζοντας την IP του client που θέλουμε πρίν το port στο οποίο ακούμε, για παράδειγμα ssh -nNT -R <safe-IP>:8081:localhost:80 user@<IP-address>.

Στιγμιότυπα οθόνης από Local/Remote SSH Port Forwarding

Παρακάτω εμφανίζονται στιγμιότυπα οθόνης από Local/Remote SSH Port Forwarding όπως περιγράφονται παραπάνω:

usurifconfig
openportsusur
htmlcontent
worker2 L SSH PF
worker2 curl
worker2 lynx
usur R SSH PF
GatewayPorts
curl remote pf

lynx remote pf

Δημιουργία VPN

Η δημιουργία VPN (Virtual Private Network) επιτρέπει την σύνδεση απομακρυσμένων δικτύων σε ένα εικονικό δίκτυο. Αυτό προσφέρει ασφάλεια στην επικοινωνία ανάμεσα των δυο δικτύων. Χρησιμοποιείται πολύ εκτός από την ασφάλεια από πολλούς βασικούς χρήστες για ανωνυμία και προστασία των προσωπικών τους δεδομένων. Η σύνδεση γίνεται πάνω στον VPN Server. Στο παρακάτω ζητούμενο θα αναλυθεί η δημιουργία του VPN Server πάνω στον υπολογιστή μας καθώς και πως μπορούν χρήστες που βρίσκονται σε άλλα δίκτυα, στην περίπτωση μας οι κόμβοι του swarm να συνδεθούν και να εμφανίζονται σαν μέλη του δικτύου μας.

Note
Τα VPN δουλεύουν με μοντέλο client-server, ο server είναι που ενώνει τα δίκτυα και από τον οποίο περνάει όλη η κίνηση από τα δίκτυα πρός τα έξω. Στο παρακάτω παράδειγμα, ο υπολογιστής μας θα είναι VPN Server και θα συνδέσουμε τον master του Swarm ως client.

Δημιουργία OpenVPN Server σε Docker container

Αρχικά θα δημιουργήσουμε στον υπολογιστή μας ένα αρχείο create-vpn.sh στο οποίο βάζουμε το παρακάτω περιεχόμενο:

#!/bin/bash
IP=127.0.0.1                                            # Server IP
P=1194                                                  # Server Port
OVPN_SERVER='10.80.0.0/16'                              # VPN Network

#vpn_data=/var/lib/swarmlab/openvpn/openvpn-services/   # Dir to save data ** this must exist **
vpn_data=$PWD/openvpn-services/
if [ ! -d $vpn_data ]; then
 mkdir -p $vpn_data
fi

NAME=swarmlab-vpn-services                              # Name of docker service
DOCKERnetwork=swarmlab-vpn-services-network             # Docker network
docker=registry.vlabs.uniwa.gr:5080/myownvpn            # Docker image

docker stop  $NAME					      #Stop container
sleep 1
docker container rm  $NAME				#rm container

# rm config files
rm -f $vpn_data/openvpn.conf.*.bak
rm -f $vpn_data/openvpn.conf
rm -f $vpn_data/ovpn_env.sh.*.bak
rm -f $vpn_data/ovpn_env.sh

# create network
sleep 1
docker network create --attachable=true --driver=bridge --subnet=172.50.0.0/16 --gateway=172.50.0.1 $DOCKERnetwork

#run container        see ovpn_genconfig
docker run --net=none -it -v $vpn_data:/etc/openvpn  -p 1194:1194 --rm $docker ovpn_genconfig  -u udp://$IP:1194 \
-N -d -c -p "route 172.50.20.0 255.255.255.0" -e "topology subnet" -s $OVPN_SERVER

# create pki          see ovpn_initpki
docker run --net=none -v $vpn_data:/etc/openvpn  --rm -it $docker ovpn_initpki

#                     see ovpn_copy_server_files
#docker run --net=none -v $vpn_data:/etc/openvpn  --rm $docker ovpn_copy_server_files

#create vpn           see --cap-add=NET_ADMIN
sleep 1
docker run --detach --name $NAME -v $vpn_data:/etc/openvpn --net=$DOCKERnetwork --ip=172.50.0.2 -p $P:1194/udp --cap-add=NET_ADMIN $docker

sudo sysctl -w net.ipv4.ip_forward=1

#show created
docker ps

Στο παραπάνω αρχείο δηλώνουμε, την τοπική IP του server, την port στην οποία θα ακούει, το δίκτυο VPN που δημιουργούμε. Στην συνέχεια θα δημιουργηθεί ένας φάκελος, δηλώνεται το όνομα του docker service, network και το image που θα κάνουμε pull. Στην συνέχεια θα δημιουργηθεί το δίκτυο και θα τρέξει το docker container στο οποίο μέσα σηκώνουμε τον OpenVPN server μας. Τρέχουμε το παραπάνω script με την εντολή:

sudo ./create-vpn.sh

Θα χρειαστεί να ακολουθήσουμε τις οδηγίες που θα εμφανιστούν και να εισάγουμε τους κωδικούς που θα ζητηθούν. Εάν όλα πήγαν καλά με το docker ps που θα τρέξει θα πρέπει να βλέπουμε το swarmlab-vpn-services container να τρέχει. Αφού δημιουργηθεί το VPN μας, χρειάζεται να δημιουργήσουμε ένα αρχείο χρήστη για να μπορεί να συνδεθεί. Δημιουργούμε το αρχείο create-user.sh και βάζουμε μέσα τα παρακάτω:

#!/bin/bash
USERNAME=testusermaster
vpn_data=$PWD/openvpn-services/
docker=registry.vlabs.uniwa.gr:5080/myownvpn

docker run -v $vpn_data:/etc/openvpn --rm -it $docker easyrsa build-client-full $USERNAME nopass
docker run -v $vpn_data:/etc/openvpn --log-driver=none --rm $docker ovpn_getclient $USERNAME  > $USERNAME.ovpn

Τρέχουμε το παραπάνω script με την παρακάτω εντολή:

sudo ./create-user.sh

Το αρχείο που θα δημιουργηθεί περιέχει τα απαραίτητα κλειδιά για να μπει ο χρήστης μας στο VPN και κάποιες επιπλέον ρυθμίσεις. Προθέτουμε τις παρακάτω γραμμές στην κορυφή του αρχείου βάζοντας την IP του VPN Server μας πάνω στον οποίο θα γίνει η σύνδεση δίπλα στην πόρτα που χρησιμοποιούμε (1194).

client
nobind
dev tun
comp-lzo
resolv-retry infinite
keepalive 15 60

remote-cert-tls server
remote <host-IP> 1194 udp
float

Το αρχείο με τα παραπάνω και με τα κλειδιά που έχει μέσα θα τα χρησιμοποιήσει ο χρήστης (ο master του swarm μας) για να συνδεθεί. Αρκεί να μπούμε στον master και να εγκαταστήσουμε το openvpn με την παρακάτω εντολή:

sudo apt-get install openvpn

Αφου εγκαταστήσουμε το OpenVPN, θα εκτελέσουμε την παρακάτω εντολή με το αρχείο που δημιουργήσαμε πριν, στην περίπτωση μας το testusermaster.ovpn για παράμετρο ως εξής:

openvpn --config testusermaster.ovpn

Θα εμφανιστεί μήνυμα επιτυχίας εάν ο χρήστης συνδεθεί με επιτύχια και μπορούμε να ελέγξουμε αν έχει αποκτήσει IP του VPN μας μέσω ifconfig όπου θα πρέπει να εμφανιστεί σε μια διεπαφή διεύθυνση του δικτύου VPN μας (στην περίπτωση μας 10.80.0.0/16).

Στον VPN Server μπορούμε να δούμε τους users καθώς και τους connected clients με τις παρακάτω εντολές αντίστοιχα:

docker exec -it swarmlab-vpn-services ovpn_listclients
docker exec -it swarmlab-vpn-services cat /tmp/openvpn-status.log

Τέλος εάν θέλουμε να αφαιρέσουμε τον χρήστη από το VPN μας, δημιουργούμε αρχείο rm-user.sh με το παρακάτω περιεχόμενο:

#!/bin/bash

CLIENTNAME=testusermaster
U=$CLIENTNAME

vpn_data=$PWD/openvpn-services/
docker=registry.vlabs.uniwa.gr:5080/myownvpn

rm -f $vpn_data/pki/reqs/$CLIENTNAME.req
rm -f $vpn_data/pki/private/$CLIENTNAME.keyVP
rm -f $vpn_data/pki/issued/$CLIENTNAME.crt
rm -f $vpn_data/server/ccd/$CLIENTNAME
rm -f $vpn_data/ccd/$CLIENTNAME
pem=$(sudo grep "CN=$U$"  $vpn_data/pki/index.txt | cut  -f4)

rm -f $vpn_data/pki/certs_by_serial/$pem.pem
sed -i "/CN=$U$/d"  $vpn_data/pki/index.txt
echo $pem
docker run -v $vpn_data:/etc/openvpn --log-driver=none --rm -it $docker ovpn_revokeclient  $CLIENTNAME remove

rm -f $vpn_data_user_config/$CLIENTNAME.ovpn
rm -f $vpn_data_user_config1/$CLIENTNAME.ovpn
Tip
Βάζουμε για CLIENTNAME το όνομα του χρήστη που θέλουμε να αφαιρέσουμε.

Και τέλος ο χρήστης θα αφαιρεθεί με την εκτέλεση του παραπάνω script με την παρακάτω εντολή:

sudo ./rm-user.sh

Στιγμιότυπα οθόνης από δημιουργία VPN στο swarm

create vpn.sh
create vpn2.sh
ca creation
swarmlab vpn services up
create user.sh
create user.sh2
serverIP
testusermaster.ovpn
ovpn config
ifconfig vpn
viewclients
rm user.sh
rm user.sh2