En este artículo exploramos los principales protocolos y configuraciones que te ayudarán a blindar tu instancia de PostgreSQL frente a accesos no autorizados y vulnerabilidades comunes, y a registralo todo.
Que vamos ver en este artículo
1) Seguridad de conexión
En el primer punto tenemos dos temas a mirar:- SSL/TLS (postgresql.conf). Cifrar la comunicación entre el cliente y el servidor con SSL/TLS activando los siguintes opciones del fichero de configuración de PostgreSQL.
Normalmente, en servidores Debian esta aquí /etc/postgresql/16/main/postgresql.conf
Pero si no sabemos donde esta podemos buscarlo ejecutando la consultaSHOW config_file
En ese fichero revisamos que tenga activo y los certificados en las rutas correctasssl = on
ssl_cert_file = '/etc/ssl/certs/ssl-cert-snakeoil.pem'
ssl_key_file = '/etc/ssl/private/ssl-cert-snakeoil.key'
Este certificado que veis ssl-cert-snakeoil se genera al instalar PostgreSQL por el sistema. En producción "sería interesante" cambiarlo por uno certificado de verdad, por ejemplo, por Let's Encrypt que se puede crear con certbot - Autenticación segura (pg_hba.conf). Controla quién puede conectarse, desde dónde y con qué método de autenticación.
Este fichero que se encuentra en /etc/postgresql/16/main/pg_hba.conf y si no sabemos muy bien donde esta, lo podemos localizar ejecutando esta consulta en PostgreSQLSHOW hba_file;
Este fichero tiene entradas con la siguiente estructuraTYPE DATABASE USER ADDRESS METHOD
Ejemplohostssl all all 192.168.1.100/32 scram-sha-256
En la siguiente tabla podeis ver un resumen de tipo de host permitidos.
Tipo TCP/IP Requiere SSL Prohíbe SSL Uso típico local ❌ — — Conexión interna por socket host ✔ Opcional ❌ Redes normales hostssl ✔ ✔ ❌ Conexiones seguras hostnossl ✔ ❌ ✔ Casos especiales
2) Seguridad de autenticación y usuarios
Aquí podemos revisar dos cosas: el uso de roles de usuario y las politicas de caducidad.- Roles con privilegios mínimos (principio de menor privilegio), evitar el uso del usuario postgres (que es como usar el root)
- Políticas de caducidad y complejidad de contraseñas. PostgreSQL no gestiona contraseñas complejas de forma nativa, pero se puede:
- Usar pgcrypto para manejar contraseñas en aplicaciones.
- Controlar caducidad con VALID UNTIL:
ALTER ROLE user1 VALID UNTIL '2025-12-31';
3) Seguridad de objetos y acceso a datos
Utilizar los comandos de control GRANT / REVOKE para gestionar los permisos sobre los diferentes objetos de la base de datos.Quitar permisos o darlos según sea el caso. Por ejemplo:
-- Quitar permisos peligrosos, quita acceso general
REVOKE ALL ON DATABASE mi_bd FROM PUBLIC;
-- Otorgar permisos específicos
GRANT SELECT, INSERT ON tabla_ventas TO rol_analista;
Esto sería una forma simplificada de lo que se podría hacer porque el tema de Seguridad de objetos y accesos da para un par de artículos por si solo.
De momento quedaros con la idea que hay que revisarlo y asignar solo los permisos necesarios a los objetos que los necesiten para evitar males mayores.
4) Auditoría y monitoreo
La auditoría es el proceso de revisar lo que pasa por la base de datos, ¿que tenemos que auditar?, entre otras cosas:- Conexiones y desconexiones de usuarios.
- Consultas ejecutadas (SELECT, INSERT, UPDATE, DELETE).
- Cambios en la estructura de la base de datos (CREATE, ALTER, DROP).
- Acceso o cambios a datos sensibles.
- Actividades sospechosas o violaciones de políticas de seguridad.
- pgAudit, una extensión oficial de PostgreSQL, se instala y después se configuran parámetros en postgresql.conf para auditar
- Logging nativo de PostgreSQL (los propios logs)
- Configurar el parámetro log_statement = 'all' en postgresql.conf para registrar todas las sentencias SQL.
Esto en producción con cuidado y solo para resolver incidencias porque este log tiende siempre a infinito.
- Se puede ajustar con log_line_prefix para incluir usuario, aplicación, PID, etc.
- Configurar el parámetro log_statement = 'all' en postgresql.conf para registrar todas las sentencias SQL.
- Triggers personalizados, se pueden crear AFTER INSERT/UPDATE/DELETE triggers que registren los cambios en una tabla de auditoría como los cambios en tablas sencibles.
La otra opción en monitoreo que no es mas que ir revisando y mirando el estado de la base de datos en tiempo real o a intervalos para detectar posibles problemas.
¿Qué podemos mirar? pues cosas como:
- Uso de CPU, memoria y disco
- Conexiones activas
- Que consultas son las mas lentas
- Uso de espacio en tablas y bases de datos y sus incrementos
Para esto tenemos herramientas como
- pg_stat_*, vistas internas como: pg_stat_activity, pg_stat_user_tables, pg_stat_replication permiten ver en detalle la actividad
- pg_stat_statements que es una extensión para analizar el rendimiento de las consultas.
- Y por supuesto herramientas externas como Prometheus + Grafana: combinación muy usada para recolectar métricas y graficarlas, pgMonitor, Zabbix, Nagios, Datadog, etc.
- Y por supuesto los logs del sistema tan odiados pero tan interesantes de leer.
Un tail + un log + un grep y se hacen maravillas.
5) Seguridad del servidor
Aquí tendremos que revisar cosas como el- Firewall y red, Asegura que el puerto (por defecto 5432) solo esté abierto para IPs autorizadas.
- Usa VPN o tunel SSH para conexiones remotas.
- Separación de entorno, usar entornos separados para desarrollo, pruebas y producción.
- No alojar PostgreSQL directamente en internet.
- Actualizaciones de servidores. Mantener PostgreSQL y el sistema operativo actualizados. Aplica parches de seguridad regularmente, lo que decíamos en el punto 4 revisión constante del servidor.
6) Cifrado de datos en reposo
PostgreSQL no cifra nativamente los datos en disco, pero puedes:- Usar cifrado a nivel de disco (ej. LUKS, BitLocker, EBS encryption en AWS).
- Cifrar campos sensibles manualmente con pgcrypto con pgp_sym_encrypt
7) Conclusión
Como podemos ver hay un checklist interesante para mantener nuestro servidor seguro y actualizado.Al servidor de PostgreSQL hay que darle "cariño" no se puede instalar configurar, olvidarnos de el y esperar que funcione por inercia, porque, la inercia nos lleva directamente al desastre.
Ah!, y recordaros que esto aplica "en principio" a Linux, no lo he probado en Windows pero si tienes tu sistema en producción en Windows ya puedes ir pensando en migrarlo a Linux, será mas estable, seguro y rápido.
Si queréis un checklist para mantener vuestro servidor con buena salud para las bases de datos apuntaros a la newsletter y os podréis descargar el checklist.
... y esto es todo amig@s!!! hasta la próxima ...
Saludos
Alex
:-)
/