מתג הרג pf ב-macOS עבור OpenVPN: כללים שנסגרים
אוסף כללי pf חוסם תעבורה ישירה בזמן שהמנהרה למטה. שמרו על הנתיב של הלקוח לשרת שלו, ואז הוכיחו את החסימה עם המנהרה כבויה.
ב-macOS, מתג הרג טוב רק כמו מדיניות מסנן החבילות שמאחוריו, ו-pf הוא החלק שאוכף את המדיניות הזו. המדיניות חייבת לעשות שני דברים מנוגדים בעת ובעונה אחת: לתת ללקוח להגיע לשרת שלו כדי שמנהרה תוכל להתקיים, ולעצור כל דבר אחר מלצאת ישירות. רוב אוספי הכללים המפורסמים מצליחים בשני ושוכחים את הראשון, ולכן המכונה מאבדת קישוריות במקום לזכות בהגנה. הגרסה שעובדת נוקבת בשם נקודת הקצה, הפותר והמנהרה, ולא יותר.
מה מסנן חבילות יכול להחליט, ומה הוא לא יכול
pf מסתכל על ממשקים, כתובות, מספרי פרוטוקול ופורטים, ושם הוא עוצר. הוא לעולם לא לומד איזה תהליך פתח שקע, ולכן הרשאה שנכתבה עבור תוכנית אחת הופכת להרשאה לכל תוכנית שיכולה להגיע לאותו פורט. כך חריגת UDP נדיבה מחזירה מתג הרג לרשת רגילה. חסימה מודעת ליישום שייכת ללקוח או להרחבה של המערכת, לא לקובץ הזה.
המסנן גם לא יוצר נתיבים. כשהלקוח נופל, נתיב ברירת המחדל עשוי עדיין להצביע על מנהרה מתה, ו-pf הופך זאת לחבילות חסומות במקום נפילה שקטה חזרה ל-Wi-Fi. החסימה היא התוצאה המכוונת, לא תקלה שיש לעקוף.
הסדר מכריע בתוצאה לעתים קרובות יותר מטקסט הכלל. בלי quick, pf ממשיך להעריך אחרי התאמה והכלל האחרון שמתאים מנצח, ולכן מעבר רחב ליד התחתית מבטל את החריגים הזהירים שמעליו. סימון המעברים ב-quick הופך את ההתאמה הראשונה לסופית, וזה מה שמחבר מדיניות בדרך כלל מתכוון אליו.
קראו קודם את עובדות הממשק ונקודת הקצה
ממשקים אלחוטיים אינם ממוספרים באותה דרך בכל Mac, והתקן המנהרה מקבל מספר שעשוי להשתנות בין אתחולים. כלל שמזכיר התקן שאינו קיים נכשל בפענוח, וזה רועש וקל לתפיסה, בעוד כלל שמזכיר את ההתקן הקיים הלא נכון מפוענח נקי ומתיר תעבורה שרציתם לעצור.
אספו את העובדות בזמן שהלקוח מחובר, כי התקן המנהרה קיים רק אז. אתם צריכים את הממשק שמחזיק בנתיב ברירת המחדל, את ההתקן שהלקוח יצר, ואת הכתובת והפורט של השרת שאליו הוא מחייג. הערך האחרון הזה הוא זה שרוב אוספי הכללים משמיטים, וההשמטה שלו היא הסיבה שאוסף כללים שהועתק חוסם את המנהרה של עצמו.
route -n get default
ifconfig -l
scutil --nc list
הפקודה הראשונה נוקבת בשם הממשק שמנצח כרגע, השנייה מפרטת כל התקן שהגרעין מכיר, והשלישית מציגה את תצורות ה-VPN שהמערכת יכולה להפעיל. רשמו את התשובות, ואז קראו את כתובת השרת והפורט מתצורת הלקוח עצמו.
כתבו את אוסף הכללים סביב נתיב המנהרה
הקובץ שלמטה מסרב כברירת מחדל ומקבל מחדש חמישה דברים: loopback, התקן המנהרה, הנתיב של הלקוח לשרת שלו, הפותר שמשמש לפני שהמנהרה קיימת, ושתי החלופות ששומרות על קישור אלחוטי שמיש. שמות ממשקים וכתובת השרת מגיעים מהמכונה שלכם, לכן החליפו את הערכים שאישרתם. גם מספר המנהרה לא יתאים לשלכם.
set skip on lo0
block all
pass out quick on utun0
# maintain this line when the server address changes
pass out quick on en1 inet proto udp to 203.0.113.10 port 1194
# only the resolver the client uses before the tunnel exists
pass out quick on en1 inet proto udp to 192.0.2.53 port 53
pass out quick on en1 inet proto udp from any port 68 to any port 67
pass out quick on en1 inet proto udp to 224.0.0.251 port 5353
שורת ה-DHCP קיימת כי Mac מבקש כתובת לפני שיש לו אחת, ולכן הבקשה יוצאת מפורט 68 לעבר פורט 67 בלי כתובת מקור שמישה. שורת ה-multicast מאפשרת למערכת לשפוט אם כדאי להשתמש בקישור האלחוטי, והסרתה מייצרת מכונה שמדווחת שאין חיבור ברשת שעובדת. שורת נקודת הקצה היא מה שמאפשר ל-OpenVPN להגיע לשרת שלו בכלל; בלעדיה block all מפיל את לחיצת היד החיצונית והמנהרה לא עולה לעולם. שורת הפותר צרה יותר מהרשאת DNS כללית, כי היא נוקבת בכתובת אחת ובפורט אחד במקום בכל שאילתה שהמכונה עושה.
חריגי נקודת הקצה והפותר הם השניים שחייבים להתקיים; כל השאר נשאר חסום. אם הלקוח מחייג לכתובת מפורשת, הסירו את שורת הפותר והשאירו את שורת נקודת הקצה. אם כתובת השרת משתנה, עדכנו את השורה לפני החיבור הבא, או מלאו טבלת pf מהקרס של הלקוח עצמו והתאימו את הטבלה במקום.
הורידו את המנהרה, ואז אתחלו
נתחו לפני טעינה, כי שגיאת תחביר זולה בהרצה יבשה ויקרה בהפעלה מרחוק. אחר כך טענו את הקובץ, הפעילו את המסנן אם היה כבוי, וקראו חזרה מה באמת בתוקף. הקריאה חזרה אינה טקס: עוגן אחר יכול להוסיף כללים שלא כתבתם, לכן השוו את האוסף המודפס לקובץ שלכם.
sudo pfctl -n -v -f /etc/pf.conf
sudo pfctl -f /etc/pf.conf
sudo pfctl -e
sudo pfctl -s rules
sudo pfctl -s Anchors
sudo pfctl -a <anchor> -s rules
sudo pfctl -s info
עם הכללים טעונים, הורידו את המנהרה ונסו לטעון דף. תעבורה רגילה אמורה לעצור, והיא אמורה להישאר עצורה אחרי שהמכונה נרדמת ומתעוררת, כי במעבר הזה מצב מיושן זוחל חזרה. התחברו מחדש ואשרו שהתעבורה חוזרת בלי לגעת באוסף הכללים. אם דפדפן עדיין עובד עם המנהרה למטה, כלל אחד רחב מכפי שחשבתם, והקריאה חזרה בדרך כלל נוקבת בשמו.
האתחול הוא החלק שאנשים מדלגים עליו. macOS קורא את /etc/pf.conf בזמן האתחול, אבל קריאת הקובץ אינה אותו דבר כמו הפעלת המסנן, ולכן אוסף כללים שעובד עכשיו יכול להיות לא פעיל אחרי אתחול. הריצו אחר כך sudo pfctl -s info ואשרו ששורת המצב מדווחת שהמסנן פעיל.
שמרו על היציאה ועל נתיב האתחול ביושר
אוסף כללים שחוסם הכול יכול גם לנעול אתכם מחוץ למכונה שאתם מנהלים מרחוק. ערכו מהפעלה מקומית כשאפשר, שמרו את הקובץ הקודם לצד החדש, ודעו את הדרך חזרה לפני שתזדקקו לה. הפקודות שלמטה מפסיקות את המסנן וטוענות מחדש את העותק ששמרתם, וזה הרצף להפעלה ממסוף ולא דרך המנהרה שזה עתה חתכתם. חזרה בחמש שניות מנצחת כלל חכם בכל פעם.
sudo pfctl -d
sudo pfctl -f /etc/pf.conf.previous
sudo pfctl -s rules
התמדה דורשת daemon אתחול שמריץ pfctl -e וטוען את הקובץ שלכם באתחול. התייחסו אליו כמו לכל עבודה מורשית אחרת: נתיבים מוחלטים, יומן שתוכלו לקרוא אחר כך, ובדיקה במכונה שאפשר להגיע אליה פיזית. daemon שנכשל בשקט משאיר את המכונה לא מוגנת ונראית רגילה.
תעדו את הפערים, החל מלקוח VPN שני שיוצר התקן מנהרה משלו. הכללים שלכם נוקבים בממשק מנהרה אחד, ולכן השני נשאר חסום או נתפס בכלל רחב שנוסף מאוחר יותר. ממשקי tethering ונקודת גישה מופיעים רק לפעמים וראויים לאותה הערה. אף אחד מהפערים האלה אינו סיבה לדלג על המדיניות; הם התנאים שבהם היא עדיין מחזיקה.