המחשב הנייד של מפתח פג בזמן שהוא מתחבר לנקודת הקצה הפרטית של RDS, בעוד שאותם פרטי התחברות עובדים ממארח bastion. שום דבר לא נפל. למסלול בין המחשב הנייד הזה למסד הנתונים חסר אחד משלושה דברים: שם שמתפרש, מסלול שנושא את התנועה, או כלל בקבוצת אבטחה שמתיר את המקור שמסד הנתונים באמת רואה. גלו מה חסר לפני שתשנו את השניים האחרים.

קראו את הכשל בשכבה הנכונה

פג אינו שגיאה אחת. שם שאינו מתפרש נכשל לפני שחבילה יוצאת מהמכונה. כתובת בלי מסלול שולחת חבילות לחור שחור. פורט מסונן יוצר המתנה שנראית בדיוק כמו מארח שגוי. הריצו את השלבים לפי הסדר ועצרו בראשון שנכשל.

dig +short db.internal.example
nc -vz db.internal.example 5432

אם השם מחזיר כתובת ציבורית, או לא מחזיר כלום, המנהרה עדיין לא הבעיה.

אם השם מתפרש ובדיקת הפורט נתקעת, השוו את הכתובת שפרשתם לכתובת שמסד הנתונים מדווח. נקודת קצה מנוהלת יכולה להתפרש לכתובת פרטית בתוך ה-VPC ולשום דבר שימושי מחוצה לו, וכתובת שהועתקה מחיפוש ישן תצביע על מארח שכבר לא עונה.

הפרידו את המנהרה מהמסלול

חיבור VPN של לקוח לא מנתב אוטומטית כל טווח פרטי. הפרופיל נושא את המסלולים שהשירות דוחף, והלקוח עשוי להתקין רק חלק מהם. בדקו אילו טווחים הלקוח באמת הוסיף והאם כתובת מסד הנתונים נופלת בתוך אחד מהם.

ip route get 10.20.40.15
ip addr show tun0

מסלול שמצביע על ממשק המנהרה הכרחי; הוא אינו מספיק, כי הצד השני עדיין צריך לקבל את התנועה.

פרופילי מנהרה מפוצלת הם המקור הרגיל לכשל החציוני הזה. הם עובדים עבור היישום שלמענו תוכנן הפרופיל ומשאירים את טווח מסד הנתונים מחוץ למנהרה, מה שיוצר בדיוק את הפג שחומת אש הייתה יוצרת.

התאימו את קבוצת האבטחה למקור האמיתי

קבוצת האבטחה של RDS מתירה מקורות, לא אנשים. בהתאם לארכיטקטורה, המקור עשוי להיות מאגר לקוחות ה-VPN, הכתובת הפרטית של bastion, או כתובת NAT שאליה מתורגמת התנועה. קראו את הכלל ואת מקור החבילה בפועל יחד.

aws ec2 describe-security-groups --group-ids sg-0123456789abcdef0 \
  --query 'SecurityGroups[].IpPermissions'

כלל לכתובת הבית של מחשב נייד אחד הוא בעיית תחזוקה ולא תכנון גישה.

כאשר VPN של לקוח או שער NAT נמצא בדרך, מסד הנתונים עשוי לראות את כתובת המתרגם במקום את כתובת המנהרה של המפתח. לכן כלל שהועתק מהגדרת bastion עובדת עשוי להיכשל במחשב נייד: שני המסלולים מגיעים ממקורות שונים אף ששניהם נראים פנימיים.

העדיפו מסלול צר על פני רחב

כשמפתח אחד צריך מסד נתונים אחד, העברה מבוססת הפעלה לרוב זולה לתפעול ממנהרת רשת מלאה. הלקוח המקומי מתחבר לפורט מועבר, והרכיב המרוחק יוצר את החיבור למסד הנתונים מתוך הרשת.

ssh -N -L 5432:db.internal.example:5432 bastion.internal.example

שמרו על אימות TLS שלם בתכנון הזה. הלקוח עדיין צריך לאמת את תעודת השרת מול השם שהוא מצפה לו; פורט מועבר מקומי אינו סיבה לבטל את האימות, וביטולו מסתיר בדיוק את בעיית הזהות ששווה לתפוס.

הבחירה בין מנהרה מלאה להעברה צרה היא החלטה על היקף, לא על תיאטרון אבטחה.

השאירו מאחוריכם מסלול שאפשר לחזור עליו

תעדו את שם נקודת הקצה במקום כתובת מפורשת, את טווח המקור שקבוצת האבטחה מתירה, ואת תפקיד מסד הנתונים שבו המפתח משתמש. שלוש העובדות האלה מסבירות את רוב הכשלים העתידיים בלי שיחה. הוסיפו גם את גרסת פרופיל הלקוח, כי שינוי פרופיל יכול להסיר מסלול שהפרופיל הישן נשא.

אחר כך בדקו פעם אחת את המקרה השלילי: לקוח מחוץ למקור המאושר אמור עדיין להידחות.

מסד נתונים פרטי שעובד רק עבור האדם שהגדיר אותו אינו גישה פרטית; הוא חריגה לא מתועדת שמחכה להתגלות מחדש. כתבו את המסלול, והמפתח הבא יירש שיטה במקום תעלומה.

מאמרים קשורים