ה-VPN לא חוסם את psql: הלקוח שלך מחייג למקום אחר
psql ולקוח גרפי עשויים לחייג ליעדים שונים מאותה מכונה. השווה מארח, socket, תפקיד ו-TLS לפני שאתה מאשים את ה-VPN.
שני הלקוחות יושבים על אותו מחשב נייד, עוברים דרך אותה מנהרה, ורק אחד מהם מתחבר. ההשוואה הזו נראית כמו הוכחה שה-VPN בררן, בעוד שההסבר השכיח הרבה יותר הוא ששני הלקוחות מחייגים ליעדים שונים. ממשק גרפי שומר לעצמו מארח, פורט, תפקיד והגדרות TLS משלו ובונה בשקט העברת SSH כשהוא זקוק לה, בעוד psql מרכיב חיבור מערכי ברירת המחדל של libpq שאולי ה-shell שלך כבר הגדיר. שחזור החיבור העובד הוא עניין של קריאת הגדרות הממשק הגרפי, לא של התקנה מחדש של המנהרה.
המיתוס: לקוח אחד שעובד מוכיח את המסלול
אם הממשק הגרפי מתחבר, המנהרה מעבירה תעבורה, וזה הדבר היחיד שהממשק הגרפי מוכיח. הוא אינו אומר דבר על איזו כתובת psql מפענח, באיזה תפקיד הוא מאמת, או אם ה-socket שהוא פותח יוצא אי פעם מהמכונה. המסלול משותף; הפרמטרים לא.
העברה מקומית מגדילה את הפער. הממשק הגרפי עשוי להתחבר ל-127.0.0.1 בפורט שהעביר דרך SSH, ומאזין כזה קיים רק כל עוד הפעלת הממשק נמשכת. psql שמכוון ל-localhost בלי ההעברה מקבל חיבור שנדחה ושאין לו שום קשר ל-VPN.
קרא את היעד שהממשק הגרפי באמת משתמש בו
פתח את מאפייני החיבור והעתק ארבעה ערכים: מארח, פורט, מסד נתונים ותפקיד. לאחר מכן חפש לשונית מנהרה, כי העברת SSH הופכת כתובת פרטית לפורט מקומי ומשנה את מה שצריך לומר ל-psql.
| Setting | What the GUI holds | What psql uses when the value is absent |
|---|---|---|
| Destination | A saved hostname, sometimes behind a forward | A local Unix socket, not the remote endpoint |
| Port | The direct port or a forwarded local port | 5432, or the port from a service file |
| Role and database | Stored per connection profile | Your operating-system user name |
| TLS identity | Its own CA bundle and verification mode | Whatever PGSSLMODE or the service file says |
| Startup files | Not read at all | Read unless -X is passed |
כל שורה נכשלת בשכבה אחרת, וההודעה שאתה מקבל נוקבת בשם אותה שכבה. הדבקת השם הידידותי של הפרופיל השמור בתוך psql אינה נושאת אף אחד מהערכים שלמעלה, ושם שירות מפוענח דרך קובץ שהמסוף אולי לעולם לא יקרא.
מה libpq יורש מה-shell שלך
psql הוא לקוח דק מעל libpq, ו-libpq קורא את הסביבה לפני שהוא קורא כל דבר אחר. משתנים כמו PGHOST, PGHOSTADDR, PGPORT, PGDATABASE, PGUSER, PGSERVICE ו-PGSSLMODE יכולים כל אחד להפנות מחדש חלק מהחיבור. הם עוברים בירושה ולא מוקלדים, ולכן שום דבר בפקודה שהרצת לא מציג אותם. PGSSLMODE שיוצא לסביבה יכול גם לשנות את מה שהלקוח מקבל בלי מילה בשורת הפקודה.
שניים מהמשתנים האלה ראויים לחשד ראשונים. PGHOSTADDR מספק יעד מספרי שעוקף פענוח שמות בזמן ששם המארח עדיין קובע את זהות התעודה, ו-PGSERVICE שולף מארח, מסד נתונים ובחירות TLS מקובץ שירות. שפיכת כל הסביבה כדי לנפות את זה היא הרגל רע, כי היא עשויה להכיל סיסמאות ואסימונים לא קשורים; בחר במקום זאת את המשתנים שמעניינים אותך.
השמטת גם host וגם hostaddr בוחרת socket של תחום Unix ולא כתובת רשת. לכן קריאה ל-psql בלי -h עשויה להצליח מקומית, או להיכשל בשגיאת socket, בלי לגעת במסלול שהממשק הגרפי משתמש בו.
שלח את אותם פרמטרים ביד
כשערכי הממשק הגרפי בידך, העבר אותם במפורש ודלג על קובץ האתחול שעלול להוסיף עקיפות. מחרוזת החיבור שלמטה היא להמחשה: החלף את היעד, הפורט, מסד הנתונים והתפקיד בערכים שהמנהל שלך אישר, ושמור על תצורת האמון שכבר עובדת.
psql -X "host=db.internal.example port=6432 dbname=orders user=report_ro sslmode=verify-full connect_timeout=5"שלושה פרטים בפקודה הזו מכוונים. -X מדכא את קובץ האתחול של psql, אם כי אינו מדכא את הסביבה של libpq או הגדרת שירות. connect_timeout=5 מונע ממסלול שנבלע לחלוטין לתלות את המסוף לדקות. sslmode=verify-full משאיר את בדיקות התעודה ושם המארח דלוקות, שזה בדיוק החלק שאנשים מכבים כשמופיעה שגיאת TLS.
אם היעד המאושר נמצא מאחורי pooler, פורט 6432 ופורט 5432 עשויים להגיע לאותם נתונים דרך זהויות שרת שונות, והאימות עלול להיכשל על שם ה-pooler ולא על שם מסד הנתונים. תקן את השם במחרוזת החיבור במקום להחליש את המצב.
תן להודעת השגיאה לבחור את הצעד הבא
טקסט הכשל אומר עד כמה הגיע הניסיון, וזה עדיף על כל ניחוש לגבי המנהרה. שם שלא יפוענח נכשל לפני שקיים socket, פסק זמן אומר שהמסלול או חומת אש הפילו מנות, דחייה אומרת שמשהו ענה וסירב, ושגיאת אימות אומרת שהרשת כבר עבדה.
psql -X -w "host=db.internal.example port=6432 dbname=orders user=report_ro sslmode=verify-full connect_timeout=5" -c '\conninfo'
env | grep -E '^PG'
psql --versionהשווה את הפלט של \conninfo למושב החי של הממשק הגרפי: אותו מארח, אותו פורט, אותו תפקיד, אותו מצב TLS. כשהארבעה האלה מסכימים, ל-VPN לא נשאר מה להסביר. עד שהם מסכימים, כל שינוי נוסף במנהרה הוא ניחוש לגבי חיבור שהמסוף מעולם לא עשה.