Beide Clients sitzen auf demselben Laptop, durchqueren denselben Tunnel, und nur einer von ihnen verbindet sich. Dieser Vergleich wirkt wie ein Beweis, dass das VPN wählerisch ist, während die weit häufigere Erklärung lautet, dass die beiden Clients unterschiedliche Ziele anwählen. Eine GUI behält ihren eigenen Host, Port, ihre Rolle und ihre TLS-Einstellungen und baut bei Bedarf still eine SSH-Weiterleitung auf, während psql eine Verbindung aus libpq-Standardwerten zusammensetzt, die deine Shell vielleicht schon gesetzt hat. Die funktionierende Verbindung nachzubauen bedeutet, die Einstellungen der GUI zu lesen, nicht den Tunnel neu zu installieren.

Der Mythos: Ein funktionierender Client beweist den Pfad

Wenn sich die GUI verbindet, überträgt der Tunnel Verkehr, und das ist das Einzige, was die GUI beweist. Sie sagt nichts darüber aus, welche Adresse psql auflöst, mit welcher Rolle es sich authentifiziert oder ob der Socket, den es öffnet, die Maschine überhaupt verlässt. Der Pfad ist gemeinsam; die Parameter nicht.

Eine lokale Weiterleitung vergrößert die Lücke. Die GUI kann sich mit 127.0.0.1 auf einem Port verbinden, den sie über SSH weitergeleitet hat, und dieser Listener existiert nur, solange die GUI-Sitzung dauert. psql, ohne die Weiterleitung auf localhost gerichtet, bekommt eine abgelehnte Verbindung, die nichts mit dem VPN zu tun hat.

Lies den Endpunkt, den die GUI tatsächlich nutzt

Öffne die Eigenschaften der Verbindung und kopiere vier Werte: Host, Port, Datenbank und Rolle. Suche dann einen Tunnel-Tab, denn eine SSH-Weiterleitung verwandelt eine private Adresse in einen lokalen Port und ändert, was psql gesagt werden muss.

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

Jede Zeile scheitert auf einer anderen Ebene, und die Meldung, die du bekommst, benennt diese Ebene. Den freundlichen Namen des gespeicherten Profils in psql einzufügen, überträgt keinen der obigen Werte, und ein Dienstname wird über eine Datei aufgelöst, die das Terminal vielleicht nie liest.

Was libpq von deiner Shell erbt

psql ist ein dünner Client über libpq, und libpq liest die Umgebung, bevor es irgendetwas anderes liest. Variablen wie PGHOST, PGHOSTADDR, PGPORT, PGDATABASE, PGUSER, PGSERVICE und PGSSLMODE können jeweils einen Teil der Verbindung umleiten. Sie werden geerbt statt getippt, also zeigt nichts in dem Befehl, den du ausgeführt hast, sie an. Ein exportiertes PGSSLMODE kann ebenfalls ändern, was der Client akzeptiert, ohne ein Wort auf der Kommandozeile.

Zwei dieser Variablen verdienen zuerst Verdacht. PGHOSTADDR liefert ein numerisches Ziel, das die Namensauflösung überschreibt, während der Hostname weiterhin die Zertifikatsidentität bestimmt, und PGSERVICE zieht Host, Datenbank und TLS-Auswahl aus einer Dienstdatei. Die gesamte Umgebung zum Debuggen auszugeben ist eine schlechte Angewohnheit, da sie Passwörter und unabhängige Token enthalten kann; wähle stattdessen die Variablen aus, die dich interessieren.

Das Weglassen von host und hostaddr wählt einen Unix-Domain-Socket statt einer Netzwerkadresse. Ein psql-Aufruf ohne -h kann daher lokal gelingen oder mit einem Socket-Fehler scheitern, ohne jemals die Route zu berühren, die die GUI nutzt.

Sende dieselben Parameter von Hand

Mit den Werten der GUI zur Hand, übergib sie ausdrücklich und überspringe die Startdatei, die Überschreibungen hinzufügen könnte. Die Verbindungszeichenfolge unten ist illustrativ: Ersetze Endpunkt, Port, Datenbank und Rolle durch die von deinem Administrator genehmigten Werte und behalte die Vertrauenskonfiguration, die bereits funktioniert.

psql -X "host=db.internal.example port=6432 dbname=orders user=report_ro sslmode=verify-full connect_timeout=5"

Drei Details in diesem Befehl sind beabsichtigt. -X unterdrückt die Startdatei von psql, allerdings nicht die Umgebung von libpq oder eine Dienstdefinition. connect_timeout=5 verhindert, dass eine Route ins Leere das Terminal minutenlang hängen lässt. sslmode=verify-full hält Zertifikats- und Hostnamenprüfungen eingeschaltet, was genau der Teil ist, den Leute abschalten, wenn ein TLS-Fehler auftaucht.

Wenn der genehmigte Endpunkt hinter einem Pooler liegt, können Port 6432 und Port 5432 dieselben Daten über unterschiedliche Serveridentitäten erreichen, und die Verifikation kann am Namen des Poolers statt an dem der Datenbank scheitern. Korrigiere den Namen in der Verbindungszeichenfolge, statt den Modus abzuschwächen.

Lass die Fehlermeldung den nächsten Schritt wählen

Der Fehlertext sagt, wie weit der Versuch gekommen ist, und das schlägt jede Vermutung über den Tunnel. Ein Name, der sich nicht auflösen lässt, scheitert, bevor ein Socket existiert, ein Timeout bedeutet, dass die Route oder eine Firewall Pakete verworfen hat, eine Ablehnung bedeutet, dass etwas geantwortet und abgelehnt hat, und ein Authentifizierungsfehler bedeutet, dass das Netzwerk bereits funktioniert hat.

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

Vergleiche die Ausgabe von \conninfo mit der laufenden Sitzung der GUI: derselbe Host, derselbe Port, dieselbe Rolle, derselbe TLS-Zustand. Wenn diese vier übereinstimmen, hat das VPN nichts mehr zu erklären. Bis sie übereinstimmen, ist jede weitere Tunneländerung eine Vermutung über eine Verbindung, die das Terminal nie aufgebaut hat.

Ähnliche Artikel