sábado, 26 de dezembro de 2009

Autenticando usuários Linux no servidor LDAP(Debian)


Depois de muito Google e um pouco de leitura(LDAP System Administration- GERALD, Carter - O'Reilly Media,ed 2003) Fiz um tutorial bem limpo e rápido de como configurar um servidor LDAP para autenticar clientes Linux.


Atenção!
Vale lembrar que aqui é feito uma abordagem técnica sem maiores detalhes sobre o protocolo LDAP(LDAPv3), sobre os conceitos de diretório, etc. Para um melhor aproveitamento do tutorial é importante dar uma olhada em todo o material citado aqui.

Resumo:

Na primeira parte configuramos o servidor LDAP, também responsável por endereçar as máquinas da rede(DHCP) e compartilhar os arquivos dos usuários(NFS).Adicionamos grupos e usuário ao diretório OpenLDAP e mostramos como utilizar as ferramentas de migração.
Na segunda parte configuramos as máquinas clientes(também Debian) para que autentiquem no nosso servidor LDAP.
(As configurações do servidor e clientes no final deste post.)

A estrutura lógica de nosso servidor  é:


Cabe ao nosso servidor responder por todas as requisições realizadas, seja por clientes ou até mesmo pelo próprio servidor.

Primeira Parte – Configurando o nosso Servidor

Depois de instalar e configurar o servidor DHCP, façamos o primeiro passo. Instale os pacotes:

$ sudo apt-get install slapd ldap-utils

As perguntas seguintes você deve responder:

Omit OpenLDAP server configuration? No
DNS domain name: seudominio.com
Organization name? seudominio.com
Administrator password: suasenha
Confirm password: suasenha
Database backend to use: HDB
Do you want the database to be removed when slapd is purged? No
Allow LDAPv2 protocol? No

Configuração Inicial
Assim que as perguntas terminam o nosso servidor OpenLDAP inicia sua execução.


Editamos agora o arquivo de configuração de todos os clientes LDAP. Isto nos permitirá executar o comando ldapsearch e outros comandos sem ter que escrever os parâmetros mais básicos todas as vezes que for necessário.
Descomente as linhas abaixo e altere-as de acordo com suas configurações:

#/etc/ldap/ldap.conf
base dc=seudominio,dc=com
uri ldap://endereço.ip.do.servidor/

Em seguida editamos o arquivo de configuração do servidor
-Antes de iniciar verificamos se todos os arquivos esquema estão habilitados

#/etc/ldap/slapd.conf

# Esquema principal exigido do OpenLDAP. Esse esquema define atributos e objetos
# básicos de LDAPv3 descritos nos RFCs 2251-2256.
include /etc/ldap/schema/core.schema
# Esquema para suportar guias de diretório COSINE e X.500. Com base no RFC 1274.
include /etc/ldap/schema/cosine.schema
# Esquema que define atributos e objetos necessários para utilizar o LDAP com o NIS
# (Network Information Service) como descrito no RFC 2307.
include /etc/ldap/schema/nis.schema
# Esque que define a classe de objeto inetOrgPerson e seus atributos associados
# definidos no RFC 2798. Esse objeto é frequentemente utilizado para armazenar
# informações de contatos para pessoas
include /etc/ldap/schema/inetorgperson.schema

-Altere o nível de detalhamento do log(essa diretiva aceita um número inteiro representando os tipos de informações que devem ser registradas nos registros cronológicos do sistema - veja a tabela no fim do post). O valor padrão é 256(stats):

loglevel 256

-Ache a linha "index objectClass eq" e deixe-a como o exemplo abaixo:

index objectClass eq
index uid eq

Nesse momento pare o serviço e siga com os comandos para que as opções de indexação sejam aplicadas:

$ sudo invoke-rc.d slapd stop
$ sudo slapindex
$ sudo chown openldap:openldap /var/lib/ldap/*
$ sudo invoke-rc.d slapd start

Um, dois... testando.

Vejamos agora qual o estado atual de nosso servidor. Façamos uma busca usando alguns comandos que temos, como ldapsearch e slapcat.
Com o ldapsearch(e outras ferramentas LDAP prefixadas por "ldap") executamos tarefas online, usando o protocolo LDAP.
Pelo comando slapcat(e outras ferramentas OpenLDAP prefixadas por "slap") executamos tarefas "offline", ou seja, acessando diretamente os arquivos locais. Por este motivo, só podem ser executados localmente no servidor OpenLDAP e sob os privilégios do usuário administrador.

Na saída desses dois comandos de pesquisa, você verá duas respostas, uma representando o nível mais alto da árvore, e outra representando o registro LDAP do administrador.

$ ldapsearch -x
# extended LDIF
#
# LDAPv3
# base (default) with scope subtree
# filter: (objectclass=*)
# requesting: ALL
#

# seudominio.com
dn: dc=seudominio,dc=com
objectClass: top
objectClass: dcObject
objectClass: organization
o: seudominio.com
dc: seudominio

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

# search result
search: 2
result: 0 Success

# numResponses: 3
# numEntries: 2


Na saída do comando slapcat, alguns atributos extras merecem a nossa atenção. Um deles é o userPassword, que não é mostrado ao usuário anônimo devido a restrição de acesso apropriada em /etc/ldap/sldap.conf

$ sudo slapcat

dn: dc=seudominio,dc=com
objectClass: top
objectClass: dcObject
objectClass: organization
o: seudominio.com
dc: seudominio
structuralObjectClass: organization
entryUUID: fe08595e-8443-102e-8ed4-9dfd31c2aa98
creatorsName:
modifiersName:
createTimestamp: 20091223192036Z
modifyTimestamp: 20091223192036Z
entryCSN: 20091223192036.331542Z#000000#000#000000

dn: cn=admin,dc=seudominio,dc=com
objectClass: simpleSecurityObject
objectClass: organizationalRole
cn: admin
description: LDAP administrator
userPassword:: e2NyeXB0fXUxZ1dWbWtnc0RxajI=
structuralObjectClass: organizationalRole
entryUUID: fe0bca3a-8443-102e-8ed5-9dfd31c2aa98
creatorsName:
modifiersName:
createTimestamp: 20091223192036Z
modifyTimestamp: 20091223192036Z
entryCSN: 20091223192036.355046Z#000000#000#000000

Criando a estrutura básica de nossa árvore

A estrutura do banco de dados LDAP funciona como uma árvore. No nível mais alto se encontra a nossa organização geralmente o nome de domínio. No nosso caso o nome de dominio é seudominio.com(substitua pelo seu), o topo da nossa árvore ficaria dc=seudominio,dc=com.

No nível mais abaixo, nossa organização é dividida em unidades organizacionais("organizational units"), como pessoas, usuarios, grupos, maquinas, serviços, redes, protocolos etc.
Criaremos então duas das unidades organizacionais citadas. As mesmas corresponderão as arquivos /etc/passwd e /etc/group Unix.

As informações de configuração LDAP e conteúdos de diretórios são armazenadas em arquivos de texto puro conhecidos por LDIF. Em sua forma mais básica, um arquivo LDIF é:

*Um conjunto de entradas separadas umas das outras por linhas em branco
*Um mapeamento de nomes de atributo a valores
*Um conjunto de diretivas que instruem o analisador sobre como processar a informação

Os dados no arquivo LDIF devem obedecer às regras de esquemas de seu diretório LDAP.

Desse modo criaremos um arquivo no formato LDIF que especifica as duas unidades organizacionais que desejamos adicionar ao servidor:
(pela padronização manteremos os nomes das ou's em inglês)

/var/tmp/ou.ldif

dn: ou=People,dc=seudominio,dc=com
ou: People
objectClass: organizationalUnit

dn: ou=Group,dc=seudominio,dc=com
ou: Group
objectClass: organizationalUnit

Para carregar o arquivo no servidor precisamos parar o serviço e seguir com os passos:

$ sudo invoke-rc.d slapd stop
$ sudo slapadd -c -v -l /var/tmp/ou.ldif
$ sudo invoke-rc.d slapd start

Agora vejamos se nossas unidades organizacionais foram adicionadas ao servidor com sucesso, para isso usamos ldapsearch;

$ ldapsearch -x ou=people

# extended LDIF
#
# LDAPv3
# base (default) with scope subt
# filter: ou=people
# requesting: ALL
#

# People, seudominio.hr
dn: ou=People,dc=seudominio,dc=com
ou: People
objectClass: organizationalUnit

# search result
search: 2
result: 0 Success

# numResponses: 2
# numEntries: 1


Filé! Vamos dar continuidade nas criação dos nossos usuários.

Criando os usuários

Continuando com a mesma lógica da criação das nossas unidades organizacionais. Criamos um arquivo contendo entradas que definem o usuário e o grupo a que ele pertence.

/var/tmp/user.ldif

dn: cn=locke,ou=group,dc=seudominio,dc=com
cn: locke
gidNumber: 1000
objectClass: top
objectClass: posixGroup

dn: uid=locke,ou=people,dc=seudominio,dc=com
uid: locke
uidNumber: 1000
gidNumber: 1000
cn: locke
sn: locke
objectClass: top
objectClass: person
objectClass: posixAccount
objectClass: shadowAccount
loginShell: /bin/bash
homeDirectory: /home/locke

Utilizaremos a ferramenta ldapadd para adicionar ao servidor nosso usuário. ldapadd utiliza o protocolo LDAP, nos conectamos ao servidor como administrador do sistema e então entramos com a senha:

$ ldapadd -c -x -D cn=admin,dc=seudominio,dc=com -W -f /var/tmp/user.ldif

Enter LDAP Password: suasenha
adding new entry "cn=locke,ou=group,dc=seudominio,dc=com"

adding new entry "uid=locke,ou=people,dc=seudominio,dc=com"

Para definir a senha do nosso usuario utilizamos a ferramenta ldappasswd, que também funciona online. Assim, temos que nos conectar ao servidor como administrador do sistema e então entramos com a senha do usuário:

$ ldappasswd -x -D cn=admin,dc=seudominio,dc=com -W -S \
uid=locke,ou=people,dc=seudominio,dc=com

New password: senhadousario
Re-enter new password: senhadousuario
Enter LDAP Password: suasenha

Vericamos agora se nosso usuário realmente foi criado. Para isso utilizamos a ferramenta ldapsearch. Note que o campo de senha, userPassword, não é mostrado, mesmo que você a tenha criado, devido as retrições de acesso padrão em /etc/ldap/slapd.conf.

$ldapsearch -x uid=locke

# extended LDIF
#
# LDAPv3
# base (default) with scope subtree
# filter: uid=locke
# requesting: ALL
#

# locke, people, seudomino.com
dn: uid=locke,ou=people,dc=seudominio,dc=com
uid: locke
uidNumber: 1000
gidNumber: 1000
cn: locke
sn: locke
objectClass: top
objectClass: person
objectClass: posixAccount
loginShell: /bin/bash
homeDirectory: /home/locke

# search result
search: 2
result: 0 Success

# numResponses: 2
# numEntries: 1


Pronto. Agora temos um servidor OpenLDAP funcionando. wow!



Configuração NFS

Para montar a partição /home do servidor nos clientes siga com os passos:

$ sudo apt-get install portmap nfs-kernnel-server nfs-common

Edite o arquivo /etc/exports e adicione a linha:

/etc/exports

/home 192.168.0.*(rw,no_root_squash)
(substitua pelo endereço da sua rede)

Segunda parte

Configurar os clientes LDAP

Para começar precisamos instalar os pacotes necessários:

$ apt-get install libnss-ldap nscd

Responda as perguntas que surgirão(se não aparecer, tente dpkg-reconfigure libnss-ldap):

LDAP server Uniform Resource Identifier: ldap://endereço.ip.do.servidor/ (Nota: "ldap://", e não "ldapi://"!)
Distinguished name of the search base: dc=seudominio,dc=com
LDAP version to use: 3
Does the LDAP database require login? No
Special LDAP privileges for root? No
Make the configuration file readable/writeable by its owner only? No
Make local root Database admin. No
Does the LDAP database require login? No

Agora temos que adicionar as seguintes linhas ao arquivo de configuração /etc/libnss-ldap.conf

/etc/libnss-ldap.conf

base dc=seudominio,dc=com
uri ldap://endereço.ip.do.servidor/

Antes de irmos para o próximo passo executemos alguns comandos para verificar qual o comportamento do sistema.

$ id root
uid=0(root) gid=0(root) grupos=0(root)
$id locke
id: locke Usuário inexistente

Como é possível notar o sistema ainda não consegue "enxergar" o usuário criado no nosso servidor OpenLDAP. Para que isso seja possível ativamos o módulo LDAP NSS, para isso editamos o arquivo de configuração /etc/nsswitch.conf alterando os atributos passwd, group e shadow:

/etc/nsswitch.conf

passwd: files ldap
group: files ldap
shadow: files ldap

Para darmos continuidade aos testes e verificar se o cliente está requisitando os arquivos do servidor, seguimos com a parada temporária do serviço nscd, Name Service Caching Daemon, serviço reponsável por armazenar localmente em cache os metadados(uid's, gid's, nomes reais, membros dos grupos, etc), evitando novas requisições ao servidor.
Executamos novamente o teste para verificar se o usuário locke é encontrado:

$id locke
uid=1000(locke) gid=1000(locke) grupos=1000(locke)

O último passo é integrar o LDAP com o procedimento de autenticação do sistema.

Devemos então instalar e configurar o libpam-ldap(Talvez já tenha sido instalado automaticamente durante a instalação do libnss-pam).

$ sudo apt-get install libpam-ldap

Responda as perguntas:

Make local root Database admin. No
Does the LDAP database require login? No

Edite o arquivo de configuração do módulo PAM em /etc/pam_ldap.conf:

/etc/pam_ldap.conf

base dc=seudominio,dc=com
uri ldap://endereço.ip.do.servidor/

Agora temos que configurar o Linux-PAM(http://www.kernel.org/pub/linux/libs/pam/). Vale lembrar que a configuração aqui deve ser feita com cuidado. Para maiores detalhes sobre a sintaxe do arquivo de configuração veja(http://www.kernel.org/pub/linux/libs/pam/Linux-PAM-html/sag-configuration-file.html).

Em nosso casa PAM requisitará que o usuário esteja presente localmente ou no servidor OpenLDAP.(É seguro que seja possível se logar caso ocorra algum problema com o serviço de diretório). Nota: a autenticação através de LDAP não é feita de forma segura pois nas conexões feitas o tráfego dos dados é realizado em texto puro. Para saber como se trabalhar isso veja(http://www.debian-administration.org/articles/570) Guia MIT Kerberos 5.

Editando as configurações PAM:

/etc/pam.d/common-account

account sufficient pam_unix.so
account required pam_ldap.so

/etc/pam.d/common-auth

auth [success=1 default=ignore] pam_unix.so nullok_secure
auth required pam_ldap.so use_first_pass
auth required pam_permit.so

/etc/pam.d/common-session

session required        pam_unix.so
session required        pam_mkhomedir.so skel=/etc/skel/ umask=0022

Configuração NFS

Instale os pacotes necessários:

$ sudo apt-get install nfs-common portmap

Para montar a partição durante o boot edite o arquivo de configuração /etc/fstab e comente a linha onde o /home aparece em seguida adicione a linha:

/etc/fstab

endereço.ip.do.servidor:/home /home nfs rw,sync,auto 0 0

É isso! Até breve.

 Tabela: Níveis de registro do OpenLDAP
Nível      HEX           Nome no log       Informação Registrada
-1          0xFFFF                Todas as informações de registro
0          0x0000                Nenhuma informação de registro
1          0x1        acl        Chamadas de função de trace
2          0x2        packets        Informação de depuração para lidar com pacotes
4          0x4        args        Depuração de processo de trace pesado
8          0x8        conns        Gerenciamento de conexão
16         0x10        BER        Pacotes enviados e recebidos
32         0x20        filter        Processamento do filtro de busca
64         0x40        config        Processamento do arquivo de configuração
128       0x80        ACL        Processamento da lista de controle de acesso
256       0x100        stats        Estatísticas para conexão, operações e resultados
512       0x200        stats2        Estatísticas para resultados devolvidos aos clientes
1024      0x400        shell        Comunicação com backends de shell
2048      0x800        parse        Informação de depuração de análise de entradas
4096      0x1000        cache        Informações de cache(não utilizado)
8192      0x2000        index        Informações de indexação(não utilizado)
16384         sync        Estatísticas(log) do syncrepl
32768     0x8000                Mensagens que não categorizadas
(desculpem a não formatação da tabela)

Ex.:
# Habilita os registros 1, 2, 4, 8, 32, 64 e 128
# 1 + 2 + 4 + 8 + 32 + 64 + 128
loglevel 255

# Habilita os registros 128, 2048
# 2048 + 128
loglevel 2176

# Habilita os registros 8, 32, 256
# 256 + 32 + 8
loglevel 296

# Usando um único valor hexa (128)
loglevel 0x80

# Usando múltiplos valores (1 + 128)
loglevel 0x81
# O mesmo resultado também é obtido em
loglevel 0x1 0x80

# Usando o nome de log(um único valor)
loglevel acl

# Usando múltiplos nomes de log
loglevel acl sync

# Usando combinações
loglevel 1 0x40 conns

Fontes:

http://pt.wikipedia.org/wiki/LDAP
http://www.ietf.org/rfc/rfc2252.txt -- Mais sobre arquivos de esquema OpenLDAP
http://www.zytrax.com/books/ldap/ -- LDAP for Rocket Scientists - Livro online
http://www.zytrax.com/books/ldap/ch6/#loglevel --Tabela de níveis de log
http://www.debuntu.org/ldap-server-and-linux-ldap-clients -- Tutorial para servidor e clientes Ubuntu
http://www.moduli.net/sysadmin/sarge-ldap-auth-howto.html#2
http://techpubs.eudominiosolutions.com/dklar/ldap.html
http://www2.savant.com.br/index.php/eventos/mao-na-massa-openldap
http://www.linuxjournal.com/article/6266
http://www.jukie.net/~bart/ldap/ldap-authentication-on-debian/

Imagens:
Archteture
http://quark.humbug.org.au/publications/ldap/images/architecture.png
OpenLDAP
http://www.openldap.org/images/headers/LDAPworm.gif