210.4 Configurando um Servidor OpenLDAP
Introdução
O OpenLDAP é um software de código aberto, que é usado para armazenar informações de diretório, como nomes de usuário, senhas e outras informações de autenticação. Ele usa o protocolo LDAP (Lightweight Directory Access Protocol) para se comunicar com outros aplicativos e sistemas de diretório. O OpenLDAP é frequentemente usado para centralizar a autenticação da Rede para que outros sistemas e aplicativos em Rede consigam autenticar usuários, permitindo que os usuários façam login em vários sistemas com as mesmas credenciais de login.
Estrutura do serviço de diretório
A estrutura de dados foi desenvolvida para representar limites geográfico ou organizacionais, essa estrutura pode ser representada na forma de uma árvore, semelhante ao DNS.
Uma das formas de construir essa árvore é usando o Domain Component (DC), também conhecido como Domínio de Internet, ele vem sendo cada vez mais usado porque permite o uso de DNS e é mais fácil estruturar dessa forma.
Entrada | Descrição |
---|---|
dc | É o Domain Component. |
ou | Organization Unit - Unidade organizacional, o mesmo que o setor de uma empresa. |
cn | Common Name - Nome do usuário. |
uid | User ID - É o ID do usuário. |
dn | Distinguished Name - Serve para identificar exclusivamente uma entrada no diretório. Exemplo: dn: cn:fulano,ou=employees,dc=exemplo,dc=com,dc=br . |
Schemas
No LDAP, o Schema é um conjunto de regras usado para definir atributos, classes de objetos e controles. Dentro deles, o schema ainda define os tipos dos objetos, quais atributos são opcionais e quais não são.
Classe de objetos
Todas as entradas de um diretório são padronizadas, podendo uma entrada pertencer a uma ou mais classe, essas classes vão identificar quais dados podem ser armazenados naquela entrada. A Classe (de objeto) também vai especificar quais atributos são obrigatórios e quais são opcionais.
As classes formam uma hierarquia de classes dentro do LDAP, sendo a classe top
o topo dessa estrutura, segue abaixo uma imagem mostrando a relação de algumas Classes dentro do Schema chamado core.schema
:
Existem três tipos de classes de objetos:
Estruturais
Indica o(s) atributo(s) que uma entrada pode ter, não tem a necessidade de ter outras classes de objetos, ou seja, permite que o dado seja inserido diretamente no Diretório LDAP.Auxiliares
Somente indicam os atributos que uma entrada pode ter, para isso necessita de uma classe do tipo estrutural para que essa classe faça a inserção dos registros no diretótio LDAP.Abstratas
Possui especificação parcial da hierarquia de uma determinada classe, apenas subclasses estruturais e auxiliares permitem o uso desta classe.
Instalação e Configuração slapd.conf
O OpenLDAP possui dois modos de configuração, são eles:
Modo de configuração de arquivo de texto
É o modo antigo de configurar o servidor OpenLDAP, utiliza um arquivo de configuração chamadoslapd.conf
. Neste modo, as configurações são definidas no arquivo de configuração e as alterações só são aplicadas após a reinicialização do serviço.Esse modo é considerado obsoleto e não é mais recomendado para uso em ambientes de produção.
Modo de configuração dinâmica
Esse modo usa o diretório LDAP para armazenar as configurações do LDAP, o diretório fica em/etc/ldap/slapd.d
e toda a configuração nesse modo deve ser feita aqui.As configurações são armazenadas em um diretório especial chamado
cn=config
. Neste modo, as configurações são gerenciadas por meio de ferramentas de linha de comando, como oldapmodify
, e as alterações são aplicadas imediatamente, sem a necessidade de reiniciar o serviço.Esse modo é considerado mais flexível e escalável, e é o modo recomendado para uso em ambientes de produção.
Como explicado acima, vamos instalar o OpenLDAP, mas para o uso na LPIC-2 temos que usar o modo antigo, que não é recomendado, por esse motivo algumas coisas podem não funcionar e temos que fazer algumas correções para que funcionem.
- CentOS 7
- Ubuntu 20.04
$ sudo yum install openldap openldap-servers openldap-clients -y
# openldap-clients = Contém utilitários usados no Cliente LDAP.
# openldap = Servidor LDAP.
# openldap-servers = Fornece ferramentas adicionais de gerenciamento do servidor.
# Agora vamos definir o modo de configuração usado:
$ sudo vim /etc/sysconfig/slapd
## Deixe a variável 'SLAPD_OPTIONS' igual abaixo:
SLAPD_OPTIONS="-f /etc/openldap/ldap.conf"
# Baixe o arquivo (precisa modificar o caminho para o /etc/openlad):
$ sudo wget -O /etc/openldap/ldap.conf https://gitlab.com/sysnetbr/codes/-/raw/main/ldap/slapd.conf
# Crie o diretório abaixo:
$ sudo mkdir /var/run/slapd
# Reinicie o serviço:
$ sudo systemctl restart slapd
## Vai dar erro, não sei como corrigir no CentOS, então use Ubuntu ou não use mais esse modo de configuração.
Para fazer instalação no CentOS 8, recomendo que siga os passos descritos nesse link.
Os arquivos de configurações ficam em /etc/openldap
.
$ sudo apt install slapd ldap-utils -y
# ldap-utils = Contém utilitários usados no Cliente LDAP.
# slapd = Servidor LDAP.
# Agora vamos definir o modo de configuração usado:
$ sudo vim /etc/default/slapd
# Deixe a variável 'SLAPD_CONF' igual abaixo:
SLAPD_CONF=/etc/ldap/slapd.conf
# Agora crie esse arquivo, pode usar o meu como exemplo:
$ sudo wget -O /etc/ldap/slapd.conf -q https://gitlab.com/sysnetbr/codes/-/raw/main/ldap/slapd.conf
# Gere uma nova senha:
$ sudo slappasswd
New password:
Re-enter new password:
{SSHA}seSjSt7BB6AkZUPcfHb9q9zdj3uroGxS
# Com a senhas em mãos edite o arquivo abaixo:
$ sudo vim /etc/ldap/slapd.conf
## Adicione a senha acima em 'rootpw':
rootpw {SSHA}seSjSt7BB6AkZUPcfHb9q9zdj3uroGxS
# Agora reinicie o serviço:
$ sudo systemctl restart slapd
# Agora veja se subiu:
sudo systemctl status slapd
● slapd.service - LSB: OpenLDAP standalone server (Lightweight Directory Access Protocol)
Loaded: loaded (/etc/init.d/slapd; generated)
Drop-In: /usr/lib/systemd/system/slapd.service.d
└─slapd-remain-after-exit.conf
Active: active (running) since Sun 2023-04-16 01:36:24 UTC; 9s ago
Docs: man:systemd-sysv-generator(8)
Process: 11240 ExecStart=/etc/init.d/slapd start (code=exited, status=0/SUCCESS)
Tasks: 4 (limit: 460)
Memory: 5.8M
CGroup: /system.slice/slapd.service
└─11255 /usr/sbin/slapd -h ldap:/// ldapi:/// -g openldap -u openldap -f /etc/ldap/slapd.conf
Apr 16 01:36:24 ubuntu2004.localdomain slapd[11255]: config_build_entry: "olcDatabase={2}hdb"
Apr 16 01:36:24 ubuntu2004.localdomain slapd[11255]: backend_startup_one: starting "dc=maddogs,dc=com,dc=br"
Apr 16 01:36:24 ubuntu2004.localdomain slapd[11255]: hdb_db_open: database "dc=maddogs,dc=com,dc=br": dbenv_open(/var/lib/ldap).
Apr 16 01:36:24 ubuntu2004.localdomain slapd[11255]: backend_startup_one: starting "dc=sysnetbr,dc=com,dc=br"
Apr 16 01:36:24 ubuntu2004.localdomain slapd[11255]: hdb_db_open: database "dc=sysnetbr,dc=com,dc=br": unclean shutdown detected; attempting recovery.
Apr 16 01:36:24 ubuntu2004.localdomain slapd[11255]: hdb_db_open: database "dc=sysnetbr,dc=com,dc=br": dbenv_open(/var/lib/ldap).
Apr 16 01:36:24 ubuntu2004.localdomain slapd[11255]: slapd starting
Apr 16 01:36:24 ubuntu2004.localdomain slapd[11240]: ...done.
Apr 16 01:36:24 ubuntu2004.localdomain systemd[1]: Started LSB: OpenLDAP standalone server (Lightweight Directory Access Protocol).
Apr 16 01:36:24 ubuntu2004.localdomain slapd[11255]: bdb(dc=maddogs,dc=com,dc=br): BDB0060 PANIC: fatal region error detected; run recovery
# Se quiser testar a configuração, podemos usar:
$ sudo slaptest -f /etc/ldap/slapd.conf
config file testing succeeded
Se você quiser pode usar um
slapd.conf
mais simples nesse link aqui chamado deldap.conf
.
Os arquivos de configurações ficam em /etc/ldap
.
Não perca a senha de administrador.
Após a instalação podemos ver se o serviço está rodando:
$ sudo systemctl status slapd
● slapd.service - LSB: OpenLDAP standalone server (Lightweight Directory Access Protocol)
Loaded: loaded (/etc/init.d/slapd; generated)
Drop-In: /usr/lib/systemd/system/slapd.service.d
└─slapd-remain-after-exit.conf
Active: active (running) since Sun 2023-04-16 00:21:49 UTC; 2min 26s ago
Docs: man:systemd-sysv-generator(8)
Tasks: 3 (limit: 460)
Memory: 3.7M
CGroup: /system.slice/slapd.service
└─10624 /usr/sbin/slapd -h ldap:/// ldapi:/// -g openldap -u openldap -F /etc/ldap/slapd.d
Apr 16 00:21:49 ubuntu2004.localdomain systemd[1]: Starting LSB: OpenLDAP standalone server (Lightweight Directory Access Protocol)...
Apr 16 00:21:49 ubuntu2004.localdomain slapd[10608]: * Starting OpenLDAP slapd
Apr 16 00:21:49 ubuntu2004.localdomain slapd[10614]: @(#) $OpenLDAP: slapd (Ubuntu) (May 12 2022 13:11:05) $
Debian OpenLDAP Maintainers <pkg-openldap-devel@lists.alioth.debian.org>
Apr 16 00:21:49 ubuntu2004.localdomain slapd[10624]: slapd starting
Apr 16 00:21:49 ubuntu2004.localdomain slapd[10608]: ...done.
Apr 16 00:21:49 ubuntu2004.localdomain systemd[1]: Started LSB: OpenLDAP standalone server (Lightweight Directory Access Protocol).
O LDAP usa duas portas, uma com criptografia e outra sem. A porta sem criptografia pode ser referenciada pelo nome ldap
em algumas aplicações, é equivalente ao usar a porta 389, já a porta com criptografia pode ser referenciada pelo nome ldaps
em algumas aplicações, é equivalente ao usar a porta 636.
ACL
As ACLs (Access Control Lists) são regras de controle de acesso que definem as permissões de acesso aos dados armazenados em um servidor LDAP. Elas são usadas para garantir a segurança e a privacidade das informações armazenadas no diretório, permitindo que apenas usuários autorizados possam ler, modificar ou excluir esses dados. Se não for configurado ACL todo mundo vai ter acesso de leitura.
Veja um exemplo:
1. access to *
2. by anonymous auth
3. by * read
access to *
especifica que a regra se aplica a todos os objetos do diretório;by anonymous auth
indica que usuários anônimos podem autenticar e ter acesso ao objeto.by * read
define que qualquer usuário autenticado pode ler os dados do objeto, mas não pode modificar ou excluir esses dados.
Essa configuração permite que usuários anônimos possam autenticar e ler os dados do objeto no diretório LDAP, enquanto usuários autenticados podem apenas ler os dados, mas não podem modificá-los ou excluí-los.
A configuração do rootdn
e do rootpw
não é obrigatória no arquivo sldap.conf
. Caso não coloque, por questões de segurança, podemos criar um usuário administrador e determinar suas permissões através das ACL's.
dn: cn=Manager,dc=maddogs,dc=com,dc=br
cn: Manager
sn: Manager
objectClass: person
objectClass: top
userPassword: {SSHA}HASH
Ai podemos definir a ACL para ele:
access to dn.base="cn=Manager,dc=maddogs,dc=com,dc=br"
by peername.regex=127\.0\.0\.1 auth
by peername.regex=172\.16\.1\..* auth
by users none
by * none
Banco de Dados LDAP
Com o LDAP funcionando vamos adicionar informações ao nosso LDAP. Para isso vamos usar arquivo .ldif
.
Arquivos LDIF
O LDAP possui alguns gerenciadores que podem ser acionados para manipular dados em modo batch, acontece que manipulação em modo on-line não é possível no LDAP, para inserir informações devemos usar arquivos contendo as informações para tal inserção. Esses arquivos devem seguir um formato específico chamado LDIF (LDAP Data Interchange Format).
Ao inserir informações de usuários, grupos, domínios, devemos informar quais atributos poderão fazer parte dessa entrada. Tudo é feito através de um objectClass, cada objectClass possui um tipo, vejamos alguns abaixo:
Tipo de ObejectClass | Descrição |
---|---|
dcObject | Usado para cadastrar o topo da árvore de diretórios. |
organizationalUnit | Usado para cadastrar uma Unidade Organizacional. |
inetOrgPerson | Usado para cadastrar usuários (de modo geral). |
Como exemplo, vamos criar nosso LDIF informando os dados do nosso domínio (maddogs.com.br), esse arquivo pode ser criado em qualquer lugar (por organização, você pode sempre deixar esses arquivos dentro de /etc/ldap/schema/
), depois de criarmos, vamos carregar ele na base do LDAP.
Crie um arquivo chamado domain.ldif
, vamos usar o conteúdo deste link no arquivo recém criado, para facilitar use o comando abaixo para fazer download do arquivo. Agora vamos adicionar as novas entradas no arquivo:
# Crie uma pasta para manter os nossos arquivos ldif:
$ sudo mkdir /etc/ldap/schema/maddogs
# Obtendo o arquivo 'domain.ldif':
$ sudo wget -O /etc/ldap/schema/maddogs/domain.ldif https://gitlab.com/sysnetbr/codes/-/raw/main/ldap/domain.ldif
# Carregando informações de domínio na Base do LDAP:
$ sudo ldapadd -x -D "cn=admin,dc=maddogs,dc=com,dc=br" -W -f /etc/ldap/schema/maddogs/domain.ldif
Enter LDAP Password:
adding new entry "dc=maddogs,dc=com,dc=br"
adding new entry "ou=usuarios,dc=maddogs,dc=com,dc=br"
adding new entry "cn=Isabella,ou=usuarios,dc=maddogs,dc=com,dc=br"
adding new entry "cn=Leonardo,ou=usuarios,dc=maddogs,dc=com,dc=br"
adding new entry "cn=Sofia,ou=usuarios,dc=maddogs,dc=com,dc=br"
adding new entry "cn=Gabriel,ou=usuarios,dc=maddogs,dc=com,dc=br"
adding new entry "cn=Luiza,ou=usuarios,dc=maddogs,dc=com,dc=br"
# -x = Faz uma autenticação simples;
# -D = Usuário que fará a operação;
# -W = Solicita senha para executar o comando;
# -f = Informa o nome do arquivo que será processado.
Nós usamos o comando ldapadd
que é considerado um comando para ser usado no lado do cliente (perceba que comandos LDAP para uso em servidor começam com slap
, como em slapadd, slappasswd etc). Não foi usado o slapadd
porque apesar de ser usado para o mesmo propósito, ele só funciona quando o serviço do LDAP está parado, não funciona com ele rodando.
Agora vamos fazer um teste, o comando abaixo vai procurar em toda a nossa base qualquer objectClass que possa existir.
$ ldapsearch -x -b 'dc=maddogs,dc=com,dc=br' '(objectclass=*)'
# extended LDIF
#
# LDAPv3
# base <dc=maddogs,dc=com,dc=br> with scope subtree
# filter: (objectclass=*)
# requesting: ALL
#
# maddogs.com.br
dn: dc=maddogs,dc=com,dc=br
objectClass: dcObject
objectClass: organization
o: Teste Empresa
dc: maddogs
# usuarios, maddogs.com.br
dn: ou=usuarios,dc=maddogs,dc=com,dc=br
objectClass: organizationalUnit
ou: usuarios
# Isabella, usuarios, maddogs.com.br
dn: cn=Isabella,ou=usuarios,dc=maddogs,dc=com,dc=br
cn: Isabella
sn: Silva
objectClass: person
# Leonardo, usuarios, maddogs.com.br
dn: cn=Leonardo,ou=usuarios,dc=maddogs,dc=com,dc=br
cn: Leonardo
sn: Rodrigues
objectClass: person
# Sofia, usuarios, maddogs.com.br
dn: cn=Sofia,ou=usuarios,dc=maddogs,dc=com,dc=br
cn: Sofia
sn: Costa
objectClass: person
# Gabriel, usuarios, maddogs.com.br
dn: cn=Gabriel,ou=usuarios,dc=maddogs,dc=com,dc=br
cn: Gabriel
sn: Pereira
objectClass: person
# Luiza, usuarios, maddogs.com.br
dn: cn=Luiza,ou=usuarios,dc=maddogs,dc=com,dc=br
cn: Luiza
sn: Santos
objectClass: person
# search result
search: 2
result: 0 Success
# numResponses: 8
# numEntries: 7
Outra forma de ver é usando o comando slapcat
que vai pegar um dump do banco de dados do LDAP, ele não vai consultar o LDAP como se fosse um cliente, igual o comando acima, nesse caso, faz um dump do banco de dados, esse comando slapcat
só funciona no servidor (por isso começa com slap
).
$ sudo slapcat -f /etc/ldap/slapd.conf
dn: dc=maddogs,dc=com,dc=br
objectClass: dcObject
objectClass: organization
o: Teste Empresa
dc: maddogs
structuralObjectClass: organization
entryUUID: a5ae2676-70b1-103d-9a93-af66fc9b6609
creatorsName: cn=admin,dc=maddogs,dc=com,dc=br
createTimestamp: 20230416144934Z
entryCSN: 20230416144934.552595Z#000000#000#000000
modifiersName: cn=admin,dc=maddogs,dc=com,dc=br
modifyTimestamp: 20230416144934Z
dn: ou=usuarios,dc=maddogs,dc=com,dc=br
objectClass: organizationalUnit
ou: usuarios
structuralObjectClass: organizationalUnit
entryUUID: a5b115de-70b1-103d-9a94-af66fc9b6609
creatorsName: cn=admin,dc=maddogs,dc=com,dc=br
createTimestamp: 20230416144934Z
entryCSN: 20230416144934.571837Z#000000#000#000000
modifiersName: cn=admin,dc=maddogs,dc=com,dc=br
modifyTimestamp: 20230416144934Z
dn: cn=Isabella,ou=usuarios,dc=maddogs,dc=com,dc=br
cn: Isabella
sn: Silva
objectClass: person
structuralObjectClass: person
entryUUID: a5b15b52-70b1-103d-9a95-af66fc9b6609
creatorsName: cn=admin,dc=maddogs,dc=com,dc=br
createTimestamp: 20230416144934Z
entryCSN: 20230416144934.573617Z#000000#000#000000
modifiersName: cn=admin,dc=maddogs,dc=com,dc=br
modifyTimestamp: 20230416144934Z
dn: cn=Leonardo,ou=usuarios,dc=maddogs,dc=com,dc=br
cn: Leonardo
sn: Rodrigues
objectClass: person
structuralObjectClass: person
entryUUID: a5b1ad5a-70b1-103d-9a96-af66fc9b6609
creatorsName: cn=admin,dc=maddogs,dc=com,dc=br
createTimestamp: 20230416144934Z
entryCSN: 20230416144934.575717Z#000000#000#000000
modifiersName: cn=admin,dc=maddogs,dc=com,dc=br
modifyTimestamp: 20230416144934Z
dn: cn=Sofia,ou=usuarios,dc=maddogs,dc=com,dc=br
cn: Sofia
sn: Costa
objectClass: person
structuralObjectClass: person
entryUUID: a5b1f12a-70b1-103d-9a97-af66fc9b6609
creatorsName: cn=admin,dc=maddogs,dc=com,dc=br
createTimestamp: 20230416144934Z
entryCSN: 20230416144934.577453Z#000000#000#000000
modifiersName: cn=admin,dc=maddogs,dc=com,dc=br
modifyTimestamp: 20230416144934Z
dn: cn=Gabriel,ou=usuarios,dc=maddogs,dc=com,dc=br
cn: Gabriel
sn: Pereira
objectClass: person
structuralObjectClass: person
entryUUID: a5b23202-70b1-103d-9a98-af66fc9b6609
creatorsName: cn=admin,dc=maddogs,dc=com,dc=br
createTimestamp: 20230416144934Z
entryCSN: 20230416144934.579113Z#000000#000#000000
modifiersName: cn=admin,dc=maddogs,dc=com,dc=br
modifyTimestamp: 20230416144934Z
dn: cn=Luiza,ou=usuarios,dc=maddogs,dc=com,dc=br
cn: Luiza
sn: Santos
objectClass: person
structuralObjectClass: person
entryUUID: a5b2782a-70b1-103d-9a99-af66fc9b6609
creatorsName: cn=admin,dc=maddogs,dc=com,dc=br
createTimestamp: 20230416144934Z
entryCSN: 20230416144934.580909Z#000000#000#000000
modifiersName: cn=admin,dc=maddogs,dc=com,dc=br
modifyTimestamp: 20230416144934Z
Comandos importantes
Comando | Descrição |
---|---|
slapindex | Usado para reconstruir o índice do banco de dados do LDAP. Esse comando é útil após modificar manualmente o arquivo de índice, após atualizar o LDAP para uma nova versão ou após importar/atualizar uma quantidade muita grande de informação no banco. Para executar esse comando o banco de dados não pode estar em execução: sudo systemctl stop slapd Agora podemos executar o comando: sudo slapindex -f /etc/ldap/slapd.conf |