OpenVPN ו-HTTPS בפורט 443: למי שייך המאזין?
TCP ו-UDP 443 הם שקעים נפרדים. שיתוף מאזין TCP אחד דורש בעלים, ושיתוף הפורט של OpenVPN הוא הסדר צר, לא תחבולת פרוקסי.
שני שירותים יכולים שניהם להשיב בפורט 443 בלי להתחרות לעולם, מפני שמאזין נקבע לפי תחבורה, כתובת ופורט יחד, ולא לפי המספר לבדו. הציבו שרת אינטרנט ו-OpenVPN על מכונה אחת, והשאלה היחידה שראויה לתשובה ראשונה היא איזה שקע כל תהליך מבקש מהגרעין. כתבו את הרשימה הזו לפני עריכת תצורה, ורוב שגיאות «הכתובת כבר בשימוש» מסבירות את עצמן. כל מה שאחרי הרשימה הוא בחירה בין מאזין UDP, שקע TCP משותף או חזית שמנתבת לפי פרוטוקול.
התחילו בשקע שכל תהליך מבקש
bind מצליח או נכשל לפי השלשה הזו, ולכן שני דמונים מתנגשים רק כשכל שלושת החלקים חופפים. זו הסיבה שאתר על TCP 443 מתקיים ללא הגבלה לצד מאזין OpenVPN על UDP 443, וזו הסיבה שהעברת אחד מהם לכתובת מקומית שנייה באותו מארח גם היא מסיימת את הוויכוח. קראו את המאזינים החיים ולא את הקבצים שאמורים היו ליצור אותם, מפני ש-include מיושן או קובץ unit נשכח שורדים את העריכה שאתם זוכרים שעשיתם.
| Line in the listener list | What it establishes | What to do next |
|---|---|---|
| One udp row and one tcp row, each on 443 | Separate transport sockets, nothing contested | Point the VPN profile at udp and stop editing |
| A single tcp address and port listed by two processes | A real bind collision between two daemons | Move one service, or put a dispatcher in front of both |
| A proxy process owns the socket, no vpn process | The proxy accepts and has to hand off correctly | Check that its backend speaks the protocol it forwards |
הריצו ss -lntup כ-root וקראו כל שורה שמזכירה 443, כולל רשומות IPv6. מאזין v6 כללי בדרך כלל מקבל גם תעבורת v4, וכך מאזין ששכחתם מחזיק את הפורט תפוס אחרי ששיניתם את הקובץ שחשבתם שאחראי. אם שם תהליך מפתיע אתכם, צמצמו את הפלט עם ss -lntup 'sport = :443' לפני שאתם נוגעים במשהו.
העבירו את המנהרה ל-UDP כשהרשת מאפשרת
מאזין UDP עוקף את ההתנגשות לגמרי ובדרך כלל הוא התיקון הקצר ביותר, מפני שאף שקע אינו משותף ואף מוצר נוסף אינו נכנס לנתיב. אבל זה לא בחינם. רשתות לקוח מסוימות מפילות UDP 443 בלי לשלוח reset, ולכן המנהרה מפסיקה להקים במקום להיכשל ב-bind, והמשתמש מדווח שה-VPN למטה בלי שגיאה לקרוא. מאזין UDP גם שורד הפעלה מחדש של שכבת האינטרנט, וזה נחשב במכונה שהאתר שלה נפרס מחדש לעיתים קרובות. בדקו מהרשת שבה יושבים המשתמשים, מפני שמעטפת בשרת רק מוכיחה שהשרת מגיע לעצמו.
שנו את התחבורה בתצורת השרת ובפרופיל הלקוח יחד. פרופיל שעוד מבקש TCP יסתובב בלולאות התחברות מחדש מול מאזין UDP בלבד, וזה נראה כמו תקלת רשת עד שתשוו בין שני הקבצים.
הניחו לתהליך ה-VPN להחזיק ב-TCP 443 והעבירו את השאר
Community OpenVPN במצב שרת TCP קורא את הבייטים הראשונים של חיבור נכנס ומעביר כל מה שאינו הפרוטוקול שלו ל-backend של HTTPS, ולשם כך נועדה ההוראה port-share. ה-backend הוא שרת אינטרנט רגיל עם TLS מופעל, שנקרא לפי מארח ופורט בהוראה הזו ולא לפי URL.
port-share 10.0.0.5 8080
במכונה שבה האתר מחזיק בכתובת פרטית שנייה, השורה הזו שולחת תעבורה שאינה VPN אל 10.0.0.5:8080, ולכן המארח הווירטואלי של HTTPS חייב להיות קשור שם והחומה חייבת לאפשר את הקפיצה המקומית. שרת האינטרנט חייב לסיים TLS בעצמו, מפני שהבייטים המגיעים הם לחיצת היד המקורית של הדפדפן ושום דבר בדרך לא פענח אותם. כוונו את ההוראה למאזין HTTP פשוט והדפדפן יקבל שגיאת שיטה לא חוקית, שנקראת כמו אתר שבור ולא כמו backend שהוצב שלא במקומו. ההוראה קיימת רק במצב שרת TCP, ולמאזין UDP אין זרם לבדוק.
מפני שתהליך ה-VPN מקבל כל חיבור, אפליקציית האינטרנט רואה את הבקשה המועברת מגיעה מאחת מכתובות המארח עצמו ולא מהמבקר. כל מה שצריך את כתובת הלקוח האמיתית תלוי בתמיכה בפרוטוקול PROXY ב-backend או בחזית שמוסיפה אותה. העברת ה-backend לכתובת מקומית אחרת אינה מחזירה את כתובת המבקר; היא רק משנה איזו מכתובות המארח האתר רושם. כתבו את המגבלה הזו בהערות הפריסה לפני שדוח אנליטיקה יעלה את השאלה.
פרוקסי הפוך הוא הכלי הלא נכון; נתב שכבה רביעית אינו
פרוקסי הפוך של HTTP מסיים TLS כדי לקרוא בקשות, כלומר הוא אינו יכול להעביר זרם OpenVPN בלי לגעת בו. נתב שכבה רביעית שמעביר לפי SNI או לפי בדיקת החבילה הראשונה יכול לעמוד לפני שניהם, בתנאי שהוא אינו מסיים את הסשן שה-VPN תלוי בו. שני ההתקנים נראים דומים בתרשים ומתנהגים אחרת לגמרי בשקע.
Access Server המסחרי מגיע עם הגדרות שיתוף פורט משלו, והן אינן מתמפות אחת לאחת להוראה של הקהילה. זהו את המוצר והגרסה לפני התאמת מדריך שנכתב לאחר. הגדרה שהועתקה ומתעלמים ממנה בשקט גרועה מאין הגדרה, מפני שרשימת המאזינים עדיין נראית סבירה אחריה.
בדקו את האתר ואת המנהרה כשני נתיבים נפרדים
טענו את האתר וחברו את המנהרה, ואז קראו שוב את רשימת המאזינים כדי לראות איזה תהליך מחזיק ב-443 כעת. דף שנטען אינו מוכיח דבר על ה-VPN, ומנהרה שמתחברת אינה מוכיחה דבר על האתר, אף ששניהם משתמשים באותו מספר. שלוש הפקודות למטה בודקות את השקע המשותף, את נתיב האינטרנט ואת שירות ה-VPN בסדר הזה.
ss -lntup 'sport = :443' curl -sI https://vpn.example.com/ | head -n 1 journalctl -u openvpn-server@server -n 20
השוו את כתובת הלקוח ביומן הגישה של ה-backend לזו שביומן ה-VPN באותו רגע. אם האתר רושם כל מבקר כמארח עצמו, ההעברה עובדת וטיפול הכתובת לא. אם שני היומנים שותקים, החזית מעולם לא מסרה את החיבור. כך או כך, רשימת המאזינים מכריעה מי מקבל את השקע, וזו העובדה שצריך לאשר לפני שתשנו קובץ נוסף.
השאירו את מפת המאזינים ליד התצורה כדי שהאדם הבא שייגע ב-443 ידע איזה תהליך מקבל ולאן עבר הפרוטוקול האחר. אשרו בעלות אחרי השינוי במקום לסמוך על מה שהעריכה נועדה לעשות.