Servidores OpenLDAP e Kerberos no Ubuntu Server 22.04; Krb5 não está criando /var/lib/krb5kdc/principal

Servidores OpenLDAP e Kerberos no Ubuntu Server 22.04; Krb5 não está criando /var/lib/krb5kdc/principal

Eu tenho um servidor openldap existente no Ubuntu Server 22.04 e estou tentando configurar um servidor Kerberos com ele, seguindo este guia:https://ubuntu.com/server/docs/service-kerberos-with-openldap-backend

As contas são criadas e testadas, funcionam bem (eu as referencio por cn, mas elas têm um uid; acabei de criá-las primeiro no apache directory studio). Eu fiz "dpkg-reconfigure krb5-config" e editei /etc/krb5.conf para adicionar meu servidor e domínio. Uma coisa que não está nesse documento, mas que vi em outro lugar, é criar uma seção "[domain_realm]" e adicionar meu domínio a ela, o que fiz, mas não ajudou. Criei uma seção de registro, que requer a modificação dos serviços do systemd para permitir a gravação em/var/log/kerberos, mas tudo bem. Em seguida, executo o comando "kdb5_ldap_util" conforme listado e, depois de inserir as senhas, ele parece ser concluído com êxito. Eu faço o stash para as senhas kdc-service e kadmin-service, que é concluído com sucesso. Eu crio o arquivo kadm.acl, tudo bem, então quando tento iniciar o serviço, recebo isso em krb5kdc.log:

krb5kdc[712216](Error): Cannot find master key record in database - while fetching master keys list for realm SUBDOMAIN.DOMAIN.COM

Se eu executar "kadmin.local", recebo o seguinte:

Authenticating as principal root/[email protected] with password.
kadmin.local: Cannot find master key record in database while initializing kadmin.local interface

Acontece que o arquivo /var/lib/krb5kdc/principal nunca é criado. Não tenho certeza do que mais solucionar aqui, mas neste ponto estou preso e qualquer orientação seria apreciada. Arquivos de configuração abaixo, com domínio e subdomínio alterados:

/etc/krb5.conf:

[libdefaults]
        default_realm = SUBDOMAIN.DOMAIN.COM

# The following krb5.conf variables are only for MIT Kerberos.
        kdc_timesync = 1
        ccache_type = 4
        forwardable = true
        proxiable = true

# The following encryption type specification will be used by MIT Kerberos
# if uncommented.  In general, the defaults in the MIT Kerberos code are
# correct and overriding these specifications only serves to disable new
# encryption types as they are added, creating interoperability problems.
#
# The only time when you might need to uncomment these lines and change
# the enctypes is if you have local software that will break on ticket
# caches containing ticket encryption types it doesn't know about (such as
# old versions of Sun Java).

#       default_tgs_enctypes = des3-hmac-sha1
#       default_tkt_enctypes = des3-hmac-sha1
#       permitted_enctypes = des3-hmac-sha1

# The following libdefaults parameters are only for Heimdal Kerberos.
        fcc-mit-ticketflags = true

[logging]
        kdc = FILE:/var/log/kerberos/krb5kdc.log
        admin_server = FILE:/var/log/kerberos/kadmin.log
        default = FILE:/var/log/kerberos/krb5lib.log

[realms]
        SUBDOMAIN.DOMAIN.COM = {
                kdc = hostname.subdomain.domain.com
                admin_server = hostname.subdomain.domain.com
                default_domain = subdomain.domain.com
                database_module = openldap_ldapconf
        }

[domain_realm]
        .subdomain.domain.com = SUBDOMAIN.DOMAIN.COM
        subdomain.domain.com = SUBDOMAIN.DOMAIN.COM

[dbdefaults]
        ldap_kerberos_container_dn = cn=krbContainer,dc=subdomain,dc=domain,dc=com

[dbmodules]
        openldap_ldapconf = {
                db_library = kldap

                # if either of these is false, then the ldap_kdc_dn needs to
                # have write access
                disable_last_success = true
                disable_lockout  = true

                # this object needs to have read rights on
                # the realm container, principal container and realm sub-trees
                ldap_kdc_dn = "cn=kdc-service,ou=accounts,dc=subdomain,dc=domain,dc=com"

                # this object needs to have read and write rights on
                # the realm container, principal container and realm sub-trees
                ldap_kadmind_dn = "cn=kadmin-service,ou=accounts,dc=subdomain,dc=domain,dc=com"

                ldap_service_password_file = /etc/krb5kdc/service.keyfile
                ldap_servers = ldapi:///
                ldap_conns_per_server = 5
        }

/etc/krb5kdc/kadm5.acl:

*/[email protected] *

/etc/krb5kdc/kdc.conf:

[kdcdefaults]
    kdc_ports = 750,88

[realms]
    SUBDOMAIN.DOMAIN.COM = {
        database_name = /var/lib/krb5kdc/principal
        admin_keytab = FILE:/etc/krb5kdc/kadm5.keytab
        acl_file = /etc/krb5kdc/kadm5.acl
        key_stash_file = /etc/krb5kdc/stash
        kdc_ports = 750,88
        max_life = 10h 0m 0s
        max_renewable_life = 7d 0h 0m 0s
        master_key_type = des3-hmac-sha1
        #supported_enctypes = aes256-cts:normal aes128-cts:normal
        default_principal_flags = +preauth
    }

Editar: de acordo com o comentário do usuário1686, posso ver agora que tenho um possível problema de acesso às contas. Estou um pouco confuso com esta peça, mas usando 'slapcat -b cn = config' tenho as seguintes regras olcAccess:

olcAccess: {0}to * by dn="cn=admin,dc=subdomain,dc=domain,dc=com" manage by dn="cn=surfrock66,ou=accounts,dc=subdomain,dc=domain,dc=com" manage by dn="cn=ldapbinduser,ou=accounts,dc=subdomain,dc=domain,dc=com" read by * break
olcAccess: {1}to dn.children="ou=accounts,dc=subdomain,dc=domain,dc=com" attrs=userPassword,shadowExpire,shadowInactive,shadowLastChange,shadowMax,shadowMin,shadowWarning by self write by anonymous auth
olcAccess: {2}to attrs=krbPrincipalKey by anonymous auth by dn.exact="cn=kdc-service,ou=accounts,dc=subdomain,dc=domain,dc=com" read by dn.exact="cn=kadmin-service,ou=accounts,dc=subdomain,dc=domain,dc=com" write by self write by * none
olcAccess: {3}to dn.subtree="cn=krbContainer,dc=subdomain,dc=domain,dc=com" by dn.exact="cn=kdc-service,ou=accounts,dc=subdomain,dc=domain,dc=com" read by dn.exact="cn=kadmin-service,ou=accounts,dc=subdomain,dc=domain,dc=com" write by * none
olcAccess: {4}to dn.subtree="dc=subdomain,dc=domain,dc=com" by self read

2022.12.08-08-36 PST Edit: Então, estou muito mais longe e fiz o seguinte:

addprinc ldap/[email protected]
ktadd -k /etc/ldap/kerberos.ldap.hostname.subdomain.domain.com.keytab ldap/hostname.subdomain.domain.com
chown openldap:openldap /etc/ldap/kerberos.ldap.hostname.subdomain.domain.com.keytab
chmod 640 /etc/ldap/kerberos.ldap.hostname.subdomain.domain.com.keytab

Eu editei /etc/default/slapd e adicionei isto a ele:

export KRB5_KTNAME="FILE:/etc/ldap/kerberos.ldap.hostname.subdomain.domain.com.keytab"

Quando reiniciei o serviço, o testesaslauthd ainda funciona, mas o ldapsearch -D não. Estou me perguntando se há uma alteração de configuração que preciso fazer no ldap. A partir de um dos recursos em que estava trabalhando, construí este ldif para configuração, mas no final das contas não acho que entendi o que ele fará e se estava certo:

dn: cn=config
changetype: modify
add: olcSaslHost
olcSaslHost: hostname.subdomain.domain.com
-
add: olcSaslRealm
olcSaslRealm: SUBDOMAIN.DOMAIN.COM
-
add: olcAuthzRegexp
olcAuthzRegexp: {0}"cn=([^/]*),cn=subdomain.domain.com,cn=GSSAPI,cn=auth" "cn=$1,ou=accounts,dc=subdomain,dc=domain,dc=com"
-
add: olcAuthzRegexp
olcAuthzRegexp: {1}"cn=host/([^/]*).subdomain.domain.com,cn=subdomain.domain.com,cn=GSSAPI,cn=auth" "cn=$1,ou=hosts,dc=subdomain,dc=domain,dc=com"
-
add: olcAuthzRegexp
olcAuthzRegexp: {2}"uid=ldap/admin,cn=subdomain.domain.com,cn=GSSAPI,cn=auth" "cn=admin,dc=subdomain,dc=domain,dc=com"

Eu acho que este é o último passo que falta? Algo na configuração apontando LDAP para sasl? Ou estou abordando tudo errado?

Responder1

principalé o arquivo que contém o banco de dados KDC no formato DB2. Ele não foi criado no seu sistema porque você estánão useo db2back-end – você está usando LDAP, que substituitodosarmazenamento local para o KDC – portanto, um arquivo de banco de dados local é desnecessário e irrelevante para o problema que você está enfrentando.

Se você executou kdb5_ldap_util createconforme as instruções, deverá verificar via LDAP se ele realmente criou as entradas necessárias – deve haver, no mínimo, uma entrada para K/M@<realm>e outra para krbtgt/<realm>@<realm>. A mensagem de erro é sobre a entrada "K/M", que é um pseudoprincipal que contém a mkey do banco de dados (que é criptografada com a senha da "chave mestra").

Certifique-se de verificar o LDAP usando a conta do KDC, caso não tenha recebido os privilégios necessários para ler os objetos LDAP Kerberos. (As contas nãoprecisarter um fluido; elas são usadas apenas como contas vinculadas LDAP, não como contas Unix locais.)

Como o Ubuntu às vezes usa o AppArmor, certifique-se de verificar dmesgse há mensagens de negação AVC – pode ser que o KDC não tenha permissão para ler "service.keyfile" ou acessar seu soquete OpenLDAP.

Além disso, ative o statsnível de log em seu servidor LDAP para que ele registre todas as consultas – isso pode, por exemplo, revelar que o KDC está procurando em um DN diferente (normalmente "ldap_kerberos_container_dn" seria definido próximo a outros parâmetros de dbmodules).

Finalmente, se strace kadmin.localmostrar que a ferramenta não está realmente se conectando ao LDAP, mas tentando acessar um arquivo db2 local, então é possível que você tenha uma configuração kdc.conf(o arquivo de configuração específico do KDC) que substitui as configurações de todo o sistema no krb5. conf. Normalmente a configuração do KDC é carregada /var/lib/krb5kdc/kdc.confe tem prioridade sobre as configurações globais do krb5.conf.


(Além disso, se vocêeramusando o db2, o banco de dados principal ainda não seria criado automaticamente na primeira inicialização – isso precisa ser feito manualmente executando kdb5_util create [-s]e fornecendo a chave mestra de criptografia, assim como você fez para o backend LDAP usando "kdb5_ldap_util create".)

Uma coisa que não está nesse documento, mas que vi em outro lugar, é criar uma seção "[domain_realm]" e adicionar meu domínio a ela, o que fiz, mas não ajudou.

Isso só é necessário para clientes Kerberos ao obter tickets para um nome de host que não mapeia 1:1 para seu domínio (o exemplo típico é mit.edu → ATHENA.MIT.EDU). Não tem relevância para o arranque do KDC.

Eu criei uma seção de log, que requer a modificação dos serviços do systemd para permitir a gravação em/var/log/kerberos,

Isso não acontece se você fizer login SYSLOG, o que provavelmente era a intenção de quem escreveu os serviços systemd para o Ubuntu.


isso não existe, já que meu armazenamento está em LDAP?

Não, o arquivo /etc/krb5.keytab não faz parte do banco de dados KDC – ele pertence aohospedarcomo um "membro do domínio" e armazena o equivalente à senha Kerberos da conta da máquina. Cada máquina em seu domínio Kerberos deve ter seu próprio /etc/krb5.keytab com pelo menos o host/<fqdn>principal.

Estou tentando fazer com que a autenticação de passagem LDAP funcione para que a senha Kerberos seja a real; Estou descobrindo que grande parte da documentação é mais antiga. Vejo a maioria das pessoas recomendando o saslauthd que acho que configurei, mas agora está procurando por /etc/krb5.keytab

Para OpenLDAP, sim, geralmente você precisa do saslauthd.

  1. Ao vincular a um DN que possui userPassword: {SASL}foo@BAR, o slapd usará as funções de "verificação de senha" da libsasl.
  2. Dependendo do configuradopwcheck_method, libsasl entrará em contato com saslauthd para verificar a senha.
  3. saslauthd usará o backend configurado através de sua -aopção para fazer a verificação real.
  4. Com o -a krb5backend, saslauthd tentará obter um ticket Kerberos inicial de um KDC com o nome de usuário e senha fornecidos (equivalente a kinit).
  5. Se um ticket inicial foi adquirido com sucesso, o saslauthd solicitará adicionalmente umticket de serviço para sie tentará descriptografá-lo usando o keytab da máquina.
  6. Se o ticket de serviço pudesse ser adquiridoe descriptografado,a senha é aceita.

A última etapa é necessária para evitar ataques de falsificação de KDC. Tradicionalmente, os KDCs Kerberos emitiam tickets sem validar sua senha (senha errada significava apenas que o cliente não conseguiu descriptografar o ticket recebido) e um KDC malicioso ainda pode fazer isso – "pré-autorização" não é obrigatório no nível do protocolo. Portanto, o saslauthd precisa fazer a mesma coisa que qualquer outro serviço kerberizado faz para verificar se o ticket é legítimo – tentar descriptografá-lo usando um keytab de serviço. (Tanto o pam_krb5 quanto o Windows fazem o mesmo durante os logons do AD.)

Eu criei host/hostname.fqdn@REALM e ldap/hostname.fqdn@REALM. Criei um keytab para ldap; Converti o passe de 1 usuário para "{SASL}nome@REALM". Usando testesaslauthd nesse usuário, obtenho sucesso. Usando ldapsearch nesse usuário, credenciais inválidas. Acho que o ldap não está falando com o saslauthd? Em "Autenticação Kerberos" aqui adicionei as configurações: help.ubuntu.com/community/OpenLDAPServer mas quando faço "ldapsearch -Y GSSAPI" recebo "Erro GSSAPI: Nenhuma credencial foi suportada ...

-Y GSSAPIédiretoAutenticação Kerberos – completamente separada do saslauthd e da passagem de senha. Ou seja, o slapd nem recebe uma senha Kerberos – ele apenas recebe uma senha Kerberosbilhetee o valida internamente em seu keytab de serviço.

  1. Para SASL GSSAPI, o próprio serviço slapd – e não o saslauthd – precisa de um keytab para ldap/<fqdn>. (Por padrão, todos os serviços procuram suas chaves no sistema /etc/krb5.keytab, mas pode ser melhor para a segurança manter as coisas separadas e definir o KRB5_KTNAME do slapd para um caminho diferente - dessa forma, você não precisa lê-lo acesso ao keytab do sistema.)

  2. O cliente também precisasaberque se destina a solicitar um ticket para ldap/<fqdn>, portanto, conectar-se a um endereço IP provavelmente não funcionará (a menos que tenha o rDNS definido) - você deve se conectar especificamente ao ldap://<fqdn>. (É um problema muito semelhante ao TLS SNI ou nomes de host em certificados TLS).

    Em caso de dúvida, exporte KRB5_TRACE=/dev/stderrantes de ligar para o cliente para descobrir para qual principal ele está tentando fazer um TGS-REQ (ou consulte os logs do KDC ou uma captura de rede).

  3. O cliente já deve ter oinicialTicket Kerberos (krbtgt/REALM) presente, ou seja, você deve kinitcom antecedência. Se você ainda não possui um TGT, os clientes Kerberosnão vou perguntarpara sua senha – eles simplesmente não conseguirão autenticar.

A passagem de senha é relevante apenas para ligações "simples" ( ldapsearch -D <user_dn> -W) e para ligações SASL PLAIN. Teste o bind "simples" primeiro (você pode ignorar principalmente o SASL PLAIN).

Responder2

Você deve instalar libsasl2 em seu sistema operacional e conceder propriedade sobre seu krb5.keytab ao usuário openldap.

no debian:

sudo apt instalar libsasl2-2 libsasl2-modules-gssapi-mit

e então

sudo chown openldap:openldap /etc/krb5.keytab ou outro keytab

Editar: mas tenha cuidado com vários keytabs na mesma máquina/contêiner (com vários servidores).

informação relacionada