Bash openldap同步AD组织数据

文章描述了一个脚本,用于从ActiveDirectory(AD)同步组织单位(OU)到OpenLDAP,支持全量和增量同步,确保OpenLDAP数据与AD保持一致,包括处理差异、删除多余数据和添加缺失的OU。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

将AD的ou同步到openldap(可支持全量同步和增量同步)

整体思路如下:

  • 从ad导出所有的数据,然后进行参数替换以及处理,处理后的文件称为A;
  • 从openldap导出所有的数据,然后进行参数替换以及处理,处理后的文件称为B;
  • 利用A,B进行全文对比,然后将差集和增量进行添加或删除(需要注意的是,这里的需求是openldap的数据完全跟AD保持一致,即便openldap有比ad多出的数据,也会被删除掉,除非不在 同步的ou下(即修改下面的 LDAP_BASE_DN))
#!/bin/bash
# 预定义参数
AD_DOMAIN="<Your AD's domain>"
AD_ADMIN_DN="CN=<Admin account name>,OU=XXX,OU=XXX,DC=XXX,DC=XXX,DC=XXX"
AD_ADMIN_PWD="<Your admin password>"
AD_BASE_DN="DC=XXX,DC=XXX,DC=XXX"
LDAP_DOMAIN="<Your OpenLDAP's domain>"
LDAP_ADMIN_DN="cn=Manager,dc=XXX,dc=XXX,dc=XXX"
LDAP_ADMIN_PWD="<Your admin password>"
LDAP_BASE_DN="OU=xxx,DC=xxx,DC=xxx"

# 先从AD上获取OU组织信息,并保存成ldif文件
/opt/bitnami/openldap/bin/ldapsearch -x -H ldap://${AD_DOMAIN} "(&(objectClass=top)(objectClass=organizationalUnit))" dn objectClass ou -D "${AD_ADMIN_DN}" -w "${AD_ADMIN_PWD}" -b "${AD_BASE_DN}" -L | perl -MMIME::Base64 -MEncode=decode -n -00 -e 's/\n +//g;s/(?<=:: )(\S+)/decode("UTF-8",decode_base64($1))/eg;print' > /opt/tmp_query_adgroup.ldif

# 全文将 ad的域(dc=aaa,dc=com) 替换为openldap的域(dc=bbb,dc=net)
sed -i 's#DC=aaa,DC=com#DC=bbb,DC=net#g' /opt/tmp_query_adgroup.ldif
# 全文将 :: 替换为 :
sed -i 's#::#:#g' /opt/tmp_query_adgroup.ldif
# 去掉以#开头的行
sed '/^#/d' /opt/tmp_query_adgroup.ldif > /opt/tmp_handle_adgroup.ldif



# 读取OPENLDAP上所有的ou
/opt/bitnami/openldap/bin/ldapsearch -x -H ldap://${LDAP_DOMAIN} "(&(objectClass=top)(objectClass=organizationalUnit))" dn objectClass ou -D "${LDAP_ADMIN_DN}" -w "${LDAP_ADMIN_PWD}" -b "${LDAP_BASE_DN}" -L | perl -MMIME::Base64 -MEncode=decode -n -00 -e 's/\n +//g;s/(?<=:: )(\S+)/decode("UTF-8",decode_base64($1))/eg;print' > /opt/tmp_query_opgroup.ldif
# 全文将 :: 替换为 :
sed -i 's#::#:#g' /opt/tmp_query_opgroup.ldif
sed '/^#/d' /opt/tmp_query_opgroup.ldif > /opt/tmp_handle_opgroup.ldif
# 将dc,ou大写
sed -i 's#dc=#DC=#g' /opt/tmp_handle_opgroup.ldif
sed -i 's#ou=#OU=#g' /opt/tmp_handle_opgroup.ldif

#==========================================================全文比对==========================================================

#openldap比ad多出来的ou
grep -vxFf /opt/tmp_handle_adgroup.ldif /opt/tmp_handle_opgroup.ldif > /opt/tmp_del_group.ldif
sed -i "/^ou:/d" /opt/tmp_del_group.ldif
# 去掉dn
sed -i "s#dn: ##g" /opt/tmp_del_group.ldif

# opldap比ad少的ou
grep -vxFf /opt/tmp_handle_opgroup.ldif /opt/tmp_handle_adgroup.ldif > /opt/tmp_add_group.ldif
# 首次全量添加的时候,不需要添加top、organizationalUnit 属性
if ! grep -q "objectClass: top"  /opt/tmp_add_group.ldif ; then
    # 只保留dn(因为dn是唯一的)
     sed -i "/^ou:/d" /opt/tmp_add_group.ldif
     while read LINE; do
       # 如果dn中包含 / 字符,则进行转义
       if [[ "$LINE" == *"/"* ]]; then
         LINE="${LINE//\//\\/}"
       fi
       tmp_ou=$(echo $LINE | grep -o 'OU=[^,]*' | head -n 1)
       sed -i "s#^OU=#OU: #g" /opt/tmp_add_group.ldif
       sed -i "/$LINE/a"$tmp_ou /opt/tmp_add_group.ldif
     done < /opt/tmp_add_group.ldif
     sed -i "/^OU:/i\objectClass: top" /opt/tmp_add_group.ldif
     sed -i "/^OU:/i\objectClass: organizationalUnit" /opt/tmp_add_group.ldif
fi
# changetype: add必须位于第二行,也就是dn下方
sed -i "/^dn:/a\changetype: add" /opt/tmp_add_group.ldif

# 添加换行符
sed -i "/^OU:/a\\\n" /opt/tmp_add_group.ldif
sed -i "/^ou:/a\\\n" /opt/tmp_add_group.ldif


#====================================对数据进行增加或者删除====================================

# openldap添加缺少ad的ou
/opt/bitnami/openldap/bin/ldapmodify -x -H ldapi:/// -c -w "${LDAP_ADMIN_PWD}" -D "${LDAP_ADMIN_DN}" -f  /opt/tmp_add_group.ldif >& /opt/tmp_add_group_rec.log
# 防止第一次执行不成功(因为ou是无序的)
while read LINE; do
  if grep -q "ldap_add: No such object (32)" /opt/tmp_add_group_rec.log ; then
    /opt/bitnami/openldap/bin/ldapmodify -x -H ldapi:/// -c -w "${LDAP_ADMIN_PWD}" -D "${LDAP_ADMIN_DN}" -f  /opt/tmp_add_group.ldif >& /opt/tmp_add_group_rec.log
    $(sleep 1s)
  fi
done < /opt/tmp_add_group_rec.log

# 最后一步执行 openldap删除多出来的ou
while read LINE; do
  /opt/bitnami/openldap/bin/ldapdelete  -x -H ldapi:/// -c -w "${LDAP_ADMIN_PWD}" -D "${LDAP_ADMIN_DN}" -r ${LINE} > /dev/null 2>&1
done < /opt/tmp_del_group.ldif
<think>我们正在讨论如何配置OpenLDAP与Active Directory之间的双向同步。根据引用内容,我们了解到OpenLDAP 2.4及以上版本同步机制已经改变,并且提到了镜像模式(Mirror Mode)的双向同步。同时,引用中提到了同步周期设置Kerberos配置,这些对于同步过程中的认证定时同步有参考意义。 由于OpenLDAPActive Directory(AD)使用不同的协议架构,直接双向同步比较复杂。通常,我们需要一个中间工具来实现两者之间的同步。常见的工具有: 1. **LSC (LDAP Synchronization Connector)**:一个开源的LDAP同步工具,支持OpenLDAPAD之间的同步。 2. **Synchronization Service (如Identity Management解决方案)**:例如FreeIPA或MidPoint等。 3. **自定义脚本**:使用LDAP操作命令编写脚本,但维护复杂。 这里我们重点介绍使用LSC工具实现双向同步的步骤。 ### 一、前置条件 1. **网络与端口**: - 确保OpenLDAP服务器AD控制器之间网络互通。 - 开放AD的LDAPS端口(636)OpenLDAP的LDAPS端口(636)。 - 时间同步(NTP)确保一致。 2. **证书准备**: - 将AD的CA根证书导入OpenLDAP服务器信任库。 - 将OpenLDAP的CA根证书导入AD控制器信任库(如果使用自签名证书)。 3. **账户权限**: - 在AD上创建一个具有读取写入权限的账户(用于同步用户组)。 - 在OpenLDAP上创建一个具有读取写入权限的账户(如`cn=admin,dc=example,dc=com`)。 ### 二、安装LSC工具 LSC项目地址:https://lsc-project.org/ 1. **下载LSC**: ```bash wget https://github.com/lsc-project/lsc/releases/download/lsc-2.3.1/lsc-2.3.1.zip unzip lsc-2.3.1.zip cd lsc-2.3.1 ``` 2. **配置LSC**: 创建配置文件目录: ```bash mkdir /etc/lsc cp samples/* /etc/lsc/ ``` ### 三、配置同步任务 以同步用户对象为例,配置双向同步。 1. **编辑主配置文件(/etc/lsc/lsc.properties)**: ```properties # 源目录(AD) source.service = org.lsc.service.ad.AdService source.url = ldaps://ad.example.com:636 source.username = CN=SyncUser,CN=Users,DC=ad,DC=example,DC=com source.password = PASSWORD # 目标目录(OpenLDAP) destination.service = org.lsc.service.ldap.LdapService destination.url = ldaps://ldap.example.com:636 destination.username = cn=admin,dc=example,dc=com destination.password = PASSWORD # 同步策略(双向) synchronization.policy = org.lsc.policies.AlwaysBothSynchronizationPolicy ``` 2. **配置用户同步(/etc/lsc/users.properties)**: ```properties # 定义源(AD目标(OpenLDAP)的用户对象映射 source.filter = (&(objectClass=user)(sAMAccountName=*)) source.baseDn = CN=Users,DC=ad,DC=example,DC=com destination.filter = (objectClass=inetOrgPerson) destination.baseDn = ou=users,dc=example,dc=com # 属性映射 mapping.uid = sAMAccountName mapping.cn = displayName mapping.sn = sn mapping.givenName = givenName mapping.mail = mail ``` ### 四、配置Kerberos认证(可选) 如果AD要求Kerberos认证,需配置`/etc/krb5.conf`(参考引用[3]): ```ini [libdefaults] default_realm = AD.EXAMPLE.COM dns_lookup_realm = false dns_lookup_kdc = true [realms] AD.EXAMPLE.COM = { kdc = ad.example.com admin_server = ad.example.com } ``` ### 五、启动同步 1. **手动运行**: ```bash java -jar lsc.jar --config /etc/lsc -s users ``` 2. **定时任务**(参考引用[2]中的同步周期设置): 添加cron任务,例如每小时同步一次: ```bash 0 * * * * java -jar /opt/lsc/lsc.jar --config /etc/lsc -s users >> /var/log/lsc-users.log 2>&1 ``` ### 六、验证同步 1. **检查日志**:`/var/log/lsc-users.log` 2. **查询OpenLDAP**: ```bash ldapsearch -x -H ldaps://ldap.example.com -b "ou=users,dc=example,dc=com" -D "cn=admin,dc=example,dc=com" -W ``` 3. **查询AD**:使用AD管理工具查看用户是否同步成功。 ### 七、注意事项 1. **冲突处理**:双向同步可能引起数据冲突(如相同属性被两边修改),需在LSC配置中设置冲突解决策略。 2. **属性映射**:ADOpenLDAP的属性定义不同,需要仔细设计映射关系。 3. **性能优化**:大规模同步时,调整LSC的线程数批量大小。 > ⚠️ **重要**:建议在测试环境中充分验证后再部署到生产环境。 --- §§相关问题§§ 1. 如何解决OpenLDAPAD同步时的属性映射问题? 2. LSC同步工具支持哪些高级同步策略? 3. 如何监控OpenLDAPAD之间的同步状态? 4. 双向同步过程中出现数据冲突如何解决?</think>### 配置OpenLDAP与Active Directory双向同步的完整方案 要实现OpenLDAP与Active Directory的双向同步,推荐使用**LSC (LDAP Synchronization Connector)** 工具,这是专为LDAP目录同步设计的开源解决方案。以下是分步配置指南: --- #### 一、核心工具准备 1. **安装LSC工具**(Java环境要求): ```bash wget https://github.com/lsc-project/lsc/releases/download/lsc-2.3.1/lsc-2.3.1.zip unzip lsc-2.3.1.zip cd lsc-2.3.1 ``` 2. **配置Kerberos认证**(引用[3]): 编辑`/etc/krb5.conf`,确保ADOpenLDAP配置正确: ```ini [realms] AD.DOMAIN.COM = { kdc = ad-server.ad.domain.com admin_server = ad-server.ad.domain.com } OPENLDAP.DOMAIN.COM = { kdc = ldap-server.ldap.domain.com } ``` --- #### 二、双向同步配置 1. **创建同步任务配置文件** (`/etc/lsc/sync-ad-ldap.properties`): ```properties # 源目录(Active Directory) src.host = ad-server.ad.domain.com src.port = 636 src.ssl = true src.baseDn = dc=ad,dc=domain,dc=com src.bindDn = cn=admin,dc=ad,dc=domain,dc=com src.password = AD_admin_password # 目标目录(OpenLDAP) dst.host = ldap-server.ldap.domain.com dst.port = 636 dst.ssl = true dst.baseDn = dc=ldap,dc=domain,dc=com dst.bindDn = cn=admin,dc=ldap,dc=domain,dc=com dst.password = LDAP_admin_password # 同步策略(双向镜像模式,引用[1]) sync.policy = MIRROR sync.interval = 300 # 每5分钟同步一次(引用[2]) ``` 2. **配置属性映射** (`/etc/lsc/attribute-mapping.conf`): ```ini # AD属性 → OpenLDAP属性 objectClass = inetOrgPerson sAMAccountName = uid displayName = cn mail = mail memberOf = groupMembership # OpenLDAP属性 → AD属性 uid = sAMAccountName cn = displayName ``` --- #### 三、同步策略优化 1. **冲突解决机制**: ```properties # 当同一对象在两边被修改时,优先采用AD版本 conflict.resolution = SOURCE_PRIORITY ``` 2. **增量同步设置**: ```properties # 仅同步变更内容(基于时间戳) sync.scope = MODIFICATIONS sync.timestamp.attribute = modifyTimestamp ``` --- #### 四、启动与验证 1. **手动执行同步**: ```bash java -jar lsc.jar --config /etc/lsc/sync-ad-ldap.properties ``` 2. **配置定时任务**(引用[2]的同步周期): ```bash # 每天凌晨2点同步 0 2 * * * java -jar /opt/lsc/lsc.jar --config /etc/lsc/sync-ad-ldap.properties ``` 3. **验证同步结果**: ```bash # 检查AD用户是否同步OpenLDAP ldapsearch -x -H ldaps://ldap-server -b "dc=ldap,dc=domain,dc=com" "(uid=ad_user)" # 检查OpenLDAP组是否同步AD Get-ADGroup -Filter "Name -eq 'ldap_group'" ``` --- #### 五、故障排查要点 1. **证书错误**: ```bash keytool -importcert -keystore /etc/lsc/truststore.jks -file AD_CA.crt ``` 2. **权限问题**: - 确保AD服务账户有`Replicate Directory Changes`权限 - OpenLDAP账户需有`write`权限到目标OU 3. **日志检查**: ```bash tail -f /var/log/lsc/sync-ad-ldap.log ``` > ⚠️ **关键建议**: > 1. 首次同步前在测试环境验证配置 > 2. 使用`--dry-run`参数预演同步过程 > 3. 重要数据提前备份(`slapcat -l backup.ldif`) ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值