Γεια σου Habr, με λένε Ilya, εργάζομαι στην ομάδα πλατφόρμας στην Exness. Αναπτύσσουμε και υλοποιούμε τα βασικά στοιχεία υποδομής που χρησιμοποιούν οι ομάδες ανάπτυξης προϊόντων μας.
Σε αυτό το άρθρο, θα ήθελα να μοιραστώ την εμπειρία μου από την εφαρμογή κρυπτογραφημένης τεχνολογίας SNI (ESNI) στην υποδομή δημόσιων ιστοσελίδων.
Η χρήση αυτής της τεχνολογίας θα αυξήσει το επίπεδο ασφάλειας κατά την εργασία με έναν δημόσιο ιστότοπο και θα συμμορφώνεται με τα εσωτερικά πρότυπα ασφαλείας που έχουν υιοθετήσει η Εταιρεία.
Πρώτα απ 'όλα, θα ήθελα να επισημάνω ότι η τεχνολογία δεν είναι τυποποιημένη και είναι ακόμα στο προσχέδιο, αλλά το CloudFlare και η Mozilla την υποστηρίζουν ήδη (στο
Λίγο θεωρίας
ESNI είναι μια επέκταση του πρωτοκόλλου TLS 1.3 που επιτρέπει την κρυπτογράφηση SNI στο μήνυμα χειραψίας TLS "Client Hello". Δείτε πώς φαίνεται το Client Hello με την υποστήριξη ESNI (αντί για το συνηθισμένο SNI βλέπουμε το ESNI):
Για να χρησιμοποιήσετε το ESNI, χρειάζεστε τρία στοιχεία:
- DNS;
- Υποστήριξη πελατών.
- Υποστήριξη από την πλευρά του διακομιστή.
DNS
Πρέπει να προσθέσετε δύο εγγραφές DNS – AΚαι TXT (Η εγγραφή TXT περιέχει το δημόσιο κλειδί με το οποίο ο πελάτης μπορεί να κρυπτογραφήσει το SNI) - δείτε παρακάτω. Επιπλέον, πρέπει να υπάρχει υποστήριξη DoH (DNS μέσω HTTPS) επειδή οι διαθέσιμοι πελάτες (δείτε παρακάτω) δεν ενεργοποιούν την υποστήριξη ESNI χωρίς DoH. Αυτό είναι λογικό, καθώς το ESNI συνεπάγεται κρυπτογράφηση του ονόματος του πόρου στον οποίο έχουμε πρόσβαση, δηλαδή, δεν έχει νόημα η πρόσβαση στο DNS μέσω UDP. Επιπλέον, η χρήση
Επί του παρόντος διαθέσιμο
Cloudflare
А είσοδος:
curl 'https://dns.google.com/resolve?name=www.cloudflare.com&type=A'
-s -H 'accept: application/dns+json'
{
"Status": 0,
"TC": false,
"RD": true,
"RA": true,
"AD": true,
"CD": false,
"Question": [
{
"name": "www.cloudflare.com.",
"type": 1
}
],
"Answer": [
{
"name": "www.cloudflare.com.",
"type": 1,
"TTL": 257,
"data": "104.17.210.9"
},
{
"name": "www.cloudflare.com.",
"type": 1,
"TTL": 257,
"data": "104.17.209.9"
}
]
}
TXT εγγραφή, το αίτημα δημιουργείται σύμφωνα με ένα πρότυπο _esni.FQDN:
curl 'https://dns.google.com/resolve?name=_esni.www.cloudflare.com&type=TXT'
-s -H 'accept: application/dns+json'
{
"Status": 0,
"TC": false,
"RD": true,
"RA": true,
"AD": true,
"CD": false,
"Question": [
{
"name": "_esni.www.cloudflare.com.",
"type": 16
}
],
"Answer": [
{
"name": "_esni.www.cloudflare.com.",
"type": 16,
"TTL": 1799,
"data": ""/wEUgUKlACQAHQAg9SiAYQ9aUseUZr47HYHvF5jkt3aZ5802eAMJPhRz1QgAAhMBAQQAAAAAXtUmAAAAAABe3Q8AAAA=""
}
],
"Comment": "Response from 2400:cb00:2049:1::a29f:209."
}
Έτσι, από την άποψη του DNS, θα πρέπει να χρησιμοποιήσουμε DoH (κατά προτίμηση με DNSSEC) και να προσθέσουμε δύο καταχωρήσεις.
Υποστήριξη πελατών
Αν μιλάμε για προγράμματα περιήγησης, τότε αυτή τη στιγμή
Φυσικά, το TLS 1.3 πρέπει να χρησιμοποιηθεί για την υποστήριξη του ESNI, αφού το ESNI είναι επέκταση του TLS 1.3.
Για τον σκοπό της δοκιμής του backend με υποστήριξη ESNI, εφαρμόσαμε τον πελάτη σε go, Αλλά περισσότερα για αυτό αργότερα.
Υποστήριξη από την πλευρά του διακομιστή
Προς το παρόν, το ESNI δεν υποστηρίζεται από διακομιστές ιστού όπως nginx/apache κ.λπ., καθώς λειτουργούν με TLS μέσω OpenSSL/BoringSSL, οι οποίοι δεν υποστηρίζουν επίσημα το ESNI.
Ως εκ τούτου, αποφασίσαμε να δημιουργήσουμε το δικό μας στοιχείο διεπαφής (ESNI reverse proxy), το οποίο θα υποστηρίζει τον τερματισμό TLS 1.3 με ESNI και την κυκλοφορία HTTP(S) διακομιστή μεσολάβησης προς την ανοδική ροή, η οποία δεν υποστηρίζει ESNI. Αυτό σας επιτρέπει να χρησιμοποιείτε την τεχνολογία σε μια ήδη υπάρχουσα υποδομή, χωρίς να αλλάξετε τα κύρια στοιχεία - δηλαδή, να χρησιμοποιείτε τρέχοντες διακομιστές ιστού που δεν υποστηρίζουν ESNI.
Για λόγους σαφήνειας, εδώ είναι ένα διάγραμμα:
Σημειώνω ότι ο διακομιστής μεσολάβησης σχεδιάστηκε με τη δυνατότητα τερματισμού μιας σύνδεσης TLS χωρίς ESNI, για υποστήριξη πελατών χωρίς ESNI. Επίσης, το πρωτόκολλο επικοινωνίας με upstream μπορεί να είναι είτε HTTP είτε HTTPS με έκδοση TLS μικρότερη από 1.3 (αν η upstream δεν υποστηρίζει την 1.3). Αυτό το σχήμα παρέχει μέγιστη ευελιξία.
Εφαρμογή της υποστήριξης ESNI στις go δανειστήκαμε από
Για τη δημιουργία κλειδιών ESNI χρησιμοποιήσαμε
Δοκιμάσαμε την έκδοση χρησιμοποιώντας το go 1.13 σε Linux (Debian, Alpine) και MacOS.
Λίγα λόγια για τα λειτουργικά χαρακτηριστικά
Ο αντίστροφος διακομιστής ESNI παρέχει μετρήσεις σε μορφή Prometheus, όπως rps, κωδικούς καθυστέρησης και απόκρισης ανάντη, αποτυχημένες/επιτυχείς χειραψίες TLS και διάρκεια χειραψίας TLS. Με την πρώτη ματιά, αυτό φαινόταν αρκετό για να αξιολογηθεί ο τρόπος με τον οποίο ο διακομιστής μεσολάβησης χειρίζεται την κυκλοφορία.
Πραγματοποιήσαμε επίσης δοκιμή φορτίου πριν από τη χρήση. Αποτελέσματα παρακάτω:
wrk -t50 -c1000 -d360s 'https://esni-rev-proxy.npw:443' --timeout 15s
Running 6m test @ https://esni-rev-proxy.npw:443
50 threads and 1000 connections
Thread Stats Avg Stdev Max +/- Stdev
Latency 1.77s 1.21s 7.20s 65.43%
Req/Sec 13.78 8.84 140.00 83.70%
206357 requests in 6.00m, 6.08GB read
Requests/sec: 573.07
Transfer/sec: 17.28MB
Πραγματοποιήσαμε καθαρά ποιοτική δοκιμή φορτίου για να συγκρίνουμε το σχήμα χρησιμοποιώντας αντίστροφο διακομιστή μεσολάβησης ESNI και χωρίς. «Χύσαμε» την κίνηση τοπικά για να εξαλειφθούν οι «παρεμβολές» σε ενδιάμεσα εξαρτήματα.
Έτσι, με την υποστήριξη ESNI και το διακομιστή μεσολάβησης σε ανάντη ροή από το HTTP, πήραμε περίπου ~550 rps από μία παρουσία, με τη μέση κατανάλωση CPU/RAM του αντίστροφου διακομιστή μεσολάβησης ESNI:
- Χρήση CPU 80% (4 vCPU, 4 GB RAM κεντρικοί υπολογιστές, Linux)
- 130 MB Mem RSS
Για σύγκριση, το RPS για το ίδιο nginx upstream χωρίς τερματισμό TLS (πρωτόκολλο HTTP) είναι ~ 1100:
wrk -t50 -c1000 -d360s 'http://lb.npw:80' –-timeout 15s
Running 6m test @ http://lb.npw:80
50 threads and 1000 connections
Thread Stats Avg Stdev Max +/- Stdev
Latency 1.11s 2.30s 15.00s 90.94%
Req/Sec 23.25 13.55 282.00 79.25%
393093 requests in 6.00m, 11.35GB read
Socket errors: connect 0, read 0, write 0, timeout 9555
Non-2xx or 3xx responses: 8111
Requests/sec: 1091.62
Transfer/sec: 32.27MB
Η παρουσία χρονικών ορίων δείχνει ότι υπάρχει έλλειψη πόρων (χρησιμοποιήσαμε 4 vCPU, 4 GB RAM κεντρικούς υπολογιστές, Linux) και στην πραγματικότητα το δυνητικό RPS είναι υψηλότερο (λάβαμε στοιχεία έως και 2700 RPS σε πιο ισχυρούς πόρους).
Εν κατακλείδι, σημειώνω ότι η τεχνολογία ESNI φαίνεται πολλά υποσχόμενη. Υπάρχουν ακόμα πολλά ανοιχτά ερωτήματα, για παράδειγμα, τα θέματα αποθήκευσης ενός δημόσιου κλειδιού ESNI στο DNS και η περιστροφή των κλειδιών ESNI - αυτά τα θέματα συζητούνται ενεργά και η τελευταία έκδοση του προσχέδιο ESNI (τη στιγμή που γράφονται αυτές οι γραμμές) είναι ήδη
Πηγή: www.habr.com