מדוע ניהול מפתחות SSH נשבר כשהצוות גדל
כל עוד יש עשרה שרתים וחמישה מהנדסים, הגישה חיה בתיקיות אישיות ובהתכתבויות. מפתח מועתק למכונה חדשה, הישנה נשארת ברשימת המורשים, ואף אחד לא יכול לנקוב במספר המדויק של אנשים שנכנסים כעת לשרתי הייצור.
לאחר מכן ניהול מפתחות SSH הופך לטקס ידני. הענקת גישות ללא בקרה מתבצעת דרך צ'אט: מפתח ציבורי מודבק לקונפיגורציה באופן ידני, עובד שפוטר נשאר ברשימה, כי אף אחד לא מחק את השורה שלו.
מפתחות ציבוריים נשכחים בשרתים מצטברים במשך שנים — תחילה מסביבות בדיקה, אחר כך מקבלנים, ואחר כך מאנשים שכבר לא עובדים בחברה. המלאי אינו תואם את המציאות: בכמה מארחים יש גישה, באחרים אין.
רוטציה ידנית של מפתחות נדחית: היא משמעה עצירת עבודה בלילה וסיכון להפיל את פריסת הגרסה. ככל שדוחים אותה יותר, כך גדל החלון שבו מפתח שנחשף נשאר פעיל. ביקורת גישה לשרתים בסכימה כזו בלתי אפשרית — אין מקור אמת שמראה למי יש גישה, לשם מה היא ניתנה ומי אישר אותה.
שורש הבעיה אינו ב-SSH, אלא בהיעדר מקור אמת יחיד ואוטומציה של ההענקה. כל עוד מפתחות מופצים ביד, כל בדיקה נשארת סריקה חד-פעמית, והרוטציה — אירוע חירום. נבחן כיצד לקשור הענקות לתפקידי המהנדסים, להוציא מפתחות ציבוריים לרישום מנוהל ולהפוך את הרוטציה למתוכננת — עם Ansible ו-Vault.
מה נותן מעגל אחיד להענקה ולשלילת גישות
כל עוד גישות ניתנות ידנית, מפתח חי יותר מהמשימה שלשמה ניתן. עובד עוזב, קבלן מסיים פרויקט, והמפתח הפרטי נשאר פעיל — ואף אחד כבר לא יגיד על אילו מארחים הוא רשום. מעגל אחיד משנה זאת ברמת המכניקה: מפתח ניתן לתקופה ומוסר בפעולה אחת, ולא בסיבוב בין מכונות.
המעגל מחזיק מלאי גישות: מי קיבל, לאילו מארחים, עד איזה תאריך. ההענקה מצטמצמת לפקודה אחת — תפקיד Ansible מפיץ את החלק הציבורי למכונות היעד ומסיר עריכות ידניות בשרתים. זמן הענקת הגישה יורד משעות של התכתבות לדקות, והשלבים למהנדס חדש ולקבלן מפסיקים להיות שונים.
שלילת גישה — גם כן פעולה אחת: הרשומה יוצאת מהמלאי, וקונפיגורציית המארחים מובאת למצב ללא המפתח הזה. בעבר תיקונים כאלה נעשו ידנית בגלים על כל שרת, ובחלק מהמכונות השורה הנשכחת המשיכה להתקיים.
חלון הגישה של הקבלן נקבע מראש ונסגר מעצמו לפי לוח השנה, ולא לפי מכתב של מישהו "סיימנו". תוקף המפתח קשור למשימה: הסתיים — הגישה הפסיקה לעבוד בכל הצי, כולל מכונות שאיש לא זכר.
כך נעלם סוג שלם של כשלי גישה — מפתחות "תלויים" של מפוטרים וקבלנים, עותקים של מפתחות פרטיים, גישה שנותרה לאחר החלפת תפקיד. חלק הפעולות הידניות לכל גישה מצטמצם ליחידות במקום עשרה שלבים: המהנדס מתאר כוונה, ולא עורך קבצים בשרתים.
גישות לאחסון והענקה של מפתחות גישה
אופן הענקת הגישות קובע מה יהיה עליכם לעשות עם פיטורי מהנדס, פריצה למכונה או הוצאת שרת משירות. יש בדיוק ארבע אפשרויות, והן נבדלות לא בנוחות, אלא במקום שבו נשמר המפתח הפרטי ובמי שאחראי לשלילתו.
| אפשרות | מתי מתאימה | מגבלות |
|---|---|---|
קבצי authorized_keys בשרתים |
צי של כמה מכונות, צוות של עד חמישה אנשים | מפתחות מתפשטים כעותקים, שלילה — סיבוב ידני בכל המארחים |
| מאגר סודות אחיד | נדרש מקור אמת אחד ויומן של מי קיבל מה | בשרתים נשארים אותם מפתחות סטטיים, רוטציה — משימה נפרדת |
| הפצה דרך כלי ניהול קונפיגורציה | הצי כבר מתואר באופן דקלרטיבי, הרכב המארחים ידוע | הסוד עובר דרך מאגר קוד או משתנים, יש להגן על התיאורים עצמם |
| תעודות קצרות מועד | הצוות גדל, גישה ניתנת לשעות ולמשימה | נדרש מרכז אישורים מהימן ובדיקתו ברגע ההתחברות |
הענקת גישות מרוכזת — זה לא "להתקין מאגר", אלא לקשור בין חשבון המשתמש, התפקיד ותוקף המפתח. אז השלילה הופכת לפעולה אחת במקום חיפוש קובץ בעשרות שרתים, והרוטציה מפסיקה להיות חירום. בפועל משלבים בין האפשרויות: מאגר וכלי ניהול קונפיגורציה סוגרים את ההענקה, תעודות — את תוקף הגישה.
שלבי הטמעה: מספירת מלאי ועד מסירה
סדר העבודות הוא הפוך מהרגיל: תחילה מבררים אילו גישות קיימות באמת, ורק אחר כך משנים משהו. לעתים רחוקות אדם אחד יוצר מפתחות — הם מצטברים ממשימות, ניסויים ועובדים שפוטרו, ולכן התמונה בפועל כמעט תמיד אינה תואמת את התיעוד.
-
ספירת מלאי גישות. אוספים את כל נקודות הכניסה:
authorized_keysבשרתים, מפתחות בקונפיגורציות פריסה, במכונות של מהנדסים ובמערכות בניית תוכנה. עבור כל אחד מגדירים בעלים, ייעוד ותאריך כניסה אחרון — מה שלא מאושר בפעילות, עובר להסרה. -
סכימת תפקידי גישה. תפקיד מתאר משימה, לא אדם: סט שרתים, תוקף ורמת הרשאות. גישה לפרודקשן אינה עוברת בירושה מסביבת הבדיקות באופן אוטומטי.
-
הגדרת הנפקת מפתחות. פרטי הגישה מונפקים על ידי מאגר הסודות, ולא על ידי עמית דרך מסנג'ר. המפתח מקבל תוקף ונשלל אוטומטית עם פיטורים או החלפת תפקיד — אין צורך לעבור ידנית על שרתים.
-
מעגל ניסוי. משנים את הסכימה בקבוצת שרתים אחת ובוחנים כיצד היא מתפקדת בעבודה יומיומית: מי לא הצליח להיכנס, לאילו שירותים לא הספיקו הרשאות, כיצד מתבצעת שלילה מתוכננת.
-
העברת שאר המערכות. מחברים את המעגלים בזה אחר זה, מפתחות ישנים נשארים לזמן המעבר, ואחר כך מוסרים מ-
authorized_keysעם בדיקה שבפרק הזמן הזה לא היו בהם כניסות. -
מסירת נוהל תפעול. מעבירים לצוות את מחזור החיים של הגישה: כיצד לבקש, להנפיק ולשלול, מי אחראי, כיצד לטפל באירועים. בדיקות תקופתיות מתועדות בנפרד — אחרת הסכימה מתדרדרת בחזרה תוך חודשיים.
תבניות תפקידים, מדיניויות גישה ונוהלי רוטציה
התוצאה של העבודה היא לא צומת מוגדר, אלא סט ארטיפקטים שלפיו הצוות בעצמו מנפיק ושולל גישות. מהנדס חדש מקבל מפתח והרשאות בהרצה אחת של תפקידים, עזיבת עובד סוגרת גישה בדקות, ולא בימים של חיפוש ברשומות של אחרים. להלן מה בדיוק נשאר במאגר הקוד ובתיעוד שלכם.
- תיאור תפקידים וקבוצות גישה: בעל שירות, תורן, קורא לוגים — עם קישור לצמתים ספציפיים ולרמות הרשאה, ולא "מנהל / לא מנהל" מופשט.
- מדיניויות גישה: למי ולכמה זמן מונפק מפתח, מה נחשב לחריגה מהתבנית, מי מאשר את החריגה וכיצד היא מתועדת.
- קונפיגורציות הנפקת מפתחות: תפקידי אוטומציה ותבניות שיוצרות זוג, מפיצות את החלק הציבורי לצמתים הנדרשים ומונעות סטייה של הרשאות על קבצים ותיקיות.
- נוהל רוטציה: תוקף המפתח לכל סוג גישה, סדר החלפה מתוכננת, חלונות שבהם ההחלפה אינה שוברת את הפריסה, וכללים לשלילה לא מתוכננת.
- הנחיות לצוות: תרחישים שלב-אחר-שלב — לחבר מהנדס חדש, לשלול גישה עם פיטורים, לפעול בחשד לחשיפת מפתח.
- סכימת הענקה ושלילה: המסלול מהבקשה ועד הופעת המפתח הציבורי בצמתים ועד הרשומה ביומן — כדי שניתן יהיה לבדוק כל פעולה בדיעבד.
- רשימת תיוג לקבלה ודיווח: אילו אירועים מתועדים, כיצד לוודא שלא נותרו גישות מיותרות, ולפי אילו בדיקות אתם מקבלים את המעגל ללא השתתפותנו.
מקרה בוחן: חלון הגישה הצטמצם משבועות לדקות
אלינו הגיע צוות מוצר של 40 מהנדסים: גישה לשרתים ניתנה ידנית, והמפתחות חיו בהתכתבויות, במאגרים אישיים ובמכונות עבודה ישנות. לא היה רישום אחיד, ולכן עם פיטורים איש לא יכול היה לומר כמה עותקים של המפתח נותרו בעולם. עובד חדש חיכה לגישה כמה ימים — לפעמים שבוע, אם המאשר היה בנסיעה.
תחילה אספנו מלאי: עברנו על השרתים, השווינו מפתחות פתוחים לאנשים וראינו שלכל מהנדס יש 6–8 עותקים. לאחר מכן הקמנו רישום גישה אחיד והעברנו את ההנפקה לתרחישים אוטומטיים של Ansible — המפתח נוצר עבור אדם מסוים, מקבל תוקף, והחלק הסגור לא עוזב את מכונת העבודה שלו. חשבונות וסודות נשמרים באופן מרוכז, הרשאות ניתנות באמצעות תפקיד, ולא בהעתקת קובץ בצ'אטים.
מדדים לפני ואחרי
חיבור מהנדס חדש הצטמצם מ-3–5 ימי עבודה ל-15–20 דקות כולל בדיקת הרשאות. סגירת גישה לאחר עזיבה — משבועות לפעולה אחת: המפתח נשלל מהרישום ומפסיק לעבוד בכל הצמתים בבת אחת. מספר עותקי המפתחות לאדם ירד מ-6–8 לאחד.
בנפרד הגדרנו רוטציה: מפתחות מוחלפים לפי לוח זמנים, וזו כבר לא פעולה ידנית עם סיבוב בין שרתים. הרישום מראה למי איזו גישה יש ומתי היא שימשה לאחרונה — ועל זה נבנות הבדיקות השוטפות.
מה לעשות אם מפתחות כבר חולקו לשרתים ולאנשים?
תקופת מעבר היא לא החלפת מפתחות חד-פעמית, אלא מצב שבו ישנים וחדשים פועלים במקביל. משימת המיגרציה היא לא לשבור את מה שכבר עובד, ולקבל סימן נצפה שמראה שהגישה הישנה אינה נחוצה עוד. כל עוד אין סימן כזה, כל ניתוק הופך להגרלה עם סיכון להשבתה.
הכול מתחיל באיסוף עובדות, ולא ביצירת מפתחות חדשים. מיומני הכניסה נשלפת הצירוף "טביעת אצבע — חשבון — שרת — תאריך כניסה מוצלחת אחרונה". מיד רואים מפתחות מתים, מפתחות בלי כניסות בפרק הזמן המוסכם, ואלה שניגשים לעשרות מכונות בבת אחת. לאחר מכן בוחרים מסלול מיגרציה.
| מסלול מיגרציה | מתי מתאים | מגבלות |
|---|---|---|
| גישה מקבילה עם חלון | השבתה קריטית, המעגל גדול | נדרש תאריך סגירה נוקשה, אחרת תקופת המעבר נמשכת ללא הגבלה |
| בהדרגה, בקבוצות שרתים | הצי מחולק לפי סביבות ותפקידים | בלי רישום תפקידים הולך לאיבוד מי נכנס לאן |
| ניתוק לפי לוח זמנים | מעגל קטן או חשד לפריצה | הסיכון הגבוה ביותר להשבתה, נדרש תורן וחזרה מהירה לאחור |
הנפקה מחדש של מפתחות קיימים בנויה כך: החלק הפרטי לא עוזב את מכונת המהנדס, החלק הציבורי מופץ באמצעות קונפיגורציה — Ansible מעביר אותו לשרתים מתוך רישום התפקידים. תאימות לאחור נשמרת בכך שהמפתח הישן נשאר ברשימת המורשים כל עוד יש בו כניסות.
הסיכון להשבתה מוסר באמצעות חזרה לאחור: המפתח הישן מוחזר לשרתים במשימה אחת, וחלון המעבר נקבע לשעות העבודה, כאשר הבעיה נראית מיד, ולא בלילה. מדדי תקופת המעבר — שיעור הכניסות עם מפתחות חדשים, מספר הישנים שנותרו ותאריך הניתוק הכפוי.
ספקות טכניים: תאימות, חזרה לאחור וביקורת
הנפקת מפתחות מרוכזת אינה מחייבת לעדכן את כל הצי ביום אחד. בצמתים עם ענפים ישנים של OpenSSH נשאר authorized_keys סטנדרטי עם סמן שיוך המפתח, מארחים חדשים מועברים לתעודות קצרות מועד — שני המסלולים פועלים במקביל עד שהמלאי יתכנס. תנאי חובה אחד: גישת כתיבה מנוהלת לקונפיגורציית sshd ותיעוד כל שינוי ביומן.
להלן הספקות שמהנדסים מעלים לרוב לפני ההתחלה: מה יקרה בעת תקלה, כיצד מאושרת השלילה וכיצד לא לערבב גישת קבלנים עם צוותים פנימיים.
האם הסכימה תעבוד על שרתים ישנים?
כן. עבור צמתים שבהם אין לשנות את הקונפיגורציה, תפקיד Ansible מפיץ מפתח עם תגית בעלים ותוקף — לפי התגית אחר כך רואים של מי הגישה שמונחת על המארח ומתי היא פגה. צמתים כאלה מסומנים במלאי כמורשת ונכנסים לתוכנית המיגרציה, אך אינם חוסמים את שאר הצי.
מה קורה בעת תקלה וכיצד נראית החזרה לאחור?
לפני השינוי נלקחת העתקה של הקבצים והקונפיגורציה הנוכחיים, מצב המארח נלקח מהמלאי, ולא מעריכות ידניות. חזרה לאחור — העלאה מחדש של הגרסה הקודמת והשוואה חוזרת: דקות במקום סיבוב ידני.
כאשר מאגר הסודות אינו זמין, הנפקת מפתחות חדשים נעצרת, מפתחות שכבר הונפקו ממשיכים לעבוד, והגישה לא נקטעת.
כיצד מאשרים שהגישה אכן נשללה?
לא באמצעות ייצוא מהפאנל, אלא בבדיקה על המארחים עצמם: השוואת תוכן authorized_keys והתעודות הפעילות עם הרשימה המעודכנת. הדוח מראה היכן המפתח עדיין מתקבל; כל אי-התאמה — משימה עם אחראי ומועד.
כיצד מופרדת הגישה של קבלנים?
ברמת התפקידים: צוותי קבלנים מקבלים תעודות קצרות מועד ורק למעגל המוסכם, פנימיים — דרך התפקידים שלהם. קבלן אינו יורש את הרשאות העובד, ועם סיום העבודה הגישה שלו מכובה בפעולה אחת. מי, מתי, לאילו מארחים ולפי בקשתו של מי קיבל גישה — כל זה נשאר ביומן ההנפקה.
נדון במשימה ונחזור עם הערכה ותוכנית
כדי לחזור עם הערכת היקף העבודה, ולא עם משאלות כלליות, אנחנו צריכים נתוני מקור על התשתית. תארו את המשימה בצורה חופשית — זה מספיק כדי להתחיל בניתוח. ככל שהתמונה מלאה יותר, כך תוכנית היישום מדויקת יותר ופחות סבבי הבהרות.
- רשימת שרתים ותפקידים: מי נכנס ולאילו מכונות, היכן נותרו חשבונות משותפים;
- כיצד מפתחות מונפקים כעת — ידנית, בסקריפטים, דרך מאגר משותף או כקובץ במאגר קוד;
- מלאי מפתחות: כמה נמצאים בשימוש, האם יש ללא בעלים, שפג תוקפם וכפולים;
- האם כבר קיים מאגר סודות או הנפקה מרוכזת ומה נמצא בו;
- אילו מערכות במעגל: סוכני בנייה, מארחי באסטיון, עננים, ציוד רשת;
- דרישות לרוטציה ולביקורת: תוקף מפתחות, מי אמור לראות את יומן הגישות;
- מגבלות: חלונות תחזוקה, מקטעים מבודדים, גישות של קבלנים חיצוניים.
בשיחה עם מהנדס נברר את טופולוגיית הגישות, סדר הרוטציה ומקומות שבהם האוטומציה נשברת מול חריגים ידניים. לאחר מכן נחזור עם תוכנית יישום: שלבים, סדרי עדיפויות לפי מעגלים, סדר חזרה לאחור ומה נדרש מצדכם בכל שלב.
תארו את המשימה — נחזור עם הערכת היקף העבודה ותוכנית יישום.







