VPN не блокира psql: клиентът ви се свързва другаде
psql и GUI клиент могат да се обръщат към различни крайни точки от една машина. Сравнете хост, сокет, роля и TLS, преди да обвинявате VPN.
И двата клиента са на един и същ лаптоп, минават през един и същ тунел и само единият от тях се свързва. Това сравнение изглежда като доказателство, че VPN е избирателен, докато много по-честото обяснение е, че двата клиента се обръщат към различни дестинации. GUI пази свои собствени хост, порт, роля и TLS настройки и тихо изгражда SSH препращане, когато му потрябва, докато psql сглобява връзка от настройките по подразбиране на libpq, които вашата обвивка може вече да е задала. Възпроизвеждането на работещата връзка е въпрос на четене на настройките на GUI, а не на преинсталиране на тунела.
Мигът: един работещ клиент доказва пътя
Ако GUI се свързва, тунелът пренася трафик и това е единственото, което GUI доказва. Той не казва нищо за това кой адрес разрешава psql, с каква роля се удостоверява или дали сокетът, който отваря, изобщо напуска машината. Пътят е споделен; параметрите — не.
Локалното препращане разширява разликата. GUI може да се свърже с 127.0.0.1 на порт, който е препратил през SSH, и този слушател съществува само докато трае сесията на GUI. psql, насочен към localhost без препращането, получава отказ на връзката, който няма нищо общо с VPN.
Прочетете крайната точка, която GUI действително използва
Отворете свойствата на връзката и копирайте четири стойности: хост, порт, база данни и роля. След това потърсете раздел за тунел, защото 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 от вашата обвивка
psql е тънък клиент върху libpq и libpq чете средата, преди да прочете каквото и да е друго. Променливи като PGHOST, PGHOSTADDR, PGPORT, PGDATABASE, PGUSER, PGSERVICE и PGSSLMODE могат всяка да пренасочи част от връзката. Те се наследяват, а не се въвеждат, затова нищо в командата, която сте изпълнили, не ги показва. Експортирана PGSSLMODE също може да промени какво приема клиентът без нито дума на командния ред.
Две от тези променливи заслужават подозрение първи. PGHOSTADDR дава цифрова дестинация, която отменя разрешаването на имена, докато името на хоста все още определя самоличността на сертификата, а PGSERVICE изважда хост, база данни и избор на TLS от файл на услуга. Изсипването на цялата среда за отстраняване на това е лош навик, тъй като може да съдържа пароли и несвързани токени; вместо това изберете променливите, които ви интересуват.
Пропускането и на host, и на hostaddr избира Unix домейн сокет, а не мрежов адрес. Затова извикване на psql без -h може да успее локално или да се провали със сокет грешка, без изобщо да докосне маршрута, който GUI използва.
Изпратете същите параметри на ръка
Със стойностите на GUI в ръка ги подайте изрично и пропуснете файла за стартиране, който може да добави отменящи настройки. Низът за връзка по-долу е илюстративен: заменете крайната точка, порта, базата данни и ролята със стойностите, одобрени от вашия администратор, и запазете конфигурацията на доверие, която вече работи.
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 грешка.
Ако одобрената крайна точка е зад пулер, порт 6432 и порт 5432 може да достигат същите данни през различни самоличности на сървъра и проверката може да се провали на името на пулера, а не на базата данни. Коригирайте името в низа за връзка, вместо да отслабвате режима.
Оставете съобщението за грешка да избере следващата стъпка
Текстът на неуспеха казва докъде е стигнал опитът и това бие всяко предположение за тунела. Име, което не се разрешава, се проваля преди да съществува сокет, изчакването означава, че маршрутът или защитна стена е изпуснала пакети, отказът означава, че нещо е отговорило и е отказало, а грешка при удостоверяване означава, че мрежата вече е работила.
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 с живата сесия на GUI: същи хост, същ порт, съща роля, също TLS състояние. Когато тези четири съвпадат, на VPN не му остава нищо за обяснение. Докато не съвпадат, всяка допълнителна промяна на тунела е предположение за връзка, която терминалът никога не е правил.