5.3 KiB
Plan: Conectar PostgreSQL de Luminarrh de forma segura y encriptada
Contexto
Tienes una base de datos PostgreSQL (imagen postgres:18) corriendo en Docker en tu Synology NAS, contenida en luminarrh/. Actualmente:
- Sin encriptación: No hay SSL configurado en PostgreSQL
- Puerto expuesto: 5436 → 5432 sin restricción de hosts
- Sin pg_hba.conf: No hay control de acceso por IP ni requisito de SSL
Necesitas que la base se conecte de forma segura y encriptada desde:
- Internet → dominio
senabed.p-lao.com - Red local → rango
<<INTERNAL_IP_2>>/24
Tú te encargas del enrutamiento y port forwarding del router. La contraseña se mantiene igual (<<DB_PASSWORD_1>>).
Pasos de implementación
1. Generar certificado SSL
Generar un certificado SSL autofirmado para el dominio senabed.p-lao.com:
# Generar clave privada y certificado
openssl req -x509 -nodes -days 3650 -newkey rsa:2048 \
-keyout /home/aleleba/projects/synology-apps-containers/luminarrh/ssl/server.key \
-out /home/aleleba/projects/synology-apps-containers/luminarrh/ssl/server.crt \
-subj "/CN=senabed.p-lao.com" \
-addext "subjectAltName=DNS:senabed.p-lao.com"
Los archivos se guardan en luminarrh/ssl/ y se montan como solo lectura en el contenedor.
2. Actualizar postgresql.conf
Agregar configuración SSL y restricciones de red:
# Conexiones
listen_addresses = '*'
max_connections = 500
# SSL
ssl = on
ssl_cert_file = '/etc/postgresql/ssl/server.crt'
ssl_key_file = '/etc/postgresql/ssl/server.key'
ssl_min_protocol_version = 'TLSv1.2'
# Memoria
shared_buffers = 2GB
maintenance_work_mem = 128MB
# Timezone
timezone = 'America/Guatemala'
log_timezone = 'America/Guatemala'
3. Crear pg_hba.conf con control de acceso
Crear un archivo pg_hba.conf que:
- Requiera SSL para todas las conexiones externas
- Restrinja por IP a
<<INTERNAL_IP_2>>/24(red local) y la IP pública del NAS (desde internet) - Permita conexiones locales sin SSL (dentro del contenedor)
# TYPE DATABASE USER ADDRESS METHOD
# Conexión local (dentro del contenedor) - sin SSL requerido
local all all peer
# Conexiones desde red local <<INTERNAL_IP_2>>/24 - SSL requerido
hostssl all all <<INTERNAL_IP_2>>/24 scram-sha256
# Conexiones desde internet (IP pública del NAS) - SSL requerido
hostssl all sarh2 <IP_PUBLICA_NAS>/32 scram-sha256
# Rechazar todo lo demás
host all all 0.0.0.0/0 reject
Se usa hostssl (no host) para que PostgreSQL rechace automáticamente cualquier conexión que no use SSL.
4. Actualizar docker-compose.yaml
version: '3.8'
services:
postgres-luminarrh:
image: postgres:18
restart: always
environment:
POSTGRES_USER: sarh2
POSTGRES_PASSWORD: <<DB_PASSWORD_1>>
POSTGRES_DB: sarh_db
PGDATA: /var/lib/postgresql/18/docker
ports:
- '5436:5432/tcp'
network_mode: databases
volumes:
- /volume1/docker/postgres/postgres-luminarrh/data:/var/lib/postgresql
- /volume1/docker/projects/synology-apps-containers/luminarrh/postgresql.conf:/etc/postgresql/postgresql.conf
- /volume1/docker/projects/synology-apps-containers/luminarrh/luminarrh_demo.sql:/docker-entrypoint/initdb.d/luminarrh_demo.sql
- /volume1/docker/projects/synology-apps-containers/luminarrh/pg_hba.conf:/etc/postgresql/pg_hba.conf
- /volume1/docker/projects/synology-apps-containers/luminarrh/ssl:/etc/postgresql/ssl:ro
command: postgres -c config_file=/etc/postgresql/postgresql.conf -c hba_file=/etc/postgresql/pg_hba.conf
Cambios clave:
- Eliminar puerto UDP (5432/udp) — PostgreSQL no lo usa
- Mount del SSL como
ro(solo lectura) - Mount del pg_hba.conf explícito
- Mantener contraseña
<<DB_PASSWORD_1>>
5. Crear README.md como guía de conexión
Crear luminarrh/README.md con instrucciones completas de cómo conectarse usando el certificado SSL.
Resumen de archivos a modificar/crear
| Archivo | Acción |
|---|---|
luminarrh/postgresql.conf |
Modificar — agregar SSL, TLS min version |
luminarrh/pg_hba.conf |
Crear — control de acceso por IP + SSL (hostssl) |
luminarrh/docker-compose.yaml |
Modificar — mounts SSL, eliminar UDP |
luminarrh/ssl/server.key |
Crear — clave privada SSL |
luminarrh/ssl/server.crt |
Crear — certificado SSL |
luminarrh/README.md |
Crear — guía de conexión con certificado |
Verificación (la hacemos juntos)
- Verificar psql instalado:
psql --version— si no está, instalarpostgresql-client - Verificar SSL activo:
psql "host=senabed.p-lao.com port=5436 dbname=sarh_db user=sarh2 sslmode=require sslcert=... sslkey=... sslrootcert=..."— debe conectar sin error - Verificar rechazo sin SSL:
psql "host=senabed.p-lao.com port=5436 dbname=sarh_db user=sarh2 sslmode=disable"— debe rechazar - Verificar conexión desde red local: intentar conectar desde un host en
<<INTERNAL_IP_2>>/24con SSL — debe conectar - Verificar logs: revisar
/var/log/postgresql/para ver conexiones aceptadas/rechazadas