El túnel se levanta, QGIS conecta y el inicio de sesión muere con un error de certificado que nombra 127.0.0.1 en lugar del host de la base de datos. El siguiente movimiento tentador es relajar sslmode, lo que silencia la comprobación y tira la garantía de identidad que precisamente quería. El problema real es que el puerto local y el nombre del servidor se guardan en el mismo campo. Una entrada de servicio libpq los separa, así el socket va al puerto reenviado mientras TLS sigue verificando el nombre impreso en el certificado.

A qué cree el cliente que se conecta

Con sslmode=verify-full, libpq compara el certificado que presenta el servidor con el nombre de host al que se pidió llegar. Cuando ese nombre es una dirección de loopback, la comparación falla aunque el certificado sea válido para el host real de la base de datos. El reenvío SSH cambia qué socket transporta los bytes, no la identidad que el cliente debería esperar. Una vez separadas esas dos ideas, el error deja de parecer una falla de TLS.

Un reenvío tampoco es autorización. PostgreSQL sigue aplicando sus propias reglas a la conexión que hace el servidor SSH, así que mantenga la capa de transporte y la capa de base de datos separadas antes de cambiar nada.

Ate el reenvío solo a loopback

El escucha debe existir en la máquina de QGIS y en ningún otro sitio. Nombrar 127.0.0.1 explícitamente lo mantiene fuera de las demás interfaces, mientras que una dirección de enlace omitida puede exponer el puerto según la configuración de puerta de enlace del cliente SSH.

ssh -N -L 127.0.0.1:15432:127.0.0.1:5432 [email protected]

El destino tras los segundos dos puntos se resuelve del lado del servidor SSH, así que este ejemplo supone que PostgreSQL está en el mismo host que sshd; una base de datos en otra máquina necesita esa dirección y sus permisos. Ejecute la sesión con -N para que no se abra ningún intérprete, deje en paz la verificación de la clave de host y confirme que aparece el escucha antes de culpar a QGIS. Si el puerto ya está en uso, el reenvío falla al arrancar y no en el momento de la consulta.

Ponga el nombre y el socket en una sola entrada de servicio

Un archivo de servicio permite que la misma conexión lleve un nombre de verificación y un destino de socket distinto. Guarde la entrada donde libpq busca los servicios, o apunte PGSERVICEFILE hacia ella.

[gis-via-ssh]
host=db.geo.example
hostaddr=127.0.0.1
port=15432
dbname=gisdb
user=gis_reader
sslmode=verify-full
gssencmode=disable
sslrootcert=/path/to/approved-root.crt

Aquí host conserva la identidad usada para las comprobaciones de certificado mientras que hostaddr envía los paquetes al puerto de loopback reenviado, y ambas cosas hacen falta para que esta disposición funcione. gssencmode=disable importa en compilaciones que, de otro modo, negociarían primero el cifrado GSSAPI, porque esa ruta ignora la configuración de TLS recién establecida. Haga referencia al servicio por nombre desde el diálogo de conexión PostgreSQL de QGIS y entregue la contraseña mediante el aviso habitual, no dentro de un archivo compartido. Los nombres y rutas anteriores son marcadores de posición; sustitúyalos por sus propios valores aprobados.

Qué sigue comprobando PostgreSQL tras el túnel

El servidor ve una conexión desde el host SSH, loopback en esta disposición, y la compara en orden con las reglas de autenticación por host. Su rol de base de datos todavía tiene que autenticarse, y el inicio de sesión SSH no otorga por sí mismo ninguna identidad de base de datos. Verifique lo que cree el servidor y no lo que supuso el cliente.

psql "service=gis-via-ssh" -c "select inet_server_addr(), current_user"

Cierre la sesión de reenvío cuando el trabajo esté hecho; la entrada local deja entonces de funcionar y nada más cambia. Una sola ruta a la base de datos no es una VPN para todo el cliente GIS, y tratarla como si lo fuera es como se diagnostica mal la siguiente conexión.

Artículos relacionados