ברוכים הבאים למדריך SysSeder על אמון בחבילות ב־Debian וב־Ubuntu.
בפריסת יישומים, בבניית קונטיינרים ובתחזוקת מכונות בענן, apt-get update ו־apt-get install עשויים להיות שלבים קריטיים. הם זקוקים למדיניות אמון מפורשת, ולא להנחה שכל מקור מוגדר בטוח באותה מידה.
הכותרת היא מטפורה, לא דיווח על אירוע חדש שנחשף ואומת. המאמר מסביר אימות ארכיונים ב־APT, יירוט תעבורה, פגיעה במאגרים ושגיאות תצורה, ואז מתרגם את המנגנונים לרשימת בדיקה לצינורות חבילות.
מודל האבטחה של APT: לתת אמון, אבל לאמת
אימות ארכיון ב־APT ו־HTTPS פותרים בעיות שונות. מטא־נתונים חתומים מספקים שרשרת שלמות ואמון במפרסם; HTTPS מוסיף הגנה על התעבורה. אף אחד מהם אינו מוכיח שמפרסם מהימן הפיץ תוכנה בטוחה.
APT יכול לאמת ארכיון שאליו ניגשים דרך HTTP, מפני שמטא־נתונים חתומים ב־OpenPGP מאמתים שרשרת גיבובים. בדרך כלל זהו אימות ברמת הארכיון, לא חתימה נפרדת הנבדקת על כל קובץ .deb. המימוש והאלגוריתמים המתקבלים תלויים בגרסת APT; ראו apt-secure.
- קובץ
Release: כאשר מריציםapt update, APT מוריד קובץ מטא־נתונים בשםReleaseואת החתימה הנפרדת שלו, או קובץRelease.gpgInReleaseעם חתימה משולבת. - חותם מורשה: APT בודק את חתימת
Releaseמול המפתחות המותרים למקור המוגדר. הגדרתSigned-Byמצמצמת את המפתחות המתקבלים; בהיעדרה עשויים לחול מאגרי המפתחות הגלובליים הישנים. - גיבובים קריפטוגרפיים: קובץ
Releaseהמאומת כולל רשימה של קובציPackagesואת גיבובי SHA-256 שלהם. - אימות החבילה: בעת התקנת חבילה, APT מוריד את קובץ
.deb, מחשב את הגיבוב שלו ומשווה אותו לגיבוב בקובץPackagesהמאומת.
כאשר מפתחות החתימה מהימנים, הגיבובים חזקים ונתמכים ובדיקות האימות מופעלות, החלפת בתי החבילה נכשלת בשרשרת הגיבובים המאומתת. הדבר אינו מגן מפני חותם מורשה שנפרץ, מדיניות מאגרים לא בטוחה או מנהל העוקף כשלי אימות.
דרכי הפגיעה: כיצד צינורות APT נכשלים
שלוש קטגוריות שימושיות לבדיקה הן אמון רחב מדי במפתחות, הפרעה לתעבורה ופגיעה במפרסם או במאגר. זה אינו מודל איומים ממצה.
1. זיהום גלובלי באמצעות "מפתח מהימן"
בעבר, הדרך המקובלת להוסיף מאגר צד שלישי, למשל Docker, HashiCorp או NodeSource, הייתה להוריד את מפתח GPG שלו ולהוסיף אותו למאגר האמון הגלובלי באמצעות apt-key add.
מפתח במאגר אמון גלובלי עשוי להתקבל במקורות שאינם מגבילים חותמים באמצעות Signed-By. לכן למפתח שנגנב עלול להיות היקף אימות רחב מהמתוכנן. בנפרד מכך, מאגר צד שלישי מאומת יכול להציע חבילות ששמותיהן קיימים גם בהפצה. הבחירה של APT תלויה בגרסאות, בעדיפויות ובתלויות — לא רק בעצם קיום המפתח.
2. תקיפות אדם־בתווך ושידור חוזר של מטא־נתונים
HTTP חושף את תוכן התעבורה ומאפשר הפרעות בדרך. חתימות הארכיון עדיין מזהות שינוי תוכן לא מורשה, אבל עדכניות וזמינות מחייבות בקרות נוספות; חתימה לבדה אינה מעידה שהמטא־נתונים עדכניים.
APT בודק בדרך כלל את Valid-Until כאשר הארכיון מספק אותו והבדיקה המתאימה מופעלת. לכן הגנה מפני שידור חוזר תלויה במטא־נתונים, בהגדרות המקומיות ובשעון אמין. בהיעדר תפוגה נדרשת מדיניות עדכניות מכוונת. תוקף יכול גם לחסום עדכונים לחלוטין; יש להתריע על רענון שנכשל או התיישן, ולא להשבית אימות רק כדי להעביר בנייה. ראו אפשרויות העדכניות של sources.list.
3. השתלטות על מאגר ושמות מטעים
חשבון מתחזק שנפרץ מסוכן כאשר הוא יכול לשנות קוד, תוצרי שחרור, תצורת מאגר או תהליך חתימה. לא לכל חשבון GitHub או Launchpad יש אוטומטית יכולת לפרסם חבילה חתומה. יש לבדוק את הרשאות השחרור ואת משמורת המפתחות בפועל, ולאמת שמות וכתובות מאגרים מול התיעוד הרשמי במקום מול כתובת דומה ומטעה.
כיצד לאבטח את צינורות APT שלכם
השתמשו בהמשך כתוכנית בדיקה הדרגתית. מַפו מקורות קיימים ובעלים, בדקו שינויים מוצעים בסביבה מבודדת ושמרו תוכנית חזרה לאחור. המאמר אינו משנה מאגרים, מפתחות, חבילות או הגדרות מערכת.
שלב 1: להפסיק להשתמש ב־apt-key add
הימנעו מהוספת מפתחות צד שלישי באמצעות . השתמשו בהנחיות המפרסם הנתמכות ל־apt-key addSigned-By לכל מקור, ובקובץ מפתח ציבורי ייעודי הניתן לקריאה או במפתח מוטמע כאשר הוא נתמך. אל תמחקו מפתחות ישנים לפני שנבדקו כל המקורות התלויים בהם.
Signed-By מגביל אילו מפתחות רשאים לאמת את המטא־נתונים של מקור מוגדר. זו אינה הוראה השומרת שמות חבילות מסוימים למקור זה. יש לבסס את מקור המפתח באמצעות מידע מהימן של המפרסם; הורדת מפתח בלבד אינה אימות עצמאי של בעליו.
דוגמת deb822 המושבתת הבאה ממחישה את הקשר בין מקור לקובץ המפתח שלו. זו אינה הוראת התקנה: מהדורת Ubuntu והארכיטקטורה הן דוגמאות, קובץ המפתח חייב כבר לעבור אימות עצמאי, וכאן לא נכתב קובץ כלשהו. לפני תכנון שינוי יש לבדוק את הוראות מאגר Docker ל־Ubuntu עבור מערכת היעד.
# Illustration only: disabled source, not an installation script.
Types: deb
URIs: https://download.docker.com/linux/ubuntu
Suites: noble
Components: stable
Architectures: amd64
Signed-By: /etc/apt/keyrings/docker.asc
Enabled: no
אם המקור הרשמי של ההפצה מקבל רק את מפתחות הארכיון שלו, מפתח Docker אינו יכול לאמת את מטא־נתוני Release של אותו מקור. הוא עדיין יכול לאמת את מקור Docker המוגדר, שעשוי להציע שמות חבילות חופפים. הגבלת מפתחות מצמצמת את היקף האמון; היא אינה יוצרת ארגז חול לשמות חבילות.
שלב 2: להוסיף הגנת תעבורה של HTTPS כאשר היא נתמכת
העדיפו נקודת HTTPS נתמכת של המפרסם, עם אימות תעודה ושם מארח, תוך שמירת אימות חתימות הארכיון. אל תשכתבו כתובות באופן מכני בלי לבדוק תמיכה. HTTPS מצמצם חשיפה לצפייה בתעבורה ולשינוי פעיל שלה, אך אינו הופך מאגר מורשה וזדוני למהימן.
תעבורת HTTPS מובנית ב־APT מאז גרסה 1.5; חבילה נפרדת בשם אינה דרישת קדם כללית במערכות מודרניות. הדוגמה הבאה היא רק פקודת בירור גרסה לקריאה, ולא פקודה שהורצה עבור המאמר. ראו מדריך תעבורת HTTPS.apt-transport-https
apt --versionשלב 3: לקבע חבילות כדי למנוע שדרוגים לא צפויים
Pinning שולט בעדיפויות לבחירת גרסאות; הוא אינו לבדו הבטחה לבנייה ניתנת לשחזור או מדיניות אבטחה קבועה. בחירת גרסה מדויקת, שמירת תוצרים מהימנים וגיבובי דימויי בסיס יכולים לשפר חזרתיות, אך מחייבים תהליך עדכון מתוכנן כדי לא לחסום תיקוני אבטחה.
להלן העדפה לדוגמה עבור חבילות Docker בשמות מוגדרים; היא אינה מיושמת כאן. בניגוד לכלל Package: * שבמקור, היא אינה מעלה את עדיפותה של כל חבילה במאגר. התאמת origin מציינת את מארח המאגר, לא את שדה Origin החתום ב־Release. ראו משמעות העדפות APT.
# Illustration only; inspect policy and dependencies before any use.
Package: docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin
Pin: origin "download.docker.com"
Pin-Priority: 600
הדוגמה מעדיפה גרסאות של החבילות ששמותיהן צוינו מאותו מארח על פני עדיפות טיפוסית של 500. היא אינה מאמתת את מפתח החתימה, אינה מקבעת גרסאות מדויקות ואינה חוסמת את כל שאר החבילות מהמאגר. יש לבדוק את המדיניות האפקטיבית ואת התלויות בשלמותן; כלל עדיפות אינו גבול אבטחה של מאגר.
אוטומציה של אבטחת APT ב־CI/CD
Lint יכול לאכוף מוסכמות בנייה מסוימות. Hadolint מתעד את DL3008 להתקנות apt-get ללא קיבוע גרסה; אין להניח שהוא מזהה כל ייבוא מפתח לא בטוח או תצורת אמון פגומה. הוסיפו בדיקות מדיניות מפורשות לפקודות מפתחות גלובליות אסורות, לעקיפת אימות ולכתובות מקור לא מאושרות, ובדקו את קלטי הבנייה בפועל. ראו רשימת הכללים של Hadolint.
בדוגמה המקורית היה FROM אחד ולכן היא הייתה חד־שלבית, לא רב־שלבית; זמינותה ובטיחותה של גרסת Redis ההיסטורית לא אומתו. ההחלפה היא תוכנית בדיקה שאינה ניתנת להרצה, לא Dockerfile מוכן לייצור. היא משמרת את רצף הכוונות — דימוי בסיס, כלים נדרשים, אמון מוגבל ב־Redis, רישום מקור, בחירת גרסה מדויקת וניקוי — בלי להמציא גרסה או גיבוב עדכניים.
תוכנית בדיקת בנייה שאינה ניתנת להרצה
1. בחרו דימוי בסיס נתמך ורשמו את הגיבוב המאושר שלו.
2. זהו רק את הכלים שהבנייה באמת זקוקה להם.
3. אמתו את מפרסם Redis, כתובת המאגר ומקור מפתח החתימה.
4. קשרו את המקור למפתח הייעודי שלו באמצעות Signed-By.
5. ודאו שהמהדורה והארכיטקטורה מתאימות לדימוי היעד.
6. בחרו גרסה מאושרת וזמינה כעת של redis-tools ואת התלויות שלה.
7. שמרו את apt-get update ואת ההתקנה המתאימה באותו שלב RUN.
8. הסירו את /var/lib/apt/lists/* באותו שלב כאשר הדבר מתאים.
9. הגבילו מצב לא אינטראקטיבי לפעולה הזקוקה לו.
10. בדקו את הדימוי ורשמו את מלאי החבילות שנבחר בפועל.
11. הגדירו לוח זמנים לבנייה מחדש ולעדכוני אבטחה; שנו קיבועי גרסאות במכוון.
12. השתמשו בשלבי בנייה והרצה נפרדים רק כאשר היישום זקוק להם.
מחיקת רשימות החבילות שהורדו באותה שכבת יכולה לצמצם את גודל הדימוי. היא אינה מוכיחה שהחבילות או המטא־נתונים היו מהימנים, ואינה מאלצת בנייה מאוחרת מהמטמון לרענן אותם. שלבו עדכון והתקנה באותו שלב ונהלו במכוון את עדכניות הבנייה והמטמון; ראו הנחיות הבנייה של Docker.RUN
סיכום: להישאר ערניים
אבטחת APT היא משימה מתמשכת של ניהול אמון. מפתחות מוגבלים, תעבורה מאומתת, בחירת חבילות שנבדקה ומטא־נתונים עדכניים מצמצמים סיכונים מסוימים. הם אינם מסלקים פגיעה במאגר, שחרורים מורשים וזדוניים, חבילות פגיעות או כשלי זמינות. לצד התצורה יש לשמור על בעלות ברורה, ניטור ונתיב התאוששות שנבדק.
איך נראית תבנית ה־Dockerfile של הצוות שלכם? האם סקריפטי התשתית־כקוד עדיין משתמשים ב־apt-key add המיושן? כתבו בתגובות או שתפו עצות לאבטחת תלויות ברמת מערכת ההפעלה ב־CI/CD!
עד הפעם הבאה, הגדירו אמון בחבילות במפורש, בחנו קיבועי גרסאות ושמרו על נתיב עדכון שנבדק. בנייה נעימה!