Configuración SSL/TLS
TLS cifra el tráfico de PostgreSQL entre clientes y servidores. En redes en la nube e híbridas, considere las conexiones no cifradas como una violación de la política. PostgreSQL 18.4 admite TLS moderno con hostssl en pg_hba.conf y sslmode=verify-full en los clientes para una confianza mutua verificada por nombre de host.
Receta
# postgresql.conf
ssl = on
ssl_cert_file = '/etc/postgresql/server.crt'
ssl_key_file = '/etc/postgresql/server.key'
ssl_min_protocol_version = 'TLSv1.2'# pg_hba.conf - rechaza conexiones no TLS desde subredes de aplicaciones
hostssl all all 10.20.0.0/16 scram-sha-256
hostnossl all all 0.0.0.0/0 reject# Cadena de conexión del cliente
psql "host=db.internal port=5432 dbname=orders user=app_api sslmode=verify-full sslrootcert=/etc/ssl/certs/ca.pem"Cuándo usar esto:
- Cualquier cliente que cruce una red no confiable (VPC peering, VPN, endpoint público)
- Requisitos de cumplimiento para el cifrado en tránsito
- Postgres administrado donde aún debe configurar
sslmodeen las aplicaciones y rotar los paquetes de CA
Ejemplo de trabajo
Primario autoalojado con certificado de servidor Let's Encrypt y clientes de aplicaciones que verifican el nombre de host.
# Generar u obtener certificado de servidor (autofirmado simplificado para laboratorio)
openssl req -new -x509 -days 365 -nodes -text \
-out server.crt -keyout server.key -subj "/CN=db.prod.internal"
chmod 600 server.key
chown postgres:postgres server.crt server.key# postgresql.conf
ssl = on
ssl_cert_file = 'server.crt'
ssl_key_file = 'server.key'
ssl_min_protocol_version = 'TLSv1.2'# pg_hba.conf
hostssl orders app_api 10.20.0.0/16 scram-sha-256# DSN de la aplicación (ejemplo de Node pg)
export DATABASE_URL="postgresql://app_api@db.prod.internal:5432/orders?sslmode=verify-full&sslrootcert=/etc/app/ca.crt"Lo que esto demuestra:
- El servidor presenta el certificado; los clientes requieren TLS a través de
hostssl verify-fullverifica la CA y la coincidencia del nombre de host- Se rechazan explícitamente las conexiones no TLS del CIDR de la aplicación
Profundización
Matriz de clientes sslmode
| sslmode | ¿Cifra? | ¿Verifica CA? | ¿Verifica nombre de host? |
|---|---|---|---|
disable | No | No | No |
require | Sí | No | No |
verify-ca | Sí | Sí | No |
verify-full | Sí | Sí | Sí |
Use verify-full para conexiones de aplicaciones en producción, a menos que un proxy administrado documente un modelo de confianza diferente.
Rotación de certificados
# Recarga sin tiempo de inactividad después de reemplazar server.crt/server.key
pg_ctl reload -D /var/lib/postgresql/data
# O SQL:
SELECT pg_reload_conf();Rotar certificados de servidor antes de su vencimiento (advertencia de 30 días). Actualizar sslrootcert del cliente cuando cambie la CA.
Notas sobre la nube administrada
| Proveedor | TLS del servidor | Acción del cliente |
|---|---|---|
| RDS / Aurora | Obligatorio en endpoints públicos | Descargar el paquete de CA de RDS, sslmode=verify-full |
| Cloud SQL | Administrado por el servidor | Usar el conector o los parámetros SSL de la consola |
| Neon / Supabase | TLS por defecto | Usar la cadena de conexión proporcionada con sslmode=require como mínimo |
Trampas comunes
sslmode=requiresin verificación de CA - cifrado pero vulnerable a ataques MITM con un certificado no válido. Solución:verify-full+ CA anclada.hostyhostsslpermitiendo el mismo CIDR - los clientes pueden volver a texto plano si están mal configurados. Solución:hostnossl ... rejectpara rangos sensibles.- Certificado de servidor caducado después de la renovación automática en disco - Postgres no recarga certificados en caliente en todas las plataformas. Solución:
pg_reload_conf()en el hook de renovación de certificados. - CN/SAN incorrecto en el certificado -
verify-fullfalla con discrepancia de nombre de host. Solución: el SAN del certificado incluyedb.prod.internalexactamente como se conectan los clientes. - Terminación TLS solo en PgBouncer - el salto entre el pooler y Postgres puede ser texto plano dentro de la VPC. Solución: TLS también a Postgres cuando el modelo de amenaza incluye sniffing este-oeste.
- Almacén de confianza de Java sin la CA de RDS - las aplicaciones fallan con errores PKIX. Solución: importar el paquete de CA del proveedor en el almacén de confianza de JVM o en la imagen del contenedor.
Alternativas
| Alternativa | Usar cuándo | No usar cuándo |
|---|---|---|
| Private Service Connect / Solo VPC | No existe endpoint público | Los clientes fuera de la VPC necesitan acceso |
| Túnel SSH / VPN | Las aplicaciones heredadas no pueden configurar sslmode | Puede corregir el DSN del cliente correctamente |
Certificados de cliente mTLS (cert auth) | Servicio a servicio con pocos clientes | Flota grande de instancias de aplicaciones dinámicas |
| Solo lista blanca de IP | Capa adicional con TLS | Como único control (las IP son falsificables internamente) |
Preguntas frecuentes
¿Es TLS suficiente sin SCRAM?
No. TLS protege en el cable; SCRAM protege el almacenamiento del verificador de contraseña y la respuesta al desafío en el inicio de sesión.
¿Necesita PgBouncer TLS?
Sí, para cliente a pooler cuando los clientes están fuera de la VLAN de la base de datos. TLS de pooler a Postgres depende de su modelo de amenaza este-oeste.
¿Cómo pruebo TLS rápidamente?
psql "sslmode=require" luego \conninfo. OpenSSL: openssl s_client -starttls postgres -connect host:5432.
¿Puedo usar solo TLS 1.3?
PostgreSQL admite TLS 1.2+. Establezca ssl_min_protocol_version y verifique la compatibilidad de la biblioteca cliente.
¿Qué pasa con TLS para la replicación?
Use hostssl para las entradas de replicación y primary_conninfo con sslmode=verify-full en los standbys.
¿Impacto en el rendimiento?
Pequeño en CPUs modernas con reutilización de sesión. El cuello de botella siguen siendo las consultas y el disco, no el handshake TLS en estado estable.
¿Certificados autofirmados en desarrollo?
sslmode=require es aceptable localmente. La producción debe usar una CA adecuada o un paquete de proveedor administrado.
¿Dónde almacenar sslrootcert en K8s?
Montar la CA como un volumen Secret; referenciar la ruta en DATABASE_URL. Rotar mediante despliegue continuo.
¿La replicación lógica usa TLS?
Sí, cuando la cadena de conexión establece sslmode. Trate los enlaces de replicación como tráfico de aplicaciones.
¿Cómo interactúa esto con SCRAM?
Capas ortogonales: TLS para el transporte, SCRAM para la autenticación de contraseña después de que el canal esté cifrado.
Relacionado
- Conceptos básicos de seguridad - modelo de amenaza
- Autenticación SCRAM - autenticación de contraseña
- Proxies de conexión - saltos TLS de PgBouncer
- Conceptos básicos de PostgreSQL administrado - valores predeterminados de TLS en la nube
- Mejores prácticas de seguridad - lista de verificación de endurecimiento
Versiones de la pila: Esta página se escribió para PostgreSQL 18.4 (estable 18, mantenimiento 17), pgvector 0.8+, PgBouncer 1.x, Patroni 3.x y PostGIS 3.5+.