Το Client VPN δίνει στον πελάτη μια διεύθυνση, η χειραψία ολοκληρώνεται, και η σύνδεση δεν πηγαίνει πουθενά. Πριν αγγίξετε πιστοποιητικά ή εκδόσεις πελάτη, κοιτάξτε τον πίνακα διαδρομών του ίδιου του τελικού σημείου. Ένα τελικό σημείο AWS Client VPN προωθεί ένα πακέτο μόνο όταν μία από τις διαδρομές του καλύπτει το πρόθεμα προορισμού· αν δεν ταιριάζει τίποτα, το πακέτο απορρίπτεται στο τελικό σημείο και ο κεντρικός υπολογιστής προορισμού δεν βλέπει ποτέ SYN.

Αυτή είναι απόφαση προώθησης, όχι απόφαση ταυτοποίησης. Λαμβάνεται αφού σηκωθεί η σήραγγα και αφού αξιολογηθούν οι κανόνες εξουσιοδότησης, γι' αυτό ένα έγκυρο πιστοποιητικό και μια έγκυρη ομάδα μπορούν να δώσουν νεκρή σύνδεση.

Το τελικό σημείο προωθεί μόνο ό,τι καλύπτει ο πίνακας διαδρομών του

Κάθε διαδρομή είναι ένα CIDR προορισμού συν το υποδίκτυο που πρέπει να λάβει την κίνηση. Το τελικό σημείο αντιπαραβάλλει τον προορισμό του πελάτη με αυτή τη λίστα, διαλέγει την αντίστοιχη εγγραφή και στέλνει το πακέτο στο συνδεδεμένο υποδίκτυο. Χωρίς εγγραφή δεν υπάρχει επόμενο άλμα.

Προσέξτε τι δεν είναι η διαδρομή. Δεν είναι εγγραφή στον πίνακα διαδρομών του VPC, και δεν εξουσιοδοτεί τίποτα. Οι κανόνες εξουσιοδότησης κρίνουν αν μια ομάδα φτάνει σε έναν προορισμό· οι διαδρομές κρίνουν αν το τελικό σημείο έχει πού να στείλει το πακέτο. Και τα δύο πρέπει να συμφωνούν, και αποτυγχάνουν με διαφορετικά συμπτώματα, οπότε το να μαντεύετε ποιο είναι χαλασμένο σπαταλά ένα απόγευμα.

Η κλασική ασυμφωνία είναι ένα VPC με peering. Κάποιος προσθέτει διαδρομή για το 10.20.0.0/24 ενώ ο κόμβος ζει στο 10.20.4.0/24, άρα η διεύθυνση πέφτει έξω από κάθε εγγραφή. Μια σύλληψη στην πλευρά του πελάτη δείχνει επαναλαμβανόμενα SYN χωρίς απάντηση, και τα αρχεία καταγραφής του στόχου δεν δείχνουν απολύτως τίποτα.

Διαβάστε τη λίστα διαδρομών πριν το πιστοποιητικό

Οι διαδρομές του τελικού σημείου είναι ξεχωριστό αντικείμενο, οπότε ρωτήστε τις απευθείας αντί να διαβάσετε τον πίνακα του VPC:

aws ec2 describe-client-vpn-routes --client-vpn-endpoint-id cvpn-endpoint-0123456789abcdef0 --query 'Routes[].{Dest:DestinationCidr,Target:TargetSubnet,Origin:Origin}'

Πάρτε την ακριβή διεύθυνση και το μήκος προθέματος από τον πελάτη που αποτυγχάνει, και μετά ελέγξτε την κάλυψη χαρακτήρα προς χαρακτήρα. Ισχύει η αντιστοίχιση του μεγαλύτερου προθέματος, οπότε μια ευρύτερη διαδρομή δεν σας σώζει όταν μια στενότερη δείχνει αλλού.

Ένας πόρος ανά προορισμό με for_each

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

variable "client_vpn_routes" {
  type = map(string)
  default = {
    "10.20.0.0/16"  = "subnet-0aa11bb22cc33dd44"
    "172.31.0.0/20" = "subnet-0aa11bb22cc33dd44"
  }
}

resource "aws_ec2_client_vpn_route" "this" {
  for_each               = var.client_vpn_routes
  client_vpn_endpoint_id = var.client_vpn_endpoint_id
  destination_cidr_block = each.key
  target_vpc_subnet_id   = each.value
  depends_on             = [aws_ec2_client_vpn_network_association.this]
}

Διατηρήστε την εξάρτηση από τη συσχέτιση δικτύου. Μια διαδρομή χρειάζεται συνδεδεμένο υποδίκτυο, οπότε ένα apply που δημιουργεί και τα δύο πρέπει να βάλει πρώτα τη συσχέτιση, και χωρίς αυτή την αναφορά το Terraform είναι ελεύθερο να δοκιμάσει πρώτα τη διαδρομή. Μετά διαβάστε το plan: το πλήθος των προσθηκών διαδρομών πρέπει να ταιριάζει με τα προθέματα που προσθέσατε. Αν το plan αντικαθιστά και το τελικό σημείο, ο πόρος του τελικού σημείου είναι γραμμένος λάθος, και η εφαρμογή του αποσυνδέει κάθε συνδεδεμένο πελάτη.

Υιοθέτηση τελικού σημείου που δεν δημιουργήσατε

Οι περισσότερες ομάδες κληρονομούν ένα τελικό σημείο χτισμένο στην κονσόλα, γι' αυτό δεν υπάρχει κώδικας διαδρομών. Μη στήσετε δεύτερο τελικό σημείο μόνο για να βάλετε διαδρομές στο Terraform.

Κάντε import αντ' αυτού, ή περάστε τα ids ως μεταβλητές και αφήστε τα κληρονομημένα αντικείμενα χωρίς διαχείριση. Το import χρειάζεται τη μορφή αναγνωριστικού που τεκμηριώνει ο πάροχος για κάθε τύπο πόρου· κωδικοποιεί το τελικό σημείο, το πρόθεμα προορισμού και το υποδίκτυο-στόχο. Αντιγράψτε αυτό το κείμενο από την τεκμηρίωση του πόρου αντί να το συνθέσετε από μνήμης, εκτελέστε ένα plan και περιμένετε καμία αλλαγή πριν προσθέσετε κάτι νέο.

Ιχνηλατήστε το πακέτο με τη σειρά που ταξιδεύει

Όταν η διαδρομή υπάρχει και η σύνδεση αποτυγχάνει ακόμη, περπατήστε τη διαδρομή με σειρά αντί να μαντεύετε στο ανώτερο επίπεδο.

  1. Διαδρομή: ένα πρόθεμα καλύπτει τον προορισμό και δείχνει σε υποδίκτυο συνδεδεμένο με το τελικό σημείο.
  2. Εξουσιοδότηση: ένας κανόνας εξουσιοδότησης επιτρέπει αυτόν τον προορισμό για την ομάδα του χρήστη. Μια διαδρομή μόνη της δεν δίνει ποτέ πρόσβαση.
  3. Επιστροφή: ο πίνακας διαδρομών του υποδικτύου-στόχου στέλνει τις απαντήσεις πίσω προς το τελικό σημείο, και η ομάδα ασφαλείας επιτρέπει τη θύρα από τη δεξαμενή διευθύνσεων του πελάτη.
  4. Εφαρμογή: ανοίξτε πραγματική σύνδεση TCP από τον πελάτη, και μετά επιβεβαιώστε ότι τα αρχεία καταγραφής του στόχου δείχνουν την αναμενόμενη διεύθυνση προέλευσης από τη δεξαμενή.

Αλλάζετε ένα πρόθεμα ανά apply, ξαναδιαβάστε τη λίστα διαδρομών μετά, και καταγράψτε μαζί τον προορισμό, τον κανόνα που εξουσιοδοτεί και την επιστροφή. Ο επόμενος που θα αποσφαλματώσει μια απορριφθείσα σύνδεση πρέπει να ξεκινήσει από αυτό το απόθεμα, όχι από μια θεωρία περί πιστοποιητικών.

Σχετικά άρθρα