Ir al contenido

Usuarios, auth_file y seguridad mínima (Odoo + PgBouncer + PostgreSQL)

18 de noviembre de 2025 por
Usuarios, auth_file y seguridad mínima (Odoo + PgBouncer + PostgreSQL)
Juan Manuel De Castro
| Todavía no hay comentarios

Cuando metes PgBouncer entre Odoo y PostgreSQL, la pregunta real no es “¿conecta?”, sino:

  • ¿quién puede conectarse?

  • ¿dónde se guardan las credenciales?

  • ¿qué permisos mínimos tiene cada rol?

  • ¿qué pasa cuando rotas passwords?

Este post te deja un baseline de usuarios/roles, cómo mantener auth_file sano y una seguridad mínima que evita los errores más comunes (y los sustos).


1) Modelo mental rápido: hay 2 autenticaciones

Con PgBouncer, siempre hay dos “logins”:

  1. Cliente → PgBouncer (Odoo autentica contra PgBouncer)

  2. PgBouncer → PostgreSQL (PgBouncer abre conexiones reales al servidor)

Por eso tus decisiones de usuarios/auth_file afectan a dos enlaces, no uno. Crunchy Data


2) Usuarios recomendados (mínimos) y para qué sirve cada uno

A) odoo (usuario de aplicación)

Es el usuario con el que Odoo trabaja en la base. Debe tener permisos sobre su DB (tablas/funciones/secuencias que usa Odoo).

Recomendación: un usuario por instancia o por “grupo” de instancias (multi-tenant), según tu operación.


B) pgbouncer_auth (usuario técnico para auth_user / auth_query) — opcional, pero muy útil

Si quieres centralizar credenciales y no vivir sincronizando userlist.txt, PgBouncer puede consultar la contraseña en PostgreSQL usando auth_user + auth_query. PgBouncer+1

Ventaja: userlist.txt queda con muy pocos usuarios (y rotar claves se simplifica).


C) postgres / DBA (solo admin)

No lo uses para Odoo ni para PgBouncer.


3) auth_file (userlist.txt): formato, permisos y buenas prácticas

Formato correcto

PgBouncer documenta el formato así:

  • "username" "password" (texto plano)

  • "username" "md5..." (MD5 estilo Postgres)

  • "username" "SCRAM-SHA-256$<iterations>:<salt>$<storedkey>:<serverkey>" PgBouncer

Ejemplo:

"odoo" "SCRAM-SHA-256$4096:....$....:...."
"pgbouncer_auth" "super-segura-en-otro-sistema"   ; si decides usar texto plano (ver nota abajo)

Nota: PgBouncer “ignora el resto de la línea” después del segundo campo, así que puedes comentar a la derecha sin romper formato. PgBouncer


Permisos del archivo (seguridad mínima real)

  • Propietario: el usuario del servicio (ej. pgbouncer)

  • Permisos: 0600 (solo lectura/escritura dueño)

  • Ubicación: fuera de repositorios y backups “abiertos”

Esto es de lo más importante: si alguien lee ese archivo, puede abrirte la DB.


Rotación sin downtime

PgBouncer puede recargar el auth_file con reload (sin reiniciar duro). El doc de uso indica que el reload también recarga auth_file y auth_hba_file. PgBouncer


4) SCRAM, auth_user y la trampa más común

Si usas auth_type = scram-sha-256 (lo recomendado hoy), aparecen dos realidades:

  • Para validar al cliente, userlist.txt puede contener un SCRAM secret. PgBouncer+1

  • Para que PgBouncer se autentique hacia PostgreSQL usando auth_user, a veces necesitará texto plano (depende de cómo lo configures y del flujo exacto), porque el SCRAM secret no siempre es reutilizable como “credencial de login” por sí solo. Stack Overflow+1

Regla práctica para evitar dolores:

  • Si NO necesitas auth_user/auth_query: mantén todo simple con auth_file (SCRAM secrets) y listo.

  • Si SÍ necesitas auth_user/auth_query: revisa bien el caso, porque puedes terminar necesitando la password en texto plano del auth_user en userlist.txt (y eso exige aún más cuidado con permisos/secret management). GitHub+1


5) Opción 1 (simple): todo en auth_file (sin auth_user)

PgBouncer (pgbouncer.ini)

[pgbouncer]
auth_type = scram-sha-256
auth_file = /etc/pgbouncer/userlist.txt
pool_mode = transaction

Pros

  • Simple de entender y depurar.

  • No dependes de queries a DB para auth.

Contras

  • Cada rotación de password implica actualizar userlist.txt (y recargar PgBouncer).


6) Opción 2 (recomendada en equipos grandes): auth_user + auth_query para centralizar credenciales

La idea: PgBouncer consulta a Postgres el hash/password del usuario que intenta entrar, usando un usuario técnico (auth_user). PgBouncer lo soporta desde hace años (parámetros auth_user y auth_query). PgBouncer+2Crunchy Data+2


PgBouncer

[pgbouncer]
auth_type = scram-sha-256
auth_file = /etc/pgbouncer/userlist.txt

auth_user = pgbouncer_auth
auth_query = SELECT usename, passwd FROM pg_shadow WHERE usename=$1

Ojo: el default clásico fue pg_shadow, aunque en versiones recientes hubo cambios/ajustes del default auth_query (tema “VALID UNTIL”), así que si tocas auth_query custom, mantén PgBouncer actualizado y revisa changelog/release notes. PgBouncer+1

Pros

  • userlist.txt queda mínimo (solo pgbouncer_auth + quizá 1-2 más).

  • Rotación de passwords: la fuente de verdad es Postgres.

Contras

  • Más moving parts.

  • Debes asegurar permisos del auth_user y entender SCRAM/credenciales (ver sección 4).


7) Seguridad mínima adicional (la que sí importa)

A) No uses auth_type=trust (salvo laboratorios)

“Trust” es literalmente “sin password”. Incluso guías lo muestran como ejemplo, pero para prod es un NO. Percona

B) Restringe por red (firewall) y por listen_addr

  • PgBouncer no debería escuchar en 0.0.0.0 si no hace falta.

  • Permite solo IPs de tus Odoo / tu red privada.

  • PostgreSQL: permite conexiones solo desde PgBouncer (y desde tu bastión/DBA).

C) Separa credenciales por entorno

  • odoo_prod, odoo_stage, etc.

  • Nada de reutilizar contraseñas entre ambientes.

D) TLS si hay red no confiable

Si Odoo↔PgBouncer o PgBouncer↔Postgres cruzan subredes que no controlas, considera TLS. (SCRAM no sustituye cifrado del canal.)


8) Checklist rápido (para pegar al final del post)

  • Tengo usuario odoo con permisos solo para su DB

  • userlist.txt con formato correcto ("user" "secret") PgBouncer

  • userlist.txt con permisos 0600

  • Evito trust Percona

  • Puedo recargar PgBouncer tras rotación (reload recarga auth_file) PgBouncer

  • Si uso auth_user/auth_query, entendí el tema SCRAM y el posible requisito de password en claro para auth_user GitHub+1

  • Firewall: Postgres acepta solo desde PgBouncer; PgBouncer solo desde Odoo

Siguiente capítulo ->

Usuarios, auth_file y seguridad mínima (Odoo + PgBouncer + PostgreSQL)
Juan Manuel De Castro 18 de noviembre de 2025
Compartir
Archivo
Iniciar sesión dejar un comentario