Integrar o suporte a grupos do Active Directory no Kubernetes

Selecione uma versão da documentação:

Nesta página, descrevemos como configurar e gerenciar a autenticação e a autorização baseadas em grupos do Active Directory no AlloyDB Omni implantado no Kubernetes. O suporte baseado em grupos do Active Directory automatiza o gerenciamento de associações de função do PostgreSQL com base nas associações de grupo de um usuário no Active Directory, o que simplifica o gerenciamento de usuários e garante que as permissões estejam sincronizadas. Para mais informações, consulte Visão geral do Active Directory.

Este documento pressupõe que você já sabe como aplicar arquivos de manifesto do Kubernetes e usar a ferramenta de linha de comando kubectl. Para mais informações, consulte Ferramenta de linha de comando (kubectl).

Fluxo de trabalho de integração do Active Directory

A integração do Active Directory é implementada usando uma extensão do PostgreSQL (google_pg_auth) no seguinte fluxo de trabalho:

  1. Login do usuário: um usuário se autentica no AlloyDB Omni usando as credenciais padrão do Active Directory com a interface de programação de aplicativos de serviços de segurança genéricos (GSSAPI, na sigla em inglês).
  2. Criação automática de função: se uma função correspondente do PostgreSQL para o usuário não existir, o sistema vai criar uma automaticamente. Por exemplo, CREATE ROLE "user@REALM" WITH LOGIN;.
  3. Verificação de grupo LDAP: o sistema se conecta com segurança ao Active Directory usando LDAP para recuperar as associações de grupo atuais do usuário.
  4. Sincronização de associação: o sistema compara os grupos do Active Directory do usuário com os mapeamentos configurados.

    • Se o usuário estiver em um grupo mapeado do Active Directory, mas não no grupo correspondente do PostgreSQL, ele vai receber a associação.
    • Se o usuário não estiver em um grupo mapeado do Active Directory, mas estiver no grupo correspondente do PostgreSQL, a associação dele será revogada.
  5. Login concluído: a conexão do usuário é finalizada, e ele faz login no banco de dados. As permissões do usuário são determinadas pelas funções do PostgreSQL a que ele pertence, que estão sincronizadas com o status do grupo do Active Directory.

    Essa sincronização acontece automaticamente a cada login do usuário, o que garante que os direitos de acesso do PostgreSQL reflitam o estado atual do Active Directory.

Antes de começar

Antes de integrar o suporte a grupos do Active Directory com o AlloyDB Omni, confira se você atende aos seguintes requisitos.

  • Autenticação GSSAPI: é necessário ter a autenticação baseada em GSSAPI configurada e operacional para sua instância do AlloyDB Omni. Para mais informações, consulte Integrar o Active Directory ao AlloyDB Omni.
  • Funções de grupo do PostgreSQL: é necessário criar manualmente as funções de grupo do PostgreSQL que você quer mapear para grupos do Active Directory, conforme mostrado no exemplo a seguir:

    CREATE ROLE "postgres_developers";
    CREATE ROLE "postgres_read_only";
    
  • Permissões: você precisa atribuir manualmente as permissões do banco de dados, por exemplo, SELECT e INSERT, a essas funções de grupo do PostgreSQL. A integração gerencia apenas a participação, mas não os privilégios dos próprios grupos, conforme mostrado no exemplo a seguir:

    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 o suporte a grupos do Active Directory

Para configurar o suporte a grupos do Active Directory, aplique um recurso personalizado UserDefinedAuthentication no cluster de banco de dados atual.

  1. Configure o AlloyDB Omni usando as credenciais do servidor LDAP. Aplique o seguinte manifesto de recurso personalizado de autenticação definido pelo usuário:

    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
    

    Faça as seguintes substituições:

    • USER_DEFINED_AUTHENTICATION_NAME: o nome da UserDefinedConfiguration. Por exemplo, DB_CLUSTER_NAME-ad-auth.
    • DB_CLUSTER_NAMESPACE: o namespace do Kubernetes para este plano de backup. O namespace precisa corresponder ao do cluster de banco de dados.
    • DB_CLUSTER_NAME: o nome do cluster de banco de dados, que você atribuiu ao criar.
    • LDAP_URI: URI do servidor LDAP, por exemplo, ldaps://ad.example.com:636.
    • LDAP_BASE_DN: nome distinto de base para pesquisas LDAP. (por exemplo, DC=ad,DC=alloydb,DC=COM)
    • LDAP_BIND_DN: nome diferenciado (DN) do usuário de vinculação do LDAP.
    • LDAP_PASSWORD_SECRET_REF: referência ao segredo do Kubernetes com a senha do LDAP. A chave desse secret precisa ser password.
    • LDAPS_CERT_SECRET_REF: (opcional) referência ao secret do Kubernetes com o certificado LDAPS. A chave deste secret precisa ser ldap.crt.
    • CACHE_TTL_SECONDS: (opcional) tempo máximo de espera antes de acionar uma sincronização de associação a um grupo LDAP em segundos. O padrão é 3.600 segundos.
    • LDAP_CONNECTION_TIMEOUT: (opcional) tempo limite da conexão LDAP em milissegundos. O padrão é 5.000 ms.

    Veja o exemplo a seguir:

    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
    

Gerenciar mapeamentos de grupo

É possível criar e gerenciar mapeamentos entre grupos do Active Directory e funções do PostgreSQL usando funções SQL.

Faça login no cluster e carregue a extensão

  • Conectar-se ao AlloyDB Omni em execução no 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
    

Criar um mapeamento de grupo

Para mapear um grupo do Active Directory para uma função de grupo do PostgreSQL que você já criou, use a função map_ad_group().

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

No exemplo a seguir, o grupo do Active Directory ad-developers é mapeado para a função do PostgreSQL pg-developers:

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

Para recuperar o SID de um grupo específico no Active Directory, use o seguinte comando no servidor do Active Directory:

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

Remover um mapeamento de grupo

Para remover um mapeamento, use a função unmap_ad_group(), que interrompe a sincronização desse grupo. A função unmap_ad_group() não remove usuários do grupo do PostgreSQL se eles já forem membros.

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

Veja o exemplo a seguir:

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

Criar um mapeamento de usuários

Para mapear um usuário individual do Active Directory a uma função do PostgreSQL já criada, use a função map_ad_user().

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

Por exemplo, para mapear o usuário do Active Directory quinn@google.com para a função do PostgreSQL pg-developers, faça o seguinte:

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

Remover um mapeamento de usuários

Para remover um mapeamento, use a função unmap_ad_user().

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

Por exemplo, para remover o mapeamento do usuário do Active Directory quinn@google.com da função do PostgreSQL pg-developers, faça o seguinte:

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

Conectar-se ao banco de dados do AlloyDB Omni

Faça login no banco de dados do AlloyDB Omni usando o usuário do Active Directory. Você precisa ter o kinit ativado no cliente em que está se conectando.

No exemplo a seguir, o pod postgres-client tem kinit e psql instalados e está configurado para se conectar ao cluster do AlloyDB Omni usando o 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=# 

Seu acesso no banco de dados do AlloyDB Omni é determinado automaticamente com base no seguinte:

  • Sua associação atual a grupos do Active Directory.
  • Os mapeamentos definidos pelo administrador entre esses grupos do Active Directory e as funções do PostgreSQL.
  • As permissões concedidas pelo administrador a esses papéis do PostgreSQL.

Se esta for a primeira vez que você se conecta, sua função de usuário do PostgreSQL (your_ad_user@YOURDOMAIN.COM) será criada automaticamente.

Sempre que você faz login, o sistema verifica suas associações atuais a grupos do Active Directory e atualiza as associações de função correspondentes do PostgreSQL para corresponder. Não é necessário fazer nada para que essa sincronização ocorra.

Exemplo de conexão com o banco de dados

No exemplo a seguir, o usuário Quinn faz parte de um grupo do Active Directory chamado ad_developers. O administrador mapeou ad_developers para uma função do postgres chamada postgres_read_only. Essa função tem acesso de leitura a uma tabela chamada sales. Quando o usuário faz login, ele pode acessar a tabela.

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

No exemplo a seguir, Quinn é removido do grupo ad_developers no 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

Limitações

  • Gerenciamento manual de grupos e permissões: esse recurso automatiza apenas a associação de usuários a grupos do PostgreSQL. A criação desses grupos e a concessão das permissões são tarefas administrativas manuais.
  • Latência de sincronização: a associação só é sincronizada quando um usuário faz login. As mudanças feitas na associação de um usuário a um grupo no Active Directory só são refletidas no AlloyDB Omni na próxima sessão de login do usuário.
  • Performance: a pesquisa LDAP adiciona uma pequena quantidade de latência ao processo inicial de login do usuário. O armazenamento em cache ajuda a reduzir essa latência para inícios de sessão subsequentes dentro do tempo de vida (auth_cache_ttl_sec) configurado.
  • Tratamento de erros: se o servidor LDAP estiver inacessível ou se outros erros ocorrerem durante o processo de sincronização, o AlloyDB Omni vai registrar o erro. No entanto, o login do usuário ainda vai funcionar, já que a autenticação GSSAPI foi bem-sucedida. Apenas a sincronização da participação no grupo dessa sessão vai falhar.

A seguir