| Both sides previous revisionPrevious revisionNext revision | Previous revision |
| proyecto:conexion_externa [2022/04/20 06:00] – ahogan | proyecto:conexion_externa [2026/09/25 18:31] (current) – Lenguaje sin género en la guía del servidor semorale |
|---|
| ====== Conexión Externa ====== | ====== Conexión Externa ====== |
| |
| Hay que configurar Postgres para aceptar conexiones desde nuestra aplicación. | 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. |
| |
| ===== Configurar Postgres ===== | Todo esto supone que ya siguieron [[proyecto:configurar_postgres|Configurar Postgres]]. En los ejemplos usamos la máquina 40. |
| |
| Ahora tenemos que configurar Postgres para permitir conexiones externas. Tenemos que cambiar la configuración en dos archivos: | ===== 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: |
| | |
| | {{proyecto:servidor_mapa_puertos.png?direct&900|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: |
| | |
| | {{proyecto:servidor_dos_filtros.png?direct&900|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: |
| | |
| | <code>\password cc3201</code> |
| | |
| | Pide la contraseña dos veces y no muestra nada al escribirla: |
| | |
| | {{proyecto:servidor_ext_01_password.png?direct&770|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: |
| |
| <code> | <code> |
| sudo vim /etc/postgresql/11/main/pg_hba.conf | ls /etc/postgresql/ |
| | ss -ltn | grep 5432 |
| </code> | </code> |
| |
| En este archivo, la configuración, por defecto, permite solo conexiones desde localhost. Específicamente, dice: | {{proyecto:servidor_ext_02_version_y_puertos.png?direct&900|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: |
| | |
| | <code> |
| | sudo vim /etc/postgresql/17/main/pg_hba.conf |
| | </code> |
| | |
| | (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: |
| |
| <code> | <code> |
| # IPv4 local connections: | # IPv4 local connections: |
| host all all 127.0.0.1/32 md5 | host all all 127.0.0.1/32 scram-sha-256 |
| # IPv6 local connections: | # IPv6 local connections: |
| host all all ::1/128 md5 | host all all ::1/128 scram-sha-256 |
| </code> | </code> |
| |
| Tenemos que cambiar esta configuración a la siguiente: | {{proyecto:servidor_ext_03_pg_hba_antes.png?direct&900|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í: |
| |
| <code> | <code> |
| # IPv4 local connections: | # IPv4 local connections: |
| host all all 0.0.0.0/0 md5 | host all all 0.0.0.0/0 scram-sha-256 |
| # host all all 127.0.0.1/32 md5 | # host all all 127.0.0.1/32 scram-sha-256 |
| # IPv6 local connections: | # IPv6 local connections: |
| host all all ::0/0 md5 | host all all ::0/0 scram-sha-256 |
| # host all all ::1/128 md5 | # host all all ::1/128 scram-sha-256 |
| </code> | </code> |
| |
| ... y guardar el archivo. (''#'' indica un comentario, ''0.0.0.0/0'' indica permitir todo, ''::0/0'' igualmente). | {{proyecto:servidor_ext_04_pg_hba_despues.png?direct&900|pg_hba.conf después: cualquier dirección, con contraseña}} |
| |
| El segundo archivo que tenemos que cambiar es: | 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: |
| |
| <code> | <code> |
| sudo vim /etc/postgresql/11/main/postgresql.conf | sudo vim /etc/postgresql/17/main/postgresql.conf |
| </code> | </code> |
| |
| En ese archivo, hay que cambiar ''localhost'' por ''*'' para escuchar a cada IP (no solo localhost): | Es un archivo largo. Para encontrar la línea, en vim escriban ''/listen_addresses'' y apreten Enter (el ''/'' busca texto). Viene así: |
| |
| <code> | <code> |
| listen_addresses = '*' # what IP address(es) to listen on; | #listen_addresses = 'localhost' # what IP address(es) to listen on; |
| </code> | </code> |
| |
| ... y guardar el archivo. | {{proyecto:servidor_ext_05_listen_antes.png?direct&900|listen_addresses viene comentado}} |
| |
| Finalmente, hay que recargar la configuración de Postgres. Entonces, en ''psql'', se debería ejecutar: | 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": |
| |
| <code>SELECT pg_reload_conf();</code> | <code> |
| | listen_addresses = '*' # what IP address(es) to listen on; |
| | </code> |
| | |
| | {{proyecto:servidor_ext_06_listen_despues.png?direct&900|listen_addresses sin # y con asterisco}} |
| | |
| | ... y guardar el archivo con ''Esc'' y '':wq''. |
| | |
| | ===== Paso 5: reiniciar Postgres ===== |
| |
| A veces no funciona (no sé porque) pero para tener seguridad, se puede quitar ''psql'' y ejecutar: | Postgres lee estos archivos al arrancar, así que hay que reiniciarlo. Se hace desde la terminal del servidor, no desde ''psql'': |
| |
| <code> | <code> |
| sudo service postgresql stop | sudo systemctl restart postgresql |
| sudo service postgresql start | |
| </code> | </code> |
| |
| (Hemos reiniciado Postgres.) | ''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. |
| |
| ==== La Contraseña ==== | (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.) |
| |
| Ahora tenemos que configurar la contraseña. No es la misma contraseña que la contraseña de SSH para ingresar al servidor. De hecho, en principio no hay una contraseña (en el servidor, Postgres usa los credenciales de SSH por defecto, pero la aplicación se conectará directamente con Postres, no por SSH). | Para revisar que quedó escuchando hacia afuera, repitan el ''ss'' del paso 2: |
| |
| En ''psql'', hay que poner: | <code> |
| | ss -ltn | grep 5432 |
| | </code> |
| |
| <code>\password cc3201</code> | {{proyecto:servidor_ext_07_reinicio.png?direct&900|Antes del reinicio escucha en 127.0.0.1, después en 0.0.0.0}} |
| |
| Luego esta contraseña la pueden usar para conectarse desde un código. | 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 ''#''). |
| |
| ===== Los Puertos ===== | 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. |
| |
| En caso de querer establecer una conexión 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, si uno estuviera utilizando la máquina 6, y quisiera establecer una conexión con Postgres en esa máquina **desde otra máquina**, el puerto sería 5506; si estuviera en el máquina 21, sería 5521. | ===== 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. |
| |
| <code> | <code> |
| hostname: cc3201.dcc.uchile.cl | hostname: cc3201.dcc.uchile.cl |
| puerto: 55XX (donde XX es el número de la máquina) | 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 |
| </code> | </code> |
| |
| Si uno quiere establecer una conexión con Postgres en la misma máquina, el puerto será ''5432'' y el host será ''localhost''. El puerto ''55XX'' no va a funcionar dentro de la misma máquina. | Para conectarse con Postgres desde 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): |
| | |
| | <code> |
| | psql -h cc3201.dcc.uchile.cl -p 5540 -U cc3201 cc3201 |
| | </code> |
| | |
| | ''-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): |
| | |
| | {{proyecto:servidor_ext_08_conexion_notebook.png?direct&900|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. | |