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

הסדר הוא שקובע, לא קיומו של הכלל

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

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

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

הוסיפו מעל ההרשאה הרחבה

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

sudo ufw --dry-run route insert 1 deny in on tun0 proto tcp from 10.88.0.55/32 to 192.0.2.88/32

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

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

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

זרימות מבוססות שורדות את הכלל החדש

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

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

זכרו גם את הגבולות. הכלל הזה לא אומר דבר על ICMP, UDP או IPv6, ולכן ping מוצלח אינו הוכחה שהחסימה נכשלה. גם כתובת IPv4 אחת אינה אתר: שם יכול להתפרש לכמה כתובות, ורק זו שציינתם מכוסה.

בדקו עם זרימה חדשה

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

sudo ufw status numbered
sudo ufw show raw
# from 10.88.0.55, a new TCP connection to 192.0.2.88 should fail

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

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

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

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