Agrupación de conexiones con PgBouncer

PgBouncer es un gestor de conexiones ligero para PostgreSQL. Mantiene un número reducido de conexiones a la base de datos y las comparte entre muchos clientes de la aplicación, lo que ayuda a que tu implementación se mantenga dentro del límite de conexiones y evita la sobrecarga que supone abrir una nueva conexión para cada cliente.

IBM Cloud® Databases for PostgreSQL Las implementaciones incluyen compatibilidad integrada con la auth_query autenticación PgBouncer's. Cada implementación proporciona una función public.pgbouncer_lookup y un pgbouncer_auth rol, por lo que una instancia de PgBouncer que ejecutes puede validar a los usuarios de la base de datos directamente en función de tu implementación. No se mantiene una lista local de contraseñas para los usuarios de la base de datos, y los cambios de contraseña surten efecto de forma inmediata, sin necesidad de reiniciar ni recargar PgBouncer.

Databases for PostgreSQL no aloja ni gestiona PgBouncer. PgBouncer se instala, se ejecuta, se protege y se actualiza en su propia infraestructura, como un servidor virtual, un clúster de Kubernetes o un sidecar de aplicación. Para obtener más información sobre la gestión de conexiones, consulta Gestión de conexiones.

Antes de empezar

Necesita:

  • Una implementación de Databases for PostgreSQL con la contraseña de administrador configurada.
  • Un usuario de la base de datos para tu aplicación, creado en la interfaz de usuario, la CLI o la API.
  • PgBouncer 1.11.0 o posterior, que admita la autenticación SCRAM, instalado en una infraestructura que usted controle. Si tiene previsto utilizar sentencias preparadas a nivel de protocolo en el modo de agrupación de transacciones, utilice PgBouncer 1.21.0 o una versión posterior.
  • Un cliente psql.
  • Información de conexión de tu implementación:
    • Nombre de host y puerto, de las [cadenas de conexión]...
    • Certificado CA, obtenido con ibmcloud cdb deployment-cacert.

La compatibilidad con pgbouncer_lookup se está implementando en todas las instalaciones. Para comprobar que tu implementación cuenta con la función, conéctate como psql admin y ejecuta \df public.pgbouncer_lookup. Si el resultado es nulo, tu implementación recibirá la función con una próxima actualización de mantenimiento.

Creación de un usuario de autenticación específico

PgBouncer se ejecuta auth_query como un rol de inicio de sesión designado, su auth_user. Crea un rol que se utilice únicamente para este fin. Un rol específico que no posea datos ni ejecute ninguna otra tarea es la opción de privilegios mínimos.

Inicia sesión psql como usuario admin, crea el rol y asígnale pgbouncer_auth:

CREATE ROLE pool_auth WITH LOGIN PASSWORD '<POOL_AUTH_PASSWORD>';
GRANT pgbouncer_auth TO pool_auth;

El rol pgbouncer_auth conlleva un único privilegio: el permiso para ejecutar la función pgbouncer_lookup. El usuario admin dispone pgbouncer_auth de la opción de administrador, por lo que tú mismo puedes conceder y revocar la pertenencia al grupo. También puedes crear el usuario con ibmcloud cdb user-create si quieres que aparezca en tus credenciales de servicio, pero los usuarios creados de esa forma son miembros de ibm-cloud-base-user y pueden crear usuarios y bases de datos, lo cual es más de lo que necesita el usuario de autenticación.

Conceder acceso pgbouncer_auth únicamente al usuario con permisos de autor. Cualquier miembro del rol puede leer los verificadores de contraseña almacenados de los demás usuarios de la base de datos, por lo que cada miembro adicional amplía el impacto de una credencial comprometida.

Para dar de baja a un usuario autorizado, revoca su pertenencia al grupo:

REVOKE pgbouncer_auth FROM pool_auth;

Configuración de PgBouncer

Para conectarse a una implementación de Databases for PostgreSQL, es necesario configurar los siguientes parámetros de PgBouncer:

  • auth_type = scram-sha-256, ya que las implementaciones almacenan verificadores de contraseñas de SCRAM-SHA-256.
  • auth_query = SELECT * FROM public.pgbouncer_lookup($1), ya que el valor predeterminado de PgBouncer's se lee auth_query directamente pg_authid y los usuarios de tu base de datos no pueden leerlo.
  • TLS del lado del servidor, ya que las implementaciones solo aceptan conexiones TLS. Establece server_tls_sslmode = verify-full y guarda el certificado que has recuperado con en ibmcloud cdb deployment-cacert la ruta que hayas establecido en server_tls_ca_file.

PgBouncer lee sus propias credenciales desde auth_user auth_file, por lo que, en esta configuración, userlist.txt solo contiene las credenciales de auth_user. Uno de cada dos usuarios resuelve sus problemas a través de auth_query. Restringe los permisos del archivo al propietario del proceso PgBouncer, por ejemplo, con el modo 0600.

"pool_auth" "<POOL_AUTH_PASSWORD>"

Una configuración mínima completa, en la que <HOSTNAME> y provienen <PORT> de tus cadenas de conexión:

[databases]
ibmclouddb = host=<HOSTNAME> port=<PORT> dbname=ibmclouddb
[pgbouncer]
listen_addr = 127.0.0.1
listen_port = 6432
auth_type = scram-sha-256
auth_file = /etc/pgbouncer/userlist.txt
auth_user = pool_auth
auth_query = SELECT * FROM public.pgbouncer_lookup($1)
server_tls_sslmode = verify-full
server_tls_ca_file = /etc/pgbouncer/ca-certificate.crt
pool_mode = session
max_client_conn = 200
default_pool_size = 20

No establezcas auth_dbname = postgres. La función de búsqueda no está instalada en la base postgres de datos. Déjalo sin auth_dbname configurar, para que la consulta de autenticación se ejecute en la base de datos a la que se conecta el cliente. Las bases de datos que cree posteriormente incluirán esta función automáticamente.

Para obtener descripciones de cada parámetro, consulta la guía de configuración de PgBouncer.

Verificación de la configuración

  1. Comprueba que la búsqueda corresponda a uno de los usuarios de tu base de datos. Conéctate con como psql admin y ejecuta:

    SELECT usename, passwd IS NOT NULL AS can_authenticate
      FROM public.pgbouncer_lookup('<APP_USERNAME>');
    

    El resultado es una fila con can_authenticate = t. La consulta está redactada de tal forma que no se muestre el verificador de contraseña. Los usuarios reservados para el servicio, incluidos admin, no devuelven ninguna fila.

  2. Conéctate a través de PgBouncer como usuario de la base de datos:

    psql "host=127.0.0.1 port=6432 dbname=ibmclouddb user=<APP_USERNAME>"
    

    Si la conexión se establece correctamente, PgBouncer autentica correctamente a los usuarios a través de auth_query.

  3. Cambia la contraseña del usuario de la base de datos y, a continuación, vuelve a conectarte a través de PgBouncer con la nueva contraseña:

    ibmcloud cdb user-password <DEPLOYMENT_NAME_OR_CRN> <APP_USERNAME> <NEW_PASSWORD>
    

    La nueva contraseña funciona de inmediato. No es necesario reiniciar, recargar ni realizar ningún cambio userlist.txt en PgBouncer.

Cómo funciona el modelo de seguridad

La función pgbouncer_lookup solo muestra la información que PgBouncer necesita para la autenticación.

  • La función se ejecuta con y SECURITY DEFINER un anclado search_path, y lee pg_catalog.pg_authid en tu nombre. El acceso directo a y pg_authid sigue pg_shadow bloqueado.
  • Devuelve verificadores SCRAM con hash, nunca contraseñas en texto sin cifrar.
  • Solo se resuelven los roles a los que se les permite iniciar sesión. Los usuarios reservados para el servicio, como admin y los usuarios internos de replicación y operaciones, nunca se resuelven.
  • Si la marca VALID UNTIL de tiempo de un rol corresponde a una fecha pasada, la función devuelve una contraseña NULL, por lo que la autenticación falla y se sigue aplicando la caducidad de la contraseña.
  • Se revoca el permiso para ejecutar la función a y PUBLIC se concede únicamente a admin y a los miembros de pgbouncer_auth.

PgBouncer's La auth_query lectura por defecto es directa pg_authid, algo que los usuarios de tu base de datos no pueden hacer. En este caso, se recomienda PgBouncer documentación llamar a una función SECURITY DEFINER a través de un usuario que no sea superusuario. La función pgbouncer_lookup es esa función, excluyendo a los usuarios reservados del servicio.

Limitaciones y consideraciones

  • PgBouncer no afecta a la implementación max_connections. Ajuste el tamaño de default_pool_size modo que el número total de conexiones al servidor desde todas sus instancias de PgBouncer se mantenga dentro del límite de conexiones. Si alcanzas el límite, consulta cómo aumentar el número máximo de conexiones.
  • El usuario admin no puede autenticarse a través de auth_query. Para las tareas administrativas, conéctate directamente admin a la implementación, sin pasar por PgBouncer.
  • La base postgres de datos no dispone de la función de búsqueda, por lo que nunca se debe establecer auth_dbname = postgres.
  • En el modo de agrupación de transacciones (pool_mode = transaction), el estado de la sesión —como las variables SET, las tablas temporales, los bloqueos de aviso y los LISTEN canales— no se transfiere entre transacciones. Las sentencias preparadas a nivel de protocolo requieren max_prepared_statements y PgBouncer 1.21.0 o una versión posterior. Para obtener más información, consulta las características de PgBouncer.
  • Durante una actualización importante de la versión in situ, su implementación sufre un breve periodo de inactividad y se cierran las conexiones abiertas (SQLSTATE 57P01). PgBouncer Restablece automáticamente las conexiones con el servidor, pero tus aplicaciones deben reintentar las transacciones interrumpidas y volver a preparar las instrucciones.
  • Los usuarios con acceso de solo lectura no pueden conectarse al punto final principal. Para agrupar sus conexiones, añade una entrada [databases] independiente que apunte a turéplica de solo lectura.

Próximos pasos