Integrar la compatibilidad con grupos de Active Directory en Kubernetes

Selecciona una versión de la documentación:

En esta página se describe cómo configurar y gestionar la autenticación y la autorización basadas en grupos de Active Directory en AlloyDB Omni desplegado en Kubernetes. La asistencia basada en grupos de Active Directory automatiza la gestión de las pertenencias a roles de PostgreSQL en función de las pertenencias a grupos de un usuario en tu Active Directory, lo que agiliza la gestión de usuarios y asegura que los permisos estén sincronizados. Para obtener más información, consulta la descripción general de Active Directory.

En este documento se da por hecho que sabes cómo aplicar archivos de manifiesto de Kubernetes y usar la herramienta de línea de comandos kubectl. Para obtener más información, consulta Herramienta de línea de comandos (kubectl).

Flujo de trabajo de integración de Active Directory

La integración de Active Directory se implementa mediante una extensión de PostgreSQL (google_pg_auth) en el siguiente flujo de trabajo:

  1. Inicio de sesión de usuario: un usuario se autentica en AlloyDB Omni con sus credenciales estándar de Active Directory mediante la interfaz de programación de aplicaciones de servicios de seguridad genéricos (GSSAPI).
  2. Creación automática de roles: si no existe un rol de PostgreSQL correspondiente al usuario, el sistema lo crea automáticamente. Por ejemplo, CREATE ROLE "user@REALM" WITH LOGIN;.
  3. Comprobación de grupos LDAP: el sistema se conecta de forma segura a tu Active Directory mediante LDAP para obtener la información sobre los grupos a los que pertenece el usuario.
  4. Sincronización de la pertenencia: el sistema compara los grupos de Active Directory del usuario con las asignaciones que has configurado.

    • Si el usuario pertenece a un grupo de Active Directory asignado, pero no al grupo de PostgreSQL correspondiente, se le concederá la pertenencia.
    • Si el usuario no está en un grupo de Active Directory asignado, pero sí en el grupo de PostgreSQL correspondiente, se revoca su pertenencia.
  5. Inicio de sesión completado: la conexión del usuario se finaliza y se inicia sesión en la base de datos. Los permisos del usuario se determinan en función de los roles de PostgreSQL a los que pertenezca, que están sincronizados con el estado de su grupo de Active Directory.

    Esta sincronización se produce automáticamente cada vez que un usuario inicia sesión, lo que garantiza que los derechos de acceso de PostgreSQL reflejen el estado actual de tu Active Directory.

Antes de empezar

Antes de integrar la compatibilidad con grupos de Active Directory en AlloyDB Omni, asegúrate de que cumples los siguientes requisitos.

  • Autenticación GSSAPI: debes tener configurada y operativa la autenticación basada en GSSAPI en tu instancia de AlloyDB Omni. Para obtener más información, consulta Integrar Active Directory con AlloyDB Omni.
  • Roles de grupo de PostgreSQL: debes crear manualmente los roles de grupo de PostgreSQL que quieras asignar a grupos de Active Directory, tal como se muestra en el siguiente ejemplo:

    CREATE ROLE "postgres_developers";
    CREATE ROLE "postgres_read_only";
    
  • Permisos: debes asignar manualmente los permisos de la base de datos (por ejemplo, SELECT y INSERT) a estos roles de grupo de PostgreSQL. La integración solo gestiona la pertenencia, pero no los privilegios de los grupos, como se muestra en el siguiente ejemplo:

    GRANT SELECT ON ALL TABLES IN SCHEMA sales TO postgres_read_only;
    GRANT USAGE ON SCHEMA finance TO postgres_developers;
    GRANT USAGE ON SCHEMA sales TO postgres_read_only;
    GRANT SELECT, INSERT ON finance.transactions TO postgres_developers;
    

Configurar la compatibilidad con grupos de Active Directory

Para configurar la compatibilidad con grupos de Active Directory, debes aplicar un UserDefinedAuthenticationrecurso personalizado en tu clúster de base de datos.

  1. Configura AlloyDB Omni con las credenciales del servidor LDAP. Aplica el siguiente manifiesto de recurso personalizado de autenticación definido por el usuario:

    apiVersion: alloydbomni.dbadmin.goog/v1
    kind: UserDefinedAuthentication
    metadata:
     name: USER_DEFINED_AUTHENTICATION_NAME
     namespace: DB_CLUSTER_NAMESPACE
    spec:
     dbclusterRef: 
    name: DB_CLUSTER_NAME
     keytabSecretRef: 
    name: KEYTAB_SECRET_NAME
     pgHbaEntries:
       PG_HBA_ENTRIES
     pgIdentEntries:
       PG_IDENT_ENTRIES
    ldapConfiguration:
       enableGroupMapping: true
       ldapURI: LDAP_URI
       ldapBaseDN: LDAP_BASE_DN
       ldapBindDN: LDAP_BIND_DN
       cacheTTLSeconds: CACHE_TTL_SECONDS
       ldap_connection_timeout_ms: LDAP_CONNECTION_TIMEOUT
       ldapBindPasswordSecretRef:
         name: LDAP_PASSWORD_SECRET_REF
       ldapsCertificateSecretRef:
         name: LDAPS_CERT_SECRET_REF
    

    Haz las siguientes sustituciones:

    • USER_DEFINED_AUTHENTICATION_NAME: nombre de la UserDefinedConfiguration. Por ejemplo, DB_CLUSTER_NAME-ad-auth.
    • DB_CLUSTER_NAMESPACE: el espacio de nombres de Kubernetes de este plan de copia de seguridad. El espacio de nombres debe coincidir con el del clúster de la base de datos.
    • DB_CLUSTER_NAME: el nombre del clúster de bases de datos, que asignaste al crearlo.
    • LDAP_URI: URI del servidor LDAP, por ejemplo, ldaps://ad.example.com:636.
    • LDAP_BASE_DN: nombre completo base de las búsquedas LDAP. Por ejemplo, DC=ad,DC=alloydb,DC=COM.
    • LDAP_BIND_DN: nombre completo (DN) del usuario de enlace LDAP.
    • LDAP_PASSWORD_SECRET_REF: referencia al secreto de Kubernetes con la contraseña de LDAP. La clave de este secreto debe ser password.
    • LDAPS_CERT_SECRET_REF: (Opcional) Referencia al secreto de Kubernetes con el certificado LDAPS. La clave de este secreto debe ser ldap.crt.
    • CACHE_TTL_SECONDS: (Opcional) Tiempo máximo de espera antes de activar una sincronización de pertenencia a grupos LDAP en segundos. El valor predeterminado es 3600 segundos.
    • LDAP_CONNECTION_TIMEOUT: (Opcional) Tiempo de espera de la conexión LDAP en milisegundos. El valor predeterminado es 5000 ms.

    Consulta el siguiente ejemplo:

    apiVersion: v1
    kind: Secret
    metadata:
      name: ldaps-secret
    type: Opaque
    data:
      ldap.crt: LDAPS_CERTIFICATE_CONTENT_BASE64_ENCODED
    ---
    apiVersion: v1
    kind: Secret
    metadata:
      name: ldap-password-dbcluster-sample
    type: Opaque
    data:
      password: LDAPS_PASSWORD_CONTENT_BASE64_ENCODED
    ---
    apiVersion: v1
    kind: Secret
    metadata:
      name: db-pw-dbcluster-sample
    type: Opaque
    data:
      dbcluster-sample: POSTGRES_PASSWORD
    ---
    apiVersion: alloydbomni.dbadmin.goog/v1
    kind: DBCluster
    metadata:
      name: dbcluster-sample
    spec:
      databaseVersion: 16.8.0
      primarySpec:
        adminUser:
          passwordRef:
            name: db-pw-dbcluster-sample
        resources:
          memory: 5Gi
          cpu: 1
          disks:
          - name: DataDisk
            size: 10Gi
    ---
    apiVersion: v1
    kind: Secret
    metadata:
      name: db-keytab-dbcluster-sample
    type: Opaque
    data:
      krb5.keytab: |
    DUMMY_KEYTAB    
    ---
    apiVersion: alloydbomni.dbadmin.goog/v1
    kind: UserDefinedAuthentication
    metadata:
      name: dbcluster-sample-ad-auth
    spec:
      dbclusterRef: 
        name: dbcluster-sample
      keytabSecretRef: 
        name: db-keytab-dbcluster-sample
      pgHbaEntries:
        - hostgssenc all           all      0.0.0.0/0     gss
        - hostgssenc all           all      ::1/128       gss
        - hostssl all all 0.0.0.0/0 scram-sha-256
        - hostssl all all ::/0 scram-sha-256
      ldapConfiguration:
        enableGroupMapping: true
        ldapURI: ldaps://ad.alloydb.com:636
        ldapBaseDN: DC=ad,DC=alloydb,DC=COM
        ldapBindDN: read-only-admin@ad.alloydb.com
        cacheTTLSeconds: 60
        ldapBindPasswordSecretRef:
          name: ldap-password-dbcluster-sample
        ldapsCertificateSecretRef:
          name: ldaps-secret
    

Gestionar asignaciones de grupos

Puedes crear y gestionar asignaciones entre grupos de Active Directory y roles de PostgreSQL mediante funciones SQL.

Inicia sesión en el clúster y carga la extensión

  • Conéctate a AlloyDB Omni que se ejecuta en Kubernetes.

    export DBPOD=`kubectl get pod --selector=alloydbomni.internal.dbadmin.goog/dbcluster=DB_CLUSTER_NAME,alloydbomni.internal.dbadmin.goog/task-type=database -n DB_CLUSTER_NAMESPACE -o jsonpath='{.items[0].metadata.name}'`
    
    kubectl exec -ti $DBPOD -n DB_CLUSTER_NAMESPACE -c database -- psql -h localhost -U postgres
    postgres=# CREATE EXTENSION google_pg_auth;
    CREATE EXTENSION
    

Crear una asignación de grupo

Para asignar un grupo de Active Directory a un rol de grupo de PostgreSQL que ya hayas creado, usa la función map_ad_group().

SELECT google_pg_auth.map_ad_group(ad_group_name TEXT, ad_group_sid TEXT, pg_role_name TEXT);

En el ejemplo siguiente, el grupo de ad-developers Active Directory se asigna al rol de pg-developers PostgreSQL:

SELECT google_pg_auth.map_ad_group('ad-developers', 'S-1-5-21-.....', 'postgres_read_only');

Para obtener el SID de un grupo concreto de Active Directory, usa el siguiente comando en tu servidor de Active Directory:

C:\Users\Admin> Get-ADGroup -Identity ad-developers | select SID
            
             SID
-----------------------------------------------
S-1-5-21-3168537779-1985441202-1799118680-1612

Quitar una asignación de grupos

Para quitar una asignación, usa la función unmap_ad_group(), que detiene la sincronización de ese grupo. La función unmap_ad_group() no elimina a los usuarios del grupo de PostgreSQL si ya son miembros.

SELECT google_pg_auth.unmap_ad_group(ad_group_sid TEXT, pg_role_name TEXT);

Consulta el siguiente ejemplo:

SELECT google_pg_auth.unmap_ad_group('S-1-5-21-.....', ''postgres_read_only'');

Crear una asignación de usuario

Para asignar un usuario de Active Directory a un rol de PostgreSQL que ya hayas creado, usa la función map_ad_user().

SELECT google_pg_auth.map_ad_user(ad_username TEXT, pg_role_name TEXT);

Por ejemplo, para asignar el usuario de quinn@google.com Active Directory al rol de pg-developers PostgreSQL, haz lo siguiente:

SELECT google_pg_auth.map_ad_user('quinn@google.com', ''postgres_read_only'');

Quitar una asignación de usuario

Para quitar una asignación, usa la función unmap_ad_user().

SELECT google_pg_auth.unmap_ad_user(ad_username TEXT, pg_role_name TEXT);

Por ejemplo, para desasignar el usuario de quinn@google.com Active Directory del rol de pg-developers PostgreSQL, haz lo siguiente:

SELECT google_pg_auth.unmap_ad_user('quinn@google.com', ''postgres_read_only'');

Conectarse a la base de datos de AlloyDB Omni

Inicia sesión en la base de datos de AlloyDB Omni con el usuario de Active Directory. Debes tener kinit habilitado en el cliente al que te conectes.

En el siguiente ejemplo, el pod postgres-client tiene instalados kinit y psql, y está configurado para conectarse al clúster de AlloyDB Omni mediante el cliente psql.

root@postgres-client:/# kinit AD_USER_NAME
Password for user1REALM:

root@postgres-client:/# psql -h ALLOYDB_SERVER_HOST_NAME -U AD_USER_NAME -d postgres
psql (16.6 (Ubuntu 16.6-0ubuntu0.24.04.1), server 16.3)
GSSAPI-encrypted connection
Type "help" for help.

user1=# 

Tu acceso a la base de datos de AlloyDB Omni se determina automáticamente en función de lo siguiente:

  • Tu pertenencia actual a grupos de Active Directory.
  • Las asignaciones definidas por el administrador entre esos grupos de Active Directory y los roles de PostgreSQL.
  • Los permisos que el administrador ha concedido a esos roles de PostgreSQL.

Si es la primera vez que te conectas, tu rol de usuario de PostgreSQL (your_ad_user@YOURDOMAIN.COM) se creará automáticamente.

Cada vez que inicias sesión, el sistema comprueba tus pertenencias a grupos de Active Directory y actualiza las correspondientes pertenencias a roles de PostgreSQL para que coincidan. No es necesario que hagas nada para que se produzca esta sincronización.

Ejemplo de conexión a una base de datos

En el siguiente ejemplo, el usuario Quinn forma parte de un grupo de Active Directory llamado ad_developers. El administrador ha asignado ad_developers a un rol de postgres llamado postgres_read_only. Este rol tiene acceso de lectura a una tabla llamada sales. Cuando el usuario inicie sesión, podrá acceder a la tabla.

root@postgres-client:/# kinit quinnREALM
Password for quinn@YOUR.REALM:

root@postgres-client:/# psql -h ALLOYDB_SERVER_HOST_NAME -U quinnREALM -d postgres
psql (16.6 (Ubuntu 16.6-0ubuntu0.24.04.1), server 16.3)
GSSAPI-encrypted connection
Type "help" for help.

postgres=# select * from sales;
// Query will be run successfully

En el siguiente ejemplo, se elimina a Quinn del grupo ad_developers en Active Directory.

root@postgres-client:/# kinit quinnREALM
Password for quinn@YOUR.REALM:

root@postgres-client:/# psql -h ALLOYDB_SERVER_HOST_NAME -U quinnREALM -d postgres
psql (16.6 (Ubuntu 16.6-0ubuntu0.24.04.1), server 16.3)
GSSAPI-encrypted connection
Type "help" for help.

postgres=# select * from sales;
// Query will fail

Limitaciones

  • Gestión manual de grupos y permisos: esta función solo automatiza la pertenencia de los usuarios a grupos de PostgreSQL. La creación de esos grupos y la concesión de sus permisos es una tarea administrativa manual.
  • Latencia de sincronización: la pertenencia solo se sincroniza cuando un usuario inicia sesión. Los cambios que se hagan en la pertenencia a un grupo de un usuario en Active Directory solo se reflejarán en AlloyDB Omni en la siguiente sesión de inicio de sesión del usuario.
  • Rendimiento: la búsqueda de LDAP añade una pequeña latencia al proceso inicial de inicio de sesión del usuario. El almacenamiento en caché ayuda a mitigar esta latencia en los inicios de sesión posteriores dentro del tiempo de vida configurado (auth_cache_ttl_sec).
  • Gestión de errores: si no se puede acceder al servidor LDAP o se producen otros errores durante el proceso de sincronización, AlloyDB Omni registra el error. Sin embargo, el usuario podrá iniciar sesión porque la autenticación GSSAPI se ha realizado correctamente. Solo fallará la sincronización de la pertenencia al grupo de esa sesión.

Siguientes pasos