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

שלושה תפקידים שכרגע חולקים הכול

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

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

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

הפרידו שלושה תפקידים, לא שלושה תהליכים

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

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

host
├─ vpn-gw      10.60.10.2/24   public 51820/udp only
├─ services    10.60.0.10/24   no route to the management network
└─ ci-runner   10.60.20.2/24   outbound only, no host socket

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

תנו לאורח ה-VPN לפתוח רק את הדלתות שהוא מחזיק

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

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

virsh net-list --all
virsh net-dumpxml lab-private
sudo nft list ruleset | grep -n -E '51820|10.60'

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

משימות בנייה זקוקות לסוג אחר של גבול

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

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

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

תכננו לכשל שכל השלושה חולקים

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

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

virsh list --all
systemctl is-active libvirtd
curl -sS -m 5 -o /dev/null -w '%{http_code}\n' https://10.60.0.10/
ss -ltnp | grep -E ':51820|:443'

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

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