NAT והעברת פורטים ב-Linux: הגדרת iptables/nftables

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

היכולות שלנו:

שאלות נפוצות

העבודות האחרונות

  • פיתוח אפליקציית ווב עבור FEEDME
    פיתוח אפליקציית ווב עבור FEEDME
    1359
  • פיתוח חנות מקוונת לחברת FURNORO
    פיתוח חנות מקוונת לחברת FURNORO
    1330
  • עיצוב לוגו לחברת B2B Advance
    עיצוב לוגו לחברת B2B Advance
    776
  • פיתוח אפליקציית ווב עבור Enviok
    פיתוח אפליקציית ווב עבור Enviok
    1077
  • פיתוח לוגו חברת AIDER
    פיתוח לוגו חברת AIDER
    1022
  • פיתוח CRM עבור Chasseurs
    פיתוח CRM עבור Chasseurs
    1113

מדוע NAT קוטע חיבורים בעת העברת פורטים

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

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

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

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

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

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

מה משתנה לאחר סדר בכללים

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

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

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

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

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

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

מצבי NAT: השוואת גישות ומגבלות

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

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

אפשרות מתי מתאימה מגבלות
המרה דינמית (masquerade / SNAT) גישה יוצאת מהרשת הפנימית, כתובת היציאה משתנה או אינה ידועה מראש חיבור נכנס מבחוץ בלתי אפשרי; בצד המרוחק רואים רק את כתובת השער
הצמדה סטטית של SNAT הצד החיצוני מאמת את כתובת המקור לפי רשימה לבנה כתובת אחת לשירות, ההצמדות מתוחזקות ידנית ומאבדות סנכרון בעת העברות
פרסום שירות לפי פורטים (DNAT) השירות מאזין לפורט קבוע, שאין לשנותו הפורט שייך לנמען אחד; שינוי כתובת או פורט פנימיים — עריכת כללים וטעינה מחדש של הטבלאות
פרוקסי הפוך כמה שירותים תחת שם אחד, נדרשים תעודות וניתוב לפי שם הבקשה מתווסף צומת בשרשרת; נדרשת העברה תקינה של כתובת הלקוח האמיתית הלאה

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

סדר העבודות: איסוף כללי NAT, בדיקה, מסירה

כללי המרת הכתובות כמעט никогда לא נאספים מאפס: על מכונה חיה כבר קיימות שרשראות, חלקן נוספו ידנית ואינן מתועדות בשום מקום. לכן אנו מתעדים תחילה את הטופולוגיה בפועל ואת מערכת הכללים הנוכחית, ורק אחר כך מתכננים את הסכמה הרצויה — אחרת השינוי הראשון שובר תעבורה של מישהו אחר.

  1. ניתוח הטופולוגיה. אילו ממשקים פונים החוצה, היכן שער ברירת המחדל, אילו שירותים צריכים להיות נגישים מבחוץ, ואילו — רק בתוך הרשת.
  2. ביקורת כללים. מייצאים את השרשראות הפעילות של iptables או nftables יחד עם מוני החבילות: כללים בלי תעבורה, כפילויות, חפיפות, רשומות "זמניות" שחיות שנים. התוצאה — טבלה "כלל — ייעוד — בעלים".
  3. סכמת המרת כתובות. מפרידים היכן נדרשת החלפת כתובת מקור והיכן — העברת פורט נכנס לצומת פנימי, ומפצלים את הזרמים לשרשראות נפרדות, כך שעריכת שירות אחד לא תפגע בשכנים.
  4. בדיקת כללים על סטנד. משחזרים את הטופולוגיה במתחם בדיקות ומריצים את הכללים הרצויים: החיבורים הנדרשים עוברים, המיותרים סגורים. הקונפיגורציה נשמרת במאגר גרסאות.
  5. החלפה מבוקרת. מחילים על צומת הייצור עם חזרה לאחור מוגדרת לפי טיימר: אם הבדיקות המוסכמות לא עברו — הקונפיגורציה חוזרת לקודמת אוטומטית, בלי עבודה ידנית.
  6. ניטור. ביממה הראשונה עוקבים אחר המונים, היומנים ומספר החיבורים הפתוחים, משווים לתחזית ובודקים בנפרד את ההתנהגות בעומס שיא.
  7. מסירת הקונפיגורציה. מוסרים את קובץ הכללים ב�控制系统 גרסאות, את סכמת ההמרה, את מפת הפורטים והוראות החזרה לאחור, ועוברים עם הצוות שלכם על סדר העריכות הבאות.

חבילת המסירה: קונפיגורציות, סכמות, נהלים

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

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

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

מקרה בוחן: ניתוקי חיבורים לאחר בנייה מחדש של הרשת

השירות עבד יציב עד שהרשת נבנתה מחדש: הוסף ערוץ חיצוני שני, וחלק מתת-הרשתות הועבר לשער נפרד. בשעות שיא עד 4% מהפניות הסתיימו בשגיאת חיבור, וכל טעינה מחדש של כללי NAT בשער קטעה סשנים שכבר נוצרו.

חלון ההשבתה בשינוי מתוכנן התארך ל-30–40 דקות — חלק מהחיבורים לא שוחזרו מעצמם, ולקוחות חזרו עם ניסיונות חוזרים.

מה מצאנו

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

מה שינינו

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

מה התקבל

לאחר המעבר שיעור הפניות הכושלות בשיא ירד מ-4% ל-0,15%, שינויים מתוכננים בשער עוברים בלי לקטוע סשנים פעילים, ומקרים שדרשו הזעקת תורן הפכו לאפס–אחד בחודש במקום שבעה–תשעה. הפתרון משוחזר על כל שער: ההיגיון זהה גם למערכות כללים ישנות וגם לערימה החדשה (Netfilter).

במה שונה מסכור מהמרת כתובות סטטית?

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

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

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

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

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

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

בחירת המצב מצטמצמת לאחת: אם נדרשת רק גישה יוצאת והכתובת החיצונית אינה קבועה — מסכור; אם השירות צריך לקבל חיבורים מבחוץ או שהכתובת קבועה — המרה סטטית.

נקודות שנויות במחלוקת: המרה כפולה, אסימטריה, יומנים

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

אנחנו מאחורי צומת גבול של מישהו אחר — המרה כפולה

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

התשובה לא חזרה — ניתוב אסימטרי

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

היכן לראות איזה כלל פעל

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

נדון במשימה: שלחו את סכמת הרשת ואת הכללים הנוכחיים

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

  • סכמת רשת או רשימת תת-רשתות: מי צריך לראות את מי, היכן השערים, אילו סגמנטים מבודדים, והיכן כרגע נשברת הקישוריות.
  • כללים נוכחיים בצורת דאמפ: טבלאות הסינון, ההמרה והניתוב במלואן, ולא קטע — חלק מהבעיות חיות במפגש בין שרשראות ונראות רק בפלט המלא.
  • מה מנהל את הקונפיגורציה: iptables או nftables, האם מעליהם יש עטיפה כמו firewalld או ufw, והאם המצב נשמר לאחר אתחול.
  • ניסוח המשימה: העברת פורט החוצה, המרה ליציאה לאינטרנט, פרסום שירות מאחורי מאזן עומסים או גישה מסניף.
  • כיצד הכללים מיושמים היום: ידנית לפי הוראה, דרך מערכת לניהול קונפיגורציות, לפי תבנית או יחידת שירות בעלייה.
  • מגבלות: חלון שינויים מותר, דרישה לחזרה לאחור, מי יש לו גישה לצמתים והאם קיים ערוץ גיבוי.
  • תסמינים ויומנים: מה בדיוק לא עובד, האם התקלה משוחזרת תמיד או תחת עומס, ומה כותבות הליבה והשירותים ברגע הכשל.

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