Configuración de SSL/TLS para Conexiones Seguras en PostgreSQL: Una Guía Completa
Aprenda a asegurar las conexiones de PostgreSQL con cifrado SSL/TLS. Esta guía completa cubre la configuración del servidor y del cliente, incluyendo la generación de certificados, la modificación de `postgresql.conf` y `pg_hba.conf`, y la configuración de clientes para una comunicación segura y cifrada. Proteja sus datos sensibles en tránsito y garantice el cumplimiento de los estándares de seguridad modernos.
Configuración de SSL/TLS para Conexiones Seguras en PostgreSQL: Una Guía Completa
La configuración de SSL/TLS en PostgreSQL tiene dos trabajos separados. El primero es el cifrado, para que alguien en la red no pueda leer las credenciales ni los resultados de las consultas en tránsito. El segundo es la identidad, para que el cliente sepa que está hablando con el servidor de base de datos real y no con una máquina que se hace pasar por él. Muchas configuraciones hacen la primera parte y accidentalmente omiten la segunda.
Esa distinción importa en implementaciones reales. sslmode=require cifra la conexión, pero por sí solo no verifica completamente el nombre de host del servidor. sslmode=verify-full sí lo hace. Si su aplicación se conecta a través de una red pública, una red corporativa compartida, una superposición de Kubernetes que no controla completamente, o cualquier entorno donde el tráfico pueda ser interceptado, verify-full debería ser el objetivo.
Entendiendo SSL/TLS en PostgreSQL
SSL/TLS (Secure Sockets Layer/Transport Layer Security) es un protocolo criptográfico diseñado para proporcionar seguridad en la comunicación a través de una red informática. Cuando se aplica a PostgreSQL, cifra los datos intercambiados entre el servidor de base de datos y sus clientes. Esto evita que partes no autorizadas intercepten y lean información sensible como credenciales, datos financieros o detalles personales.
Los clientes de PostgreSQL soportan varios modos SSL:
sslmode=disable: Solo usa una conexión simple y sin cifrar.sslmode=prefer: Intenta TLS primero, luego retrocede a TCP simple si TLS no está disponible. Esto es conveniente, pero puede ocultar una mala configuración.sslmode=require: Requiere cifrado TLS, pero no necesariamente verifica el nombre de host del servidor.sslmode=verify-ca: Requiere TLS y verifica que el certificado esté encadenado a una CA de confianza.sslmode=verify-full: Requiere TLS, verifica la CA y verifica que el nombre de host coincida con el certificado.
En el lado del servidor, ssl = on solo significa que PostgreSQL es capaz de aceptar conexiones TLS. No obliga a todos los clientes a usar TLS. La aplicación se realiza en pg_hba.conf con reglas hostssl y evitando reglas host más amplias que permitan a los mismos usuarios y redes conectarse sin TLS.
Requisitos Previos para la Configuración SSL/TLS
Antes de comenzar a configurar PostgreSQL para SSL/TLS, asegúrese de tener lo siguiente:
- OpenSSL Instalado: El kit de herramientas OpenSSL es esencial para generar y gestionar certificados SSL. Generalmente está preinstalado en sistemas Linux y macOS. Para Windows, es posible que necesite descargarlo e instalarlo por separado.
- Acceso a los Archivos de Configuración de PostgreSQL: Necesitará privilegios administrativos para modificar los archivos
postgresql.confypg_hba.conf. - Comprensión de las Autoridades de Certificación (CA): Aunque puede crear certificados autofirmados para pruebas, los entornos de producción deben usar certificados firmados por una Autoridad de Certificación (CA) de confianza o una CA empresarial interna.
Configuración SSL/TLS del Lado del Servidor
La configuración del lado del servidor implica habilitar SSL, especificar la ubicación de los certificados y claves SSL, y configurar la autenticación del cliente.
1. Generación u Obtención de Certificados y Claves SSL
Hay dos formas principales de obtener certificados SSL para su servidor PostgreSQL:
- Certificados Autofirmados (para pruebas/desarrollo): Estos se crean usando OpenSSL y no son confiables por defecto para clientes externos. Son útiles para la configuración inicial y pruebas internas.
- Certificados de una Autoridad de Certificación (CA) (para producción): Obtenga certificados de una CA pública de confianza (por ejemplo, Let's Encrypt, DigiCert) o una CA empresarial interna. Esto asegura que los clientes puedan verificar la identidad del servidor.
Creación de Certificados Autofirmados usando OpenSSL:
Este es un enfoque común para entornos de desarrollo e internos. Ejecute los siguientes comandos en su servidor PostgreSQL o en una máquina con OpenSSL:
Cree un directorio para los certificados: Es una buena práctica mantener los certificados organizados.
sudo mkdir -p /etc/postgresql/ssl sudo chown postgres:postgres /etc/postgresql/ssl cd /etc/postgresql/sslGenere la Clave Privada del Servidor: Esta clave debe mantenerse en secreto.
sudo openssl genrsa -out server.key 2048Cree una Solicitud de Firma de Certificado (CSR) del Servidor: Esto contiene información sobre su servidor.
sudo openssl req -new -key server.key -out server.csrUse el nombre de host al que se conectarán sus clientes, como
db01.internal.example.com. Los clientes modernos normalmente verifican el Nombre Alternativo del Sujeto (SAN), así que incluya nombres DNS en la solicitud de certificado cuando su proceso de CA lo soporte.Firme el Certificado con su Propia CA (para uso interno):
- Cree una clave privada y un certificado de CA raíz (si no tiene uno):
# Generar clave privada de CA sudo openssl genrsa -des3 -out root.key 2048 # Crear certificado de CA (válido por 3650 días) sudo openssl req -new -x509 -days 3650 -key root.key -out root.crt - Firme la CSR del servidor con la CA: Esto crea el certificado de servidor de confianza.
sudo openssl x509 -req -days 365 -in server.csr -CA root.crt -CAkey root.key -set_serial 01 -out server.crt
- Cree una clave privada y un certificado de CA raíz (si no tiene uno):
Establezca Permisos: Asegúrese de que el usuario de PostgreSQL pueda leer estos archivos.
sudo chown postgres:postgres server.key server.crt root.crt sudo chmod 600 server.key sudo chmod 644 server.crt root.crt
Uso de Certificados de una CA Pública/Empresarial:
Si obtiene certificados de una CA, normalmente recibirá:
server.crt: El certificado público de su servidor.server.key: La clave privada de su servidor.root.crt(o similar): El certificado raíz de la CA (y potencialmente certificados intermedios).
Coloque estos archivos en un directorio seguro (por ejemplo, /etc/postgresql/ssl/) y asegúrese de que el usuario de PostgreSQL tenga permisos de lectura.
2. Configuración de postgresql.conf
Edite su archivo postgresql.conf (generalmente ubicado en su directorio de datos de PostgreSQL) para habilitar SSL y especificar los archivos de certificado.
#------------------------------------------------------------------------------
# SSL
#------------------------------------------------------------------------------
ssl = on
# Estos están todos en formato PEM, y se ignoran si la clave/certificado del servidor no
# están configurados. Por defecto, se espera que los archivos estén en el directorio de datos
# del servidor. Alternativamente, se pueden especificar como rutas completas.
ssl_cert_file = '/etc/postgresql/ssl/server.crt' # (cambie el nombre de archivo si es necesario)
ssl_key_file = '/etc/postgresql/ssl/server.key' # (cambie el nombre de archivo si es necesario)
ssl_ca_file = '/etc/postgresql/ssl/root.crt' # (opcional, para verificación de certificado del cliente)
# Opcional: especifique la lista de cifrados si es necesario
#ssl_ciphers = 'HIGH:MEDIUM:+3DES:!aNULL'
# Opcional: habilite la verificación del certificado del cliente
#ssl_ca_file debe estar configurado en un archivo que contenga el/los certificado(s) de CA de confianza
#ssl_crl_file = ''
#ssl_crl_dir = ''
ssl = on: Habilita el soporte SSL en el servidor.ssl_cert_file: Ruta al certificado público del servidor.ssl_key_file: Ruta a la clave privada del servidor.ssl_ca_file: Ruta a los certificados CA que PostgreSQL debe confiar al verificar los certificados del cliente. Los clientes usan su propio archivo CA, comosslrootcert, para verificar el servidor.
3. Configuración de pg_hba.conf para la Aplicación SSL
El archivo pg_hba.conf controla la autenticación del cliente. Necesita modificar las entradas para aplicar conexiones SSL.
Por defecto, las entradas en pg_hba.conf se ven así:
# TYPE DATABASE USER ADDRESS METHOD
local all all peer
# Conexiones locales IPv4:
host all all 127.0.0.1/32 scram-sha-256
# Conexiones locales IPv6:
host all all ::1/128 scram-sha-256
Para aplicar SSL, cambie las entradas host a hostssl:
# TYPE DATABASE USER ADDRESS METHOD
local all all peer
# Conexiones locales IPv4:
hostssl all all 127.0.0.1/32 scram-sha-256
# Conexiones locales IPv6:
hostssl all all ::1/128 scram-sha-256
# Ejemplo para acceso a red externa - requiere SSL
hostssl all app_user 10.20.0.0/16 scram-sha-256
hostssl all app_user 2001:db8:20::/48 scram-sha-256
hostssl: Este tipo de registro requiere conexiones SSL. Cualquier intento de conexión sin SSL será rechazado.hostnossl: Este tipo de registro prohíbe explícitamente las conexiones SSL.host: Permite conexiones SSL y no SSL. Si existe una reglahostcoincidente antes o en lugar de su reglahostssl, los clientes aún pueden conectarse sin TLS.
Evite publicar acceso 0.0.0.0/0 a menos que haya una razón sólida y otros controles estén en su lugar. La mayoría de las bases de datos de producción deberían aceptar conexiones solo desde subredes de aplicaciones, hosts bastión, poolers de conexión o rangos de red privados.
4. Reinicio del Servidor PostgreSQL
Después de modificar postgresql.conf y pg_hba.conf, debe reiniciar el servicio PostgreSQL para que los cambios surtan efecto.
# Para sistemas que usan systemd (la mayoría de las distribuciones Linux modernas)
sudo systemctl restart postgresql
# Para sistemas que usan init.d
sudo service postgresql restart
Configuración SSL/TLS del Lado del Cliente
Los clientes también deben configurarse para conectarse de forma segura. Esto implica especificar parámetros de conexión, potencialmente proporcionar certificados de cliente y verificar el certificado del servidor.
1. Parámetros de la Cadena de Conexión
Al conectarse a través de psql o cualquier biblioteca cliente de PostgreSQL, puede especificar parámetros SSL en la cadena de conexión o como opciones individuales.
Conexión SSL Básica (Solo Autenticación del Servidor):
psql "sslmode=require host=nombre_de_su_servidor dbname=su_bd user=su_usuario"
sslmode: Controla el comportamiento SSL del cliente.disable: Solo permite conexiones no SSL.allow: Permite conexiones no SSL, pero prefiere SSL si el servidor lo soporta.prefer(predeterminado): Prefiere SSL, pero permite no SSL si SSL falla.require: Solo permite conexiones SSL. Si el servidor no soporta SSL, la conexión falla.verify-ca: Solo permite conexiones SSL y verifica que el certificado del servidor esté firmado por una CA de confianza. El parámetrosslrootcertdebe estar configurado.verify-full: Solo permite conexiones SSL, verifica el certificado del servidor contra una CA de confianza y verifica que el nombre de host del servidor coincida con el nombre común (CN) o el nombre alternativo del sujeto (SAN) del certificado.
Verificación del Certificado del Servidor (verify-ca o verify-full):
Para una seguridad mejorada, los clientes deben verificar la identidad del servidor. Esto requiere que el cliente confíe en la CA que firmó el certificado del servidor.
- Obtenga el Certificado CA: Obtenga el archivo
root.crt(o el certificado CA apropiado) que se usó para firmar el certificado del servidor. - Especifique
sslrootcert: Indique al cliente dónde encontrar este certificado CA.
psql "sslmode=verify-full host=nombre_de_su_servidor dbname=su_bd user=su_usuario sslrootcert=/ruta/a/su/root.crt"
Esta es la cadena de conexión que debe probar desde el mismo host o contenedor que ejecuta la aplicación. Un fallo común es que psql funcione desde una computadora portátil de administrador porque el archivo CA existe allí, mientras que el contenedor de la aplicación falla porque el paquete CA nunca se montó.
2. Certificados de Cliente (Autenticación Mutua)
Para un nivel aún más alto de seguridad, puede implementar autenticación mutua, donde el servidor también verifica la identidad del cliente usando certificados de cliente.
Generación de Certificados de Cliente:
Similar a los certificados de servidor, necesitará una clave privada de cliente y un certificado de cliente firmado por una CA de confianza para el servidor (a menudo la misma CA que el certificado del servidor).
Genere la Clave Privada del Cliente:
openssl genrsa -des3 -out client.key 2048Cree la CSR del Cliente:
openssl req -new -key client.key -out client.csrProporcione detalles, asegurándose de que el Nombre Común sea único para el cliente.
Firme la CSR del Cliente con la CA:
sudo openssl x509 -req -days 365 -in client.csr -CA root.crt -CAkey root.key -set_serial <serial_único> -out client.crtEstablezca Permisos:
chmod 600 client.key chmod 644 client.crt
Configuración de pg_hba.conf para la Autenticación con Certificado de Cliente:
En el servidor, necesita configurar pg_hba.conf para aceptar la autenticación con certificado de cliente. Esto a menudo usa el método de autenticación cert.
# TYPE DATABASE USER ADDRESS METHOD
# Requiere SSL y autenticación con certificado de cliente para usuario/bd específicos
hostssl all su_usuario ip_del_cliente/32 cert map=su_mapa_cert
También podría necesitar definir un archivo de mapa de certificados (opción cert_map) si desea mapear detalles específicos del certificado del cliente (como Subject o SubjectAltName) a usuarios de PostgreSQL. Consulte la documentación oficial de PostgreSQL para obtener una configuración detallada de autenticación cert y mapeo de certificados.
Configuración del Cliente para Usar Certificados:
Actualice la cadena de conexión del cliente para incluir rutas a su certificado y clave:
psql "sslmode=verify-full host=nombre_de_su_servidor dbname=su_bd user=su_usuario \
sslrootcert=/ruta/a/su/root.crt sslcert=/ruta/a/su/client.crt sslkey=/ruta/a/su/client.key"
Mejores Prácticas y Consejos
- Use
sslmode=verify-full: Apunte a usarverify-fullen el lado del cliente para reducir el riesgo de intermediario. - Proteja las Claves Privadas: Asegúrese de que las claves privadas (archivos
.key) tengan permisos de archivo estrictos (por ejemplo,chmod 600) y solo sean legibles por el usuario de PostgreSQL en el servidor y el usuario que se conecta en el cliente. - Renueve los Certificados Regularmente: Los certificados tienen fechas de vencimiento. Implemente un proceso para renovarlos antes de que expiren para evitar interrupciones en la conexión.
- Gestión Centralizada de Certificados: Para implementaciones más grandes, considere usar un sistema de gestión de certificados o automatizar la emisión y renovación de certificados.
- Monitoree los Registros: Revise los registros de PostgreSQL en busca de errores relacionados con SSL durante el inicio o los intentos de conexión.
- Documentación: Consulte la documentación oficial de PostgreSQL para conocer los parámetros más actualizados y las opciones de configuración avanzada específicas de su versión de PostgreSQL.
Lista de Verificación Rápida
Después de reiniciar PostgreSQL, verifique que el servidor esté escuchando con TLS habilitado:
SHOW ssl;
SHOW ssl_cert_file;
SHOW ssl_key_file;
Luego pruebe desde un host cliente:
psql "host=nombre_de_su_servidor dbname=su_bd user=su_usuario sslmode=verify-full sslrootcert=/ruta/a/root.crt"
Dentro de la sesión, confirme que la conexión está cifrada:
SELECT ssl, version, cipher
FROM pg_stat_ssl
WHERE pid = pg_backend_pid();
Si ssl es falso, sus reglas pg_hba.conf no están aplicando lo que cree. Si verify-full falla pero require funciona, probablemente el certificado carece del nombre de host correcto, el cliente no confía en la CA, o la aplicación se conecta por dirección IP mientras el certificado se emitió para un nombre DNS.
Una buena configuración TLS de PostgreSQL no es solo ssl = on. Es una cadena: un certificado con los nombres correctos, claves privadas con permisos estrictos, reglas hostssl que realmente aplican TLS, y clientes que verifican el servidor en lugar de simplemente cifrar el socket.