OpenVPN דוחה את השורה הראשונה? הקובץ כנראה ב-UTF-16
שגיאה בשורה הראשונה עם תווים מוזרים בדרך כלל מעידה שהפרופיל נשמר כ-UTF-16. קראו את הבתים הראשונים ואז המירו את הקובץ כראוי.
השגיאה מצביעה על השורה הראשונה של קובץ .ovpn ומצטטת משהו שנראה כמו אותיות מבולבלות במקום שבו אמור להופיע client. הקובץ נפתח כראוי בעורך שלכם, השורה הראשונה נקראת client, וההוראה רגילה לחלוטין. שתי התצפיות נכונות, מפני שהעורך מפענח את הבתים והלקוח אינו עושה זאת. מה שאתם רואים הוא כמעט תמיד בעיית קידוד, לא בעיית תחביר.
המיתוס: העורך מראה לכם את הקובץ
עורך טקסט מפענח בתים לתווים בקידוד שהוא או מזהה או מנחש. כשהוא מנחש UTF-16, הקובץ נראה מושלם על המסך בעוד הבתים שמתחתיו הם זוגות, עם בית אפס אחרי כל אות לטינית. OpenVPN קורא את הבתים האלה כתווים, והאי-התאמה מופיעה בהוראה הראשונה שהוא מנסה לנתח.
לכן השורה הנראית והשורה הנמסרת הן שני דברים שונים. מחיקת התווים המוזרים שאתם רואים היא שינוי בתצוגה, לא בקידוד, והניתוח הבא נכשל מאותה סיבה עם הודעה מעט שונה. לכן המרדף אחרי האסימון שבשגיאה לא מוביל לשום מקום. הבתים שגויים במקור, וכל קורא בהמשך מנחש את אותו רצף שבור.
כדאי לזהות את הצורה המדויקת של הכשל, מפני שהוא אבחוני בדרך מסוימת. אסימון ממש בתחילת הקובץ, בפרופיל שעבד אחרת במכונות אחרות, הוא שאלה של סדר בתים ולא שאלה של אוצר מילים.
מה אומרים הבתים הראשונים באמת
קראו את הבתים ולא את התווים. שתי פקודות קטנות מכריעות את העניין בשניות, ואף אחת מהן לא דורשת לפתוח את הקובץ ביישום שעלול לשנות אותו:
file client.ovpn
head -c 24 client.ovpn | od -An -tx1
התבנית שאתם מחפשים היא זוג בתים מובילים שאחריו טקסט שבו כל בית שני הוא אפס. FF FE מסמן UTF-16 little-endian, FE FF מסמן big-endian, ו-EF BB BF מסמן UTF-8 עם סימן סדר בתים. קובץ UTF-8 רגיל בלי סימן מתחיל ישירות בבית של האות הראשונה.
בתי אפס בין האותיות הם הרמז. ב-UTF-16 little-endian המילה client תופסת שנים עשר בתים במקום שישה, מפני שכל תו ASCII נגרר אחריו אפס. את המבנה הזה תצוגת עורך לא יכולה להראות לכם, וזה לא משהו שמחיקת שני בתים יכולה להסיר.
יש כאן ניואנס חשוב: קורא התצורה של OpenVPN אכן מדלג על סימן סדר בתים של UTF-8 בראש הקובץ, כפי שמראה קורא התצורה 2.6. הסובלנות הזו ספציפית לאותו סימן, והיא לא עושה דבר לקובץ UTF-16 שאותיותיו מרופדות באפסים. התייחסות לשני הסימנים כאל אותה בעיה היא החצי השני של המיתוס.
המרה היא שמירה בשם, לא מחיקה
שמרו עותק לא נגוע של המקור של המפעיל לפני כל פעולה, ועבדו על קובץ נפרד. פרופיל עשוי להכיל מפתח פרטי או חומר חשבון, ולכן העותק הוא גם דרך החזרה שלכם וגם ההפניה שלכם.
לאחר מכן בצעו המרת קידוד אמיתית, בין באמצעות תפריט הקידוד המפורש של העורך ובין באמצעות ממיר שמציין את קידוד הקלט והפלט שלו:
iconv -f UTF-16 -t UTF-8 client.ovpn > client-utf8.ovpn
file client-utf8.ovpn
אמתו את התוצאה במקום לסמוך על מצב היציאה של הפקודה. ההמרה אמורה לשמר כל הוראה, והיא חייבת לשמר כל בלוק תעודה או מפתח מוטמע בית אחר בית בתוך הסימנים שלו. עטיפה מחדש של נתוני PEM, שינוי סופי שורות בתוך בלוק או עיצוב מחדש של הפרופיל בזמן ההמרה יוצרים בעיה חדשה בזמן תיקון הישנה.
כוונו את הלקוח או את השירות לקובץ המומר והסתכלו על השגיאה הראשונה שהוא מדווח. אם האסימון המבולבל נעלם, עבודת הקידוד הסתיימה, וכל מה שנכשל אחר כך הוא שאלה אחרת.
מה קידוד מתוקן לא מתקן
קידוד קובע איך נקרא הטקסט; הוא לא אומר דבר על אם האפשרויות תקפות ללקוח שלפניכם. פרופיל שיוצא למימוש אחר יכול להינתח נקי ובכל זאת להידחות בגלל אפשרות שהבנייה הפועלת אינה תומכת בה, או בגלל הוראה שהארגומנט שלה משמעות אחרת בלקוח ההוא.
השגיאות המאוחרות האלה ראויות לחקירה משלהן: האיות המדויק, תחביר הארגומנט והגרסה שמקבלת אותו. אל תתייחסו לניתוח מוצלח כאל פרופיל מוצלח.
השאירו את החקירה מקומית כשאתם עוסקים בזה. ממירים ציבוריים ברשת ותצוגות hex מודבקות הם מקום גרוע לקובץ שעשוי להכיל מפתח פרטי, מפני שבעיית הקידוד קלה לתיקון ומפתח שדלף אינו.