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

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

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

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

מה באמת עושה האפשרות multihome

ההנחיה נכתבת בתור multihome בקובץ תצורה ובתור --multihome בשורת הפקודה, והיא גורמת לשרת UDP לענות מהכתובת שאליה הגיעה החבילה של הלקוח. הגרעין מוסר את כתובת היעד המקורית כנתונים נלווים בקליטה, ו-OpenVPN משתמש בערך הזה כמקור התשובה. כך שרת שמאזין בכתובת כללית, local 0.0.0.0 עבור IPv4 או המקבילה שלה ב-IPv6, מתנהג כאילו כל לקוח הגיע למאזין ייעודי. לקוחות שהגיעו דרך הכתובת הציבורית מקבלים תשובות מהכתובת הציבורית, ולקוחות בכתובת פנימית מקבלים אותן ממנה. שום דבר אחר בנתיב החבילה לא זז: המסלול, כללי הסינון ותצורת המנהרה נשארים בדיוק כפי שהיו.

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

מתי כתובת מקומית קבועה היא ברירת המחדל השגויה

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

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

הוכיחו את מקור התשובה מבחוץ

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

tcpdump -ni any udp port 1194
ss -lunp 'sport = :1194'
ip route get 203.0.113.10 from 198.51.100.20

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

ניתוב, גילוי וסינון נשארים נפרדים

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

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

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