ipipou: κάτι περισσότερο από μια μη κρυπτογραφημένη σήραγγα
Τι λέμε στον Θεό του IPv6;
Σωστά, το ίδιο θα πούμε και στον θεό της κρυπτογράφησης σήμερα.
Εδώ θα μιλήσουμε για μια μη κρυπτογραφημένη σήραγγα IPv4, αλλά όχι για μια «θερμή λάμπα», αλλά για μια σύγχρονη «LED». Και υπάρχουν επίσης ακατέργαστες υποδοχές που αναβοσβήνουν εδώ και η εργασία βρίσκεται σε εξέλιξη με πακέτα στο χώρο χρήστη.
Υπάρχουν N πρωτόκολλα σήραγγας για κάθε γούστο και χρώμα:
Αλλά είμαι προγραμματιστής, επομένως θα αυξήσω το N μόνο κατά ένα κλάσμα και θα αφήσω την ανάπτυξη πραγματικών πρωτοκόλλων στους προγραμματιστές της Kommersant.
Σε ένα αγέννητο σχέδιοΑυτό που κάνω τώρα είναι να προσεγγίσω οικοδεσπότες πίσω από το NAT από έξω. Χρησιμοποιώντας πρωτόκολλα με κρυπτογραφία ενηλίκων για αυτό, δεν μπορούσα να διώξω την αίσθηση ότι ήταν σαν να πυροβολώ σπουργίτια από ένα κανόνι. Επειδή η σήραγγα χρησιμοποιείται ως επί το πλείστον μόνο για να ανοίξει τρύπες στο NAT-e, η εσωτερική κίνηση συνήθως είναι επίσης κρυπτογραφημένη, αλλά εξακολουθούν να πνίγονται στο HTTPS.
Ενώ ερευνούσα διάφορα πρωτόκολλα διάνοιξης σήραγγας, η προσοχή του εσωτερικού τελειομανή μου τραβούσε το IPIP ξανά και ξανά λόγω των ελάχιστων γενικών εξόδων του. Αλλά έχει ενάμιση σημαντικά μειονεκτήματα για τις εργασίες μου:
απαιτεί δημόσιες IP και στις δύο πλευρές,
και δεν υπάρχει έλεγχος ταυτότητας για εσάς.
Επομένως, ο τελειομανής οδηγήθηκε πίσω στη σκοτεινή γωνία του κρανίου ή όπου κι αν κάθεται εκεί.
Και τότε μια μέρα, ενώ διάβαζα άρθρα στο εγγενώς υποστηριζόμενες σήραγγες στο Linux συνάντησα το FOU (Foo-over-UDP), δηλ. οτιδήποτε, τυλιγμένο σε UDP. Μέχρι στιγμής, υποστηρίζονται μόνο IPIP και GUE (Generic UDP Encapsulation).
«Εδώ είναι η ασημένια σφαίρα! Ένα απλό IPIP είναι αρκετό για μένα." - Σκέφτηκα.
Μάλιστα, η σφαίρα αποδείχθηκε ότι δεν ήταν εντελώς ασημένια. Η ενθυλάκωση στο UDP λύνει το πρώτο πρόβλημα - μπορείτε να συνδεθείτε με πελάτες πίσω από το NAT από έξω χρησιμοποιώντας μια προκαθορισμένη σύνδεση, αλλά εδώ το μισό από το επόμενο μειονέκτημα του IPIP ανθίζει με νέο φως - οποιοσδήποτε από ιδιωτικό δίκτυο μπορεί να κρυφτεί πίσω από το ορατό δημόσια IP και θύρα πελάτη (στο καθαρό IPIP αυτό το πρόβλημα δεν υπάρχει).
Για να λυθεί αυτό το ενάμιση πρόβλημα, γεννήθηκε το βοηθητικό πρόγραμμα ηπιπου. Εφαρμόζει έναν οικιακό μηχανισμό για τον έλεγχο ταυτότητας ενός απομακρυσμένου κεντρικού υπολογιστή, χωρίς να διακόπτεται η λειτουργία του πυρήνα FOU, ο οποίος θα επεξεργάζεται γρήγορα και αποτελεσματικά πακέτα στο χώρο του πυρήνα.
Δεν χρειαζόμαστε το σενάριό σας!
Εντάξει, αν γνωρίζετε τη δημόσια θύρα και την IP του πελάτη (για παράδειγμα, όλοι πίσω από αυτήν δεν πάνε πουθενά, το NAT προσπαθεί να αντιστοιχίσει τις θύρες 1 σε 1), μπορείτε να δημιουργήσετε μια σήραγγα IPIP-over-FOU με το ακολουθούν τις εντολές, χωρίς κανένα σενάριο.
στον διακομιστή:
# Подгрузить модуль ядра FOU
modprobe fou
# Создать IPIP туннель с инкапсуляцией в FOU.
# Модуль ipip подгрузится автоматически.
ip link add name ipipou0 type ipip
remote 198.51.100.2 local 203.0.113.1
encap fou encap-sport 10000 encap-dport 20001
mode ipip dev eth0
# Добавить порт на котором будет слушать FOU для этого туннеля
ip fou add port 10000 ipproto 4 local 203.0.113.1 dev eth0
# Назначить IP адрес туннелю
ip address add 172.28.0.0 peer 172.28.0.1 dev ipipou0
# Поднять туннель
ip link set ipipou0 up
στον πελάτη:
modprobe fou
ip link add name ipipou1 type ipip
remote 203.0.113.1 local 192.168.0.2
encap fou encap-sport 10001 encap-dport 10000 encap-csum
mode ipip dev eth0
# Опции local, peer, peer_port, dev могут не поддерживаться старыми ядрами, можно их опустить.
# peer и peer_port используются для создания соединения сразу при создании FOU-listener-а.
ip fou add port 10001 ipproto 4 local 192.168.0.2 peer 203.0.113.1 peer_port 10000 dev eth0
ip address add 172.28.0.1 peer 172.28.0.0 dev ipipou1
ip link set ipipou1 up
όπου
ipipou* — όνομα της διεπαφής τοπικού δικτύου σήραγγας
203.0.113.1 — δημόσιος διακομιστής IP
198.51.100.2 — δημόσια IP του πελάτη
192.168.0.2 — IP πελάτη που έχει εκχωρηθεί στη διεπαφή eth0
10001 — τοπική θύρα πελάτη για FOU
20001 — δημόσια θύρα πελάτη για FOU
10000 — δημόσια θύρα διακομιστή για FOU
encap-csum — επιλογή προσθήκης αθροίσματος ελέγχου UDP σε ενθυλακωμένα πακέτα UDP. μπορεί να αντικατασταθεί από noencap-csumΓια να μην αναφέρουμε, η ακεραιότητα ελέγχεται ήδη από το εξωτερικό στρώμα ενθυλάκωσης (ενώ το πακέτο βρίσκεται μέσα στη σήραγγα)
eth0 — τοπική διεπαφή στην οποία θα συνδεθεί η σήραγγα ipip
172.28.0.1 — IP της διεπαφής της σήραγγας πελάτη (ιδιωτική)
172.28.0.0 — Διεπαφή διακομιστή σήραγγας IP (ιδιωτική)
Όσο η σύνδεση UDP είναι ζωντανή, το τούνελ θα είναι σε κατάσταση λειτουργίας, αλλά αν χαλάσει, θα είστε τυχεροί - αν η θύρα IP: του πελάτη παραμείνει ίδια - θα ζει, αν αλλάξουν - θα σπάσει.
Ο ευκολότερος τρόπος για να επιστρέψετε τα πάντα είναι να ξεφορτώσετε τα modules του πυρήνα: modprobe -r fou ipip
Ακόμα κι αν δεν απαιτείται έλεγχος ταυτότητας, η δημόσια IP και η θύρα του πελάτη δεν είναι πάντα γνωστά και συχνά είναι απρόβλεπτα ή μεταβλητά (ανάλογα με τον τύπο NAT). Αν παραλείψετε encap-dport από την πλευρά του διακομιστή, το τούνελ δεν θα λειτουργήσει, δεν είναι αρκετά έξυπνο για να πάρει τη θύρα απομακρυσμένης σύνδεσης. Σε αυτή την περίπτωση μπορεί να βοηθήσει και το ipipou ή το WireGuard και άλλα παρόμοια.
Πώς λειτουργεί;
Ο πελάτης (που συνήθως βρίσκεται πίσω από το NAT) ανοίγει μια σήραγγα (όπως στο παραπάνω παράδειγμα) και στέλνει ένα πακέτο ελέγχου ταυτότητας στον διακομιστή έτσι ώστε να διαμορφώσει τη σήραγγα στο πλάι του. Ανάλογα με τις ρυθμίσεις, αυτό μπορεί να είναι ένα κενό πακέτο (μόνο για να μπορεί ο διακομιστής να δει τη δημόσια IP: θύρα σύνδεσης) ή με δεδομένα με τα οποία ο διακομιστής μπορεί να αναγνωρίσει τον πελάτη. Τα δεδομένα μπορεί να είναι μια απλή φράση πρόσβασης σε καθαρό κείμενο (η αναλογία με το HTTP Basic Auth έρχεται στο μυαλό) ή ειδικά σχεδιασμένα δεδομένα υπογεγραμμένα με ιδιωτικό κλειδί (παρόμοιο με το HTTP Digest Auth μόνο ισχυρότερο, βλέπε λειτουργία client_auth στον κώδικα).
Στον διακομιστή (στην πλευρά με τη δημόσια IP), όταν ξεκινά το ipipou, δημιουργεί έναν χειριστή ουράς nfqueue και διαμορφώνει το φίλτρο net έτσι ώστε τα απαραίτητα πακέτα να αποστέλλονται εκεί που πρέπει: πακέτα που αρχικοποιούν τη σύνδεση με την ουρά nfqueue και [σχεδόν] όλα τα υπόλοιπα πάνε κατευθείαν στον ακροατή ΦΟΥ.
Για όσους δεν γνωρίζουν, το nfqueue (ή NetfilterQueue) είναι ένα ιδιαίτερο πράγμα για ερασιτέχνες που δεν ξέρουν πώς να αναπτύσσουν μονάδες πυρήνα, το οποίο χρησιμοποιώντας το netfilter (nftables/iptables) σας επιτρέπει να ανακατευθύνετε πακέτα δικτύου στον χώρο χρήστη και να τα επεξεργάζεστε εκεί χρησιμοποιώντας αρχέγονο μέσο: τροποποιήστε (προαιρετικό ) και δώστε το πίσω στον πυρήνα ή απορρίψτε το.
Για ορισμένες γλώσσες προγραμματισμού υπάρχουν δεσμεύσεις για εργασία με nfqueue, για το bash δεν υπήρχε καμία (heh, δεν αποτελεί έκπληξη), έπρεπε να χρησιμοποιήσω python: ipipou χρησιμοποιεί NetfilterQueue.
Εάν η απόδοση δεν είναι κρίσιμη, χρησιμοποιώντας αυτό το πράγμα, μπορείτε σχετικά γρήγορα και εύκολα να επινοήσετε τη δική σας λογική για την εργασία με πακέτα σε αρκετά χαμηλό επίπεδο, για παράδειγμα, να δημιουργήσετε πειραματικά πρωτόκολλα μεταφοράς δεδομένων ή να τρολάρετε τοπικές και απομακρυσμένες υπηρεσίες με μη τυπική συμπεριφορά.
Οι Raw sockets λειτουργούν χέρι-χέρι με το nfqueue, για παράδειγμα, όταν το tunnel είναι ήδη διαμορφωμένο και το FOU ακούει στην επιθυμητή θύρα, δεν θα μπορείτε να στείλετε ένα πακέτο από την ίδια θύρα με τον συνηθισμένο τρόπο - είναι απασχολημένο, αλλά μπορείτε να πάρετε και να στείλετε ένα τυχαία δημιουργημένο πακέτο απευθείας στη διεπαφή δικτύου χρησιμοποιώντας μια ακατέργαστη πρίζα, αν και η δημιουργία ενός τέτοιου πακέτου θα απαιτήσει λίγο περισσότερη επεξεργασία. Έτσι δημιουργούνται τα πακέτα με έλεγχο ταυτότητας στο ipipou.
Δεδομένου ότι το ipipou επεξεργάζεται μόνο τα πρώτα πακέτα από τη σύνδεση (και αυτά που κατάφεραν να διαρρεύσουν στην ουρά πριν από τη δημιουργία της σύνδεσης), η απόδοση σχεδόν δεν υποφέρει.
Μόλις ο διακομιστής ipipou λάβει ένα πιστοποιημένο πακέτο, δημιουργείται ένα τούνελ και όλα τα επόμενα πακέτα στη σύνδεση υποβάλλονται ήδη σε επεξεργασία από τον πυρήνα παρακάμπτοντας το nfqueue. Εάν η σύνδεση αποτύχει, τότε το πρώτο πακέτο του επόμενου θα σταλεί στην ουρά nfqueue, ανάλογα με τις ρυθμίσεις, αν δεν είναι πακέτο με έλεγχο ταυτότητας, αλλά από την τελευταία απομνημόνευση IP και θύρα πελάτη, μπορεί είτε να περάσει επάνω ή απορρίφθηκε. Εάν ένα πιστοποιημένο πακέτο προέρχεται από μια νέα IP και θύρα, η σήραγγα διαμορφώνεται εκ νέου ώστε να τα χρησιμοποιεί.
Το συνηθισμένο IPIP-over-FOU έχει ένα ακόμη πρόβλημα όταν εργάζεστε με NAT - είναι αδύνατο να δημιουργηθούν δύο σήραγγες IPIP ενθυλακωμένες σε UDP με την ίδια IP, επειδή οι μονάδες FOU και IPIP είναι αρκετά απομονωμένες μεταξύ τους. Εκείνοι. Ένα ζεύγος πελατών πίσω από την ίδια δημόσια IP δεν θα μπορεί να συνδεθεί ταυτόχρονα στον ίδιο διακομιστή με αυτόν τον τρόπο. Στο μέλλον, ίσως, θα λυθεί σε επίπεδο πυρήνα, αλλά αυτό δεν είναι σίγουρο. Εν τω μεταξύ, τα προβλήματα NAT μπορούν να λυθούν από το NAT - αν συμβεί ότι ένα ζευγάρι διευθύνσεων IP έχει ήδη καταληφθεί από ένα άλλο τούνελ, το ipipou θα κάνει NAT από δημόσια σε εναλλακτική ιδιωτική IP, voila! - μπορείτε να δημιουργήσετε τούνελ μέχρι να εξαντληθούν οι θύρες.
Επειδή Δεν είναι υπογεγραμμένα όλα τα πακέτα στη σύνδεση, τότε αυτή η απλή προστασία είναι ευάλωτη στο MITM, οπότε αν υπάρχει ένας κακός που παραμονεύει στη διαδρομή μεταξύ του πελάτη και του διακομιστή που μπορεί να ακούσει την κίνηση και να τη χειριστεί, μπορεί να ανακατευθύνει τα πιστοποιημένα πακέτα μέσω άλλη διεύθυνση και δημιουργήστε ένα τούνελ από έναν μη αξιόπιστο κεντρικό υπολογιστή.
Αν κάποιος έχει ιδέες για το πώς να το διορθώσετε, αφήνοντας το μεγαλύτερο μέρος της κίνησης στον πυρήνα, μη διστάσετε να μιλήσετε.
Παρεμπιπτόντως, η ενθυλάκωση σε UDP έχει αποδειχθεί πολύ καλά. Σε σύγκριση με την ενθυλάκωση μέσω IP, είναι πολύ πιο σταθερή και συχνά πιο γρήγορη παρά την πρόσθετη επιβάρυνση της κεφαλίδας UDP. Αυτό οφείλεται στο γεγονός ότι οι περισσότεροι κεντρικοί υπολογιστές στο Διαδίκτυο λειτουργούν καλά μόνο με τα τρία πιο δημοφιλή πρωτόκολλα: TCP, UDP, ICMP. Το απτό μέρος μπορεί να απορρίψει εντελώς οτιδήποτε άλλο ή να το επεξεργαστεί πιο αργά, επειδή είναι βελτιστοποιημένο μόνο για αυτά τα τρία.
Για παράδειγμα, αυτός είναι ο λόγος για τον οποίο το QUICK, στο οποίο βασίζεται το HTTP/3, δημιουργήθηκε πάνω από το UDP και όχι πάνω από το IP.
Λοιπόν, αρκετά λόγια, ήρθε η ώρα να δούμε πώς λειτουργεί στον «πραγματικό κόσμο».
Μάχη
Χρησιμοποιείται για να μιμηθεί τον πραγματικό κόσμο iperf3. Όσον αφορά τον βαθμό εγγύτητας με την πραγματικότητα, αυτό είναι περίπου το ίδιο με την εξομοίωση του πραγματικού κόσμου στο Minecraft, αλλά προς το παρόν θα είναι.
Συμμετέχοντες στον διαγωνισμό:
κύριο κανάλι αναφοράς
ο ήρωας αυτού του άρθρου είναι η ipipou
OpenVPN με έλεγχο ταυτότητας αλλά χωρίς κρυπτογράφηση
OpenVPN σε λειτουργία all inclusive
WireGuard χωρίς PresharedKey, με MTU=1440 (από IPv4 μόνο)
Τεχνικά στοιχεία για geeks Οι μετρήσεις λαμβάνονται με τις ακόλουθες εντολές:
στον πελάτη:
UDP
CPULOG=NAME.udp.cpu.log; sar 10 6 >"$CPULOG" & iperf3 -c SERVER_IP -4 -t 60 -f m -i 10 -B LOCAL_IP -P 2 -u -b 12M; tail -1 "$CPULOG"
# Где "-b 12M" это пропускная способность основного канала, делённая на число потоков "-P", чтобы лишние пакеты не плодить и не портить производительность.
Υγρό άσχημο σημάδι
Το φορτίο της CPU του διακομιστή δεν είναι πολύ ενδεικτικό, επειδή... Υπάρχουν πολλές άλλες υπηρεσίες που τρέχουν εκεί, μερικές φορές καταναλώνουν πόρους:
proto bandwidth[Mbps] CPU_idle_client[%] CPU_idle_server[%]
# 20 Mbps канал с микрокомпьютера (4 core) до VPS (1 core) через Атлантику
# pure
UDP 20.4 99.80 93.34
TCP 19.2 99.67 96.68
ICMP latency min/avg/max/mdev = 198.838/198.997/199.360/0.372 ms
# ipipou
UDP 19.8 98.45 99.47
TCP 18.8 99.56 96.75
ICMP latency min/avg/max/mdev = 199.562/208.919/220.222/7.905 ms
# openvpn0 (auth only, no encryption)
UDP 19.3 99.89 72.90
TCP 16.1 95.95 88.46
ICMP latency min/avg/max/mdev = 191.631/193.538/198.724/2.520 ms
# openvpn (full encryption, auth, etc)
UDP 19.6 99.75 72.35
TCP 17.0 94.47 87.99
ICMP latency min/avg/max/mdev = 202.168/202.377/202.900/0.451 ms
# wireguard
UDP 19.3 91.60 94.78
TCP 17.2 96.76 92.87
ICMP latency min/avg/max/mdev = 217.925/223.601/230.696/3.266 ms
## около-1Gbps канал между VPS Европы и США (1 core)
# pure
UDP 729 73.40 39.93
TCP 363 96.95 90.40
ICMP latency min/avg/max/mdev = 106.867/106.994/107.126/0.066 ms
# ipipou
UDP 714 63.10 23.53
TCP 431 95.65 64.56
ICMP latency min/avg/max/mdev = 107.444/107.523/107.648/0.058 ms
# openvpn0 (auth only, no encryption)
UDP 193 17.51 1.62
TCP 12 95.45 92.80
ICMP latency min/avg/max/mdev = 107.191/107.334/107.559/0.116 ms
# wireguard
UDP 629 22.26 2.62
TCP 198 77.40 55.98
ICMP latency min/avg/max/mdev = 107.616/107.788/108.038/0.128 ms
Κανάλι 20 Mbps
κανάλι ανά 1 αισιόδοξο Gbps
Σε όλες τις περιπτώσεις το ipipou είναι αρκετά κοντά σε απόδοση με το βασικό κανάλι, κάτι που είναι υπέροχο!
Το μη κρυπτογραφημένο τούνελ openvpn συμπεριφέρθηκε αρκετά περίεργα και στις δύο περιπτώσεις.
Αν κάποιος πρόκειται να το δοκιμάσει, θα είναι ενδιαφέρον να ακούσει σχόλια.