· ~4 λεπτά ανάγνωσης
Ένα site-to-site IPsec VPN με strongSwan και δική μου PKI
Δύο LAN ενωμένα μέσα από ένα μη έμπιστο δίκτυο με ένα tunnel IKEv2, gateways που αυθεντικοποιούνται με πιστοποιητικά από ιδιωτική CA αντί για κοινό κλειδί, και απόδειξη στο Wireshark ότι στο καλώδιο περνά μόνο ESP.
Στόχος
Να συνδέσω δύο απομονωμένα LAN μέσα από ένα δίκτυο που δεν εμπιστεύομαι, ώστε οι hosts κάθε πλευράς να μιλούν μεταξύ τους σαν να ήταν τοπικοί, και όποιος παρακολουθεί τη σύνδεση στη μέση να μη βλέπει τίποτα χρήσιμο. Το lab τρέχει σε τέσσερα Linux VMs: δύο VPN gateways και έναν εσωτερικό host πίσω από το καθένα.
Τα configs και όλα τα βήματα είναι στο repository στο GitHub.
Τοπολογία
| Μηχάνημα | Εξωτερική | Εσωτερική |
|---|---|---|
| Gateway 1 | 10.0.3.3 | 192.168.1.1/24 |
| Gateway 2 | 10.0.3.4 | 192.168.2.1/24 |
| Host 1 | 192.168.1.10 (gateway 192.168.1.1) | |
| Host 2 | 192.168.2.10 (gateway 192.168.2.1) |
Πριν από οποιοδήποτε tunnel, τα gateways χρειάζονται απλό routing: ενεργό IP forwarding και ένα static route σε κάθε gateway προς το LAN της άλλης πλευράς, μέσω της εξωτερικής διεύθυνσης του άλλου gateway. Αν το layer 3 είναι σωστό από την αρχή, κάθε αποτυχία αργότερα είναι πρόβλημα του IPsec και όχι του routing.
Πιστοποιητικά αντί για pre-shared key
Ο γρήγορος τρόπος να αυθεντικοποιήσεις δύο IPsec peers είναι ένα pre-shared key. Είναι και ο αδύναμος: ένα string κοινό ανάμεσα στα sites, συχνά μικρό, που σπάνια αλλάζει, και αν διαρρεύσει εκτίθεται κάθε tunnel που το χρησιμοποιεί. Αντί γι' αυτό έστησα μια μικρή ιδιωτική CA:
- ένα κλειδί CA (RSA 4096) και ένα αυτο-υπογεγραμμένο πιστοποιητικό CA, το trust anchor·
- ένα ζεύγος κλειδιών και ένα αίτημα υπογραφής πιστοποιητικού για κάθε gateway, υπογεγραμμένο από την CA·
- τα κλειδιά στο
/etc/swanctl/με δικαιώματα 600.
Έτσι κάθε gateway αποδεικνύει την ταυτότητά του με το δικό του ιδιωτικό κλειδί και ελέγχει το πιστοποιητικό της άλλης πλευράς απέναντι στην CA, μέχρι το ακριβές distinguished name.
Η ρύθμιση του strongSwan
Το tunnel ορίζεται στο swanctl.conf. Η πλευρά του Gateway 1, συντομευμένη:
connections {
gw1-to-gw2 {
remote_addrs = 10.0.3.4
local {
auth = pubkey
certs = g1Cert.pem
}
remote {
auth = pubkey
id = "C=GR, O=Lab, CN=gateway2"
}
children {
net {
local_ts = 192.168.1.0/24
remote_ts = 192.168.2.0/24
start_action = trap
}
}
}
}
Δύο ρυθμίσεις μετράνε περισσότερο. Το auth = pubkey μαζί με το ακριβές id σημαίνει ότι ο peer πρέπει να έχει πιστοποιητικό υπογεγραμμένο από την CA για το gateway2, όχι απλώς οποιοδήποτε πιστοποιητικό της CA. Και το start_action = trap εγκαθιστά μια πολιτική στον kernel που ανεβάζει το tunnel όταν χρειαστεί: το πρώτο πακέτο που ταιριάζει στα δύο subnets ξεκινά τη διαπραγμάτευση IKEv2.
Η απόδειξη ότι δουλεύει
Μετά το swanctl --load-all, ένα ping από το ένα LAN στο άλλο ανέβασε το tunnel, και το swanctl --list-sas έδειξε τα security associations. Μετά ήρθε το κομμάτι που με ενδιαφέρει περισσότερο, μια καταγραφή στην εξωτερική διεπαφή του gateway:
- κανένα ICMP σε απλό κείμενο στο εξωτερικό τμήμα·
- μόνο πακέτα ESP, με αδιαφανές περιεχόμενο·
- οι τιμές SPI στο Wireshark ταίριαζαν με αυτές που έδειχνε το
swanctl --list-sas, άρα τα κρυπτογραφημένα πακέτα στο καλώδιο ανήκαν σε αυτό το tunnel και σε τίποτα άλλο.
Τι έμαθα
Κοιτώντας το ξανά, αυτά θα έκανα πιο αυστηρά.
- Κλείδωσε τους αλγορίθμους. Bytes που μοιάζουν τυχαία δείχνουν ότι η κρυπτογράφηση είναι ενεργή, όχι ποιος cipher χρησιμοποιείται. Θα όριζα ρητά τα
proposalsκαιesp_proposals(για παράδειγμα AES-GCM με σύγχρονο DH group) αντί να βασίζομαι σε defaults που αλλάζουν ανά έκδοση, και θα έβαζα DH group και στο ESP proposal, ώστε τα child SAs να έχουν perfect forward secrecy στα rekeys. - Τα πρώτα πακέτα μιας πολιτικής trap χάνονται. Όσο διαπραγματεύεται το IKE, τα πακέτα που το ξεκίνησαν πετιούνται, οπότε το πρώτο ένα-δύο ping αποτυγχάνουν. Είναι αναμενόμενο, αλλά μπερδεύει τους ελέγχους monitoring· για συνδέσεις που πρέπει να είναι πάντα πάνω, το
start_action = startείναι καλύτερη επιλογή. - Μια CA χρειάζεται ζωή και μετά την έκδοση. Η CA του lab δεν είχε ανάκληση (CRL ή OCSP), είχε διάρκεια δέκα χρόνια και το κλειδί της ζούσε σε μηχάνημα του lab. Σε παραγωγή, το κλειδί της CA μένει offline, τα πιστοποιητικά των gateways είναι μικρής διάρκειας, και υπάρχει τρόπος να ανακαλέσεις ένα όταν χαθεί ένα gateway.
- Μετράει και το firewall μπροστά. Ανάμεσα στα gateways χρειάζεται να περνούν μόνο IKE (UDP 500 και 4500) και ESP (IP protocol 50). Οτιδήποτε άλλο στην εξωτερική διεπαφή είναι επιφάνεια επίθεσης.
Προσωπικό lab σε virtual machines.
Θέλεις τα configs ή τον κώδικα από αυτό το lab, ή έχεις κάποια ερώτηση; Στείλε μου email στο papas@viotnet.com