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

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

שתי בקרות שעונות על שאלות שונות

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

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

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

מה apt באמת מאמת

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

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

apt-get update
apt-cache policy
apt-config dump | grep -iE 'AllowInsecure|AllowDowngrade'

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

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

מה dnf5 בודק בנפרד

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

dnf5 config-manager --dump 2>/dev/null | grep -iE 'gpgcheck|repo_gpgcheck'
rpm -q --qf '%{NAME} %{SIGPGP:pgpsig}\n' bash

שאילתת החבילה מראה איך נראים מטא-נתוני החתימה של העותק המותקן, וזהו בדיקת מציאות שימושית מול קובץ תצורה שמצהיר על הקפדה. מה שהיא לא אומרת לכם הוא המדיניות הנתמכת של ההפצה, ואותה צריך לפעול לפיה ולא לפי הוראה כללית «הפעילו GPG» מהפורום.

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

מה המנהרה מוסיפה ומה לא

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

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

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

אבחנו את הגבול שנכשל

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

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

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

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