עמית ישן אחד כופה TLS 1.0: הגבילו את החריגה, לא את המארח
מכשיר אחד שתקוע על TLS 1.0, או תעודה ישנה של ספק, יכול לכפות רצפה חלשה יותר. הגבילו את החריגה, ואז מדדו מה באמת נוהל משא ומתן.
מכשיר ישן אחד מופיע, נכשל בהתחברות, והתיקון הנראה המהיר ביותר הוא להחליש את כל המארח עד שהחיבור יצליח. העסקה הזו בלתי נראית ברגע וקבועה בפועל, כי אף אחד לא מסיר רצפה שסוף סוף עובדת. שתי תקלות שונות מאוד יוצרות את הלחץ, ורק אחת מהן עוסקת בכלל בצפנים. מיינו קודם את התקלה, ואז הניחו את החריגה במקום שממנו היא לא יכולה להתפשט.
פצלו את הכשל לשניים לפני עריכת הנחיה
שורה ביומן השרת על היעדר צופן משותף, או על גרסת פרוטוקול לא נתמכת, מגיעה מערוץ הבקרה: שני הקצוות לא הצליחו להסכים כיצד להגן על המשא ומתן עצמו. לעומת זאת, השורה של הלקוח שאומרת שלא מופעלת שום שיטה לאימות תעודת שרת מגיעה ממקום אחר לגמרי, כי אותו לקוח בכלל לא בודק מי ענה. החלפת צופן נתונים לא עושה דבר במקרה השני, והוספת בדיקת תפקיד לא עושה דבר בראשון.
קחו את השורה הכושלת המוקדמת ביותר מכל צד ולא את השורה האחרונה לפני הניתוק, כי האחרונה היא בדרך כלל תוצאה. לאחר מכן קבעו איזה קובץ הלקוח באמת פתח: פרופיל מיובא קיים לעתים קרובות פעמיים תחת שמות תצוגה שונים, ועריכת ההעתק שאיש לא קורא מייצרת אי-שינוי משכנע. תהליך שרץ שומר את ההגדרות שאיתן התחיל, כך שקובץ שמור אינו קובץ טעון. הפקודות שלמטה מציגות את המשא ומתן של הלקוח לצד תמונת השרת של אותו ניסיון.
openvpn --config <profile>.ovpn --verb 4 2>&1 | head -n 40
journalctl -u [email protected] --since '-10 min' | grep -iE 'cipher|tls|verify'
מאזין שני הוא המקום הכנה לרצפה חלשה יותר
כשהמכשיר מגיע רק עד TLS 1.0 עם ערוץ נתונים מלפני 2.5, השרת חייב להציע רצפת ערוץ בקרה נמוכה יותר וצופן נתונים שהלקוח הישן מזהה. הנחיית הגיבוי קיימת בדיוק עבור אותו עמית, בעוד רשימת הצפנים משאירה לקוחות מודרניים על חבילות מודרניות. שתי ההנחיות שייכות למאזין ולא למשתמש או לחיבור, ואין אפשרות לכל לקוח שמצמצמת אותן לאחר מכן. לכן מכשיר ישן אחד בפורט הראשי הוא החלטה על כל עמית שחולק אותו.
היכן שהפלטפורמה מאפשרת, הריצו את המאזין הישן כמופע נפרד משלו בפורט נפרד, אפשרו את הפורט הזה רק מכתובת המכשיר, והשאירו את השירות הראשי בשקט. רשמו למה המאזין השני קיים, בקובץ שנושא את התצורה שלו, כי ניקוי עתידי יקרא אותו אחרת כשאריות. הפיצול שווה משהו רק אם הרצפה החלשה יותר נגמרת במקום שבו המכשיר נגמר.
tls-version-min 1.0
data-ciphers AES-128-GCM:AES-256-GCM:AES-256-CBC
data-ciphers-fallback AES-256-CBC
מה תעודה ישנה של ספק באמת שוברת
שגיאת האימות היא קישור תפקיד חסר: בלעדיו הלקוח יקבל כל תעודה שמשתלשלת ל-CA מהימן, בין אם הונפקה לשרת ובין אם לא. קשרו קודם את התעודה לתפקיד השרת, והתייחסו לקישור כדרישה ולא ככפתור כוונון. רק פרופיל שעדיין נכשל אחרי השלב הזה סובל מבעיית תעודה אמיתית.
תעודה ישנה של ספק שגודל המפתח או אלגוריתם החתימה שלה כבר לא עומד במדיניות ברירת המחדל של OpenSSL היא המקרה לשינוי מוגבל של רמת האבטחה בערוץ הבקרה. הורדת הרמה שם לא מכבה את האימות, ואסור לשלבה לעולם עם CA ריק, הגדרת אימות מושבתת או שם מארח שלא נבדק. החזיקו את השורה בתוך הפרופיל היחיד שזקוק לה; ייצוא גלובלי של תצורת OpenSSL מרופית היה נותן אותה הקלה לכל תוכנית במכונה.
remote-cert-tls server
tls-cipher "DEFAULT:@SECLEVEL=0"
קראו את הערכים המנוהלים, לא את הבאנר
ברמת פירוט 4 שני הקצוות מדפיסים את גרסת ה-TLS והצופן של ערוץ הבקרה שעליהם הסכימו, ואת צופן הנתונים של הסשן. קראו את השורות האלה ולא את באנר האתחול, שמדווח על הצלחה ולא על תנאיה. לאחר מכן חברו לקוח מודרני מחדש למאזין הראשי ואשרו שהוא עדיין נוחת על חבילה מודרנית, כי חריגה שדלפה לתצורה המשותפת נראית כאן ראשונה. הערכים שתעתיקו הופכים לקו הבסיס לסקירה הבאה.
בדקו את המכשיר הישן לבדו: הוא אמור להתחבר, והוא אמור להיות הסשן היחיד ביומנים שמציג את הפרמטרים החלשים יותר. אם עמית שני גם מנהל משא ומתן על החבילה הישנה, החריגה רחבה מהמתוכנן והפיצול של המאזין לא קרה באמת. תעדו את שתי התצפיות ולא רק את המסקנה.
כל חריגה צריכה בעלים ותאריך
חריגה בלי תנאי הסרה הופכת בשקט לברירת המחדל, אז הניחו את המכשיר, הבעלים, הסיבה והתאריך שבו היא נעלמת לצד התצורה שהיא מצדיקה. בלי השורה הזו הרצפה החלשה יותר שורדת את החומרה שנזקקה לה.
החלפת הלקוח, או בקשה מהספק לפרופיל עדכני, היא התוצאה שיש לשאוף אליה; החריגה היא עיכוב ולא עיצוב. כשהמכשיר יוצא משירות, הסירו את המאזין והפרופיל באותו שינוי כדי שאף חצי לא יישאר פועל. דבר מזה לא הופך את הפרמטרים הישנים לבטוחים, הוא רק מונע שמגבלה של מכשיר אחד תהפוך לקו הבסיס של כולם.