AD와 OPENLDAP 동기화 하기 by lsc 본문
반응형
아래와 같이 구성하면 Active Directory 서버를 보호하면서 OpenLDAP을 이용하요 인증을 수행할 수 있다.
위 그림을 구성하기 위해 사용되는 솔류션이 LSC(LDAP Synchronization Connector)와 saslauthd 서비스이다.
※ saslauthd 서비스 자세히 보기) OpenLDAP Pass-through 구성 (tistory.com)
LSC란?
LSC는 다른 LDAP 서버, DB, 파일 등 데이터의 ID를 동기화하는 오픈 소스 커텍터이다.
설치
다운로드
cd ~
#https://ltb-project.org/wiki/lib/RPM-GPG-KEY-LTB-project
vim RPM-GPG-KEY-LTB-project
sudo rpm --import /home/ec2-user/RPM-GPG-KEY-LTB-project
wget https://lsc-project.org/archives/lsc-2.1.6-1.el7.noarch.rpm
sudo yum localinstall lsc*
구성
mkdir /etc/lsc/ad2openldap
vim /etc/lsc/ad2openldap/lsc.xml
lsc.xml (연동 소스 예시)
<?xml version="1.0" ?>
<lsc xmlns="http://lsc-project.org/XSD/lsc-core-2.1.xsd" revision="0">
<connections>
<ldapConnection>
<name>ldap-src-conn</name>
<url>ldap://ad-server.publicdomain.xyz:389/DC=your_ad_domain,DC=local</url>
<username>user_to_login@your_ad_domain.local</username>
<password>password_to_login_ad</password>
<authentication>SIMPLE</authentication>
<referral>IGNORE</referral>
<derefAliases>NEVER</derefAliases>
<version>VERSION_3</version>
<pageSize>-1</pageSize>
<factory>com.sun.jndi.ldap.LdapCtxFactory</factory>
<tlsActivated>false</tlsActivated>
</ldapConnection>
<ldapConnection>
<name>ldap-dst-conn</name>
<url>ldap://localhost:389/dc=your_ad_domain,dc=local</url>
<username>cn=admin,dc=your_ad_domain,dc=local</username>
<password>demopassword</password>
<authentication>SIMPLE</authentication>
<referral>IGNORE</referral>
<derefAliases>NEVER</derefAliases>
<version>VERSION_3</version>
<pageSize>-1</pageSize>
<factory>com.sun.jndi.ldap.LdapCtxFactory</factory>
<tlsActivated>false</tlsActivated>
</ldapConnection>
</connections>
<tasks>
<task>
<name>Sync_1_Users</name>
<bean>org.lsc.beans.SimpleBean</bean>
<ldapSourceService>
<name>ad-source-service</name>
<connection reference="ldap-src-conn" />
<baseDn>DC=your_ad_domain,DC=local</baseDn>
<pivotAttributes>
<string>samAccountName</string>
</pivotAttributes>
<fetchedAttributes>
<string>description</string>
<string>cn</string>
<string>sn</string>
<string>givenName</string>
<string>samAccountName</string>
<string>userPrincipalName</string>
<string>title</string>
<string>physicalDeliveryOfficeName</string>
<string>telephoneNumber</string>
<string>facsimileTelephoneNumber</string>
<string>department</string>
<string>company</string>
<string>mail</string>
<string>mobile</string>
<string>jpegPhoto</string>
</fetchedAttributes>
<!-- <getAllFilter>(objectClass=user)</getAllFilter> -->
<getAllFilter>(&(objectCategory=person)(objectClass=user)(!(UserAccountControl:1.2.840.113556.1.4.803:=2)))</getAllFilter>
<!-- <getOneFilter>(&(objectClass=user)(samAccountName={samAccountName})(mail=*))</getOneFilter> -->
<getOneFilter>(&(objectCategory=person)(objectClass=user)(!(UserAccountControl:1.2.840.113556.1.4.803:=2))(samAccountName={samAccountName}))</getOneFilter>
<!-- <cleanFilter>(&(objectClass=user)(samAccountName={uid})(mail=*))</cleanFilter> -->
<cleanFilter>(&(objectCategory=person)(objectClass=user)(!(UserAccountControl:1.2.840.113556.1.4.803:=2))(samAccountName={uid}))</cleanFilter>
</ldapSourceService>
<ldapDestinationService>
<name>opends-dst-service</name>
<connection reference="ldap-dst-conn" />
<baseDn>ou=Users,dc=your_ad_domain,dc=local</baseDn>
<pivotAttributes>
<string>uid</string>
</pivotAttributes>
<fetchedAttributes>
<string>description</string>
<string>cn</string>
<string>sn</string>
<string>userPassword</string>
<string>objectClass</string>
<string>uid</string>
<string>title</string>
<string>physicalDeliveryOfficeName</string>
<string>telephoneNumber</string>
<string>telexNumber</string>
<string>ou</string>
<string>o</string>
<string>mail</string>
<string>mobile</string>
<string>jpegPhoto</string>
</fetchedAttributes>
<getAllFilter>(objectClass=inetorgperson)</getAllFilter>
<getOneFilter>(&(objectClass=inetorgperson)(uid={samAccountName}))</getOneFilter>
</ldapDestinationService>
<propertiesBasedSyncOptions>
<mainIdentifier>"uid=" +
srcBean.getDatasetFirstValueById("samAccountName") +
",ou=Users,dc=your_ad_domain,dc=local"</mainIdentifier>
<defaultDelimiter>;</defaultDelimiter>
<defaultPolicy>FORCE</defaultPolicy>
<dataset>
<name>description</name>
<policy>FORCE</policy>
<forceValues>
<string>js:(srcBean.getDatasetFirstValueById("sn") != null ? srcBean.getDatasetFirstValueById("sn").toUpperCase() : null )</string>
</forceValues>
</dataset>
<dataset>
<name>userPassword</name>
<policy>KEEP</policy>
<createValues>
<string>js:"{SASL}" +
srcBean.getDatasetFirstValueById("samAccountName") + "@your_ad_domain.local"</string>
</createValues>
</dataset>
<dataset>
<name>sn</name>
<!-- <policy>FORCE</policy> -->
<policy>KEEP</policy>
<createValues>
<string>js:srcBean.getDatasetFirstValueById("samAccountName")</string>
</createValues>
</dataset>
<dataset>
<name>description</name>
<policy>FORCE</policy>
<forceValues>
<string>js:(srcBean.getDatasetFirstValueById("sn") != null ? srcBean.getDatasetFirstValueById("sn").toUpperCase() : null )</string>
</forceValues>
</dataset>
<dataset>
<name>uid</name>
<policy>KEEP</policy>
<createValues>
<string>js:srcBean.getDatasetFirstValueById("samAcccountName")</string>
</createValues>
</dataset>
<dataset>
<name>objectClass</name>
<policy>KEEP</policy>
<createValues>
<string>"inetOrgPerson"</string>
</createValues>
</dataset>
<dataset>
<name>telexNumber</name>
<policy>FORCE</policy>
<forceValues>
<string>js:srcBean.getDatasetFirstValueById("facsimileTelephoneNumber")</string>
</forceValues>
</dataset>
<dataset>
<name>o</name>
<policy>FORCE</policy>
<forceValues>
<string>js:srcBean.getDatasetFirstValueById("company")</string>
</forceValues>
</dataset>
<dataset>
<name>ou</name>
<policy>FORCE</policy>
<forceValues>
<string>js:srcBean.getDatasetFirstValueById("department")</string>
</forceValues>
</dataset>
</propertiesBasedSyncOptions>
</task>
<task>
<name>Sync_2_Groups</name>
<bean>org.lsc.beans.SimpleBean</bean>
<ldapSourceService>
<name>group-source-service</name>
<connection reference="ldap-src-conn" />
<baseDn>DC=your_ad_domain,DC=local</baseDn>
<pivotAttributes>
<string>cn</string>
</pivotAttributes>
<fetchedAttributes>
<string>cn</string>
<string>description</string>
<string>member</string>
<!-- <string>objectClass</string> -->
</fetchedAttributes>
<getAllFilter><![CDATA[(objectClass=group)]]></getAllFilter>
<getOneFilter><![CDATA[(&(objectClass=group)(cn={cn}))]]></getOneFilter>
<cleanFilter><![CDATA[(&(objectClass=group)(cn={cn}))]]></cleanFilter>
<!-- <serverType>ActiveDirectory</serverType> -->
</ldapSourceService>
<ldapDestinationService>
<name>group-dst-service</name>
<connection reference="ldap-dst-conn" />
<baseDn>ou=Groups,dc=your_ad_domain,dc=local</baseDn>
<pivotAttributes>
<string>cn</string>
</pivotAttributes>
<fetchedAttributes>
<string>cn</string>
<string>description</string>
<string>uniqueMember</string>
<string>objectClass</string>
<!-- <string>gidNumber</string> -->
</fetchedAttributes>
<getAllFilter><![CDATA[(objectClass=groupOfUniqueNames)]]></getAllFilter>
<getOneFilter><![CDATA[(&(objectClass=groupOfUniqueNames)(cn={cn}))]]></getOneFilter>
</ldapDestinationService>
<propertiesBasedSyncOptions>
<mainIdentifier>js:"cn=" + srcBean.getDatasetFirstValueById("cn") + ",OU=Groups,dc=your_ad_domain,dc=local"</mainIdentifier>
<defaultDelimiter>;</defaultDelimiter>
<defaultPolicy>FORCE</defaultPolicy>
<conditions>
<create>true</create>
<update>true</update>
<delete>true</delete>
<changeId>true</changeId>
</conditions>
<dataset>
<name>uniqueMember</name>
<policy>FORCE</policy>
<forceValues>
<string>
<![CDATA[rjs:
var membersSrcDn = srcBean.getDatasetValuesById("member");
var membersDstDn = new java.util.ArrayList();;
for (var i=0; i < membersSrcDn.size(); i++) {
var memberSrcDn = membersSrcDn.get(i);
var sAMAccountName = "";
try {
sAMAccountName = srcLdap.attribute(memberSrcDn, "samAccountName").get(0);
} catch(e) {
continue;
}
var destDn = ldap.search("ou=Users", "(uid=" + sAMAccountName + ")");
if (destDn.size() == 0 || destDn.size() > 1) {
continue;
}
var destMemberDn = destDn.get(0) + "," + ldap.getContextDn();
membersDstDn.add(destMemberDn);
}
if (membersDstDn.size() == 0) {
membersDstDn.add("uid=empty_member,dc=your_ad_domain,dc=local");
}
membersDstDn
]]>
</string>
</forceValues>
</dataset>
<dataset>
<name>objectClass</name>
<policy>FORCE</policy>
<forceValues>
<string>"groupOfUniqueNames"</string>
<string>"top"</string>
</forceValues>
<delimiter>$</delimiter>
</dataset>
</propertiesBasedSyncOptions>
</task>
</tasks>
</lsc>
로그백 설정:
cp /etc/lsc/logback.xml /etc/lsc/ad2openldap/
테스트:
/usr/bin/lsc -f /etc/lsc/ad2openldap -s all -c all -n
(실제 실행은 -n 옵션 제거)
크론탭 설정 (매 6시간마다)
crontab -e
0 */6 * * * /usr/bin/lsc -f /etc/lsc/ad2openldap -s all
전체 Flow
참고)
반응형
'Linux Server' 카테고리의 다른 글
CentOS 7에 phpRedisAdmin 설치하기 (0) | 2023.04.24 |
---|---|
APM - 핀포인트(2.4.0) 설치 (0) | 2022.11.18 |
[Centos] 런덱 설치 스크립트 (0) | 2022.01.21 |
Gitlab self-managed Edition 변경 (CE -> EE) (0) | 2022.01.10 |
OpenLDAP Pass-through 구성 (0) | 2022.01.03 |
Comments