ProtectHome מול זרע TOTP: מדוע הכניסה ל-VPN נכשלת
קוד נכון לא יועיל למודול PAM שאינו יכול לפתוח את הזרע. בחרו בין drop-in לנתיב מצב שניתן לכתיבה, ואז בדקו את היחידה.
המאמת מציג קוד בן שש ספרות טרי, ה-VPN דוחה אותו, ואותו קוד מאומת היטב כשאתה בודק אותו מהמעטפת שלך. הפער הזה הוא כל הסיפור. מודול PAM שאינו יכול לפתוח את סוד ההרשמה מחזיר כשל שנראה זהה לקוד שגוי, וסביבת השירות שמסתירה תיקיות בית היא סיבה נפוצה לכך. לפני שאתה מרפה הרשאה כלשהי, החלט באיזה משלושה מצבים אתה נמצא.
איזה משלושת הכשלים זה?
הראשון הוא סוד שהמודול כלל אינו יכול לקרוא. השני הוא סוד שהוא יכול לקרוא אך לא לעדכן. השלישי הוא קוד שבאמת שגוי, בדרך כלל בגלל סחיפת שעון או ערך ששוחק מחדש.
הפרד ביניהם על ידי קריאת יומן השירות ויומן האימות של המערכת עבור ניסיון כושל אחד, ואז אמת איזה שירות PAM הטעינה התוספת ואיזו שורת מודול משתמשת באותו שירות. הודעת כשל אימות כללית אינה מבחינה ביניהם, וגם לא בדיקה ידנית מוצלחת, כי המעטפת שלך אינה סביבת השירות.
תצוגת מערכת הקבצים של היחידה היא האשם הרגיל כשרק השירות נכשל.
systemctl show -p ProtectHome -p ProtectSystem -p ReadWritePaths [email protected]
ls -l /var/lib/vpn-otp/*/.google_authenticator 2>/dev/null | head -n 20אפשרות A: להוציא את הסוד מתיקיית הבית
כשהשירות מסתיר את /home ואתה מעדיף לשמור על ההגנה הזו, אחסן את הסוד במקום שהוא יכול לראות. המודול מקבל נתיב secret= וחשבון user= שמבצע את פעולות הקבצים, מה שמאפשר למאגר מרכזי לשרת זהויות רבות.
זו האפשרות המסודרת, והיא זו שדורשת את מירב הזהירות, כי מאגר משותף הופך תיקייה אחת לגבול האבטחה של כל חשבון.
auth required pam_google_authenticator.so secret=/var/lib/vpn-otp/${USER}/.google_authenticator user=vpn-otpבדוק שלושה דברים לפני שתסמוך עליו: החשבון קיים, תהליך העבודה של המודול יכול לעבור אליו, והקבצים בבעלותו עם מצבים מגבילים. אל תשתמש ב-~ או בנתיב עם משתנה בית יחד עם user=, ואל תכבה את בדיקות הבעלות של המודול כדי לגרום לנתיב לעבוד. שמור על שלב הסיסמה ועל שאר המחסנית שלמים.
אפשרות B: להשאיר את הקובץ ולפתוח נתיב
אם הסוד חייב להישאר בתיקיית הבית של המשתמש, היחידה צריכה תצוגה שכוללת את התיקייה האחת הזו בלי לחשוף כל תיקיית בית במארח. drop-in יכול להוסיף עיגון צר ומוגבל תחת בית מסונדקס.
זה שומר על בעלות לכל משתמש כמודל, במחיר שינוי ביחידה שצריך לסקור בכל פעם שהסביבה המבודדת משתנה.
שני גבולות קלים לפספוס. נתיב לקריאה בלבד שנוסף תחת תיקייה שהסביבה המבודדת מסתירה אינו חושף אותה, כי ההורה פשוט איננו. והעיגון חייב להיות ניתן לכתיבה אם המודול צריך לעדכן מצב, מה שמכניס את האפשרות הבאה למשחק. כתוב את ה-drop-in כקובץ נפרד במקום לערוך את היחידה הארוזת תחת /usr/lib, כדי שעדכון חבילה לא יבטל אותו בשקט.
אפשרות C: להשאיר את הסביבה המבודדת ולתקן כתיבות מצב
קריאת הסוד היא רק חצי מהאימות. המודול עשוי לשכתב מידע על סחיפת זמן, הגנה מפני שידור חוזר או מונה, וקובץ שעובר בדיקת קריאה עדיין יכול להיכשל בכתיבה.
הכשל הזה נראה כמו קוד רע בניסיון הבא ולא בניסיון הזה, ולכן הוא מתבלבל עם סחיפת שעון.
תן לו תיקייה ניתנת לכתיבה משלו והפנה לשם את נתיב הסוד, במקום להפוך את כל תיקיית הבית לניתנת לכתיבה. אמת את בעל התיקייה, את המקום הפנוי במערכת הקבצים ואם היחידה מגבילה כתיבות במקום אחר. אחר כך בדוק שתי כניסות עוקבות, כי השנייה מוכיחה את נתיב הכתיבה והראשונה רק את הקריאה.
אמת כשירות, לא כעצמך
כל בדיקה שחשובה חייבת לרוץ בתוך הסביבה המבודדת של היחידה עם הזהות של היחידה.
פקודה שמצליחה כ-root אומרת לך שהקובץ קיים ושום דבר אחר. כניסה דרך השירות האמיתי אומרת לך אם המודול יכול לקרוא את הסוד, להשתמש בו ולכתוב בחזרה את מה שהוא צריך.
לבסוף, שמור על הדרישה שלמה. הוספת אפשרות סיסמה ריקה, קבלת כשלי קריאה בלבד או הסרת הסביבה המבודדת היו מעלימות את התסמין על ידי שינוי המדיניות. משתמש שנדרש להציג קוד עדיין צריך להידחות כשהסוד אינו נגיש.