ביליתי בוקר שלם עם מנה שעלתה בצורה נקייה והעבירה תנועה בכיוון אחד בלבד: הסניף הצליח להגיע לשרת הקבצים במטה, וכל חיבור שנפתח מהמטה לסניף מת ב-SYN הראשון. ה-SA היו פעילים, מוני המנה עלו, והלחיצה לא הייתה הבעיה מעולם. התשובה נותבה למקום שהמנה לא מכסה, והבחירה הזאת שייכת לצד המרוחק. VPN מאתר לאתר מעביר רק את החבילות שהמארח מוסר לשער, וכל מארח עושה את הבחירה הזאת בנפרד, בכל כיוון, מטבלת הניתוב שלו.

שני הכיוונים מנותבים בנפרד

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

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

המארח המרוחק לא יודע דבר על המנה שלכם

בתוך ה-LAN המרוחק התשובה היא חבילה רגילה שממוענת ללקוח שלכם. מארח היעד לא רואה שום כותרת IPsec ואין לו סיבה להעדיף את שער ה-VPN; הוא מחפש את התחילית שלכם, לא מוצא דבר ספציפי יותר מנתיב ברירת המחדל שלו והולך אחריו. אם ברירת המחדל מצביעה על חומת אש ליבתית, לחומה יש נתיב חזרה למנה או שאין. כשאין, אתם מקבלים זריקה שקטה, ICMP unreachable או תשובה שיוצאת דרך הממשק הפונה לאינטרנט ומתה.

ממשק שני מספיק כדי לשבור את זה גם כשקיים נתיב. NAS עם קישור ניהול ב-VLAN אחר, שרת עם uplink גיבוי, כלל מדיניות ששולח טווח מקורות אחד לטבלה שנייה: כל אחד מאלה יכול ללכוד את התשובה. ב-Linux, ip rule show ו-ip route show table all חושפים כללים וטבלאות שהרשימה המוגדרת כברירת מחדל מסתירה.

קראו את ההחלטה במכונה ששולחת את התשובה

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

ip route get 10.10.5.10 from 10.20.30.15
ip rule show
ip route show table all
ss -tn state established "( sport = :445 )"

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

ב-Windows המקבילות הן Find-NetRoute -RemoteIPAddress 10.10.5.10 להחלטה ו-Get-NetRoute לטבלה. נתיב שנוסף עם New-NetRoute ונושא מדד גבוה מברירת המחדל מפסיד בשקט, אז קראו את עמודת המדד, לא את הרשומה. אחר כך אשרו עם חבילות: tcpdump -ni any "host 10.10.5.10 and tcp port 445" בממשק ה-LAN המרוחק מראה את הבקשה, ואותו מסנן בצד המנה מראה אם חזרה תשובה. בקשה נראית בלי תשובה פירושה שהתשובה נותבה למקום אחר או נזרקה; תשובה בממשק הלא נכון נותנת לכם את האשם לפני שאתם נוגעים בנתיב.

כשהשער של השרת אינו נקודת הקצה של ה-VPN

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

לשער יש מסנן שני משל עצמו. סינון נתיב הפוך ב-Linux זורק חבילות שהמקור שלהן אינו נגיש דרך הממשק שממנו הן הגיעו, וזה בדיוק הצורה של נתיב חזור לא סימטרי לגיטימי. מדריך ההעברה של strongSwan דורש net.ipv4.ip_forward ו-net.ipv4.conf.all.rp_filter מרוכך מהסיבה הזאת. ערך קפדני של 1 בכל אחד מהשערים שובר בשקט נתיב תקין, ו-nstat -az מציג את הזריקות אם אתם יודעים היכן להסתכל.

SymptomWhere the reply is most likely lost
Gateway ping works, LAN host silentSource address the far host cannot place in its table
SYN arrives, no SYN-ACK, tunnel counters flatNo route to the client prefix on the far host or its gateway
Reply counted on the internet-facing interfaceDefault route or policy rule on the far host
Firewall reports invalid stateAsymmetric path through a stateful device
Worked until a link failed overNew path is asymmetric, or rp_filter now rejects it

נתבו או תרגמו, ואז אמתו בשני הכיוונים

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

iptables -t nat -A POSTROUTING -o eth1 -s 10.20.30.0/24 -j MASQUERADE

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

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

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