היכן צריך לחיות מפתח VPN פרטי: קובץ, CNG או TPM?
בחרו בין קובץ מפתח, מאגר תוכנה שאינו ניתן לייצוא ו-TPM לזהות VPN, ואז הוכיחו את הבחירה בפקודות ובתוכנית חזרה.
שתי שאלות קובעות היכן שייך מפתח VPN פרטי: האם אפשר להעתיק את חומר המפתח מהמארח, והאם תהליך יכול להשתמש בו בלי שאיש נמצא במקלדת. תווית השיווק של מאגר אינה עונה על אף אחת מהן. דמון מנהרה שצריך לחזור לאחר אתחול דורש שימוש ללא השגחה, מה ששולל כל דבר התלוי ב-PIN שאדם מקליד.
בחרו בין העתקה לשימוש
העתקה ושימוש נכשלים בדרכים שונות, לכן התייחסו אליהם כשתי דרישות ולא כאחת. תוקף שיכול לקרוא את בייטי המפתח מעביר את הזהות למארח אחר, והמכונה המקורית לא מבחינה. תוקף שלא יכול לקרוא את הבייטים אך מגיע לתהליך החתימה עדיין מאמת את עצמו כל עוד הגישה נמשכת.
מפתח בקובץ ניתן להעתקה טריוויאלית, ולכן הוא גם הקל ביותר לגיבוי ולשחזור. מאגר מפתחות תוכנתי משנה את ה-API, לא את הגבול: הספק דוחה את קריאות הייצוא שלו עצמו, אבל לאותו הקשר מנהל שהתקין את המפתח יש בדרך כלל נתיבים אחרים לחומר. אי-ניתנות לייצוא אצל ספק תוכנה היא הצהרה על פעולות נתמכות, לא הוכחה לחומת חומרה. התייחסו לזה כמעכב מול העתקה מזדמנת, לא כהגנה מפני מי שכבר מחזיק בהפעלה שלכם.
TPM או כרטיס חכם מבצע את פעולת החתימה בתוך החומרה ומחזיר רק את התוצאה. זה סוגר את נתיב ההעתקה ומשאיר את נתיב השימוש פתוח לכל דבר שיכול לבקש חתימה.
התאימו את המאגר לדמון המנהרה
הדמון מגביל זאת יותר ממדיניות האבטחה. WireGuard לוקח מפתח פרטי base64 מקובץ או מקלט של wg set ואין לו נתיב למאגר תעודות, לכן מפתח ממשק מגובה TPM אינו בא בחשבון. OpenVPN שנבנה מול OpenSSL 3 יכול לטעון מפתח דרך URI של ספק, ו-strongSwan מספק תוסף TPM לצד תמיכת PKCS#11, אבל שניהם תלויים באופן שבו החבילה שלכם הורכבה.
דמון שלא מגיע למאגר שנבחר הופך את גבול החומרה לקישוט. מישהו מייצא את המפתח פעם אחת, משאיר אותו בקובץ, ושאר העיצוב רץ בשקט על אותה העתקה.
החידוש הוא החצי השני של ההתאמה, ושם מתפרקים רוב העיצובים. מאגר שעובד בהרשמה הראשונה אבל דורש התחברות לקונסולה לכל הוצאה מחדש עוקף את עצמו בפעם הראשונה שתעודה פגה בשעה לא נוחה. בדקו את נתיב ההוצאה מחדש כל עוד למפתח הנוכחי יש חודשים.
עשו מלאי של המפתח לפני העברתו
רשמו מהו המפתח לפני שתשנו היכן הוא חי, כי העברה שמאבדת subject alternative names שוברת את המנהרה באופן שנקרא כשגיאת ניתוב. ייצאו את התעודה, אשרו שהמפתח הפרטי קריא במקום שבו הדמון מצפה לו, ובדקו שהזוג באמת תואם.
openssl x509 -in vpn.crt -noout -subject -ext subjectAltName
openssl pkey -in vpn.key -check -noout
openssl x509 -in vpn.crt -noout -pubkey | openssl sha256
openssl pkey -in vpn.key -pubout | openssl sha256
שני התקצירים האחרונים חייבים להיות זהים. אם לא, הדמון מסיים את ההתקנה ואז נכשל בכל ניסיון בשגיאת תעודה או חתימה שלא מצביעה לשום מקום קרוב לסיבה האמיתית. המקבילה של WireGuard קצרה יותר, כי המפתח הציבורי נגזר ישירות מהפרטי: wg pubkey < /etc/wireguard/wg0.key חייב להדפיס את מפתח העמית שהשרת שלכם כבר שומר.
ההרשאות שייכות לאותו מלאי. stat -c '%a %U:%G' /etc/wireguard/wg0.key אמור להחזיר 600 root:root, וכל דבר קריא לקבוצה או לעולם פירושו שהמפתח כבר היה זמין לתהליכים שלא התכוונתם אליהם.
בדקו את המאגר ואת נתיב השימוש
לאימות שלושה חלקים, והשלישי הוא זה שמדלגים עליו. אשרו שהמפתח קיים במאגר שבחרתם, אשרו שהדמון טען את המפתח הזה ולא העתקה שנשארה, ואז אשרו שהוא עדיין עולה כאשר חפץ הייצוא נעלם.
certutil -store -user My
certutil -csp "Microsoft Platform Crypto Provider" -key -user
certutil -verifykeys -user My
ipsec listcerts
ב-Windows הפקודה הראשונה מציגה את המאגר האישי ומדפיסה את ספק המפתח לצד כל רשומה, ושם מופיע תעודה שנראית מגובה בחומרה אבל יושבת בספק התוכנה. השנייה מציגה מפתחות שמחזיק ספק הקריפטוגרפיה של הפלטפורמה, לכן זהות VPN שחסרה שם כשהתעודה נוכחת פירושה שהחצי הפרטי חי במקום אחר. בשער Linux, ipsec listcerts מדווח מה strongSwan טען, כולל מפתחות שהגיעו מתוסף ה-TPM. השוו טביעות אצבע או גיבובי מפתח ציבורי למלאי במקום לסמוך על מספר הרשומות.
המבחן השלילי הוא זה שמוכיח את העיצוב. העבירו את המפתח המיוצא מחוץ לספריית התצורה של הדמון, הפעילו מחדש את השירות וקראו ביומן איזו זהות הוא מציג. מנהרה שעולה בכל זאת משתמשת במאגר; הפעלה שנכשלה פירושה שהעיצוב באמת רץ על העתקה.
כתבו את החידוש והחזרה
החזרה שונה בחדות בין שתי המשפחות, וההבדל הזה שייך להערת העיצוב, לא לשיחת תקלה. מפתח בקובץ ניתן לגבות מוצפן ולשחזר, לכן העברה שנכשלה הפיכה. מפתח שאינו ניתן לייצוא אינו ניתן לגיבוי כלל, מה שהופך הוצאה מחדש והרשמה מחדש לנתיב השחזור היחיד כשהמכשיר מת.
בדקו את הפקיעה לפני שהיא הופכת להפסקה: openssl x509 -in vpn.crt -noout -checkend 2592000 מסתיים בקוד שאינו אפס כאשר התעודה פגה בתוך שלושים יום, כך שהוא נכנס ישירות לבדיקת ניטור. הרצה שבועית של השורה הזו תופסת את החידוש שאיש לא תכנן.
ההסרה מתרחשת בשרת: מחקו את העמית או בטלו את המספר הסידורי, ואז אשרו שהמנהרה נכשלת, כי לקוח עם הפעלה שמורה במטמון יכול להסתיר ביטול חצי-גמור לזמן מה. הביטול צריך להגיע גם לנתיב ה-CRL או ה-OCSP של המרכזן, לא רק למסד הנתונים של ה-CA. תעודה היא מסמך ציבורי, ו־פרופיל RFC 5280 מכסה כיצד היא מאומתת; שום דבר באימות הזה לא מגן על מפתח פרטי שהועתק לפני הרוטציה.
כתבו את ההחלטה במקום אחד: איזה מאגר מחזיק את המפתח, איזה תהליך רשאי להשתמש בו, מי יכול להוציא אותו מחדש ומהי החזרה. הפסקה הזו היא מה שמבקשים מבקרים, ומה ששורד החלפת צוות.