Serviço LDAP no Debian

De Eriberto Wiki
Ir para navegação Ir para pesquisar
Este artigo foi baseado em Debian Jessie.

O que é o LDAP?

Existem milhares de definições sobre LDAP nos livros e páginas da Internet. No entanto, para um rápido entendimento, seria mais fácil dizer que LDAP é um banco de dados que segue padrões descritos em RFCs. É como se estivéssemos trabalhando com tabelas de bancos de dados que tivessem campos com nomes predefinidos.

O objetivo principal deste arquivo será mostrar como configurar o LDAP em um Debian e, a seguir, como realizar a conexão de clientes.

Instalação do LDAP

Primeiramente, deveremos instalar o servidor e pacote de comandos básicos.

# apt-get install slapd ldap-utils
Apenas por curiosidade:
  • slapd significa Stand-alone LDAP Daemon.
  • O pacote slapd contém os seguintes executáveis: slapacl - slapadd - slapauth - slapcat - slapd - slapdn - slapindex - slappasswd - slapschema - slaptest.
  • O pacote ldap-utils contém: ldapadd - ldapcompare - ldapdelete - ldapexop - ldapmodify - ldapmodrdn - ldappasswd - ldapsearch - ldapurl - ldapwhoami.

Depois de emitido o comando de instalação, surgirá uma janela solicitando uma senha de administrador para o usuário admin. Utilize a senha 123, pois teremos que trocá-la logo em seguida. O próximo passo será fazer um configuração mais detalhada do LDAP. Para isso, emita o comando:

# dpkg-reconfigure slapd

A partir deste ponto, teremos uma sequência de telas com perguntas.

Tela (1): Omitir a configuração do servidor OpenLDAP?

  • Nesta tela deverá ser respondido Não, para que possamos continuar a configuração detalhada do LDAP.


Tela (2): Nome do domínio DNS

  • Aqui deverá ser digitado o domínio DNS da rede que terá os seus usuários cadastrados no LDAP. Apenas como exemplo, darknet.com.br. O LDAP transformará isso em dc=darknet,dc=com,dc=br (mas deverá ser digitado darknet.com.br).
  • A abreviatura dc significa Domain Component.


Tela (3): Nome da organização

  • Neste ponto deverá ser informado o nome da organização. Exemplo: Darknet Redes e Solucoes
  • É importante não usar acentuação ou cedilha neste passo.


Tela (4): Senha do administrador

  • Agora deverá ser digitada a senha definitiva do admin, que será o usuário administrador do LDAP.
  • Preocupe-se em utilizar uma senha forte e confiável.


Tela (5): "Backend" de base de dados a ser usado

  • O LDAP utiliza um sistema de banco de dados para armazenar as informações. Nesta fase, um sistema deverá ser escolhido.
  • As opções BDB e HDB são formatos antigos.
  • O formato mais atual e recomendado é o MDB. Há algumas comparações de performance entre os formatos em http://wiki.zimbra.com/wiki/OpenLDAP_MDB_vs_HDB_performance.


Tela (6): Você deseja que a base de dados seja removida quando o pacote slapd for expurgado ("purge")?

  • Esta será uma decisão pessoal do admnistrador. A base de dados, que fica em /var/lib/ldap, deverá ser deletada, caso o pacote de instalação do LDAP seja removido via apt-get purge?
  • Se esta for a sua máquina LDAP definitiva, sugiro responder não, a fim de evitar acidentes.


Tela (7): Mover a base de dados antiga?

  • Esta base de dados antiga foi criada no momento da instalação do LDAP e está vazia. Como o LDAP está sendo reconfigurado, ela deverá ser removida para evitar conflitos. Responda Sim.


Tela (8): Permitir o protocolo LDAPv2?

  • A versão 2 do LDAP (LDAPv2) está em desuso e não possui várias funcionalidades existentes no LDAPv3, como autenticação via SASL, suporte a TLS e a UTF-8. Então, a não ser que você tenha um muito bom motivo para não fazer isso, responda Não para esta questão.


Uma vez configurado o servidor LDAP, poderemos ver o resultado com o seguinte comando:

$ ldapsearch -xb dc=darknet,dc=com,dc=br

A resposta deverá ser algo similar a isto:

# extended LDIF
#
# LDAPv3
# base <dc=darknet,dc=com,dc=br> with scope subtree
# filter: (objectclass=*)
# requesting: ALL
#

# darknet.com.br
dn: dc=darknet,dc=com,dc=br
objectClass: top
objectClass: dcObject
objectClass: organization
o: darknet Redes e Solucoes
dc: darknet

# admin, darknet.com.br
dn: cn=admin,dc=darknet,dc=com,dc=br
objectClass: simpleSecurityObject
objectClass: organizationalRole
cn: admin
description: LDAP administrator

# search result
search: 2
result: 0 Success

Caso algo errado ocorra, o resultado será similar a isto:

# numResponses: 3
# numEntries: 2
# extended LDIF
#
# LDAPv3
# base <dc=darknet,dc=com,dc=br> with scope subtree
# filter: (objectclass=*)
# requesting: ALL
#

# search result
search: 2
result: 32 No such object

# numResponses: 1

Migrando uma base passwd/shadow/group

Os procedimentos a seguir servirão apenas para redes que já possuirem usuários cadastrados em seus Linux. Assim, os comandos a seguir importarão tais usuários para o LDAP.

Procedimentos na máquina que contém os usuários

Estando a máquina que contém o cadastro dos usuários da rede, inicialmente, deveremos instalar o pacote migrationtools.

# apt-get install migrationtools

A seguir, edite o arquivo /etc/migrationtools/migrate_common.ph e procure as linhas:

$DEFAULT_MAIL_DOMAIN = "padl.com";
$DEFAULT_BASE = "dc=padl,dc=com";

Altere-as para que sejam compatíveis com a sua rede, como no exemplo a seguir:

$DEFAULT_MAIL_DOMAIN = "darknet.com.br";
$DEFAULT_BASE = "dc=darknet,dc=com,dc=br";
Observe que DEFAULT_MAIL_DOMAIN corresponde ao domínio DNS usado na sua rede.

Após a modificação, salve o arquivo e saia. O passo seguinte será criar arquivos secundários, a partir do /etc/passwd e do /etc/group. O arquivo /etc/shadow será lido automaticamente, no momento em que o arquivo /etc/passwd for processado. O processamento se dará com os comandos awk e sort. É importante salientar que, no Debian, os UID dos usuários comuns e os GID dos grupos que não são específicos do sistema começam em 1000. Por isso o awk colherá as linhas que iniciam com o UID > 999. Em outros sistemas esse número inicial poderá ser diferente. No RedHat e derivados, por exemplo, esses números começam em 500.

# awk -F: '$3 > 999' /etc/passwd | sort -nt: -k 3 > /tmp/passwd.new
# awk -F: '$3 > 999' /etc/group | sort -nt: -k 3 > /tmp/group.new

Agora que temos apenas um extrato do que nos interessa a respeito dos arquivos /etc/passwd e /etc/group, deveremos gerar arquivos no formato ldif. O ldif é o formato utilizado pelo LDAP para a importação e exportação de dados. Para gerar o ldif do /tmp/passwd.new, você deverá executar os seguintes comandos:

# cd /usr/share/migrationtools
# ./migrate_passwd.pl /tmp/passwd.new /tmp/passwd.ldif
É importante executar o comando migrate_passwd.pl dentro do diretório /usr/share/migrationtools. Para funcionar, o migrate_passwd.pl terá que enxergar o arquivo migrate_common.ph, que se encontra no referido diretório.

Após a execução do comando migrate_passwd.pl, observe o conteúdo do arquivo /tmp/passwd.ldif. Os hashes das senhas dos usuários deverão existir, significando que as mesmas foram exportadas a partir do arquivo /etc/shadow. Observe também que cada bloco inicia com uma linha chamada dn, como mostrado a seguir.

dn: uid=fulano,ou=People,dc=darknet,dc=com,dc=br
uid: fulano
cn: teste
objectClass: account
objectClass: posixAccount
objectClass: top
objectClass: shadowAccount
userPassword: {crypt}$6$/UWh49nl$bm9RVncNfHo9M3ZY/v8Fomj07EJRp5Anr90fufUdFk/DPw.Rzxb7EVRHywXAMt8ISFtDaiVWx4ueX1lWGn8.
shadowLastChange: 16107
shadowMax: 99999
shadowWarning: 7
loginShell: /bin/bash
uidNumber: 1005
gidNumber: 1005
homeDirectory: /home/fulano
gecos: teste,,,

DN significa Distinguished Name. O DN serve para identificar o usuário, unicamente, uma vez que cita o seu UID (neste caso o UID é um nome, pois o número do usuário no sistema se chama uidNumber), a sua OU (Organizational Unit) e os respectivos DCs. A OU é a subárvore do LDAP onde cada UID será colocado. A figura a seguir mostrará a situação:



Observe que há o OU. Então, em breve, antes da importação final do ldif, criaremos essa estrutura no servidor LDAP.

O passo semifinal desta fase será transformar o arquivo /tmp/group.new em ldif. Para isso, utilize os comandos:

# cd /usr/share/migrationtools
# ./migrate_group.pl /tmp/group.new /tmp/group.ldif

Finalmente, considerando que o LDAP foi instalado em outra máquina, mova os arquivos ldif gerados para a máquina servidora LDAP e apague os arquivos que ficaram em /tmp.

Procedimentos na máquina com serviço LDAP

Estando na máquina servidora LDAP, o primeiro passo será gerar um arquivo ldif para criar as OU People e Group. Como já foi dito anteriormente, essas OU receberão os usuários e os grupos. Assim, dentro do diretório /tmp, crie o arquivo ou.ldif com o seguinte conteúdo:

dn: ou=People,dc=darknet,dc=com,dc=br
ou: People
objectclass: organizationalUnit

dn: ou=Group,dc=darknet,dc=com,dc=br
ou: Group
objectclass: organizationalUnit

A seguir, importe o ldif anterior para a base. Utilize o comando a seguir:

# ldapadd -WD cn=admin,dc=darknet,dc=com,dc=br -f /tmp/ou.ldif

Será pedida a senha de administrador e ocorrerá a consequente importação dos dados.

Note que o hash da senha de administrador e demais dados ficam armazenados em /etc/ldap/slapd.d/cn\=config/olcDatabase\=\{1\}hdb.ldif.

Para verificar a situação atual, emita o comando:

# ldapsearch -xb dc=darknet,dc=com,dc=br

A seguir, faça a importação dos usuários para dentro do LDAP (as senhas serão, automaticamente, buscadas no arquivo /etc/shadow):

# ldapadd -WD cn=admin,dc=darknet,dc=com,dc=br -f /tmp/passwd.ldif

Para ver os dados importados, utilize o comando:

# ldapsearch -xb dc=darknet,dc=com,dc=br

Por último, importe os grupos:

# ./migrate_group.pl /tmp/group.new /tmp/group.ldif

Gerenciando usuários e grupos

As tarefas de gerenciamento de usuários e grupos poderão ser feitas, facilmente, por intermédio do aplicativo web phpLDAPadmin. No Debian, o aplicativo poderá ser instalado via apt-get.

Há a possibilidade de inserir, excluir e alterar dados de usuários via linha de comando. No entanto, essa tarefa será um pouco complexa, uma vez que dependerá da confecção de arquivos LDIF. Então, a forma mais prática e mais usada é a administração via phpLDAPadmin.

A seguir, um exemplo do ambiente do phpLDAPadmin:

Instalação do phpLDAPadmin

No Debian, a instalação do phpLDAPadim poderá ser feita com o seguinte comando:

# apt-get install phpldapadmin
O phpLDAPadmin poderá gerenciar o servidor LDAP a partir de qualquer outra máquina. Assim sendo, por questões de segurança, evite instalar o phpLDAPadmin no servidor.

Configuração básica do phpLDAPadmin

Após a instalação, edite o arquivo /etc/phpldapadmin/config.php e faça uma configuração básica, alterando as seguintes linhas:

$servers->setValue('server','name','LDAP Server');
$servers->setValue('server','host','127.0.0.1');
[...]
$servers->setValue('server','base',array('dc=example,dc=com'));
[...]
$servers->setValue('login','bind_id','cn=admin,dc=example,dc=com');

Exemplo:

$servers->setValue('server','name','LDAP Darknet');
$servers->setValue('server','host','192.168.0.31');
[...]
$servers->setValue('server','base',array('dc=darknet,dc=com,dc=br'));
[...]
$servers->setValue('login','bind_id','cn=admin,dc=darknet,dc=com,dc=br');

Adaptação e criação de templates do phpLDAPadmin

O phpLDAPadmin já traz diversos templates consigo. No entanto, é possível criar os seus próprios templates e exibir apenas esses.

Os templates deverão ficar dentro do diretório /etc/phpldapadmin/templates. Um template customizado deverá ter o seu nome iniciando com custom_. Para habilitar apenas a exibição de templates customizados, no arquivo /etc/phpldapadmin/config.php, descomente a seguinte linha:

$config->custom->appearance['custom_templates_only'] = true;
Mais detalhes sobre o arquivo de configuração do phpLDAPadmin poderão ser vistos no próprio arquivo de configuração e em http://phpldapadmin.sourceforge.net/wiki/index.php/Config.php.

Dentro do arquivo /etc/phpldapadmin/templates/template.dtd há uma relação de elementos que poderão ser utilizados nos seus templates. Cada um desses elementos, bem como a construção básica de um template, está explicado em http://phpldapadmin.sourceforge.net/wiki/index.php/Templates.

Um fato importante durante a criação de um template é o uso dos object classes. O object class é responsável por fornecer os elementos necessários à construção de um template. Como exemplo, para se colocar todos os elementos existentes em uma autenticação POSIX tradicional, composta pelos arquivos /etc/{passwd,shadow,group}, será necessário utilizar os seguintes object classes: account, posixAccount, top, shadowAccount. A classe top é a que está acima de todas as outras, atuando como uma classe mãe.

As definições dos elementos providos pelos objectClass estão descritos em RFCs. Um bom exemplo é a RFC 2307.

Modelo de template de criação de usuário

Um dos templates que eu desenvolvi foi para a criação de usuários POSIX. Veja a figura a seguir para entender como ficou o resultado final (clique se quiser ampliar).

O código usado no template, que possui vários recursos avançados, como autocompletamento, foi o seguinte:

<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!DOCTYPE template SYSTEM "template.dtd">

<!--
 
 CHANGELOG
 
 Created from posixAccount.xml
 by Joao Eriberto Mota Filho
 
 20120626 - initial version.
 
 -->
 
 <template>
 <askcontainer>1</askcontainer>
 <description>Criação de nova conta</description>
 <icon>ldap-user.png</icon>
 <invalid>0</invalid>
 <rdn>uid</rdn>
 <title>(1) Darknet: novo usuário</title>
 <visible>1</visible>
 
 <objectClasses>
 <objectClass id="account"></objectClass>
 <objectClass id="posixAccount"></objectClass>
 <objectClass id="top"></objectClass>
 <objectClass id="shadowAccount"></objectClass>
 </objectClasses>
 
 <attributes>
 
 
 <attribute id="uid">
        <display>Nome de usuário (login)</display>
        <onchange>=autoFill(homeDirectory;/home/%uid%)</onchange>
        <onchange>=autoFill(cn;%uid%)</onchange>
        <icon>ldap-user.png</icon>
        <order>1</order>
        <page>1</page>
 </attribute>
 
 
 <attribute id="cn">
        <display>Nome real</display>
        <readonly>1</readonly>
        <order>2</order>
        <page>1</page>
        <spacer>1</spacer>
 </attribute>
 
 
 <attribute id="userPassword">
        <display>Password (a conferência é opcional)</display>
        <helper>
                <display>Encryption</display>
                <default>md5crypt</default>
                <id>enc</id>
                <value>=php.PasswordEncryptionTypes()</value>
        </helper>
        <icon>lock.png</icon>
        <order>3</order>
        <page>1</page>
        <post>=php.PasswordEncrypt(%enc%;%userPassword%)</post>
 </attribute>
 
 
 <attribute id="shadowMax">
     <display>Validade da senha (em dias)</display>
     <order>4</order>
     <value>1</value>
 </attribute>
 
 
 <attribute id="shadowWarning">
     <display>Aviso de troca de senha (dias antes de expirar)</display>
     <order>5</order>
     <value>45</value>
 </attribute>
 
 
 <attribute id="shadowLastChange">
     <display>Última troca de senha (dias desde 01 Jan 1970)</display>
     <order>7</order>
     <spacer>1</spacer>
 </attribute>
 
 
 <attribute id="uidNumber">
        <display>UID</display>
        <icon>login.png</icon>
        <order>8</order>
        <page>1</page>
        <readonly>1</readonly>
        <value>=php.GetNextNumber(/;uidNumber)</value>
        <spacer>0</spacer>
 </attribute>
 
 
 <attribute id="gidNumber">
        <display>Grupo</display>
        <icon>ldap-ou.png</icon>
        <order>9</order>
        <page>1</page>
        <value><![CDATA[=php.PickList(/;(&(objectClass=posixGroup));gidNumber;%cn%;;;;cn)]]></value>
 </attribute>
 
 
 <attribute id="homeDirectory">
        <display>Diretório Home</display>
        <icon>folder.png</icon>
        <readonly>1</readonly>
        <order>10</order>
        <page>1</page>
 </attribute>
 
 
 <attribute id="loginShell">
        <display>Ambiente shell</display>
        <icon>terminal.png</icon>
        <order>11</order>
        <page>1</page>
        <type>select</type>
        <default>/bin/bash</default>
        <value id="/bin/bash">/bin/bash</value>
        <value id="/bin/false">/bin/false</value>
        <value id="/bin/sh">/bin/sh</value>
        <spacer>1</spacer>
 </attribute>
 
 
 <attribute id="gecos">
        <display>Diversos (CPF, outros dados)</display>
        <icon>catalog.png</icon>
        <order>12</order>
 </attribute>
 
 
 </attributes>
 
 </template>


Ondem dos campos

Uma outra possibilidade é a de estabelecer a ordem na qual os campos serão mostrados na tela. Isso poderá ser feito dentro do arquivo de configuração do phpLDAPadmin (/etc/phpldapadmin/config.php), por intermédio da linha $config->custom->appearance['attr_display_order']. A seguir, um exemplo para o caso mostrado neste item:

 $config->custom->appearance['attr_display_order'] = array(
  'uid',
  'cn',
  'userPassword',
  'shadowMax',
  'shadowWarning',
  'shadowLastChange',
  'shadowExpire',
  'uidNumber',
  'gidNumber',
  'homeDirectory',
  'loginShell',
  'gecos'
 );

Configuração dos clientes

Há três formas de se configurar os clientes para utilizarem o servidor LDAP. A primeira forma é apontando um programa cliente que suporta LDAP para o socket (IP e porta) do servidor. A segunda forma é fazer com que o PAM (Pluggable Authentication Modules), que opera os arquivos /etc/{passwd,shadow,group} e outros meios de autenticação, se dirija ao LDAP. Com isso, qualquer atividade que dependa de /etc/{passwd,shadow,group}, terminará utilizando o LDAP. Uma outra alternativa é instalar o sistema conhecido como SASL, que permite a conexão de uma máquina a vários sistemas de autenticação diferentes.

A configuração para que um programa atue como cliente LDAP é específica. Você precisará seguir as orientações do referido programa. Nesta parte deste artigo será mostrada a configuração via PAM.

O Name Service Switch (NSS) é utilizado no Linux para centralizar alguns tipos de procedimentos de autenticação e resolução de nomes. Ele entende os arquivos como /etc/passwd, /etc/hosts, sistemas DNS, LDAP e outros. A ideia aqui é fazer com que o LDAP se integre com o NSS e com o PAM.

Inicialmente, instale o pacote libnss-ldap, com a opção --no-install-recommends, para que o pacote nscd (Name Service Caching Daemon) não seja instalado. O problema é que o NSCD é um sistema de cache para resoluções de nomes e ele poderá interferir na atividade do LDAP por gerar caches indesejados.

# apt-get install --no-install-recommends libnss-ldap

A partir deste ponto, teremos uma sequência de telas com perguntas.

Tela (1): Identificador Uniforme de Recursos do servidor LDAP

  • Nesta tela deverá ser colocado o endereço IP ou nome DNS do servidor LDAP da sua rede. Exemplo: ldap://10.10.5.1/.


Tela (2): Nome distinto da base de pesquisa

  • Aqui deverá ser digitado o nome LDAP relativo ao domínio DNS da rede. Apenas como exemplo, para o domínio darknet.com.br, deverá ser digitado dc=darknet,dc=com,dc=br.


Tela (3): Versão LDAP a usar

  • Escolha a versão 3, a não ser que você tenha um excelente motivo para não fazer isso.


Tela (4): Conta LDAP para o root

  • Digite o nome da conta administrativa do servidor LDAP. No nosso caso, essa conta será a cn=admin,dc=darknet,dc=com,dc=br.


Tela (5): Password da conta root do LDAP

  • Neste ponto deverá ser inserida a senha do administrador do servidor LDAP. Note que este tipo de configuração não deverá ser utilizado em máquinas de usuários comuns para não expôr a senha. A referida senha ficará armazenada em claro em /etc/libnss-ldap.secret.


O próximo passo será instalar o pacote libpam-ldap para que haja a comunicação entre PAM e LDAP. Esse pacote fornecerá o arquivo pam_ldap.so, que será utilizado por alguns ambientes gráficos e clientes específicos para realizar login.

# apt-get install libpam-ldap

Logo após a instalação do pacote, surgirão algumas telas:

Tela (1): Permitir que a conta administrativa do LDAP se comporte como o usuário root local?

  • Cada caso é um caso. Mas penso que a melhor resposta para essa pergunta será não. Assim, só o root local terá plenos poderes sobre a máquina.


Tela (2): A base de dados LDAP requer autenticação?

  • A melhor resposta para essa pergunta será não.


Tela (3): Conta administrativa do LDAP

  • Digite o nome da conta administrativa do servidor LDAP. Idem ao que ocorreu na configuração da libnss-ldap, ou seja, no nosso exemplo, cn=admin,dc=darknet,dc=com,dc=br.


Tela (4): Senha para a conta administrativa no LDAP

  • Neste ponto deverá ser inserida a senha do administrador do servidor LDAP. A referida senha ficará armazenada em claro em /etc/pam_ldap.secret.
Pode ser que o libpam-ldap peça para autoconfigurar os arquivos existentes em /etc/pam.d/ para que possam usar o LDAP. Será emitida a mensagem: Sobrescrever as modificações locais de /etc/pam.d/common-*?. Responda sim.

Caso você deseje que os diretórios home dos usuários sejam criados automaticamente, logo após o login, verifique se existe a linha session required pam_mkhomedir.so umask=0022 skel=/etc/skel (ou similar) em /etc/pam.d/common-session. Caso não exista, proceda da seguinte forma:

  • Crie o arquivo /usr/share/pam-configs/mkhomedir, com o seguinte conteúdo:
Name: Create home directory during login
Default: yes
Priority: 900
Session-Type: Additional
Session:
        required        pam_mkhomedir.so umask=0022 skel=/etc/skel
  • A seguir, digite o comando:
# pam-auth-update
  • Serão feitas perguntas. Aceite as opções default.
  • Confira o resultado em /etc/pam.d/common-session.

O próximo passo será conferir se o arquivo /etc/nsswitch.conf está com as linhas passwd, group e shadow preparadas para utilizarem a máquina local (compat) e para o LDAP. Essas três linhas deverão estar assim:

passwd:         compat ldap
group:          compat ldap
shadow:         compat ldap

Finalmente, para testar se a máquina está obtendo informações do servidor LDAP, utilize os seguinte comandos:

# getent passwd
# getent shadow
# getent group

Os comandos anteriores deverão mostrar dados dos usuários cadastrados no LDAP.

Segurança do servidor

Um servidor LDAP convencional utiliza a porta 389. É recomentável criar um script, baseado em filtro de pacotes (iptables), para permitir o acesso apenas de máquinas específicas. Isso evitará ataques diversos ao servidor, evitando comprometer a sua integridade.

Referências