И двата клиента са на един и същ лаптоп, минават през един и същ тунел и само единият от тях се свързва. Това сравнение изглежда като доказателство, че VPN е избирателен, докато много по-честото обяснение е, че двата клиента се обръщат към различни дестинации. GUI пази свои собствени хост, порт, роля и TLS настройки и тихо изгражда SSH препращане, когато му потрябва, докато psql сглобява връзка от настройките по подразбиране на libpq, които вашата обвивка може вече да е задала. Възпроизвеждането на работещата връзка е въпрос на четене на настройките на GUI, а не на преинсталиране на тунела.

Мигът: един работещ клиент доказва пътя

Ако GUI се свързва, тунелът пренася трафик и това е единственото, което GUI доказва. Той не казва нищо за това кой адрес разрешава psql, с каква роля се удостоверява или дали сокетът, който отваря, изобщо напуска машината. Пътят е споделен; параметрите — не.

Локалното препращане разширява разликата. GUI може да се свърже с 127.0.0.1 на порт, който е препратил през SSH, и този слушател съществува само докато трае сесията на GUI. psql, насочен към localhost без препращането, получава отказ на връзката, който няма нищо общо с VPN.

Прочетете крайната точка, която GUI действително използва

Отворете свойствата на връзката и копирайте четири стойности: хост, порт, база данни и роля. След това потърсете раздел за тунел, защото SSH препращането превръща частен адрес в локален порт и променя това, което трябва да се каже на psql.

SettingWhat the GUI holdsWhat psql uses when the value is absent
DestinationA saved hostname, sometimes behind a forwardA local Unix socket, not the remote endpoint
PortThe direct port or a forwarded local port5432, or the port from a service file
Role and databaseStored per connection profileYour operating-system user name
TLS identityIts own CA bundle and verification modeWhatever PGSSLMODE or the service file says
Startup filesNot read at allRead 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 не му остава нищо за обяснение. Докато не съвпадат, всяка допълнителна промяна на тунела е предположение за връзка, която терминалът никога не е правил.

Подобни статии