segunda-feira, 25 de julho de 2016

Active Directory com OpenLDAP proxy

Introdução

Neste post irei mostrar como configurar um servidor OpenLDAP como proxy para um ou mais servidores Active Directory na rede. No final iremos fazer um servidor Linux se autenticar utilizando a solução de proxy.

Esta solução é útil quando você deseja gerenciar os seus usuários de rede apenas pelo AD e permitir que servidores Linux se autentiquem utilizando a mesma base de dados de usuário.

Imagine que você tenha vários clientes e para cada um há um servidor Active Directory gerenciando os usuários. Os seus operadores possuem usuários cadastrados no Active Directory da sua empresa e você precisa fazer com que os servidores Linux do cliente se autentique via LDAP permitindo que tanto usuários da sua empresa quanto usuários do cliente possam se conectar em seus servidores Linux. Esta solução é chamada de Proxy LDAP.

Existem ao menos três formas de se configurar o Proxy LDAP mas para este post iremos focar na solução que adotei para resolver o cenário acima onde teremos uma base de LDAP contendo metadados dos usuários que estão cadastrados no AD e iremos utilizar SASL para que o servidor LDAP passe o serviço de autenticação para o AD.

A solução proposta neste post funcionará da seguinte forma:

  • O usuário irá solicitar autenticação na base de dados LDAP utilizando o uid e password cadastrados
  • O LDAP terá um parâmetro no campo userPassword no formato {SASL}usuario@dominio onde o LDAP irá interpretar que deverá passar a autenticação adiante para o serviço saslauthd
  • Ao receber a requisição de autenticação o serviço saslauthd irá fazer a comunicação com o serviço AD utilizando o Proxy LDAP que poderá fazer ponte com um ou mais ADs.
  • Se o usuário e senha forem validados corretamente pelo serviço AD, a mensagem de autenticação é respondida com sucesso para o serviço saslauthd que por sua vez irá responder ao LDAP que a autenticação foi bem sucedida.
Para atingir este objectivo iremos fazer as configurações no servidor LDAP em quatro passos:

  • Passo 1 - Configurar a base de dados para armazenamento de metadados onde usuários cadastrados terão em seu atributo userPassword o valor {SASL}usuario@dominio para instruir que este usuário deverá se autenticar utilizando o Proxy LDAP
  • Passo 2 - Configurar o proxy LDAP para que este normalize a base de dados do AD transformando o domínio ex. contoso.com em um domínio local do LDAP de forma que todo o domínio do AD possa ser consultado a partir de uma OU (Organizational Unit) LDAP1
  • Passo 3 - Configurar o serviço saslauthd para que este se comunique com o Proxy LDAP afim de autenticar os usuários cadastrados no AD. O saslauthd irá receber o usuário no formato usuario@LDAP1 onde usuário é o uid que será mapeado para o campo sAMAccountName cadastrado no AD
  • Passo 4 - Criaremos os usuário na base LDAP com o mesmo uid informando no atributo userPassword que este usuário deverá passar adiante o serviço de autenticação para o saslauthd que por sua vez irá se comunicar com o Proxy LDAP que irá se comunicar com o AD para realizar a autenticação   

Requisitos:

  • Servidor Active Directory ( Windows 2008 R2 ou Windows 2012 )
  • Usuário e senha no AD com permissão de consulta
  • Servidor OpenLDAP CentOS 7.x

Para este post iremos utilizar:

Servidor AD: ad.contoso.com
Usuário: openldap
Senha: secret
IP: 192.168.0.5

Servidor CentOS 7.x: openldap.local
Usuário: root
Senha: secret
IP: 192.168.0.10
SELINUX: disabled
FIREWALLD: disabled

A instalação do SO dos servidores mencionados acima vão além do escopo deste post. Vou assumir que você já tenha um servidor Active Directory instalado e funcionando na rede e que tenha instalado o servidor CentOS 7.x com o mínimo de pacotes necessários e com SELINUX e FIREWALLD desabilitados.

Passo 1


No servidor openldap instalamos os seguintes pacotes:

# yum install openldap-servers openldap-clients cyrus-sasl cyrus-sasl-ldap

Como preciso configurar uma base de dados LDAP vou simplificar essa instalação não utilizando a base de dados cn=config. Todas as configurações serão realizadas a partir de arquivos que serão disponibilizados no final do post como referencia para a sua instalação. Mais para frente irei disponibilizar um post abordando OpenLDAP com cn=config e replicação.

Primeiro paramos o serviço slapd e removemos o diretório /etc/openldap/slapd.d

# systemctl stop slapd
# rm -rf /etc/openldap/slapd.d

Gere um hash de senha para o usuário Manager:

# slappasswd -s secret
{SSHA}KR81a+hZjAgFFdMPcBFebVQFX4nwCDnp

Crie o arquivo /etc/openldap/slapd.conf com o conteúdo abaixo. Altere rootpw com o hash gerado pelo comando slappasswd acima

sasl-host localhost
sasl-secprops none

include /etc/openldap/schema/core.schema
include /etc/openldap/schema/cosine.schema
include /etc/openldap/schema/inetorgperson.schema
include /etc/openldap/schema/nis.schema
include /etc/openldap/schema/misc.schema
include /etc/openldap/schema/corba.schema
include /etc/openldap/schema/openldap.schema
include /etc/openldap/schema/ppolicy.schema
include /etc/openldap/schema/ldapns.schema
include /etc/openldap/schema/microsoft.minimal.schema

pidfile /var/run/openldap/slapd.pid
argsfile /var/run/openldap/slapd.args

modulepath /usr/lib64/openldap
moduleload back_meta.la
moduleload back_ldap.la
moduleload rwm.la

database mdb
maxsize 1073741824
suffix "dc=local"
rootdn "cn=Manager,dc=local"
rootpw {SSHA}KR81a+hZjAgFFdMPcBFebVQFX4nwCDnp
directory /var/lib/ldap

index objectClass eq

Deixei disponível os schemas ldapns.schema e microsoft.minimal.schema no link https://drive.google.com/open?id=0B9k1h3Guk1hmWHVnQ1BXVEJCbmM. Os outros arquivos estão disponíveis na distribuição. Faça o download desses dois arquivos e os copie para a pasta /etc/openldap/schema

Teste o arquivo de configuração para verificar se há algum erro:

# slaptest -f /etc/openldap/slapd.conf -u
57956906 config_back_initialize: warning, unable to get "olcDbIDAssertPasswd" attribute description: 17: attribute type undefined

config file testing succeeded

Ignore a mensagem de WARNING acima. Se você receber a mensagem "config file testing succeeded" é porque o arquivo está OK. Senão receber essa mensagem reveja o arquivo de configuração antes de proceder.

Criando a base de dados LDAP que irá armazenar os metadados

Crie um arquivo mydomain.ldif com o seguinte conteúdo:

dn: dc=local
dc: local
objectClass: dcObject
objectClass: organizationalUnit
ou: local

Execute o comando slapadd para inicializar a base de dados:

# slapadd -v -l mydomain.ldif
57956ae0 config_back_initialize: warning, unable to get "olcDbIDAssertPasswd" attribute description: 17: attribute type undefined
57956ae0 mdb_monitor_db_open: monitoring disabled; configure monitor database to enable
added: "dc=local" (00000001)

_#################### 100.00% eta   none elapsed            none fast!         

Ignore a mensagem de WARNING. Se você visualizar added: "dc=local" e a barra de progresso aparecer 100.00% a inicialização da base foi concluída com sucesso.

Ajuste as permissões para que o serviço slapd tenha acesso aos arquivos da base de dados

# chown ldap:ldap -R /var/lib/ldap

Inicie o serviço slapd

# systemctl start slapd.service

Verifique se o serviço está no ar consultando a base com o comando ldapsearch

# ldapsearch -H ldap://localhost -D 'cn=Manager,dc=local' -w secret -b 'dc=local' -LLL
dn: dc=local
dc: local
objectClass: dcObject
objectClass: organizationalUnit
ou: local

Passo 2

Agora que temos o serviço LDAP com a base de dados para armazenar metadados iremos criar uma nova instancia ldap que fará a comunicação com o servidor AD.

Crie o diretório /etc/openldap/proxy para armazenar as configurações de proxy.

# mkdir /etc/openldap/proxy

Crie o arquivo /etc/openldap/proxy/LDAP1.conf contendo o seguinte conteúdo:

database ldap
suffix "ou=LDAP1,dc=local"
uri ldap://192.168.0.5:3268
idassert-bind bindmethod=simple
  binddn="cn=openldap,cn=Users,dc=contoso,dc=com"
  credentials="secret"
  mode=none
  flags=non-prescriptive
idassert-authzFrom "dn.exact:cn=Manager,dc=local"

overlay rwm
rwm-suffixmassage "ou=LDAP1,dc=local" "dc=contoso,dc=com"

rwm-map attribute uid sAMAccountName
rwm-map attribute * *

Substitua os parâmetros uri, binddn, bindpw e rwm-suffixmassage para os valores necessários para o funcionamento no seu ambiente.

Crie o arquivo /etc/openldap/slapd-proxy.conf com o seguinte conteúdo:

modulepath /usr/lib64/openldap
moduleload back_meta.la
moduleload back_ldap.la
moduleload rwm.la

include /etc/openldap/schema/core.schema
include /etc/openldap/schema/cosine.schema
include /etc/openldap/schema/inetorgperson.schema
include /etc/openldap/schema/nis.schema
include /etc/openldap/schema/misc.schema
include /etc/openldap/schema/corba.schema
include /etc/openldap/schema/openldap.schema
include /etc/openldap/schema/ppolicy.schema
include /etc/openldap/schema/ldapns.schema
include /etc/openldap/schema/microsoft.minimal.schema

#Database
database ldap
suffix "cn=Manager,dc=local"
rootdn "cn=Manager,dc=local"
rootpw secret

include /etc/openldap/proxy/LDAP1.conf

Agora iniciamos o serviço Proxy LDAP em outra porta para não conflitar com a instancia de metadados que já está rodando. Vamos utilizar o endereço localhost e a porta 390

# slapd -f /etc/openldap/slapd-proxy.conf -h ldap://localhost:390

Agora verificamos se o proxy está funcionando consultando o serviço LDAP que está rodando na porta 390

# ldapsearch -x -H ldap://localhost:390 -b "ou=LDAP1,dc=local" -D "cn=Manager,dc=local" -w secret '(sAMAccountName=openldap)' uid userPrincipalName -LLL
dn: cn=openldap,cn=Users,ou=LDAP1,dc=local
uid: openldap
userPrincipalName: openldap@contoso.com

Se o comando acima retornar os atributos dn, uid e userPrincipalName. Parabéns a sua instancia de Proxy está funcionando corretamente. Senão verifique os arquivos de configuração e tente novamente.

Passo 3

Agora vamos configurar o SASL para autenticar usuários pela instancia do Proxy LDAP. Edite o arquivo /etc/saslauthd.conf com o seguinte conteúdo:

ldap_servers: ldap://127.0.0.1:390
ldap_search_base: ou=%d,dc=local
ldap_timeout: 10
ldap_filter: uid=%U
ldap_bind_dn: cn=Manager,dc=local
ldap_password: secret
ldap_deref: never
ldap_restart: yes
ldap_scope: sub
ldap_use_sasl: no
ldap_start_tls: no
ldap_version: 3
ldap_auth_method: bind

Edite o parametro MECH no arquivo /etc/sysconfig/saslauthd para ldap

# Directory in which to place saslauthd's listening socket, pid file, and so
# on. This directory must already exist.
SOCKETDIR=/run/saslauthd

# Mechanism to use when checking passwords. Run "saslauthd -v" to get a list
# of which mechanism your installation was compiled with the ablity to use.
MECH=ldap

# Additional flags to pass to saslauthd on the command line. See saslauthd(8)
# for the list of accepted flags.
FLAGS=

Habilite e inicie o serviço saslauthd

# systemctl enable saslauthd.service
Created symlink from /etc/systemd/system/multi-user.target.wants/saslauthd.service to /usr/lib/systemd/system/saslauthd.service.
# systemctl start saslauthd.service

Agora verifique se o serviço consegue autenticar usuários no AD.

# testsaslauthd -u openldap@LDAP1 -p P@ssw0rd
0: OK "Success."

Se você receber a mensagem 0: OK "Success." parabéns. O SASL pode autenticar utilizando o seu proxy LDAP.

Passo 4

Neste último passo é onde colocamos tudo para funcionar junto. O serviço LDAP irá se comunicar com o serviço saslauthd através de um objeto mutex.

Para configurar criaremos o arquivo /usr/lib64/sasl2/slapd.conf com o seguinte conteúdo

pwcheck_method: saslauthd
saslauthd_path: /var/run/saslauthd/mux

Veja que o arquivo slapd.conf possui o mesmo nome do arquivo configurado anteriormente mas são para propósitos diferentes.

Agora adicionamos o usuário ldap no grupo sasauthd para que o nosso serviço LDAP possa consultar o serviço.

# usermod -a -G saslauth ldap

Tenha certeza que possui os parâmetros sasl-host e sasl-secprops devidamente configurados no arquivo /etc/openldap/slapd.conf conforme instruções no Passo 1.

Reinicie o serviço do LDAP

# systemctl restart slapd.service

Agora iremos criar um usuário em nossa base de dados LDAP. Mas antes vamos criar uma unidade organizacional LDAP1 (OU) para organizar os usuários que pertencem a este domínio AD.

Crie um arquivo LDAP1.ldif com o seguinte conteúdo

dn: ou=LDAP1,dc=local
objectclass: organizationalUnit
objectclass: top
ou: LDAP1

Agora adicionamos a unidade organizacional utilizando o comando ldapadd

# ldapadd -H ldap://localhost -D cn=Manager,dc=local -w secret -f LDAP1.ldif

adding new entry "ou=LDAP1,dc=local"


A resposta do comando acima indica que a entrada da unidade organizacional foi efetuada com sucesso. Podemos verificar a operação utilizando o comando ldapsearch

# ldapsearch -H ldap://localhost -D cn=Manager,dc=local -w secret -b dc=local -LLL
dn: dc=local
dc: local
objectClass: dcObject
objectClass: organizationalUnit
ou: local

dn: ou=LDAP1,dc=local
objectClass: organizationalUnit
objectClass: top
ou: LDAP1

Criaremos agora um grupo Users com o gid 501 como o grupo padrão para nossos usuários. Crie o arquivo UsersGroup.ldif com o seguinte conteúdo

dn: cn=Users,dc=local
cn: Users
gidnumber: 501
objectclass: posixGroup
objectclass: top

Usamos então o comando ldapadd para adicionar o grupo na base LDAP

# ldapadd -H ldap://localhost -D cn=Manager,dc=local -w secret -f UsersGroup.ldif
adding new entry "cn=Users,dc=local"


Agora criaremos o usuário Angus MacGyver em nossa base LDAP instruindo pelo campo userPassword que este usuário deverá se autenticar via serviço SASL. Crie o arquivo AngusMacGyver.ldif com o seguinte conteúdo

dn: cn=Angus MacGyver,ou=LDAP1,dc=local
cn: Angus MacGyver
gidnumber: 501
givenname: Angus
homedirectory: /home/angus.mcgyver@contoso.com
loginshell: /bin/bash
objectclass: inetOrgPerson
objectclass: posixAccount
objectclass: top
sn: MacGyver
uid: angus.macgyver
uidnumber: 1000
userpassword: {SASL}angus.macgyver@LDAP1

Utilizamos o comando ldapadd para adicionar o usuário em nossa base LDAP

# ldapadd -H ldap://localhost -D cn=Manager,dc=local -w secret -f AngusMacGyver.ldif adding new entry "cn=Angus MacGyver,ou=LDAP1,dc=local"


Agora consultando a base com o comando ldapsearch teremos o seguinte resultado

# ldapsearch -H ldap://localhost -D cn=Manager,dc=local -w secret -b ou=LDAP1,dc=local -LLL
dn: ou=LDAP1,dc=local
objectClass: organizationalUnit
objectClass: top
ou: LDAP1

dn: cn=Angus MacGyver,ou=LDAP1,dc=local
cn: Angus MacGyver
gidNumber: 501
givenName: Angus
homeDirectory: /home/angus.mcgyver@contoso.com
loginShell: /bin/bash
objectClass: inetOrgPerson
objectClass: posixAccount
objectClass: top
sn: MacGyver
uid: angus.macgyver
uidNumber: 1000
userPassword:: e1NBU0x9YW5ndXMubWFjZ3l2ZXJATERBUDE=


Veja que o resultado do comando ldapsearch traz o usuário Angus MacGyver cadastrado na base LDAP. Veja que o campo userPassword está criptografado com base64 mas podemos decodificar esse campo utilizando o comando abaixo para simples verificação do valor armazenado

# echo e1NBU0x9YW5ndXMubWFjZ3l2ZXJATERBUDE= | perl -MMIME::Base64 -ne 'print decode_base64($_) . "\n"'

{SASL}angus.macgyver@LDAP1

Tchan Tchan!!! Esse valor será utilizado para autenticação via SASL

Agora, a partir de um servidor Linux CentOS 7 iremos configurá-lo para se autenticar utilizando a nossa base de dados LDAP.

Na linha de comando utilize o comando authconfig para realizar a configuração

# authconfig --enableldap --enableldapauth --ldapserver=192.168.0.10 --ldapbasedn="dc=local" --enablemkhomedir --update

Agora logue no servidor linux com o usuário angus.macgyver utilizando a senha cadastrada no AD e VIVA!! O seu servidor de Proxy LDAP está devidamente configurado e integrado com o serviço AD.

Você poderá aperfeiçoar essas configurações criando redundância entre mais servidores LDAP replicando a base de metadados e replicando a configuração do Proxy. Deverá também criar um script de inicialização para subir automaticamente o serviço Proxy LDAP toda vez que o servidor for reiniciado. Mais para frente farei mais posts abordando mais um pouco sobre LDAP e apresentando arquivos manifests para o puppet para subir mais servidores proxy para compor a solução.

Por enquanto este post mostra como funciona e como se implanta uma solução com Proxy LDAP que pode ser usada para integrar vários servidores ADs a partir de um único serviço de LDAP.


Até a próxima.

- Rafael Baena


Referencias:

http://ltb-project.org/wiki/documentation/general/sasl_delegation









Postar um comentário