מארח iptables ב-VPN בלבד: תנו שם להתקן tun, לא tun+
tun+ תואם לכל מנהרה במכונה. קבעו שם התקן אחד, שימו את חריגת ה-endpoint ראשונה ושמרו על נתיב שחזור בזמן שאתם בודקים את המדיניות.
כתיבת -o tun+ מרגישה כמו הוראה מדויקת ולמעשה היא תו כללי שמתאים לכל מנהרה שבגרעין. לקוח VPN שני, גשר מכולות או ממשק שנשאר מסשן שקרס — כולם מספקים אותו, והמארח אז מתיר תעבורה שהמדיניות נועדה למנוע. הנוהל שלהלן קובע שם התקן אחד, מסדר את החריגים כך שהמנהרה באמת תוכל להיווצר, ומשאיר לכם דרך חזרה אם הכללים ייפלו לרעה. כל שלב קצר מספיק כדי לבטל אותו לבדו.
שלב 1: תעדו את הכללים שיש לכם עכשיו
לפני שינוי מדיניות ברירת מחדל, שמרו את המצב הנוכחי כדי שהחזרה תהיה פקודה ולא זיכרון. iptables-save > /root/iptables.pre כותב כל טבלה לקובץ שאתם יכולים לשחזר, ומסוף שני עם סשן root פתוח אינו פרנויה כשהמדיניות שאתם עומדים לקבוע מפילה את החיבור שנושא אותה. אם אתם עובדים מרחוק, תזמנו גם flush כמתג אדם מת.
לאחר מכן פרטו את הממשקים, כי שם שהנחתם הוא שם שהייתם צריכים לקרוא: ip -br link מראה מה קיים כרגע, והמנהרה לא תופיע עד שהיא תהיה למעלה. רשמו את שמות ההתקנים תוך כדי קריאה.
שלב 2: תנו למנהרה שם משלה
OpenVPN מקבל dev tun_work בקונפיגורציית הלקוח, ואז Linux יוצר ממשק עם בדיוק השם הזה במקום להקצות tun0. השם נשאר יציב בין התחברויות חוזרות כל עוד שום דבר אחר לא תובע אותו, וזה מה שהופך כלל שמנקב את שם ההתקן למשמעותי.
כאשר אי אפשר לשלוט בשם, התאימו במקום זאת לכתובת המנהרה או לסימון חבילה. שניהם עובדים, שניהם קשים יותר לקריאה, ושניהם נכשלים בשקט רב יותר כשהמנהרה ממספרת מחדש. בכל מקרה, התאימו לדבר אחד והיו מפורשים לגבי איזה.
שלב 3: כתבו את המדיניות כשחריגת ה-endpoint ראשונה
מארח עם VPN בלבד הוא מארח עם דחייה כברירת מחדל ורשימת חריגים קצרה, והחריג החשוב ביותר הוא זה שמאפשר למנהרה להתקיים. בנו אותו בסדר הזה, עם כלל ה-endpoint לפני כלל התקן המנהרה, כדי שלחיצת היד תהיה לאן ללכת:
# allow the tunnel to be built, then everything the tunnel carries
iptables -P INPUT DROP
iptables -P OUTPUT DROP
iptables -A INPUT -i lo -j ACCEPT
iptables -A OUTPUT -o lo -j ACCEPT
iptables -A OUTPUT -d 198.51.100.7 -p udp --dport 1194 -j ACCEPT
iptables -A OUTPUT -o tun_work -j ACCEPT
iptables -A INPUT -i tun_work -j ACCEPT
iptables -A INPUT -m conntrack --ctstate ESTABLISHED,RELATED -j ACCEPTכתובת ה-endpoint והפורט המילוליים שייכים לספק שלכם, לא לדף הזה. אם ה-endpoint הוא שם מארח, פתרו אותו פעם אחת וקבעו את התוצאה, כי כלל אינו יכול לחפש שם ותשובה מתחלפת תשבור את המדיניות בשקט אחרי שינוי ה-DNS הבא. בדקו גם את הפורט, כי ספקים שמעבירים אתכם ל-TCP 443 יצטרכו אחרת כלל שאיש לא כתב. מנהרה שעובדת רק בפרוטוקול אחד היא בדרך כלל ההחמצה הזו ולא תקלה בחומת האש.
בנתב אותה צורה נכנסת לשרשרת FORWARD עבור הלקוחות שמאחוריו, והתעבורה של הנתב עצמו צריכה כללים משלה. מערך כללים שמכסה רק מנות שהועברו הלאה משאיר את SSH ו-DNS במסלול הישן, וכך נתב הופך לבלתי נגיש ברגע שהמנהרה עולה.
שלב 4: בדקו את הסדר, לא רק את הנוכחות
כללים מוערכים לפי הסדר, כך ש-ACCEPT שמגיע מוקדם יותר פשוט מסתיר את ה-REJECT שהוספתם אחריו. התאמת established ו-related היא מה שמאפשר לתשובות לבקשות היוצאות שלכם לחזור בלי לפתוח נתיב נכנס כללי, והצבתה אחרי אישור המנהרה פירושה שמנהרה שנפלה עדיין מעבירה תעבורת חזרה בממשק שלה.
השאירו את מספר הכללים קטן מספיק כדי לקרוא במסך אחד. מערך כללים שאינכם יכולים לבקר הוא כזה שתטלאו על ידי הוספת חריגים בראש, וכך מדיניות דחייה כברירת מחדל מקבלת בהדרגה שולי הרשאה כברירת מחדל. ספרו את ה-ACCEPT לפני ואחרי השינוי.
שלב 5: עשו שזה ישרוד את האתחול ואת משפחת הכתובות
כללים שהוזנו ביד נעלמים באתחול מחדש, לכן טענו אותם משירות חומת האש של ההפצה או מ-unit שרץ אחרי שממשק המנהרה קיים. הפניה ל-tun_work בסקריפט שרץ לפני ש-OpenVPN מתחיל היא דרך נפוצה ליצור לולאת אתחול של תעבורה שנפלה.
לאחר מכן בדקו IPv6 בנפרד, כי מדיניות דחייה כברירת מחדל טובה ל-IPv4 לא אומרת דבר על המשפחה האחרת. ip -6 route יגיד לכם אם למארח יש מסלול שיכול לשאת תעבורה סביב מנהרה שמטפלת רק ב-IPv4, ו-ip6tables או nftables זקוקים לכללים מקבילים משלהם. בדקו עם יעד IPv6-only במקום לסמוך על הסימטריה של מערך הכללים.
שלב 6: אמתו והיו מוכנים לשחזר
העלו את המנהרה, ודאו שהשירות המיועד עובד, ואז נסו משהו שהמדיניות אמורה לסרב לו. שחזרו עם iptables-restore < /root/iptables.pre אם התשובה מפתיעה אתכם, ורק אז התחילו לערוך כללים. התמדה בתוספת נתיב שחזור שנבדק היא מה שהופך את זה לשינוי שאפשר לעשות פעמיים.