LDAP客户端或多个LDAP服务器的代理
multildap的Python项目详细描述
pymultildap
pymultildap可以从多个ldap服务器收集数据,可以使用重写规则进行数据聚合和操作。 pymultildap还可以充当代理服务器,位于openldap的slapd sock后端或任何自定义实现之后。
功能
- 将LDAP客户端作为单个服务器连接到多个服务器;
- 处理返回数据的自定义函数(重写规则);
- 以python dictionary、json或ldiff格式导出数据;
- 代理服务器,公开可与slapd-sock backend一起使用的服务器守护进程。
pyMultiLDAP不向LDAP服务器写入数据,它只允许我们处理只读数据 以一种非常简单的方式在飞行中实现智能数据处理的自动化。
请参阅example/settings.py.example
和multildap/attr_rewrite.py
,了解如何配置和扩展它。
测试时间
- Debian9;
- 德比安10。
设置
在settings.py
中配置多个连接和搜索参数
安装
git clone https://github.com/peppelinux/pyMultiLDAP.git
cd pyMultiLDAP
pip install -r requirements
python3 setup.py install
或者使用pipy[wip]
pip install pyMultiLDAP
ldapclient类用法
from multildap.client import LdapClient
from settings import LDAP_CONNECTIONS
lc = LdapClient(LDAP_CONNECTIONS['SAMVICE'])
# get all the results
lc.get()
# apply a filter
lc.get(search="(&(sn=de marco)(schacPersonalUniqueId=*DMRGPP83*))")
搜索并获取
见examples/run_test.py
。
.search
和.get
之间的差异:
- searchrelyies on connection configuration并返回结果(raw)
- get处理自定义搜索筛选器,并以dictionary、json、ldif或python对象格式检索结果它还应用重写规则。
import copy
from multildap.client import LdapClient
from settings import LDAP_CONNECTIONS
lc = LdapClient(LDAP_CONNECTIONS['DEFAULT'])
kwargs = copy.copy(lc.conf)
kwargs['search']['search_filter'] = "(&(sn=de medici)(givenName=aurora))"
r = lc.search(**kwargs['search'])
结果为json格式
from multildap.client import LdapClient
from . settings import LDAP_CONNECTIONS
for i in LDAP_CONNECTIONS:
lc = LdapClient(LDAP_CONNECTIONS[i])
print('# Results from: {} ...'.format(lc))
# get all as defined search_filter configured in settings connection
# but in json format
r = lc.get(format='json')
print(r)
# set a custom search as method argument
r = lc.get(search="(&(sn=de marco)(schacPersonalUniqueId=*DMRGPP345tg86H))", format='json')
print(r)
print('# End {}'.format(i))
运行服务器
from multildap.client import LdapClient
from . settings import LDAP_CONNECTIONS
for i in LDAP_CONNECTIONS:
lc = LdapClient(LDAP_CONNECTIONS[i])
print('# Results from: {} ...'.format(lc))
# get all as defined search_filter configured in settings connection
# but in json format
r = lc.get(format='json')
print(r)
# set a custom search as method argument
r = lc.get(search="(&(sn=de marco)(schacPersonalUniqueId=*DMRGPP345tg86H))", format='json')
print(r)
print('# End {}'.format(i))
网络地址
multildapd.py -conf settings.py -port 1234
Unix域套接字(用于slapd sock后端)
multildapd.py -conf ./settings.py -loglevel "DEBUG" -socket /var/run/multildap.sock -pid /var/run/multildap.pid -uid openldap
未配置任何LDAP客户端连接的虚拟测试,仅用于测试slapd sock:
multildapd.py -conf ./settings.py -dummy -loglevel "DEBUG" -socket /var/run/multildap.sock -pid /var/run/multildap.pid
从cli测试Unix域套接字
nc -U /tmp/multildap.sock
与openldap slapd sock接口
那Slapd-sock slapd的后端使用外部程序处理 询问。就这样 可能有一个进程池,在请求之间持续存在。 这允许多线程操作和更高级别的效率。 multildapd在unix域套接字上侦听,它必须独立启动;
此模块也可用作其他模块上的覆盖 数据库用作覆盖允许在中触发外部操作 对主数据库上的操作的响应。
将slapd sock配置为数据库
添加模块。
ldapadd -Y EXTERNAL -H ldapi:/// <<EOF
dn: cn=module,cn=config
objectClass: olcModuleList
cn: module
olcModuleLoad: back_sock.la
EOF
创建数据库。
ldapadd -Y EXTERNAL -H ldapi:/// <<EOF
dn: olcDatabase={4}sock,cn=config
objectClass: olcDbSocketConfig
olcDatabase: {4}sock
olcDbSocketPath: /var/run/multildap.sock
olcSuffix: dc=proxy,dc=testunical,dc=it
olcDbSocketExtensions: binddn peername ssf
EOF
如果要包装现有的后端
,则添加覆盖项ldapmodify -H ldapi:// -Y EXTERNAL <<EOF
dn: olcOverlay=sock,olcDatabase={1}mdb,cn=config
changetype: add
objectClass: olcConfig
objectClass: olcOverlayConfig
objectClass: olcOvSocketConfig
olcOverlay: sock
olcDbSocketPath: /var/run/multildap/multildap.sock
olcOvSocketOps: bind unbind search
olcOvSocketResps: search
EOF
记住要配置一个acl,否则只有ldapsearch -H ldapi:// -Y EXTERNAL
作为根用户才能获取ldif。
记住在每个olaaccess行后面添加一个空格字符' '
,否则您将得到Implementation specific error(80)
。
export BASEDC="dc=testunical,dc=it"
ldapadd -Y EXTERNAL -H ldapi:/// <<EOF
dn: olcDatabase={4}sock,cn=config
changeType: modify
replace: olcAccess
olcAccess: to *
by dn.exact=gidNumber=0+uidNumber=0,cn=peercred,cn=external,cn=auth manage
by * break
# the following permits self BIND by users
olcAccess: to dn.subtree="dc=proxy,$BASEDC"
by self read
by * break
# the following two permits SEARCH by idp and foreign auth system
olcAccess: to dn.subtree="ou=people,$BASEDC"
by dn.children="ou=auth,$BASEDC" read
by self read
by * break
olcAccess: to dn.subtree="ou=people,$BASEDC"
by dn.children="ou=idp,$BASEDC" read
by self read
by * break
olcAccess: to *
by anonymous auth
by * break
EOF
必须使用属性配置multildapd顶部的身份验证(绑定)
rewrite_dn_to
关于settings.py中的每个连接。如果Abcent,指定的连接将被排除在身份验证之外。
待办事项:采用openldap proxy authz语句
ldapsearch -H ldap://localhost:389 -D "uid=peppe,dc=proxy,dc=testunical,dc=it" -w thatsecret -b 'uid=peppe,dc=proxy,dc=unical,dc=it'
提示
查看当前安装的数据库:
ldapsearch -Y EXTERNAL -H ldapi:/// -b 'cn=config' -LLL "olcDatabase=*"
;- 在settings.py中使用
client_strategy = RESTARTABLE
而不是REUSABLE
,以获得更好的性能; - 在OpenLDAP 2.5发布之前,不能通过ldapdelete/modify删除后端;
- 更改套接字路径
ldapmodify -Y EXTERNAL -H ldapi:/// <<EOF
dn: olcDatabase={4}sock,cn=config
changetype: modify
replace: olcDbSocketPath
olcDbSocketPath: /var/run/multildap.sock
EOF
- 使用socat部署一个虚拟的socket侦听器,以便调试slapd sock的传入连接。
socat -s UNIX-LISTEN:/tmp/slapd-sock,umask=000,fork EXEC:"$your_command"
其他slapd sock资源:
待办事项
- 使用slapd的代理授权规则的示例配置(authzTo:dn.regex:^uid=[^,]*,dc=Example,dc=com$)
- 只有SEARCH、BIND和UNBIND是可用的,其他LDAP方法应该实现