DBeaver SSH tunnel vs PostgreSQL JDBC sslmode: independent layers or silent override?
0 reputation · 31 May 2020, 12:49 UTC
0 reputation · 31 May 2020, 12:49 UTC
Goal: confirm whether DBeaver's built-in SSH tunnel host-key verification and the PostgreSQL JDBC driver's sslmode setting enforce encryption independently, or whether one layer can silently bypass the other when the tunnel forwards a local port and the JDBC URL points to localhost.
SSH tunneling and JDBC TLS are separate configuration boundaries in DBeaver. The tunnel authenticates the SSH host and forwards traffic; sslmode is a driver property that may secure only the localhost leg unless the remote PostgreSQL server also requires TLS. Disabling SSH host-key verification can expose the tunnel to man-in-the-middle attacks even when JDBC SSL appears enabled.
Available SSH host-key policies, encrypted-key and agent support, and JDBC sslmode values depend on DBeaver edition and version, so behavior should be confirmed in the installed build rather than assumed.
Do SSH host-key verification failures abort the tunnel before JDBC sslmode is evaluated? Can a disabled host-key policy silently weaken an sslmode require connection? Which layer's encryption applies to the remote host leg versus the forwarded localhost leg?
34775 reputation · 31 May 2020, 21:58 UTC
Yes. SSH tunnel establishment and PostgreSQL JDBC sslmode are independent configuration boundaries in DBeaver. Host-key verification is an SSH client check that happens before any JDBC socket is opened. sslmode controls TLS between the JDBC driver and the PostgreSQL server as seen by the driver, which with a tunnel is the local forwarded port to the SSH client process.
SSH host-key verification failures abort the tunnel before JDBC sslmode is evaluated. A disabled host-key policy does not override sslmode, but it silently weakens the whole connection: the tunnel can be MITM’d at the SSH layer, so an sslmode=require connection inside a compromised tunnel is not trustworthy.
Encryption mapping with a tunnel:
DBeaver UI merges SSH and database settings, which can create the impression of a single security toggle. In practice the tunnel and JDBC are separate processes. Available SSH host-key policies, encrypted key and agent support, and the exact JDBC parameter names depend on DBeaver edition and version, so confirm in your installed build.
Common risk pattern: sslmode=disable with a tunnel is often assumed safe because "the tunnel is encrypted". That is true for the network path, but the data is plaintext on the local loopback and only SSH provides confidentiality. Local packet capture on loopback can see it.
Assumption: you are using DBeaver’s built-in SSH tunnel with a PostgreSQL JDBC driver connecting to localhost. If your remote PostgreSQL server requires SSL, sslmode=require will still succeed inside the tunnel, but the server will see the connection as originating from the SSH server.
One diagnostic detail that changes the recommendation: what sslmode is actually set in the JDBC driver properties for this connection, and whether the remote PostgreSQL server enforces SSL. If sslmode is disable and you rely solely on SSH, ensure host-key verification is Strict and the SSH host key is pinned. If you need end-to-end TLS validation inside the tunnel, use sslmode=verify-full with a valid server cert and keep SSH host-key verification strict.
Use comments to ask for clarification. Post a solution as an answer.
5,930 reputation · 31 May 2020, 18:30 UTC
It is important to distinguish between the transport layer (SSH) and the session layer (JDBC SSL). These operate as independent wrappers. If the SSH tunnel is established, the JDBC driver treats the tunnel as a transparent pipe to localhost.
A critical detail is the leg between the SSH gateway and the PostgreSQL server. If sslmode is set to disable or prefer (and the server doesn't force SSL), the traffic travels in plaintext from the SSH jump host to the database. Only sslmode=require or verify-full ensures end-to-end encryption from the driver to the database engine, regardless of the tunnel.
To verify which layer is active, execute the following query in the DBeaver SQL editor:
SELECT datname, ssl, version FROM pg_stat_ssl JOIN pg_stat_activity ON pg_stat_ssl.pid = pg_stat_activity.pid;
If the ssl column is false, your data is only encrypted until it hits the SSH gateway.