User Tools

Site Tools


proyecto:conexion_externa

This is an old revision of the document!


Conexión Externa

Por defecto, Postgres solo acepta conexiones que vienen de la misma máquina. Eso basta mientras trabajen con psql dentro del servidor, pero no sirve si quieren conectarse desde su notebook (con psql, DBeaver o pgAdmin) o desde una aplicación que corre en su computador. Esta página explica cómo abrir esa puerta. Toma unos 15 minutos.

Todo esto supone que ya siguieron Configurar Postgres. En los ejemplos usamos la máquina 40.

Cómo llega una conexión a su máquina

Su máquina virtual no tiene una dirección propia en internet. Todas las máquinas del curso están detrás de cc3201.dcc.uchile.cl, que reenvía cada puerto a la máquina que corresponde:

El puerto 3XX llega al SSH de la máquina XX y el 55XX a su Postgres

Un puerto es un número que identifica a qué programa va dirigida una conexión dentro de una máquina. SSH atiende en el puerto 22 y Postgres en el 5432. Desde afuera, el puerto 3XX de cc3201.dcc.uchile.cl llega al puerto 22 de la máquina XX, y el 55XX llega al 5432.

Para que una conexión desde afuera llegue a su base de datos, tiene que pasar dos filtros de Postgres, y los dos vienen cerrados:

Primero listen_addresses y después pg_hba.conf

Hay que hacer tres cosas en el servidor: darle una contraseña a su rol de Postgres, abrir los dos filtros y reiniciar Postgres. Al final hay una prueba para ver si quedó funcionando.

Término Qué es
localhost “Esta misma máquina”. Su dirección IPv4 es 127.0.0.1 y la IPv6 es ::1.
dirección IP El número que identifica a un computador en la red. Hay dos formatos, IPv4 (como 192.80.24.220) e IPv6 (como 2001:db8::1).
0.0.0.0/0 “Cualquier dirección IPv4”. El /0 indica cuántos bits de la dirección tienen que coincidir; con 0, sirve cualquiera. ::0/0 es lo mismo en IPv6.
postgresql.conf El archivo de configuración general de Postgres.
listen_addresses La opción de postgresql.conf que dice en qué direcciones de red escucha Postgres.
pg_hba.conf El archivo que decide quién puede conectarse, a qué base y desde dónde (hba viene de host-based authentication).
scram-sha-256 El método de autenticación que pide contraseña y la envía cifrada.

Paso 1: la contraseña

Primero hay que configurar la contraseña de Postgres. No es la misma contraseña que la de SSH para ingresar al servidor. De hecho, en principio su rol no tiene contraseña. Dentro del servidor, Postgres confía en que ustedes son cc3201 porque entraron por SSH con ese usuario de Linux (eso se llama autenticación peer). Desde afuera no hay cómo saberlo, así que Postgres va a pedir una contraseña.

En psql, hay que poner:

\password cc3201

Pide la contraseña dos veces y no muestra nada al escribirla:

Definir la contraseña de Postgres con \password

Esta es la contraseña que van a usar para conectarse desde su notebook o desde la aplicación. Como el puerto de Postgres va a quedar abierto a todo internet, elijan una contraseña larga y que no sea la misma de SSH. Después salgan de psql con \q, porque lo que sigue se hace en la terminal del servidor.

Paso 2: ver la versión y el estado actual

Los archivos de configuración están en una carpeta que lleva el número de versión de Postgres. Para verla, y de paso ver en qué direcciones escucha Postgres ahora:

ls /etc/postgresql/
ss -ltn | grep 5432

La carpeta es 17 y Postgres escucha solo en 127.0.0.1

ls muestra 17, así que los archivos están en /etc/postgresql/17/main/. ss -ltn lista los puertos en que hay un programa escuchando (l: listening, t: TCP, n: números en vez de nombres) y grep 5432 deja solo las líneas de Postgres. Por ahora dice 127.0.0.1:5432 y [::1]:5432; es decir, Postgres escucha solo en localhost.

Paso 3: pg_hba.conf

Abran el primer archivo:

sudo vim /etc/postgresql/17/main/pg_hba.conf

(Si la ruta está mal, vim abre un archivo vacío y en la última línea aparece [New DIRECTORY]. En ese caso salgan con :q! y revisen el número de versión del paso 2.)

Cada línea que no empieza con # es una regla, con cinco columnas: tipo de conexión (local dentro de la máquina, host por red), base de datos, rol, dirección de origen y método de autenticación. Casi al final del archivo están las reglas para conexiones por red:

# IPv4 local connections:
host    all             all             127.0.0.1/32            scram-sha-256
# IPv6 local connections:
host    all             all             ::1/128                 scram-sha-256

pg_hba.conf antes: solo 127.0.0.1 y ::1

Estas dos reglas dicen “cualquier base y cualquier rol, pero solo desde esta misma máquina”. Hay que dejarlas así:

# IPv4 local connections:
host    all             all             0.0.0.0/0               scram-sha-256
# host    all             all             127.0.0.1/32            scram-sha-256
# IPv6 local connections:
host    all             all             ::0/0                   scram-sha-256
# host    all             all             ::1/128                 scram-sha-256

pg_hba.conf después: cualquier dirección, con contraseña

Las reglas nuevas aceptan conexiones desde cualquier dirección, siempre con contraseña (scram-sha-256). Las antiguas quedan como comentario (el # al comienzo hace que Postgres ignore la línea), por si quieren volver atrás.

En vim, hay que presionar i para empezar a editar; luego, para guardar y salir, Esc y después :wq [enter]. Si se perdieron, Esc y :q! [enter] sale sin guardar.

Paso 4: postgresql.conf

El segundo archivo es:

sudo vim /etc/postgresql/17/main/postgresql.conf

Es un archivo largo. Para encontrar la línea, en vim escriban /listen_addresses y apreten Enter (el / busca texto). Viene así:

#listen_addresses = 'localhost'		# what IP address(es) to listen on;

listen_addresses viene comentado

Hay que borrar el # del comienzo (si no, la línea sigue siendo un comentario y Postgres usa el valor por defecto, localhost) y cambiar localhost por *, que significa “escuchar en todas las direcciones de la máquina”:

listen_addresses = '*'		# what IP address(es) to listen on;

listen_addresses sin # y con asterisco

… y guardar el archivo con Esc y :wq.

Paso 5: reiniciar Postgres

Postgres lee estos archivos al arrancar, así que hay que reiniciarlo. Se hace desde la terminal del servidor, no desde psql:

sudo systemctl restart postgresql

systemctl es el programa que maneja los servicios de Linux (los programas que quedan corriendo de fondo, como Postgres). restart lo detiene y lo vuelve a partir; no imprime nada si funciona.

(En psql existe SELECT pg_reload_conf();, que recarga la configuración sin reiniciar. No alcanza en este caso, porque listen_addresses solo cambia al reiniciar.)

Para revisar que quedó escuchando hacia afuera, repitan el ss del paso 2:

ss -ltn | grep 5432

Antes del reinicio escucha en 127.0.0.1, después en 0.0.0.0

Tiene que aparecer 0.0.0.0:5432. Si aparece 127.0.0.1:5432, falta el reinicio o el cambio en postgresql.conf no quedó bien (revisen el #).

Si Postgres no arranca después del reinicio, lo más probable es un error de tipeo en uno de los dos archivos. sudo systemctl status postgresql muestra el estado, y sudo tail /var/log/postgresql/postgresql-17-main.log las últimas líneas del registro, donde aparece el archivo y la línea con el problema.

Los Puertos

Para conectarse con Postgres desde otra máquina (por ejemplo, un notebook), el puerto será 55XX donde XX es el número de la máquina. Por ejemplo, desde afuera la máquina 6 se conecta por el puerto 5506 y la máquina 21 por el 5521.

hostname: cc3201.dcc.uchile.cl
puerto: 55XX (donde XX es el número de la máquina)
usuario: cc3201
base de datos: cc3201
contraseña: la que pusieron con \password

Si uno quiere conectarse con Postgres en la misma máquina (por ejemplo, desde una aplicación que corre en el servidor), el puerto será 5432 y el host será localhost. El puerto 55XX no va a funcionar dentro de la misma máquina, porque el reenvío de puertos solo funciona para conexiones que vienen de afuera.

Probar la conexión

Desde su notebook, si tienen psql instalado (en la máquina 40, por ejemplo):

psql -h cc3201.dcc.uchile.cl -p 5540 -U cc3201 cc3201

-h es el host (a qué máquina conectarse), -p el puerto, -U el rol, y el último cc3201 es la base de datos. Pide la contraseña de Postgres (la del paso 1):

Conexión desde el notebook por el puerto 5540

Si muestra cc3201=#, la conexión externa funciona. La línea que empieza con SSL connection indica que la conexión va cifrada. Si la versión de psql de su notebook es distinta de la del servidor (en la imagen, 18 y 17), no hay problema.

También pueden conectarse con DBeaver o pgAdmin: al crear la conexión, elijan PostgreSQL y usen los mismos datos de la sección anterior.

Si algo falla, el mensaje de error indica qué falta:

Mensaje Qué revisar
Connection refused Postgres no está escuchando hacia afuera (el primer filtro). Revisen listen_addresses (sin #) y reinicien con sudo systemctl restart postgresql.
no pg_hba.conf entry for host … Falta la línea con 0.0.0.0/0 en pg_hba.conf (el segundo filtro), o quedó comentada. Después de corregirla, reinicien.
password authentication failed for user “cc3201” La contraseña no coincide. Vuelvan a ponerla con \password cc3201 dentro del servidor.
La conexión se queda pegada un buen rato y después dice timeout expired Probablemente usaron el puerto 55XX desde dentro del servidor (ahí es localhost y 5432), o se equivocaron en el número de máquina.
proyecto/conexion_externa.1790360747.txt.gz · Last modified: by semorale