הצפנת מנהרת WSS נעצרת במסיים ה-TLS, לא באפליקציה
כתובת wss:// מוכיחה TLS בקפיצה אחת. האם למטען יש הצפנה משלו תלוי במה הלקוח מכניס בפנים ובמי שמסיים את ה-TLS הזה.
למנהרה הנישאת בתוך WebSocket מאובטח יש בדיוק את ההצפנה שהלקוח הכניס לתוכה, ולא יותר. סכמת wss:// אומרת ש-TLS מגן על חיבור אחד בקפיצה אחת. היא אינה אומרת דבר על האם הבייטים בתוך הודעות WebSocket מוגנים בנפרד, וההבחנה הזו היא שקובעת מי יכול לקרוא את התעבורה שלך כשמשהו באמצע מסיים TLS.
שתי שכבות שנראות כאחת
WebSocket מאובטח הוא TLS שמעליו מתבצע לחיצת יד של WebSocket, כפי ש-RFC 6455 מתאר בסעיפי החיבור והאבטחה שלו. שכבת TLS מאמתת את השרת ומצפינה את הזרם, ואז שכבת WebSocket ממסגרת את מה שהאפליקציה מחליטה לשלוח.
אלה שתי החלטות בלתי תלויות, ותרשים שמצייר מנעול אחד על כל המסלול מסתיר את השנייה. שאלו מי מסיים את חיבור ה-TLS. אחר כך שאלו מה הלקוח מכניס בתוך כל הודעה. כל השאר על הפריסה נובע משתי התשובות האלה.
עיצוב A: התעבורה היא ההצפנה היחידה
בעיצוב הפשוט יותר, הלקוח לוקח מנות IP גולמיות ועוטף אותן בהודעות WebSocket. שום דבר בפנים אינו מוצפן, ולכן הרכיב שמחזיק את הפעלת ה-TLS קורא מטענים בטקסט גלוי. כשהרכיב הזה הוא שרת המנהרה שלך עצמך, זו נקודת הקצה המיועדת והעיצוב עקבי, כי השרת ממילא היה רואה את התעבורה.
זה הופך לסידור אחר כשפרוקסי בדיקה יושב על המסלול ומסיים TLS עם תעודה שהלקוח סומך עליה. הפרוקסי הזה מחזיק כעת את אותו טקסט גלוי שהשרת היה מחזיק, ושום כמות של מסגור WebSocket לא משנה זאת. מאגר האמון של הלקוח הכריע את התוצאה הזו הרבה לפני שהמנהרה נפתחה, כי הוא בחר לקבל את התעודה הזו עבור השם הזה. הפרוקסי גם רואה את המארח המבוקש ואת גודל כל הודעה, וזה מספיק כדי לקחת טביעת אצבע של פעילות רבה בלי לפענח דבר נוסף.
עיצוב B: המטען נושא את המפתחות שלו
בעיצוב השני, הלקוח מצפין ומאמת את מנותיו בפרוטוקול VPN שיש לו זהות עמית משלו וחילופי מפתחות משלו, ואז נושא את התוצאה בתוך הודעות WebSocket. סיום ה-TLS החיצוני כאן חושף טקסט מוצפן, לא תעבורה. הפרוקסי יכול לראות גדלים ותזמון של הודעות, ושום דבר אחר במטען. זו חשיפה קטנה בהרבה, ועדיין אלה מטא-נתונים שראוי לציין בסקירה ולא לגרש ביד.
נקודות הקצה של הפרוטוקול הפנימי עצמו עדיין רואות טקסט גלוי, וזו הנקודה של הסידור וגם גבולו. אם רכיב בנקודת הקצה מורשה לקרוא נתונים לפני ההצפנה או אחרי הפענוח, השכבה הנוספת אינה מגבילה אותו. מפתחות, והתוכנה שמטפלת בהם, נשארים הגבול שחשוב.
תווית VPN, סמל לקוח מוכר או עמוד שיווק אינם הוכחה שהעיצוב הזה קיים. קריאת תבנית המטען היא הוכחה.
עקבו אחרי היכן הטקסט הגלוי באמת מופיע
סכמת ה-URL נותנת לכם עובדה אחת, אז קחו את השאר מהממשקים. הריצו את הבדיקות שלמטה לפי הסדר, כי כל אחת מצמצמת את הבאה:
ss -tnp | grep -E ':(443|8443)\b' ip -br link show type tun openssl s_client -connect vpn.example.net:443 -servername vpn.example.net -brief tcpdump -ni tun0 -c 5 -X
התחילו בחיבור החיצוני. הפעלה אחת ארוכת-טווח של TCP אל פורט ה-TLS היא איך שנראה נושא WebSocket, והפעלה שנייה אל מארח לא קשור ראויה להסבר לפני שתסתכלו עמוק יותר. אחר כך מצאו את ממשק המנהרה בלקוח, כי התקן tun או tap אומר לכם שהלקוח מטפל במנות IP במקום לשמש פרוקסי לזרם אפליקציה אחד.
הלכידה בממשק המנהרה מכריעה בדרך כלל את שאלת המטען. כותרות קריאות שם אומרות שהמנות הפנימיות מעולם לא הוצפנו בנפרד, בעוד שמטענים בעלי אנטרופיה גבוהה אומרים שכן. חזרו על הלכידה בממשק החיצוני והשוו בין השניים: אם שניהם נראים אקראיים, השכבה הפנימית עושה עבודה שהחיצונית אינה יכולה לבטל.
סקרו את האמון שנתתם בפועל
תעודת שורש ארגונית מותקנת היא עובדה על מאגר האמון של הלקוח, לא הצהרה על מה שפרוקסי כלשהו מתעד או בודק. קבעו את המדיניות הפרוסה ואת נתיב החיבור האמיתי במקום להסיק התנהגות מנוכחותה של CA.
בציוד מנוהל, שאלו את המנהל איזה רכיב מסיים TLS, האם הלקוח מאמת תעודה מוצמדת או תעודה ציבורית, ומהי תבנית המטען. שלוש התשובות האלה מייצרות ממצא שתוכלו להגן עליו אחר כך.
כתבו את התוצאה כגבול ולא כפסק דין. "TLS מסתיים בפרוקסי הבדיקה, והמטען הפנימי מוצפן בנפרד במפתחות שרק נקודות הקצה מחזיקות" היא הצהרה ניתנת לבדיקה ששורדת החלפת ספק. "WebSockets מאובטחים" לא.