29.5. Protocolo leve de acesso de diretório ( LDAP )

Originalmente contribuido por Tom Rhodes.
Atualizado por Rocky Hotas.

O protocolo LDAP (LDAP) é um protocolo da camada de aplicação usado para acessar, modificar e autenticar objetos usando um serviço de informações de diretório distribuído. Pense nisso como um telefone ou livro de registro que armazena vários níveis de informações hierárquicas e homogêneas. Ele é usado nas redes do Active Directory e do OpenLDAP e permite que os usuários acessem vários níveis de informações internas utilizando uma única conta. Por exemplo, a autenticação de email, a obtenção de informações de contato dos funcionários e a autenticação interna de sites podem usar uma única conta de usuário na base de registros do servidor LDAP.

Esta seção fornece um guia de início rápido para configurar um servidor LDAP em um sistema FreeBSD. Ele pressupõe que o administrador já tenha um plano de design que inclua o tipo de informação a ser armazenada, para que essas informações sejam usadas, quais usuários devem ter acesso a essas informações e como proteger essas informações contra acesso não autorizado.

29.5.1. Terminologia e Estrutura do LDAP

O LDAP usa vários termos que devem ser entendidos antes de iniciar a configuração. Todas as entradas de diretório consistem em um grupo de attributes. Cada um desses conjuntos de atributos contém um identificador exclusivo conhecido como Distinguished Name (DN) que é normalmente criado a partir de vários outros atributos, como Common ou Relative Distinguished Name (RDN). Semelhante a como os diretórios têm caminhos absolutos e relativos, considere um DN como um caminho absoluto e o RDN como o caminho relativo.

Um exemplo de entrada LDAP é semelhante ao seguinte. Este exemplo procura a entrada para a conta de usuário especificada (uid), unidade organizacional (ou) e organização (o):

% ldapsearch -xb "uid=trhodes,ou=users,o=example.com"
# extended LDIF
#
# LDAPv3
# base <uid=trhodes,ou=users,o=example.com> with scope subtree
# filter: (objectclass=*)
# requesting: ALL
#

# trhodes, users, example.com
dn: uid=trhodes,ou=users,o=example.com
mail: trhodes@example.com
cn: Tom Rhodes
uid: trhodes
telephoneNumber: (123) 456-7890

# search result
search: 2
result: 0 Success

# numResponses: 2
# numEntries: 1

Esta entrada de exemplo mostra os valores para os atributos dn, mail, cn, uid e telephoneNumber. O atributo do cn é o RDN.

Maiores informações sobre o LDAP e sua terminologia podem ser encontradas em http://www.openldap.org/doc/admin24/intro.html.

29.5.2. Configurando um servidor LDAP

O FreeBSD não provê um servidor LDAP embutido. Comece a configuração instalando o pacote ou port net/openldap-server:

# pkg install openldap-server

Aqui está um largo conjunto de opções habilitadas no pacote. Reveja-os rodando o comando pkg info openldap-server. Se não for suficiente (por exemplo se o suporte a SQL for necessário), por favor considere recompilar o port usando o framework apropriado.

A instalação cria o diretório /var/db/openldap-data para conter os dados. O diretório para armazenar os certificados deve ser criado:

# mkdir /usr/local/etc/openldap/private

A próxima fase é configurar a autoridade de certificação. Os seguintes comandos devem ser executados em /usr/local/etc/openldap/private. Isso é importante, pois as permissões de arquivo precisam ser restritivas e os usuários não devem ter acesso a esses arquivos. Informações mais detalhadas sobre certificados e seus parâmetros podem ser encontradas em Seção 13.6, “OpenSSL”. Para criar a Autoridade de Certificação, comece com este comando e siga os prompts:

# openssl req -days 365 -nodes -new -x509 -keyout ca.key -out ../ca.crt

As entradas para os prompts podem ser genéricas exceto para o Common Name. Esta entrada deve ser diferente do nome do host do sistema. Se este será um certificado auto-assinado, prefixe o nome do host com CA para a Autoridade de Certificação.

A próxima tarefa é criar uma solicitação de assinatura de certificado e uma chave privada. Insira este comando e siga os prompts:

# openssl req -days 365 -nodes -new -keyout server.key -out server.csr

Durante o processo de geração de certificados, certifique-se de configurar corretamente o atributo Common Name. A Solicitação de Assinatura de Certificado deve ser assinada com a Autoridade de Certificação para ser usada como um certificado válido:

# openssl x509 -req -days 365 -in server.csr -out ../server.crt -CA ../ca.crt -CAkey ca.key -CAcreateserial

A parte final do processo de geração de certificados é gerar e assinar os certificados do cliente:

# openssl req -days 365 -nodes -new -keyout client.key -out client.csr
# openssl x509 -req -days 3650 -in client.csr -out ../client.crt -CA ../ca.crt -CAkey ca.key

Lembre-se de usar o mesmo atributo Common Name quando solicitado. Quando terminar, assegure-se de que um total de oito (8) novos arquivos tenham sido gerado através dos comandos procedentes.

O daemon que executa o servidor OpenLDAP é o slapd. Sua configuração é executada através do slapd.ldif: o antigo slapd.conf foi descontinuado pelo OpenLDAP.

Exemplos de configuração para o slapd.ldif estão disponíveis e também podem ser encontrados em /usr/local/etc/openldap/slapd.ldif.sample. As opções estão documentadas em slapd-config(5). Cada seção do slapd.ldif, como todos os outros conjuntos de atributos LDAP, é identificada exclusivamente por meio de um DN. Certifique-se de que nenhuma linha em branco seja deixada entre a instrução dn: e o final desejado da seção. No exemplo a seguir, o TLS será usado para implementar um canal seguro. A primeira seção representa a configuração global:

#
# See slapd-config(5) for details on configuration options.
# This file should NOT be world readable.
#
dn: cn=config
objectClass: olcGlobal
cn: config
#
#
# Define global ACLs to disable default read access.
#
olcArgsFile: /var/run/openldap/slapd.args
olcPidFile: /var/run/openldap/slapd.pid
olcTLSCertificateFile: /usr/local/etc/openldap/server.crt
olcTLSCertificateKeyFile: /usr/local/etc/openldap/private/server.key
olcTLSCACertificateFile: /usr/local/etc/openldap/ca.crt
#olcTLSCipherSuite: HIGH
olcTLSProtocolMin: 3.1
olcTLSVerifyClient: never

A Autoridade de Certificação, o certificado do servidor e os arquivos de chave privada do servidor devem ser especificados aqui. Recomenda-se que os clientes escolham a opção de criptografia de segurança e omitam olcTLSCipherSuite (incompatível com clientes TLS diferentes de openssl). A opção olcTLSProtocolMin permite que o servidor exija um nível mínimo de segurança: é recomendado. Enquanto a verificação é obrigatória para o servidor, não é para o cliente: olcTLSVerifyClient: never.

A segunda seção é sobre os módulos de backend e pode ser configurada da seguinte maneira:

#
# Load dynamic backend modules:
#
dn: cn=module,cn=config
objectClass: olcModuleList
cn: module
olcModulepath:	/usr/local/libexec/openldap
olcModuleload:	back_mdb.la
#olcModuleload:	back_bdb.la
#olcModuleload:	back_hdb.la
#olcModuleload:	back_ldap.la
#olcModuleload:	back_passwd.la
#olcModuleload:	back_shell.la

A terceira seção é dedicada a carregar os esquemas ldif necessários para serem usados pelos bancos de dados: eles são essenciais.

dn: cn=schema,cn=config
objectClass: olcSchemaConfig
cn: schema

include: file:///usr/local/etc/openldap/schema/core.ldif
include: file:///usr/local/etc/openldap/schema/cosine.ldif
include: file:///usr/local/etc/openldap/schema/inetorgperson.ldif
include: file:///usr/local/etc/openldap/schema/nis.ldif

Em seguida, a seção de configuração do frontend:

# Frontend settings
#
dn: olcDatabase={-1}frontend,cn=config
objectClass: olcDatabaseConfig
objectClass: olcFrontendConfig
olcDatabase: {-1}frontend
olcAccess: to * by * read
#
# Sample global access control policy:
#	Root DSE: allow anyone to read it
#	Subschema (sub)entry DSE: allow anyone to read it
#	Other DSEs:
#		Allow self write access
#		Allow authenticated users read access
#		Allow anonymous users to authenticate
#
#olcAccess: to dn.base="" by * read
#olcAccess: to dn.base="cn=Subschema" by * read
#olcAccess: to *
#	by self write
#	by users read
#	by anonymous auth
#
# if no access controls are present, the default policy
# allows anyone and everyone to read anything but restricts
# updates to rootdn.  (e.g., "access to * by * read")
#
# rootdn can always read and write EVERYTHING!
#
olcPasswordHash: {SSHA}
# {SSHA} is already the default for olcPasswordHash

Outra seção é dedicada ao backend de configuração, a única maneira de acessar posteriormente a configuração do servidor OpenLDAP é como um superusuário global.

dn: olcDatabase={0}config,cn=config
objectClass: olcDatabaseConfig
olcDatabase: {0}config
olcAccess: to * by * none
olcRootPW: {SSHA}iae+lrQZILpiUdf16Z9KmDmSwT77Dj4U

O nome de usuário administrador padrão é cn=config. Digite slappasswd em um shell, escolha a senha e use sua hash olcRootPW. Se essa opção não for especificada agora, antes do arquivo slapd.ldif ser importado, ninguém poderá modificar a seção de configuração global.

A última seção é sobre o back-end do banco de dados:

#######################################################################
# LMDB database definitions
#######################################################################
#
dn: olcDatabase=mdb,cn=config
objectClass: olcDatabaseConfig
objectClass: olcMdbConfig
olcDatabase: mdb
olcDbMaxSize: 1073741824
olcSuffix: dc=domain,dc=example
olcRootDN: cn=mdbadmin,dc=domain,dc=example
# Cleartext passwords, especially for the rootdn, should
# be avoided.  See slappasswd(8) and slapd-config(5) for details.
# Use of strong authentication encouraged.
olcRootPW: {SSHA}X2wHvIWDk6G76CQyCMS1vDCvtICWgn0+
# The database directory MUST exist prior to running slapd AND
# should only be accessible by the slapd and slap tools.
# Mode 700 recommended.
olcDbDirectory:	/var/db/openldap-data
# Indices to maintain
olcDbIndex: objectClass eq

Esse banco de dados hospeda os conteudos atuais do diretório LDAP. Outros tipos diferentes de mdb estão disponiveis. Esse é super-usuário, não confundir com um global, é configurado aqui: um usuário (possivelmente customizado) em olcRootDN e a hash da senha em olcRootPW; slappasswd pode ser usado como antes.

Esse repositorio contém quatro exemplos do arquivo slapd.ldif. Para converter um arquivo slapd.conf existente dentro de slapd.ldif, referencie a essa página (por favor, note que isso pode introduzir algumas opções inuteis).

Quando a configuração estiver concluída, o slapd.ldif deve ser colocado em um diretório vazio. Recomenda-se criá-lo como:

# mkdir /usr/local/etc/openldap/slapd.d/

Importe o banco de dados de configuração:

# /usr/local/sbin/slapadd -n0 -F /usr/local/etc/openldap/slapd.d/ -l /usr/local/etc/openldap/slapd.ldif

Inicie o daemon slapd:

# /usr/local/libexec/slapd -F /usr/local/etc/openldap/slapd.d/

A opção -d pode ser usada para depuração, conforme especificado em slapd(8). Para verificar se o servidor está em execução e funcionando:

# ldapsearch -x -b '' -s base '(objectclass=*)' namingContexts
# extended LDIF
#
# LDAPv3
# base <> with scope baseObject
# filter: (objectclass=*)
# requesting: namingContexts
#

#
dn:
namingContexts: dc=domain,dc=example

# search result
search: 2
result: 0 Success

# numResponses: 2
# numEntries: 1

O servidor ainda deve ser confiável. Se isso nunca foi feito antes, siga estas instruções. Instale o pacote ou o port OpenSSL:

# pkg install openssl

No diretório onde o ca.crt está armazenado (neste exemplo, /usr/local/etc/openldap), execute:

# c_rehash .

Tanto a CA quanto o certificado do servidor agora são reconhecidos corretamente em suas respectivas funções. Para verificar isso, execute este comando no diretório server.crt:

# openssl verify -verbose -CApath . server.crt

Se o slapd estiver em execução, reinicie-o. Como declarado em /usr/local/etc/rc.d/slapd, para executar corretamente o slapd na inicialização, as seguintes linhas devem ser adicionadas ao /etc/rc.conf:

lapd_enable="YES"
slapd_flags='-h "ldapi://%2fvar%2frun%2fopenldap%2fldapi/
ldap://0.0.0.0/"'
slapd_sockets="/var/run/openldap/ldapi"
slapd_cn_config="YES"

O slapd não fornece depuração na inicialização. Verifique o /var/log/debug.log, o dmesg -a e o /var/log/messages para este propósito.

O exemplo a seguir adiciona o grupo team e o usuário john ao banco de dados LDAP de domain.example, que ainda está vazio. Primeiro, crie o arquivo domain.ldif:

# cat domain.ldif
dn: dc=domain,dc=example
objectClass: dcObject
objectClass: organization
o: domain.example
dc: domain

dn: ou=groups,dc=domain,dc=example
objectClass: top
objectClass: organizationalunit
ou: groups

dn: ou=users,dc=domain,dc=example
objectClass: top
objectClass: organizationalunit
ou: users

dn: cn=team,ou=groups,dc=domain,dc=example
objectClass: top
objectClass: posixGroup
cn: team
gidNumber: 10001

dn: uid=john,ou=users,dc=domain,dc=example
objectClass: top
objectClass: account
objectClass: posixAccount
objectClass: shadowAccount
cn: John McUser
uid: john
uidNumber: 10001
gidNumber: 10001
homeDirectory: /home/john/
loginShell: /usr/bin/bash
userPassword: secret

Veja a documentação do OpenLDAP para mais detalhes. Use slappasswd para substituir a senha secret em texto puro com um hash no userPassword. O caminho especificado como loginShell deve existir em todos sistemas onde john pode se logar. Finalmente, use o administrador mdb para modificar o banco de dados:

# ldapadd -W -D "cn=mdbadmin,dc=domain,dc=example" -f domain.ldif

Modificações para a seção configurações globais podem ser feitas apenas pelo super-usuário global. Por exemplo, assume que a opção olcTLSCipherSuite: HIGH:MEDIUM:SSLv3 foi inicialmente especificada e deve agora ser deletada. Primeiro, crie um arquivo que contenha o seguinte:

# cat global_mod
dn: cn=config
changetype: modify
delete: olcTLSCipherSuite

Em seguida, aplique as modificações:

# ldapmodify -f global_mod -x -D "cn=config" -W

Quando solicitado, forneça a senha escolhida na seção configuração backend. O nome de usuário não é necessário: aqui, cn=config representa o DN da seção do banco de dados a ser modificada. Como alternativa, use ldapmodify para excluir uma única linha do banco de dados, ldapdelete para excluir uma entrada inteira.

Se algo der errado ou se o superusuário global não puder acessar o backend de configuração, é possível excluir e reescrever toda a configuração:

# rm -rf /usr/local/etc/openldap/slapd.d/

O slapd.ldif pode então ser editado e importado novamente. Por favor, siga este procedimento somente quando nenhuma outra solução estiver disponível.

Esta é a configuração do servidor apenas. A mesma máquina também pode hospedar um cliente LDAP, com sua própria configuração separada.

All FreeBSD documents are available for download at https://download.freebsd.org/ftp/doc/

Questions that are not answered by the documentation may be sent to <freebsd-questions@FreeBSD.org>.
Send questions about this document to <freebsd-doc@FreeBSD.org>.