Sincronizando Bases OpenLDAP e Active Directory

O objetivo do artigo é a centralização da base de usuários, ou seja, por um fim a vários logins e senhas de uma rede com vários serviços autenticados. Abordarei um cenário que replica alterações na base OpenLDAP para o Active Directory.

[ Hits: 54.845 ]

Por: Evandro Nabor em 14/02/2013


Instalação e configuração



Não abordarei a instalação do Active Directory e nem do OpenLDAP, pois existem centenas de artigos a respeito na internet.

AD01

Crie um usuário com privilégio administrador chamado LSC no Active Directory, o programa irá usá-lo para as importações.

Instalar o serviço de Active Directory Certificate Services e exportar uma chave para utilizarmos no GNU/Linux:

LX01

Java:

# cd /usr/src
# wget
http://javadl.sun.com/webapps/download/AutoDL?BundleId=73850 -O java.tar.gz -O java.tar.gz
# tar zxvf java.tar.gz
# mv jre1.7.0_13 /usr/local/java
# export JAVA_HOME=/usr/local/java && echo "export JAVA_HOME=/usr/local/java" >> ~/.bashrc


Certificado:

# $JAVA_HOME/bin/keytool -import -keystore $JAVA_HOME/lib/security/cacerts -file ChaveDoWin2008.crt

Obs.: Quando for solicitada, a senha padrão é: changeit

LSC

# cd /usr/src
# wget
http://tools.lsc-project.org/attachments/download/317/lsc-core-1.2.2-dist.tar.gz
# tar zxvf lsc-core-1.2.2-dist.tar.gz
# mv lsc-1.2.2/ /usr/local/lsc && cd /usr/local/lsc


O arquivo de configuração do LSC é o etc/lsc.properties.

Este é um exemplo que montei para fazer a sincronia do nosso cenário. Você deverá modificá-lo conforme suas necessidades. Todas as documentações são encontradas na página do LSC, mas de qualquer maneira, este arquivo foi extremamente comentado por min:

#/usr/local/lsc/etc/lsc.properties
# Evandro Nabor
##############
### Origem ###
##############
# base OpenLDAP

src.java.naming.security.principal=cn=Manager,dc=texas,dc=local
src.java.naming.security.credentials=3v4ndrO
src.java.naming.security.authentication=simple
src.java.naming.referral=ignore
src.java.naming.provider.url=ldap://172.31.1.28/dc=texas,dc=local
src.java.naming.ldap.version=3
src.java.naming.ldap.derefAliases=never
src.java.naming.factory.initial=com.sun.jndi.ldap.LdapCtxFactory


###################
### Destino ###
###################
# base ActiveDirectory
# repare que utilizo SSL com exportacao do certificado do AD e importacao pro java do linux

dst.java.naming.security.principal=CN=LSC,CN=Users,DC=texas,DC=local
dst.java.naming.security.credentials=3v4ndrO
dst.java.naming.security.authentication=simple
dst.java.naming.referral=ignore
dst.java.naming.provider.url=ldaps://172.31.1.99/DC=texas,DC=local
dst.java.naming.ldap.version=3
dst.java.naming.ldap.derefAliases=never
dst.java.naming.factory.initial=com.sun.jndi.ldap.LdapCtxFactory
dst.java.naming.ldap.pageSize = 1000
#dst.java.naming.tls = true


###############
### Tarefas ###
###############
#definindo tarefa para sincronia de usuarios

lsc.tasks=user
#definindo tarefa para sincronia de grupos
lsc.tasks=group

### User ###
#opcoes de permissao para update, deletar e criar em ambas as bases

lsc.tasks.user.condition.create = 1
lsc.tasks.user.condition.update = 1
lsc.tasks.user.condition.delete = 1
lsc.tasks.user.condition.modrdn = 1

#esta opcao serve pra decidir como sera criado o usuario no activedirectory. ex. cn=evandro.nabor,cn=users,dc=texas,dc=local
lsc.tasks.user.bean=org.lsc.beans.SimpleBean
lsc.tasks.user.dn = "CN=" + srcBean.getAttributeValueById("uid") + ",CN=Users"

# Source
#opcoes de selecao dos usurios no ldap, perceba os filtros para que o programa funciona dos dois lados, tanto quando cria um usuario e ele eh replicado pra o
#AD quanto pra quando deleta um usuario ele compara as duas bases e deleta o usuario no AD

lsc.tasks.user.srcService=org.lsc.jndi.SimpleJndiSrcService
lsc.tasks.user.srcService.filterAll=(&(objectClass=inetOrgPerson)(uid=*)(!(givenName=MailList)))
lsc.tasks.user.srcService.filterId = (&(objectClass=inetOrgPerson)(|(uid={uid})(uid={sAMAccountName})))
lsc.tasks.user.srcService.baseDn=ou=pessoas
# campos que serao replicados, eh importante colocar todos que serao replicados e mais tarde nas opcoes de sincronia definir como sera a sincronia
lsc.tasks.user.srcService.attrs= uid sambaLogonScript homeDirectory postalCode postOfficeBox
# campo de volta, eh a pesquisa reversa que ele faz para que quando seja deletado algum usuario do OpenLDAP ele seja tambem deletado do AD
lsc.tasks.user.srcService.pivotAttrs = uid


# Destination
# opcoes para selecao de usuarios no AD repare que filtro algumas contas padrao do windows para q elas nunca sofrao alteracoes e nao tenha problema

lsc.tasks.user.dstService=org.lsc.jndi.SimpleJndiDstService
lsc.tasks.user.dstService.baseDn=cn=Users
# idem source
lsc.tasks.user.dstService.attrs = sAMAccountName userAccountControl objectClass userPrincipalName pwdLastSet scriptPath homeDirectory displayName givenName unicodePwd
lsc.tasks.user.dstService.filterAll=(&(sAMAccountName=*)(objectClass=user)(!(sAMAccountName=Administrator))(!(sAMAccountName=Guest))(!(sAMAccountName=krbtgt))(!(sAMAccountName=LSC)))
lsc.tasks.user.dstService.filterId = (&(objectClass=user)(sAMAccountName={uid}))
# idem source
lsc.tasks.user.dstService.pivotAttrs = sAMAccountName


### Group ###
# tarefa para sincronizar grupos
#regras de update, criar e deletar

lsc.tasks.group.condition.create = 1
lsc.tasks.group.condition.update = 1
lsc.tasks.group.condition.delete = 1
lsc.tasks.group.condition.modrdn = 1

# como sera criado o grupo no AD, ex. cn=IT,cn=users,dc=texas,dc=local
lsc.tasks.group.dn = "CN=" + srcBean.getAttributeValueById("cn") + ",CN=Users"
lsc.tasks.group.bean=org.lsc.beans.SimpleBean

# Source
# opcoes para selecao de grupos no OpenLDAP, repare os filtros para alguns grupos nunca sejam replicados pro AD como Domain Users, para nao confindir com os padroes do Win.

lsc.tasks.group.srcService=org.lsc.jndi.SimpleJndiSrcService
lsc.tasks.group.srcService.filterAll = (&(objectClass=posixGroup)(cn=*)(!(cn=Print Operators))(!(cn=Backup Operators))(!(cn=Administrators))(!(cn=Domain Users))(!(cn=Admins))(!(cn=Default))(!(cn=Domain Admins))(!(cn=Domain Computers))(!(cn=Domain Guests))(!
(cn=Replicators))(!(cn=Account Operators)))
lsc.tasks.group.srcService.filterId = (&(objectClass=posixGroup)(cn={cn}))
lsc.tasks.group.srcService.baseDn=ou=Grupos
lsc.tasks.group.srcService.attrs=cn objectClass memberUid
lsc.tasks.group.srcService.pivotAttrs = cn

# Destination
# opcpes para o destino, mesmo padrao de selecao para q os grupos default do Win nao sejam deletados

lsc.tasks.group.dstService=org.lsc.jndi.SimpleJndiDstService
lsc.tasks.group.dstService.baseDn=cn=Users
lsc.tasks.group.dstService.attrs = cn objectClass member sAMAccountName
lsc.tasks.group.dstService.pivotAttrs = cn
lsc.tasks.group.dstService.filterAll = (&(objectClass=group)(sAMAccountName=*)(!(sAMAccountName=DnsAdmins))(!(sAMAccountName=DnsUpdateProxy))(!(sAMAccountName=Domain Computers))(!(sAMAccountName=Domain Controllers))(!
(sAMAccountName=Schema Admins))(!(sAMAccountName=Enterprise Admins))(!(sAMAccountName=Cert Publishers))(!(sAMAccountName=Domain Admins))(!(sAMAccountName=Domain Users))(!(sAMAccountName=Domain Guests))(!(sAMAccountName=Group Policy
Creator Owners))(!(sAMAccountName=RAS and IAS Servers))(!(sAMAccountName=Allowed RODC Password Replication Group))(!(sAMAccountName=Denied RODC Password Replication Group))(!(sAMAccountName=Read-only Domain Controllers))(!
(sAMAccountName=Enterprise Read-only Domain Controllers)))
lsc.tasks.group.dstService.filterId = (&(objectClass=group)(cn={cn}))


###################
### Syncoptions ###
###################
# opcoes de sicronia, ou seja, quais campos serao sincornizados entre bases e se eh necessario algum remanejamento de campo, ou incluir texto,
# ex. o campo de script de logon no ldap do AD chama-se scriptPath no openldap chama-se sambaLogonScript portanto
# eh preciso fazer um mapemaento para que o campo sambaLogonScript do OpenLDAP seja escrito no scriptPath do AD.

# OpenLDAP -> AD
### User ###

lsc.syncoptions.user = org.lsc.beans.syncoptions.PropertiesBasedSyncOptions
lsc.syncoptions.user.default.action = F
lsc.syncoptions.user.objectClass.action = F
# o que inserir de atributos
lsc.syncoptions.user.objectClass.force_value = "top";"user";"person";"organizationalPerson"
# uid -> DisplayName
lsc.syncoptions.user.displayName.create_value = srcBean.getAttributeValueById("uid")
# uid -> givenName
lsc.syncoptions.user.givenName.create_value = srcBean.getAttributeValueById("uid")
# uid -> sAMAccountName
lsc.syncoptions.user.sAMAccountName.create_value = srcBean.getAttributeValueById("uid")
# sambaLogonScript -> scriptPath
lsc.syncoptions.user.scriptPath.action = F
lsc.syncoptions.user.scriptPath.force_value = srcBean.getAttributeValueById("postalCode")
# uid -> userPrincipalName
lsc.syncoptions.user.userPrincipalName.force_value = srcBean.getAttributeValueById("uid") + "@texas.local"
# homeDirectory -> homeDirectory
lsc.syncoptions.user.homeDirectory.action = F
lsc.syncoptions.user.homeDirectory.force_value = srcBean.getAttributeValueById("postOfficeBox")
# opcoes de controle do AD
lsc.syncoptions.user.userAccountControl.create_value = AD.userAccountControlSet( "0", [ AD.UAC_SET_PASSWD_NOTREQD,AD.UAC_SET_NORMAL_ACCOUNT ])
# password nao precisa ser mudado no proximo logon
lsc.syncoptions.user.pwdLastSet.create_value = "-1"
# senha padrao setada na importacao do usuario do OpenLDAP pro AD
lsc.syncoptions.user.unicodePwd.action = F
lsc.syncoptions.user.unicodePwd.create_value = AD.getUnicodePwd("3v4ndrO")

### Group ### # opcoes de sincronia para grupos
lsc.syncoptions.group = org.lsc.beans.syncoptions.PropertiesBasedSyncOptions
# nome do grupo
# cn -> sAMAccountName

lsc.syncoptions.group.sAMAccountName.create_value = srcBean.getAttributeValueById("cn")
lsc.syncoptions.group.default.action = F
# atributos de grupo
lsc.syncoptions.group.objectClass.force_value = "top";"group"
# membro dos grupos, eh um javascript que entra dentro dos grupos do OpenLDAP e busca usuarios
# e replica para o determinado grupo no AD

lsc.syncoptions.group.member.delimiter = $
lsc.syncoptions.group.member.force_value = \
  var umembers = \
    srcBean.getAttributeValuesById("memberUid").toArray() ; \
  for (var i=0; i    p\try { \
        umembers[i] = ldap.attribute(ldap.list("CN=Users","(sAMAccountName=" + (umembers[i]) + ")").get(0), 'distinguishedName').get(0) \
    } catch (e) { \
        umembers[i]=null; \
    } \
  } \
  var members = new Array(); \
  var j=0; \
  for (var i=0; i<umembers.length; i++) { \
    if (umembers[i]!=null) members[j++]=umembers[i]; \
  } \
  members;

OpenLDAP

Para exemplificar, criei uma base com seis usuários e três grupos, insira o conteúdo em um arquivo ldif e importe para dentro do seu servidor LDAP:

# baseteste.ldif
dn: dc=texas,dc=local
objectClass: top
objectClass: dcObject
objectClass: organization
dc: texas
o: Texas LDAP

dn: ou=pessoas,dc=texas,dc=local
objectClass: top
objectClass: organizationalUnit
ou: pessoas

dn: ou=grupos,dc=texas,dc=local
ou: grupos
objectClass: organizationalUnit
objectClass: top

dn: uid=enabor,ou=pessoas,dc=texas,dc=local
objectClass: posixAccount
objectClass: top
objectClass: inetOrgPerson
gidNumber: 0
givenName: evandro
sn: nabor
displayName: enabor
uid: enabor
homeDirectory: /home/enabor
cn: enabor
uidNumber: 27635

dn: uid=sman,ou=pessoas,dc=texas,dc=local
objectClass: posixAccount
objectClass: top
objectClass: inetOrgPerson
gidNumber: 0
givenName: super
sn: man
displayName: sman
uid: sman
homeDirectory: /home/sman
cn: sman
uidNumber: 10548

dn: uid=lluthor,ou=pessoas,dc=texas,dc=local
objectClass: posixAccount
objectClass: top
objectClass: inetOrgPerson
gidNumber: 0
givenName: lex
sn: luthor
displayName: lluthor
uid: lluthor
homeDirectory: /home/lluthor
cn: lluthor
uidNumber: 37975

dn: uid=lverde,ou=pessoas,dc=texas,dc=local
objectClass: posixAccount
objectClass: top
objectClass: inetOrgPerson
gidNumber: 0
givenName: lanterna
sn: verde
displayName: lverde
uid: lverde
homeDirectory: /home/lverde
cn: lverde
uidNumber: 24873

dn: uid=bwayne,ou=pessoas,dc=texas,dc=local
objectClass: posixAccount
objectClass: top
objectClass: inetOrgPerson
gidNumber: 0
givenName: bruce
sn: wayne
displayName: bwayne
uid: bwayne
homeDirectory: /home/bwayne
cn: bwayne
uidNumber: 25788

dn: cn=it,ou=grupos,dc=texas,dc=local
objectClass: posixGroup
objectClass: top
cn: it
memberUid: enabor
memberUid: bwayne
memberUid: sman
gidNumber: 58946

dn: cn=managers,ou=grupos,dc=texas,dc=local
objectClass: posixGroup
objectClass: top
cn: managers
gidNumber: 61470
memberUid: lluthor
memberUid: lverde

Página anterior     Próxima página

Páginas do artigo
   1. Introdução
   2. Instalação e configuração
   3. Iniciando a sincronização
   4. Senhas
Outros artigos deste autor

Bind consultando zonas em base LDAP

Leitura recomendada

Openconnect - Conexão de VPN Paloalto no Debian

Servidor de logs para Routers e Switches Cisco

Problemas encontrados na adoção do IPv6

Configurando o segundo default gateway para um link de entrada específico

Trabalhando com subredes

  
Comentários
[1] Comentário enviado por jfernandes em 16/02/2013 - 18:01h

Amigo, parabéns pelo artigo.
Tenho uma questão pra todos ...
Tenho um cliente que tem sua base em LDAP, e por enquanto não quer migrar para o AD da Microsoft, porém, contudo, todavia, ele quer uma solução que vamos instalar ( Xen Desktop ) que precisa do Active Directory da Microsoft para autenticação de seus usuários, não sei se conhecem o Xen Desktop, mas é uma solução de virtualização de estação de trabalho, e necessita de um login no AD.
Pergunta..... com esse seu tutorial, poderei implementar essa solução no cliente ?
Fico no aguardo, e mais uma vez, parabéns pelo artigo.
Joel Fernandes

[2] Comentário enviado por evandronabor em 17/02/2013 - 09:59h

Com certeza voce poderá usa-lo para isso.
Voce pode subir um servidor AD e seguir o meu artigo que todas as suas contas do OpenLDAP serão replicadas para o AD.
Quando a base estiver replicada é so voce colocar o comando de sincronização no crontab para ser executada quando voce quiser para manter a integridade das bases.

A unica questao que é preciso atençao é com relação as senhas pois como eu havia dito não é possivel sincroniza-las.
De uma boa lida no artigo e porcure mais informações no site do LSC. é possivel sim implementa-lo do jeito que voce precisa sem problemas.

Att.

[3] Comentário enviado por fernandofrauches em 22/02/2013 - 09:41h

Parabéns pelo artigo....
Muito bom...
Estou com um problema aqui na empresa relacionado a seu artigo.
No seu artigo vc faz a sincronização nesse sentido OpenLDAP -> Active Directory, é possivel fazer a sincronização no sentido contrario? OpenLDAP <- Active Directory? Se sim, tem alguma dica de como?
Desde ja obrigado.

[4] Comentário enviado por evandronabor em 22/02/2013 - 09:48h

Sim é possivel fazer. Basicamente voce vai inverter o SRC e o DST, verifique no site do LSC tem muitos exemplos de como fazer lá.

[5] Comentário enviado por acunhasp em 26/02/2013 - 14:13h

bom tarde amigo, o meu retorna o seguinte erro:
Error opening the LDAP connection to the destination!
Fev 26 14:05:23 - ERROR - Error while synchronizing ID {uid=edsonb}: java.lang.RuntimeException: java.lang.RuntimeException: Error getting context DN from LDAP provider url
Será que pode me ajudar?

[6] Comentário enviado por lanzao em 10/09/2013 - 12:09h

tem como migrar do ad para o ldap?

[7] Comentário enviado por geowany em 12/03/2014 - 00:51h


[1] Comentário enviado por jfernandes em 16/02/2013 - 18:01h:

Amigo, parabéns pelo artigo.
Tenho uma questão pra todos ...
Tenho um cliente que tem sua base em LDAP, e por enquanto não quer migrar para o AD da Microsoft, porém, contudo, todavia, ele quer uma solução que vamos instalar ( Xen Desktop ) que precisa do Active Directory da Microsoft para autenticação de seus usuários, não sei se conhecem o Xen Desktop, mas é uma solução de virtualização de estação de trabalho, e necessita de um login no AD.
Pergunta..... com esse seu tutorial, poderei implementar essa solução no cliente ?
Fico no aguardo, e mais uma vez, parabéns pelo artigo.
Joel Fernandes


Acredito que instalar o AD não é a melhor solução. Já tentou colocar o samba.schema nesse ldap e adicionar os atributos na contas de usuário para que se tornem samba accounts? Assim fica compatível com os atributos necessários do AD.


Contribuir com comentário




Patrocínio

Site hospedado pelo provedor RedeHost.
Linux banner

Destaques

Artigos

Dicas

Tópicos

Top 10 do mês

Scripts