הפכו את העברת ה-IPv4 לקבועה גם לאחר הפעלה מחדש של שער VPN
הגדירו את ip_forward במרחב השמות שנושא את מנות הלקוח, תנו להגדרה בעלים אחד, והוכיחו שהיא שורדת הפעלה מחדש במקום רק לערוך קובץ.
פינג לשער עובד והגעה לכל דבר מאחוריו לא, וזו צורתה של בעיית העברה ולא של בעיית מנהרה. מסירה מקומית לשער מוכיחה שהמנהרה עלתה ושהקצאת הכתובת עבדה; היא לא אומרת דבר על האם הליבה תעביר מנה מממשק אחד לאחר. לפני שנוגעים ב-sysctl כלשהו, ודאו שהמכונה מיועדת לנתב את התעבורה הזו ומצאו את הקשר הרשת שמחזיק את הממשק הפונה ללקוח. לאחר מכן קראו את הערך שם, ולא במקום שבו המדריך האחרון שקראתם הסתכל במקרה.
הגעה לשער אינה אותו דבר כמו העברה
בתוך הליבה מתקבלות שתי החלטות נפרדות. מסירה לכתובת מקומית מסיימת את מסע המנה; העברה שולחת אותה שוב החוצה דרך ממשק אחר, וההחלטה השנייה הזו נשלטת לפי מרחב שמות רשת. שער יכול להיות נגיש לחלוטין בזמן שההעברה כבויה, ומשורת ping שתי התקלות נראות זהות.
רשמו על איזה ממשק מגיעה מנת הלקוח ודרך איזה ממשק יוצא המשך הדרך. שניהם שייכים למרחב שמות אחד, ומרחב השמות הזה מחזיק את ההגדרה שחשובה.
קראו את הערך במקום שבו המנות באמת נמצאות
בשער שמנתב במרחב השמות של המארח, פקודה אחת עונה על השאלה: sysctl net.ipv4.ip_forward. כשהדרך הנכנסת והמשך הדרך חיים במרחב שמות בעל שם, שאלו את מרחב השמות הזה: ip netns exec vpn-gw sysctl net.ipv4.ip_forward. ערך המארח אינו תחליף לערך מרחב השמות, ואחד במארח אינו הוכחה לשום דבר.
לא לכל הקשר ניתוב יש תווית שאפשר למסור ל-ip netns. סביבות הרצה של מכולות ושירותים יוצרות מרחבי שמות שלעולם אינם נרשמים תחת שם ידידותי, ולאלה משתמשים בכלי הבדיקה של סביבת ההרצה. החליפו את vpn-gw בשם האמיתי, או במנגנון סביבת ההרצה שמגיע לאותו הקשר, והפסיקו לנחש ברמת המארח.
תנו להגדרה בעלים אחד
בשער מארח קונבנציונלי עם systemd, הצורה העמידה היא קובץ drop-in בשם שנבחר בידי המנהל, כמו /etc/sysctl.d/60-vpn-forwarding.conf, שמכיל net.ipv4.ip_forward = 1. כתבו את הקובץ, ואז טענו בדיוק את הקובץ הזה כדי שגם המצב החי ישתנה: sudo sysctl -p /etc/sysctl.d/60-vpn-forwarding.conf, ואחריו קריאה חוזרת. שם הקובץ הוא דוגמה ולא נתיב VPN שמור, והמספר המוביל חשוב כי קבצים שממוינים מאוחר יותר מנצחים.
קדימות היא המקום שבו העמידות נשברת בשקט. בדקו גם את טוען ההפצה וגם את ה-drop-in שלכם, כי procps sysctl --system קורא גם את /etc/sysctl.conf בסוף, בעוד שסדר sysctl.d של systemd הוא רצף אחר לגמרי. הקצאה מאוחרת יותר יכולה להחזיר את אותו מפתח מיד, ולהשאיר את הקובץ שלכם נכון ואת הערך האפקטיבי שגוי. אל תדרסו קובץ מנהל קיים כדי לנצח בוויכוח הזה; מצאו את הבעלים ושנו שם.
מרחב שמות שנוצר לאחר האתחול אינו נשלט כלל בידי drop-in של המארח. ההגדרה שלו שייכת למה שיוצר אותו, בין אם זו סביבת ההרצה של המכולות ובין אם יחידת האספקה של מרחב השמות. להעניק למכולה הרשאות מארח רחבות כדי לחמוק מהשאלה הוא עסקה גרועה יותר מאשר לבזבז עשר דקות על זיהוי הבעלים הנכון.
דעו מה עולה המתג לפני שאתם הופכים אותו
ip_forward אינו ערך בוליאני בלתי מזיק. תיעוד הליבה מציין ששינוי שלו מאפס כמה פרמטרים אחרים של IPv4 לברירות המחדל של המארח או של הנתב, כך שהיפוך אבחוני עלול לזרוק כוונון שנעשה במקום אחר ואף לא להזכיר אותו. התייחסו אליו כאל שינוי תצורה עם תופעות לוואי ולא כאל בדיקה שאפשר להריץ כלאחר יד.
זה גם שולל כיבוי והדלקה בכל פעם שלקוח אינו מצליח להגיע למארח. אם הערך כבר אחד, התקלה נמצאת במקום אחר בדרך, וכתיבה שלישית של אותו מפתח לא תזיז אותו.
הוכיחו עמידות, ואז בדקו את שאר הדרך
קראו את הערך חזרה בארבעה רגעים: מיד לאחר השינוי, לאחר שהממשק VPN מופיע, לאחר התחברות מחדש ולאחר הפעלה מחדש מתוכננת. ערך שחוזר לאחור באחד מהנקודות האלה יש לו בעלים שני, ועוד כתיבה חד-פעמית רק מסתירה אותו עד לאתחול הבא.
ההעברה המופעלת עדיין מותירה שלושה דברים לבדיקה. הלקוח זקוק למסלול אל היעד, השער זקוק למסלול המשך בתוספת הרשאה להשתמש בו, והיעד זקוק למסלול חזרה לכתובת המנהרה של הלקוח. LAN פרטי ומנותב אינו זקוק אוטומטית ל-NAT, לכן אל תוסיפו masquerading לפני שאתם יודעים איזה מהשלושה חסר, ובדקו מהלקוח המיועד ולא מהשער עצמו, כי בקשה שמקורה בשער לעולם אינה נוגעת במסלול ההעברה שזה עתה הפעלתם. ל-IPv6 יש מדיניות העברה וניתוב משלו, ולכן בדיקת IPv4 מוצלחת אינה אומרת עליו דבר.
שמרו יחד ב-runbook את נתיב ה-drop-in, את בעלי מרחב השמות ואת פקודת הקריאה החוזרת. מי שייקח את זה הלאה צריך להיות מסוגל לקרוא את הערך, לראות מי הבעלים שלו, ולהחליט בתוך דקה אם הבעיה היא בעמידות או בשאר הדרך.