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

איך Squid מכריע בבקשת CONNECT

בקשת CONNECT מציינת מארח ופורט, ו-Squid עובר על שורות http_access לפי הסדר עד שאחת מהן מתאימה. דחייה מתאימה מסיימת את ההערכה מיד והלקוח מקבל 403 מהפרוקסי. לכן מיקומה של כלל חשוב יותר מהניסוח שלו. הזזת אותה שורה צעד אחד למעלה יכולה לשנות את התוצאה לחלוטין.

המגנים המקובלים דוחים כל דבר מחוץ ל-Safe_ports ודוחים CONNECT מחוץ ל-SSL_ports. השמות האלה הם ACL המוגדרים בתצורה שלכם, ולכן התוכן שלהם שלכם ולא של הפרוטוקול. הפצה עשויה להתיר טווח רחב של פורטים כ-Safe_ports ובמקביל להגביל את CONNECT בנפרד. קראו את הערכים החיים לפני שאתם מניחים שפורט חסום מלכתחילה.

ודאו שהפרוקסי הוא הרכיב שדוחה את הבקשה. 403 שמייצר Squid אינו דומה כלל להתראת TLS משרת ה-VPN, ואיחוד השניים לבעיה אחת עולה את השעה הראשונה. בדקו את שורת יומן הגישה של הבקשה, משום שהיא רושמת גם את הפעולה וגם את הכלל שיצר אותה.

בנו התאמה משולבת אחת במקום שלושה ACL נפרדים

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

הצורה שלמטה משתמשת בטווחי תיעוד שיש להחליף בערכים שנבדקו. Squid אינו שומר לעצמו אף אחד מהשמות האלה, ולכן הבחירה בהם והשמירה על עקביותם בידיים שלכם. המתכון הזה מוגבל ל-Squid 6 ו-7, שתצורתם המתועדת תומכת בקבוצת all-of. העזר הנוכחי מסמן את ההנחיות האלה כלא זמינות ב-Squid 8, ולכן התייחסו לזה כמתכון תלוי גרסה ולא כנתיב מעבר, ובדקו את ההנחיה בעזר של הגרסה שלכם לפני יישום.

acl pvpn_src src 192.0.2.128/25
acl pvpn_dst dst 198.51.100.77/32
acl pvpn_port port 1194
acl pvpn_ok all-of CONNECT pvpn_port pvpn_dst pvpn_src

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

כופפו את מגני הפורטים בלי להסיר אותם

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

http_access deny !Safe_ports
http_access deny CONNECT !SSL_ports

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

http_access deny CONNECT !SSL_ports !pvpn_ok
http_access deny !Safe_ports !pvpn_ok

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

היכן אסור למקם את החריגה

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

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

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

בדקו את הגבול עם המנתח ועם בקשה אמיתית

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

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

squid -k parse
squid -k reconfigure
curl -v -p -x http://proxy.lab.internal:3128 https://vpn.lab.internal:1194/ --max-time 5

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

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