הגנת שרת SSH: הגדרת sshd_config לגישה מאובטחת

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

היכולות שלנו:

שאלות נפוצות

העבודות האחרונות

  • פיתוח אפליקציית ווב עבור FEEDME
    פיתוח אפליקציית ווב עבור FEEDME
    1359
  • פיתוח חנות מקוונת לחברת FURNORO
    פיתוח חנות מקוונת לחברת FURNORO
    1330
  • עיצוב לוגו לחברת B2B Advance
    עיצוב לוגו לחברת B2B Advance
    776
  • פיתוח אפליקציית ווב עבור Enviok
    פיתוח אפליקציית ווב עבור Enviok
    1077
  • פיתוח לוגו חברת AIDER
    פיתוח לוגו חברת AIDER
    1022
  • פיתוח CRM עבור Chasseurs
    פיתוח CRM עבור Chasseurs
    1113

הגדרת sshd כברירת מחדל: היכן נשברת הגישה

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

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

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

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

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

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

מה נותנת תצורה מדויקת של שרת הגישה

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

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

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

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

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

השוואת גישות: הגדרת sshd לפי מפתחות ולפי סיסמה

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

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

האפשרות מתי מתאימה מה אינה סוגרת ובמה היא מסבכת את התמיכה
מפתח קבוע (AuthorizedKeysFile) מכלול שרתים קטן, הרכב מהנדסים יציב פגיעה במפתח מקנה גישה ללא הגבלת זמן; ביטול ידני בכל שרת
מפתח עם הגבלת גישה לפי כתובות (Match Address, AllowUsers) אזור ניהול מרשתות משנה קבועות או דרך בסטיון אינה מצילה בגניבת מפתח ממכונה מהימנה; נשברת בשינוי רשת
ספריית חשבונות משתמש ארגונית + אימות דו-שלבי עובדים רבים, דרישות ביקורת, רוטציה תכופה תלות בספרייה; קשה יותר לנפות כניסות, נדרש נתיב חלופי
חשבונות שירות עם מפתחות נפרדים אוטומציה, ייצוא, פריסה המפתחות חיים שנים; נדרש איסור מעטפת והגבלה לפי פקודה

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

שלבי הטמעה: מביקורת התצורה ועד מסירה

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

  1. ביקורת התצורה הנוכחית. אוספים את קובצי ההגדרה העובדים מכל השרתים, מתעדים את חשבונות המשתמש, שיטות הכניסה המותרות ואת מי שמתחבר בפועל ומאילו כתובות. מרכזים במסמך אחד את הפערים בין המכונות — בדרך כלל הם עצמם מקור ההרשאות המיותרות.
  2. סכימת גישה לפי תפקידים. מפרידים בין מנהלים, תורנים וחשבונות שירות: למי כניסה במפתח, למי רק מכתובות מסוימות, אילו קבוצות מוגבלות לסט פקודות. הסכימה הופכת לבסיס התצורה, ולא להפך.
  3. סביבת בדיקות. מעתיקים את ההגדרות הנוכחיות למכונות נפרדות ובודקים את הכללים שם, כולל בדיקת כניסה של התפקידים החדשים.
  4. עריכה מדורגת. מפעילים את השינויים בבלוקים: תחילה מפתחות, אחר כך ויתור על סיסמאות, ואז הגבלות לחשבונות השירות. חיבור חדש בודקים בהפעלה נפרדת, ואת הנוכחי מחזיקים פתוח עד לאימות.
  5. החזרה לאחור. לפני כל צעד שומרים עותק עובד של התצורה ומחזיקים תרחיש חזרה מוכן: שחזור הקובץ והפעלה מחדש של השירות בפעולה אחת.
  6. בקרה על שרתי הייצור. פורסים בקבוצות עם השהיה, כדי שכשל יופיע על חלק מהמכלול ולא על כולו בבת אחת.
  7. מסירת התיעוד. מוסרים את התצורות הסופיות, תקנון הנפקה וביטול מפתחות, סדר הפעולות בעזיבת עובד ותזכורת לתורן.

מה נשאר אצלכם לאחר העבודה: תצורות ותקנונים

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

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

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

מקרה בוחן: כיצד סגרו ניחוש סיסמאות במכלול שרתים

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

מה הראתה הביקורת

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

מה עשו ומה יצא

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

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

במה שונה כניסה במפתחות מכניסה בסיסמה

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

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

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

הגורם השני מונח על שני המצבים באופן שונה. בכניסה בסיסמה הוא חובה: סיסמה שפוצחה או שנצפתה מקנה אחרת גישה מלאה. בכניסה במפתחות מציבים את הגורם השני על החלק הפרטי — אמצעי חומרה או אישור בשירות הספרייה.

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

ספקות טכניים לפני עריכת התצורה

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

השרתים הוגדרו בזמנים שונים — התצורות שונות. מה עושים עם זה?

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

האוטומציה תיעצר אם נשנה את כללי הכניסה. כיצד להימנע מהשבתה?

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

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

קבלן זקוק לגישה לזמן העבודה — כיצד להנפיק ולסגור?

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

אם לאחר העריכה אבדה הגישה — כיצד לחזור?

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

נדון בתצורת הגישה שלכם ובתכנית העבודה

כדי שההערכה תהיה עניינית ולא "לפי העין", אנו זקוקים למינימום נתוני מקור: רשימת השרתים עם התפקידים וה-sshd_config הנוכחי. את ה-config אפשר לשלוח כשהזהות מוסרת — מפתחות ציבוריים, כתובות ושמות צמתים די לנקות, לניתוח חשובה מבנה הכללים, ולא המארחים עצמם.

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

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

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