למה AWS Client VPN מפיל תעבורה בלי מסלול תואם
נקודת הקצה מעבירה מנה רק כאשר טבלת המסלולים שלה מכסה את היעד. קראו את המסלולים, הצהירו על קידומות עם for_each, ואמתו את נתיב החזרה.
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 חופשי לנסות את המסלול קודם. אחר כך קראו את התוכנית: מספר תוספות המסלולים צריך להתאים לקידומות שהוספתם. אם התוכנית גם מחליפה את נקודת הקצה, משאב נקודת הקצה כתוב שגוי, והחלתו מנתקת כל לקוח מחובר.
לאמץ נקודת קצה שלא יצרתם
רוב הצוותים יורשים נקודת קצה שנבנתה בקונסולה, ולכן אין קוד מסלולים. אל תפילו נקודת קצה שנייה רק כדי להכניס מסלולים ל-Terraform.
במקום זאת ייבאו, או העבירו את המזהים כמשתנים והשאירו את האובייקטים המורשים ללא ניהול. ייבוא דורש את פורמט המזהה שהספק מתעד לכל סוג משאב; הוא מקודד את נקודת הקצה, את קידומת היעד ואת תת-הרשת המיועדת. העתיקו את המחרוזת מתיעוד המשאב במקום להרכיב אותה מהזיכרון, הריצו תוכנית, ואל תצפו לשינויים לפני שתוסיפו משהו חדש.
עקבו אחרי המנה לפי הסדר שבו היא נוסעת
כשהמסלול קיים והחיבור עדיין נכשל, עברו על הנתיב לפי הסדר במקום לנחש בשכבה העליונה.
- מסלול: קידומת מכסה את היעד ומצביעה על תת-רשת שמשויכת לנקודת הקצה.
- הרשאה: כלל הרשאה מתיר את היעד הזה לקבוצה של המשתמש. מסלול לבדו לא מעניק גישה לעולם.
- נתיב חזרה: טבלת המסלולים של תת-הרשת המיועדת שולחת תשובות חזרה אל נקודת הקצה, וקבוצת האבטחה מתירה את הפורט ממאגר הכתובות של הלקוח.
- יישום: פתחו חיבור TCP אמיתי מהלקוח, ואז ודאו שהלוגים של היעד מראים את כתובת המקור הצפויה מהמאגר.
שנו קידומת אחת לכל apply, קראו שוב את רשימת המסלולים אחר כך, ותעדו יחד את היעד, את הכלל שמתיר ואת נתיב החזרה. האדם הבא שיאתר תקלה בחיבור נדחה צריך להתחיל מהמלאי הזה, לא מתיאוריה על תעודות.