Como proteger tu base de datos PostgreSQL



PostgreSQL es una de las bases de datos más robustas y utilizadas, pero su seguridad no es automática en todos los casos. Para proteger tus datos y garantizar la integridad del sistema, es fundamental aplicar buenas prácticas de seguridad en cada nivel ...




Niveles como conexiones, autenticación, control de acceso, cifrado y auditoría.

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.



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 consulta

    SHOW config_file

    En ese fichero revisamos que tenga activo y los certificados en las rutas correctas

    ssl = on
    ssl_cert_file = '/etc/ssl/certs/ssl-cert-snakeoil.pem'
    ssl_key_file = '/etc/ssl/private/ssl-cert-snakeoil.key'

  • 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 PostgreSQL

    SHOW hba_file;

    Este fichero tiene entradas con la siguiente estructura

    TYPE DATABASE USER ADDRESS METHOD

    Ejemplo

    hostssl 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;

Aquí quitamos todos los permisos sobre la base de datos (mi_bd) y damos permisos solo para tareas de SELECT e INSERT para el rol analista a la tabla ventas

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.
¿Y como podemos hacerlo? con diferentes herramientas como:

  • 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.
    • Se puede ajustar con log_line_prefix para incluir usuario, aplicación, PID, etc.
  • 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.


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
:-)
/

Suscríbete a nuestra newsletter

Sin spam. Solo contenido útil para profesionales de bases de datos.