Si quieres un stack moderno y defendible, este es el camino: PostgreSQL con contraseñas SCRAM + PgBouncer autenticando clientes con SCRAM. Es más seguro que md5 (además, MD5 está deprecado en PostgreSQL y se removerá en una versión futura). PostgreSQL
Abajo tienes un procedimiento copiar/pegar, con validaciones y “pitfalls” reales.
0) Requisitos rápidos (para no tropezar)
Tu cliente (Odoo/psycopg/libpq) debe soportar SCRAM: PostgreSQL avisa que scram-sha-256 no está soportado por librerías de cliente antiguas. PostgreSQL
PgBouncer soporta auth_type = scram-sha-256 y permite que el auth_file contenga secrets SCRAM o contraseñas en texto plano. PgBouncer
1) PostgreSQL: habilita SCRAM como formato de contraseña
1.1 Ajusta password_encryption
En postgresql.conf:
password_encryption = scram-sha-256
Esto hace que las nuevas contraseñas (y las rotadas) se guarden como SCRAM. PostgreSQL
Recarga/reinicia PostgreSQL según tu método.
1.2 Rota la contraseña del usuario que usa Odoo
En psql como superuser:
ALTER ROLE odoo WITH PASSWORD 'UNA_CLAVE_LARGA_Y_UNICA';
1.3 Valida que quedó en formato SCRAM
SELECT rolname, rolpassword FROM pg_authid WHERE rolname = 'odoo';
Deberías ver un valor que empieza con SCRAM-SHA-256$... (ese es el “SCRAM secret” almacenado). PgBouncer+1
2) PostgreSQL: fuerza autenticación SCRAM en pg_hba.conf
En la regla que aplica a PgBouncer (por IP/red), cambia a:
host all all 10.0.0.0/8 scram-sha-256
Recarga PostgreSQL.
Tip de migración sin corte: PostgreSQL puede facilitar transición porque si pones md5 en pg_hba.conf pero el usuario ya tiene password SCRAM, automáticamente se usa SCRAM. Útil para migrar por etapas. PostgreSQL
3) PgBouncer: prepara auth_file (userlist.txt)
PgBouncer define el formato del archivo así:
"usuario" "password|md5...|SCRAM-SHA-256$..." PgBouncer
Tienes 2 formas (elige una):
Opción A (la más simple): guardar password en texto plano en userlist.txt
/etc/pgbouncer/userlist.txt:
"odoo" "UNA_CLAVE_LARGA_Y_UNICA"
✅ Pros: funciona bien para cliente→PgBouncer y para PgBouncer→PostgreSQL.
⚠️ Contras: debes blindar el archivo (permisos 0600, owner correcto).
Opción B (más “purista”): guardar el SCRAM secret en userlist.txt
Obtén el secret desde PostgreSQL (pg_authid.rolpassword) y pégalo:
"odoo" "SCRAM-SHA-256$4096:...$...:..."
✅ Pros: PgBouncer puede autenticar clientes con SCRAM usando secrets. PgBouncer
⚠️ OJO importante: ese secret no siempre sirve para que PgBouncer “loguee” hacia PostgreSQL, porque el secret almacenado no se puede usar “como contraseña” por diseño, salvo condiciones específicas (misma sal/iteraciones/secret idéntico, etc.). En muchos casos, si pones solo el SCRAM secret, PgBouncer no podrá autenticarse contra Postgres y te pedirá password en claro. Stack Overflow+1
Si tu prioridad es “que funcione y sea operable”, usa Opción A + permisos estrictos, o usa auth_user/auth_query (ver sección 6).
4) PgBouncer: configura auth_type = scram-sha-256
En pgbouncer.ini:
[pgbouncer] listen_addr = 0.0.0.0 listen_port = 6432 auth_type = scram-sha-256 auth_file = /etc/pgbouncer/userlist.txt ; opcional (default 4096) scram_iterations = 4096
PgBouncer documenta explícitamente auth_type = scram-sha-256 y que auth_file puede contener SCRAM secrets o texto plano. PgBouncer
scram_iterations controla el costo computacional al encriptar passwords en SCRAM (más iteraciones = más duro contra fuerza bruta, pero auth más lenta). PgBouncer
5) Recarga PgBouncer (sin reiniciar duro)
Puedes recargar config de PgBouncer y que tome cambios del auth_file con RELOAD (admin console) o SIGHUP.
PgBouncer documenta que al recargar, actualiza configuración y también recarga auth_file y auth_hba_file. PgBouncer
6) (Recomendado en equipos grandes) Centraliza auth con auth_user + auth_query
Si no quieres vivir editando userlist.txt por cada usuario, PgBouncer puede consultar credenciales desde PostgreSQL usando auth_user y auth_query. PgBouncer
Ejemplo (conceptual):
[pgbouncer] auth_type = scram-sha-256 auth_file = /etc/pgbouncer/userlist.txt auth_user = pgbouncer_auth ; usa el default o uno custom, idealmente vía función SECURITY DEFINER
PgBouncer explica que el password de auth_user se toma del auth_file y que acceder a pg_authid requiere privilegios elevados (recomienda función SECURITY DEFINER). PgBouncer
7) Odoo: apunta a PgBouncer
En tu odoo.conf:
db_host = 127.0.0.1 db_port = 6432 db_user = odoo db_password = UNA_CLAVE_LARGA_Y_UNICA
Luego reinicia Odoo.
8) Verificación rápida (para estar 100% seguro)
8.1 Desde la misma máquina de Odoo, prueba con psql contra PgBouncer
psql "host=127.0.0.1 port=6432 dbname=TU_DB user=odoo"
8.2 Confirma en PostgreSQL que el usuario tiene password SCRAM
(ya visto en paso 1.3). PostgreSQL
Problemas típicos y solución (los 3 que más se repiten)
“FATAL: SASL authentication failed”
Password incorrecta, o userlist.txt no recargó, o cliente viejo sin SCRAM. PostgreSQL+1
“PgBouncer no puede conectarse a Postgres cuando en userlist puse el SCRAM secret”
Esperable: el secret no siempre sirve como credencial de login. Usa password en claro (con permisos estrictos) o arma auth_user/auth_query. GitHub+1
Migración desde md5 con downtime inesperado
Hazlo por etapas: primero password_encryption = scram-sha-256, rota passwords, y luego cambia pg_hba.conf a scram-sha-256 cuando todo cliente esté listo. PostgreSQL