תיקון DNS של אורח libvirt שנחסם על ידי חומת אש VPN מבוססת סימון
חומת אש VPN מבוססת סימון משליכה את ה-DNS של האורח לפני ששרשרת סינון כלשהי רואה אותו. כלל אחד בעל עדיפות mangle מסמן את השאילתה ואת תשובתה, בלי לפתוח את ה-LAN שלך.
אורחים ברשת libvirt המוגדרת כברירת מחדל מפענחים שמות באופן מושלם עד שממשק WireGuard עולה, ואז כל חיפוש נתקע באותה נקודה. dnsmasq עדיין מאזין בכתובת 192.168.122.1:53, האורח עדיין משתמש בכתובת הזו כמפענח שלו, והשאילתה עדיין מגיעה. מה שהשתנה הוא ששאילתת ה-upstream של המארח עצמו, או התשובה עליה, נזרקת כעת על ידי כלל שנבחן לפני כל שרשרת סינון שהייתם חושבים לערוך. הדרך החוצה היא סימון שמוחל מוקדם מספיק, על חיבור שהתשובה יורשת.
אורחים מאבדים DNS ברגע שהמנהרה עולה
אמתו את הצורה לפני שמשנים משהו. הורידו את המנהרה, הריצו dig @192.168.122.1 example.com מאורח, וראו שהוא עונה. העלו את המנהרה, חזרו על הפעולה, וראו שהיא נגמרת בזמן. זוג התוצאות הזה שולל ברשת libvirt שבורה, כתובת מפענח שגויה ו-dnsmasq מת בצעד אחד.
לאחר מכן הביטו בצד המארח. אם dnsmasq רושם את השאילתה ואת העברת ה-upstream שלה, החבילה הגיעה והכשל ביציאה. אם dnsmasq לא רושם דבר, שאילתת האורח נזרקת בכניסה, והחריגה שייכת ל-hook אחר מזה שהמאמר הזה מסמן.
למה כלל accept בשרשרת מאוחרת לעולם לא נורה
חומת אש VPN מבוססת סימון מחליטה לפי סימון החבילה או סימון החיבור, לא לפי כתובת המקור שלכם. כל דבר שמגיע לממשק הפיזי בלי הסימון הצפוי נדחה, והדחייה הזו מתרחשת בסט הכללים שבעליו הם בדיקת הסימון. שורת ip saddr 192.168.122.0/24 accept שנוספה לאיזו שרשרת מאוחרת פשוט אינה נבדקת לעולם עבור החבילה הזו, ולכן הכלל המובן מאליו נראה נכון ואינו משנה דבר.
הרחבה עד שמשהו יעבוד היא המלכודת השנייה. קבלת כל תת-הרשת של libvirt בנתיב הכניסה של המארח פותחת כל שירות של המארח לאורחים, בעוד הצורך האמיתי הוא פורט אחד.
המנגנון שמאפשר חריגה צרה הוא מעקב חיבורים. כשאתם מגדירים ct mark על חבילה, הערך נשמר ברשומת ה-conntrack ולא רק בחבילה, כך שכל חבילה בחיבור הזה נושאת אותו אחר כך, כולל התשובה מהמארח חזרה לאורח. זה כל הטריק: סמנו את הבקשה פעם אחת, ונתיב החזרה כבר מסומן.
סמנו את השאילתה לפני שטבלת ה-VPN רואה אותה
שימו את החריגה בטבלה משל עצמה כדי שקורא מאוחר ימצא אותה בלי לנתח את כללי ה-VPN:
table inet allowedLocal {
chain guest_dns {
type filter hook input priority mangle; policy accept;
ip saddr 192.168.122.0/24 meta l4proto { tcp, udp } \
th dport 53 ct mark set 0x00000f41
}
}
priority mangle שלילי, מה שמציב את השרשרת הזו לפני שרשראות הסינון הרגילות שחבילת ה-VPN מתקינה בעדיפות אפס. סדר ה-hooks הוא מה שהופך את הכלל לאפקטיבי; אותו כלל בשרשרת שממוינת אחרי שרשרת ה-VPN הוא קישוט.
מספר הסימון עצמו אינו נייד. קחו את הערך שכללי ה-VPN המותקנים מקבלים עבור התעבורה שלהם, קראו אותו מסט הכללים החי, והשתמשו בו. סימון שגוי מייצר כלל שנטען נקי, מתאים לכל שאילתה, ואינו מכניס דבר.
השאירו את החור ברוחב פורט 53
כפי שנכתב, זה מתיר DNS מתת-הרשת של libvirt אל המארח דרך TCP או UDP בפורט 53 ושום דבר אחר. זה לא מאפשר לאורחים להגיע לאינטרנט מחוץ למנהרה, וזה לא מאפשר למארח לפתוח חיבורים אל האורחים. אם אורח יזדקק בהמשך לשירות מארח אחר, הוסיפו כלל נפרד שמציין את פורט היעד הזה במקום להקל את זה.
היו כנים לגבי מה שאתם מחליפים. אורח שיכול להגיע למפענח יכול גם לתעל נתונים שרירותיים דרך שאילתות DNS, והחריגה הזו היא פער מכוון בגבול ה-VPN ולא הצהרה שהרשת המקומית מהימנה. הגבלת המקור ל-192.168.122.0/24 מרחיקה את הפער מכל תת-רשת מקומית אחרת, וספירת שאילתות מול אותו מקור היא זולה אם האיום חשוב לכם.
גרמו לזה לשרוד אתחול והוכיחו את שני החצאים
כלל שהוקלד בשורת פקודה נעלם באתחול הבא, וכלל שנטען אחרי שממשק ה-VPN כבר מעביר תעבורה מפסיד במירוץ בחיבור הראשון. שימו את הטבלה בקונפיגורציית ה-nftables המתמשכת של המארח, או ביחידה שממוינת לפני שירות ה-VPN, ובדקו את הסדר במקום להניח אותו.
האימות דורש שלוש תשובות נפרדות. ודאו שהשרשרת נטענת וממוינת ראשונה, ודאו שרשומת ה-conntrack מציגה את הסימון בשני הכיוונים, וודאו שחיפוש של אורח מחזיר כתובת. אחר כך ודאו את החצי השני: תעבורת אינטרנט רגילה של האורח אל מארח ציבורי עדיין נכשלת כשהמנהרה למטה או חוסמת. אם DNS עובד וכל השאר דולף, הכלל שלכם רחב יותר מזה שלמעלה.
אם החיפושים עדיין נכשלים אחרי שהסימון במקום, התנגדו לדחף להרחיב את המקור. בדקו לאן dnsmasq מעביר, אם המפענח של האורח מצביע על 192.168.122.1 או על כתובת ציבורית שמישהו הקליד, ואם השאילתה בכלל מגיעה למארח. סימון מכניס את החבילה ושום דבר אחר, ולכן upstream רע או רשת וירטואלית שבורה נשארים שבורים לא משנה כמה כללים תוסיפו.