Двата клиенти се на истиот лаптоп, поминуваат низ истиот тунел, а само еден од нив се поврзува. Таа споредба изгледа како доказ дека 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 грешка.

Ако одобрената крајна точка е зад pooler, портот 6432 и портот 5432 можат да стигнат до истите податоци преку различни идентитети на серверот, а проверката може да пропадне на името на pooler наместо на базата на податоци. Поправете го името во низата за поврзување наместо да го ослабите режимот.

Нека пораката за грешка го избере следниот чекор

Текстот на неуспехот кажува колку далеку стигнал обидот, и тоа е подобро од секое нагаѓање за тунелот. Името што не се решава пропаѓа пред да постои сокет, истекот на време значи дека рутата или ѕидот за заштита ги отфрлил пакетите, одбивањето значи дека нешто одговорило и одбило, а грешката при автентикација значи дека мрежата веќе работела.

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-от нема што повеќе да објасни. Додека не се совпаднат, секоја дополнителна промена на тунелот е нагаѓање за врска што терминалот никогаш не ја направил.

Поврзани статии