大多數系統管理員在職業生涯中都會遇到需要與 LDAP 伺服器交互的情況。本文講解如何使用 LDAP 實現 Apache 身份驗證,以及如何使用 Python 模塊 python-ldap 在 OpenLDAP 資料庫上執行 CRUD(即創建、讀取、更新和刪除)操作。
簡介
在本文中,作者將講解如何在 Amazon EC2 虛擬機上安裝 OpenLDAP 的實例,設置 Apache/LDAP 身份驗證,然後使用 Python 執行 CRUD(即創建、讀取、更新和刪除)操作。一定要注意,可以在 Fedora、Ubuntu、Red Hat、AIX® 等操作系統上安裝 LDAP。但是在本文中,我們決定採用 Amazon EC2 虛擬機。您可以在任何 Linux® 發行版或手邊的任何環境中進行實踐。最後,我們將在本文中討論許多代碼和複雜的技術。您應該首先下載 示例代碼,供閱讀本文時參考。
通過程序控制 LDAP 常常是系統管理員的工作,所以 Python 中存在一個用來操作 LDAP 的庫就不奇怪了。python-ldap 模塊已經存在了一段時間了,在 參考資料 一節中可以找到官方文檔的鏈接。
我們假設您熟悉一般的 LDAP 概念,比如目錄模式、Distinguished Names (DN)、Common Names (CN)、過濾器和屬性。本文不是 LDAP 教程;我們不喜歡大談理論,而是主要關注使用和管理 LDAP 資料庫的實際示例。
|
LDAP 的初始設置和填充
如果希望按照本文的說明設置 LDAP,那麼需要一個 Fedora Core 8 實例。我們使用一個運行 Fedora Core 8 32-bit 的 Amazon EC2 虛擬機實例。可以在物理伺服器上安裝 LDAP,也可以使用您選擇的技術在虛擬機上安裝。注意,對於所有示例,我們使用一個稱為 unisonis.com 的域,但是有一份 RFC 建議使用 example.com。
步驟 1:使用 yum 安裝 openldap 包:
[root@domU ]# yum install openldap openldap-devel openldap-servers openldap-clients [root@domU ]# yum list installed | grep openldap openldap.i386 2.3.39-4.fc8 installed openldap-clients.i386 2.3.39-4.fc8 installed openldap-devel.i386 2.3.39-4.fc8 installed openldap-servers.i386 2.3.39-4.fc8 installed |
步驟 2:設置管理員密碼(我們將把 SSHA 散列值粘貼在 slapd.conf 中)。注意,slapd 代表 Standalone LDAP 服務,所以此服務控制 LDAP 本身:
[root@domU ]# slappasswd New password: Re-enter new password: |
步驟 3:編輯 slapd.conf 配置文件並添加一般 LDAP 安裝所需的條目,比如根 DN 和根/管理員密碼:
[root@domU ]# vi /etc/openldap/slapd.conf #Add entries: database bdb suffix "dc=unisonis,dc=com" rootdn "cn=Manager,dc=unisonis,dc=com" rootpw {SSHA}pasted_from_slappasswd_output directory /var/lib/ldap |
步驟 4:啟動 LDAP 服務:
[root@domU ]# service ldap start Starting slapd: [ OK ] |
步驟 5:運行 LDAP 並搜索 'namingContexts' 屬性,從而測試 LDAP:
[root@domU ]# ldapsearch -x -b '' -s base '(objectclass=*)' namingContexts # extended LDIF # # LDAPv3 # base <> with scope baseObject # filter: (objectclass=*) # requesting: namingContexts # # dn: namingContexts: dc=unisonis,dc=com # search result search: 2 result: 0 Success # numResponses: 2 # numEntries: 1 |
步驟 6:使用 ldapadd 和 LDIF 文件在 LDAP 資料庫中添加更多條目。注意,LDIF 代表 LDAP Data Interchange Format,這是用於對 LDAP 資料庫進行大量更新的數據格式:
[root@domU ]# cat unisonis.ldif dn: dc=unisonis,dc=com objectclass: dcObject objectclass: organization o: Example Company dc: unisonis dn: cn=Manager,dc=unisonis,dc=com objectclass: organizationalRole cn: Manager [root@domU ]# ldapadd -x -D "cn=Manager,dc=unisonis,dc=com" -W -f unisonis.ldif Enter LDAP Password: adding new entry "dc=unisonis,dc=com" adding new entry "cn=Manager,dc=unisonis,dc=com" |
步驟 7:下一步是用示例條目填充 LDAP 目錄。我們使用三個小丑的信息(靈感來源於 LDAP 文章 http://www.yolinux.com/TUTORIALS/LinuxTutorialLDAP.html):
[root@domU ]# cat stooges.ldif; # to conserve space, we show the LDAP data for only one of the three stooges dn: ou=MemberGroupA,dc=unisonis,dc=com ou: MemberGroupA objectClass: top objectClass: organizationalUnit description: Members of MemberGroupA dn: ou=MemberGroupB,dc=unisonis,dc=com ou: MemberGroupB objectClass: top objectClass: organizationalUnit description: Members of MemberGroupB dn: cn=Larry Fine,ou=MemberGroupA,dc=unisonis,dc=com ou: MemberGroupA o: stooges cn: Larry Fine objectClass: top objectClass: person objectClass: organizationalPerson objectClass: inetOrgPerson mail: LFine@unisonis.com givenname: Larry sn: Fine uid: larry homePostalAddress: 15 Cherry Ln. Plano TX 78888 postalAddress: 215 Fitzhugh Ave. l: Dallas st: TX postalcode: 75226 telephoneNumber: (800)555-1212 homePhone: 800-555-1313 facsimileTelephoneNumber: 800-555-1414 userPassword: larrysecret title: Account Executive destinationindicator: /bios/images/lfine.jpg [root@domU ]# ldapadd -x -D "cn=Manager,dc=unisonis,dc=com" -W -f stooges.ldif |
如果願意,現在就可以對剛才創建的 LDAP 資料庫做各種搜索。下面的示例搜索與 'stooges' 組織相關的所有 LDAP 條目:
[root@domU conf.d]# ldapsearch -x -b 'dc=unisonis,dc=com' '(o=stooges)' |
在下一節中,我們討論如何通過配置 Apache 實現 LDAP 身份驗證,然後討論 Python 和 LDAP。
設置 Apache LDAP 身份驗證
LDAP 最常見的用途之一是為 Web 服務等提供身份驗證數據。在本節中,我們使用前面預先填充的 LDAP 資料庫控制對一個 Apache 虛擬主機的訪問。
首先,需要為使用 LDAP 身份驗證的虛擬主機創建一個 Apache 配置文件。對於試圖登錄的用戶,要求提供有效的電子郵件地址和密碼。配置文件如下所示:
[root@domU ]# cat /etc/httpd/conf.d/unisonis.conf <VirtualHost *:80> ServerName www.unisonis.com DocumentRoot "/ebs1/www/unisonis" <Directory "/ebs1/www/unisonis"> AuthType Basic AuthName "unisonis.com: please login with email address" AuthBasicProvider ldap AuthLDAPURL ldap://localhost:389/dc=unisonis,dc=com?mail?sub?(o=stooges) require valid-user Order Allow,Deny Allow from all Options Indexes FollowSymLinks AllowOverride None </Directory> </VirtualHost> |
通過 mod_auth_ldap 模塊向 Apache 提供 LDAP 身份驗證,此模塊是在 Fedora Core 8 httpd 包中默認安裝的。對於試圖登錄的用戶,要求在 'stooges' 組織中包含有效的電子郵件地址和密碼,這樣才能訪問上面定義的 Apache 虛擬主機。請注意 AuthLDAPURL 指令,它指定通過 LDAP 伺服器實現用戶身份驗證所用的查詢。我們搜索 'mail' 屬性並應用過濾器 (o=stooges)。AuthLDAPURL 指令的完整語法請參見 http://httpd.apache.org/docs/2.0/mod/mod_auth_ldap.html#authldapurl。
關於在 Apache 上配置 LDAP 的更多信息請參見 參考資料。
用 Python-LDAP 執行 CRUD 操作
現在,準備使用 Python 與 LDAP 交互。為此,必須安裝 python-ldap 模塊。在 參考資料 中,可以找到關於安裝此模塊的詳細信息的鏈接。實際上,只需要執行 “easy install”。首先下載 easy_install 腳本:
http://peak.telecommunity.com/dist/ez_setup.py |
然後輸入:
sudo easy_install python-ldap |
注意,根據操作系統的不同,此包依賴的一些軟體略有差異。如果在安裝此包時遇到問題,請仔細閱讀安裝說明。
安裝 python-ldap 之後,就可以執行 CRUD 操作了。下面編寫一個執行這些操作的類。
#!/bin/env python import sys, ldap LDAP_HOST = 'localhost' LDAP_BASE_DN = 'dc=unisonis,dc=com' MGR_CRED = 'cn=Manager,dc=unisonis,dc=com' MGR_PASSWD = 'mypasswd' STOOGE_FILTER = 'o=stooges' class StoogeLDAPMgmt: def __init__(self, ldap_host=None, ldap_base_dn=None, mgr_cred=None, mgr_passwd=None): if not ldap_host: ldap_host = LDAP_HOST if not ldap_base_dn: ldap_base_dn = LDAP_BASE_DN if not mgr_cred: mgr_cred = MGR_CRED if not mgr_passwd: mgr_passwd = MGR_PASSWD self.ldapconn = ldap.open(ldap_host) self.ldapconn.simple_bind(mgr_cred, mgr_passwd) self.ldap_base_dn = ldap_base_dn def list_stooges(self, stooge_filter=None, attrib=None): if not stooge_filter: stooge_filter = STOOGE_FILTER s = self.ldapconn.search_s(self.ldap_base_dn, ldap.SCOPE_SUBTREE, stooge_filter, attrib) print "Here is the complete list of stooges:" stooge_list = [] for stooge in s: attrib_dict = stooge[1] for a in attrib: out = "%s: %s" % (a, attrib_dict[a]) print out stooge_list.append(out) return stooge_list def add_stooge(self, stooge_name, stooge_ou, stooge_info): stooge_dn = 'cn=%s,ou=%s,%s' % (stooge_name, stooge_ou, self.ldap_base_dn) stooge_attrib = [(k, v) for (k, v) in stooge_info.items()] print "Adding stooge %s with ou=%s" % (stooge_name, stooge_ou) self.ldapconn.add_s(stooge_dn, stooge_attrib) def modify_stooge(self, stooge_name, stooge_ou, stooge_attrib): stooge_dn = 'cn=%s,ou=%s,%s' % (stooge_name, stooge_ou, self.ldap_base_dn) print "Modifying stooge %s with ou=%s" % (stooge_name, stooge_ou) self.ldapconn.modify_s(stooge_dn, stooge_attrib) def delete_stooge(self, stooge_name, stooge_ou): stooge_dn = 'cn=%s,ou=%s,%s' % (stooge_name, stooge_ou, self.ldap_base_dn) print "Deleting stooge %s with ou=%s" % (stooge_name, stooge_ou) self.ldapconn.delete_s(stooge_dn) |
此類中的方法名就能夠說明方法的作用,所以我們只討論在實現這個類時的一些步驟。如果您已經按照前面的步驟填充了 LDAP 資料庫,現在還應該下載代碼示例。
首先,創建此類的實例:
l = StoogeLDAPMgmt() |
然後就可以執行 CRUD 了。
接下來,用 Python 代碼添加一些功能。應該複製並粘貼下載的源代碼,因為手工輸入容易出錯。下面是 CRUD 中的 “C”(創建):
# add new stooge: Harry Potter stooge_name = 'Harry Potter' stooge_ou = 'MemberGroupB' stooge_info = {'cn': ['Harry Potter'], 'objectClass': ['top', 'person', 'organizationalPerson', 'inetOrgPerson'], 'uid': ['harry'], 'title': ['QA Engineer'], 'facsimileTelephoneNumber': ['800-555-3318'], 'userPassword': ['harrysecret'], 'postalCode': ['75206'], 'mail': ['HPotter@unisonis.com'], 'postalAddress': ['2908 Greenville Ave.'], 'homePostalAddress': ['14 Cherry Ln. Plano TX 78888'], 'pager': ['800-555-1319'], 'homePhone': ['800-555-7777'], 'telephoneNumber': ['(800)555-1214'], 'givenName': ['Harry'], 'mobile': ['800-555-1318'], 'l': ['Dallas'], 'o': ['stooges'], 'st': ['TX'], 'sn': ['Potter'], 'ou': ['MemberGroupB'], 'destinationIndicator': ['/bios/images/hpotter.jpg'], } try: l.add_stooge(stooge_name, stooge_ou, stooge_info) except ldap.LDAPError, error: print 'problem with ldap',error |
現在對此條目執行 “R”(讀取):
# see if it was added l.list_stooges(attrib=['cn', 'mail', 'homePhone']) |
現在更新此條目,即執行 “U”:
# now modify home phone stooge_modified_attrib = [(ldap.MOD_REPLACE, 'homePhone', '800-555-8888')] try: l.modify_stooge(stooge_name, stooge_ou, stooge_modified_attrib) except ldap.LDAPError, error: print 'problem with ldap',error |
最後,執行 “D”(刪除):
# now delete Harry Potter try: l.delete_stooge(stooge_name, stooge_ou) except ldap.LDAPError, error: print 'problem with ldap',error |
結束語
本文簡要介紹了在 Amazon EC2 Fedora 實例上安裝 OpenLDAP 的過程,我們用測試數據填充了 LDAP 資料庫,簡要討論了從命令行與 LDAP 資料庫交互,演示了如何通過配置 Apache 實現 LDAP 身份驗證。最後,通過 Python 代碼控制 LDAP。Python 示例最出色的優點之一是,與腳本(比如 bash 腳本)代碼相比,Python 代碼看起來舒服得多。Python 代碼因其簡潔和可讀性強而聞名,這在處理 LDAP 編程等複雜操作時表現尤為突出。
我們實際上沒有研究 LDAP 和 Python 的實際示例,但是介紹了如何使用 API 執行 CRUD 操作。使用 python-ldap 庫是一種很實用的想法。在每次創建 TRAC 新實例時,您可能希望用 LDAP 組中的所有用戶填充不同的 TRAC 項目管理網站。這很容易用我們討論的技術實現:查詢 LDAP 組,在 TRAC 中為每個組成員插入許可。還有許多其他操作 LDAP 的實用方法,希望本文能幫助您如何在自己的項目中進一步利用 LDAP。(責任編輯:A6)
[火星人 ] Python 和 LDAP已經有863次圍觀