Skip to Content

TLS between Odoo and PgBouncer: when it is worth it (and how to do it right)

November 22, 2025 by
TLS between Odoo and PgBouncer: when it is worth it (and how to do it right)
John Wolf
| No comments yet

When you put PgBouncer between Odoo and PostgreSQL, you gain performance and control… but you also addanother network hop. The right question is not “Can I enable TLS?”, but:

Does it provide real security or just complexity?


1) When it is WORTH enabling TLS (Odoo → PgBouncer)

Enable it if any of these cases apply:Odoo and PgBouncer are on different hosts de estos casos:

  • Odoo y PgBouncer están en hosts distintosand the network between them is not 100% reliable (shared VPC, large corporate network, cross-subnet, cross-AZ, cross-DC).

  • There are compliance requirements(audit, SOC2/ISO, enterprise clients): “encryption in transit”. (auditoría, SOC2/ISO, clientes enterprise): “encryption in transit”.

  • You are in Kubernetes/multi-tenant infrastructure and are concerned aboutlateral sniffing.

  • Your threat model includesMITM(DNS poisoning, route hijack). For this, TLSwith verificationis key. PostgreSQL explains that it requires encryption butdoes notprotect against MITM; verify-full does. PostgreSQL


2) When it is NOT worth it (or you can simplify)

  • Odoo and PgBouncer on the same hostand you can useUnix socket(there is no “network” traffic as such). In that case, you typically prioritize host hardening + permissions + firewall.

  • You have an already established tunnel (VPN/Service Mesh) that encrypts and verifies identities: additional TLS may be redundant (although sometimes compliance still requires it).


3) The differentiating point: TLS "encrypts" vs TLS "truly secure"

In the PostgreSQL/libpq world (which is what Odoo/psycopg uses), the modes matter:

  • require: encrypts, butdoes not validatethe server → does not prevent MITM. PostgreSQL

  • verify-ca: encrypts + validates CA (without checking hostname) → partial mitigation. PostgreSQL

  • verify-full: encrypts + validates CA + validates hostname → the recommended standard in sensitive environments. PostgreSQL

Odoo allows you to choose this with db_sslmode (disable/allow/prefer/require/verify-ca/verify-full). Odoo


4) Recommended minimum configuration (server TLS in PgBouncer + verify-full in Odoo)

A) PgBouncer: enable TLS for clients (Odoo → PgBouncer)

In pgbouncer.ini:

[pgbouncer]
listen_addr = 0.0.0.0
listen_port = 6432

# TLS from clients to PgBouncer
client_tls_sslmode = require
client_tls_key_file  = /etc/pgbouncer/tls/pgbouncer.key
client_tls_cert_file = /etc/pgbouncer/tls/pgbouncer.crt

# (optional but recommended) limit protocols
client_tls_protocols = secure

PgBouncer documents that incoming TLS isdisabled by default, and that when enabling it you need client_tls_key_file + client_tls_cert_file. PgBouncer

If you wantmTLS(Odoo presents the certificate and PgBouncer validates it), you set client_tls_sslmode=verify-ca and define client_tls_ca_file. PgBouncer


B) Odoo: enforce TLS and (ideally) verify the server

In odoo.conf:

[options]
db_host = pgbouncer.your-internal-domain
db_port = 6432
db_user = odoo
db_password = ********
db_sslmode = verify-full

Odoo has supported db_sslmode with those values for years. Odoo


C) Provide CA (and optionally cert/key) to the Odoo client

For verify-full you need the client to have theroot CA. In libpq you can pass it through parameters or environment variables; the doc mentions sslrootcert/PGSSLROOTCERT and also sslcert/sslkey (PGSSLCERT/PGSSLKEY) if you use client certificates. PostgreSQL

Example (systemd for the Odoo service):

Environment="PGSSLROOTCERT=/etc/odoo/tls/ca.crt"
# If you are doing mTLS:
# Environment="PGSSLCERT=/etc/odoo/tls/client.crt"
# Environment="PGSSLKEY=/etc/odoo/tls/client.key"


5) "And the second hop?" (PgBouncer → PostgreSQL)

Although the post is Odoo→PgBouncer, if PgBouncer and Postgres are separate, it makes sense to encrypt both hops.

PgBouncer provides server_tls_sslmode for TLS to PostgreSQL (with verify-ca/verify-full and server_tls_ca_file). PgBouncer

Example:

[pgbouncer]
server_tls_sslmode = verify-full
server_tls_ca_file = /etc/pgbouncer/tls/pg-ca.crt


6) Real cost: the overhead exists (but it almost always pays off)

PostgreSQL makes it clear: TLS adds encryption and key-exchange overhead; it's a trade-off between performance and security. PostgreSQL

In practice:

  • If Odoo↔PgBouncer isLAN, the cost is usually marginal.

  • If you are in an environment whereMITM or sniffingare real threats, the cost is worth it.

  • If your bottleneck is DB/queries, TLS is rarely "the" problem.


7) Quick checklist for deployment (and to avoid surprises)

  • In PgBouncer, client_tls_sslmode is active and you have client_tls_key_file + client_tls_cert_file. PgBouncer

  • In Odoo, db_sslmode=verify-full (or at least require). Odoo+1

  • The hostname of db_hostmatchesthe SAN/CN of the cert (if you use verify-full). PostgreSQL

  • The CA is available in Odoo (PGSSLROOTCERT or equivalent). PostgreSQL

  • If you also encrypt PgBouncer→Postgres, you configured server_tls_sslmode + CA. PgBouncer


Next chapter ->

TLS between Odoo and PgBouncer: when it is worth it (and how to do it right)
John Wolf November 22, 2025
Share this post
Tags
Archive
Sign in to leave a comment