LDAP學習筆記<三>深入管理openLDAP

  啓動OpenLDAP服務器程序之後,接下來的操作就是通過客戶端程序對目錄進行操作,包括添加、修改、刪除和搜索數據等操作。能對LDAP進行操作的客戶端程序很多,下面簡單介紹在Linux命令方式下進行這些操作的方法。

 

向目錄數據庫中添加數據


      初始狀態下,LDAP是一個空目錄,即沒有任何數據。可通過程序代碼向目錄數據庫中添加數據,也可使用OpenLDAP客戶端工具ldapadd命令來完成添加數據的操作,該命令可將一個LDIF文件中的條目添加到目錄。因此,需要首先創建一個LDIF文件,然後再進行添加操作。

 

1.LDIF文本條目格式

 

      LDIF用文本格式表示目錄數據庫的信息,以方便用戶創建、閱讀和修改。在LDIF文件中,一個條目的基本格式如下:

寫道
# 註釋
dn: 條目名
屬性描述: 值
屬性描述: 值
屬性描述: 值
... ...
 

      dn行類似於關係數據庫中一條記錄的關鍵字,不能與其他dn重複。一個LDIF文件中可以包含多個條目,每個條目之間用一個空行分隔。
      例如,以下內容組成一個條目:

寫道
1: dn: dc=dlw, dc=com
2: objectclass: top
3: objectclass: dcobject
4: objectclass: organization
5: dc: dlw
6: o: dlw,Inc.
 

在以上文本中,各行含義如下:

 

  • 第1行的dn定義該條目的標識。
  • 第2~4行定義該條目的objectcCass,可以定義多個屬性,如上面代碼中定義了3個objectClass。條目的屬性根據objectClass的不同而不同,有的objectClass有必須設置的屬性。在2~4行的3個objectClass中,top沒有必須定義的屬性,dcobject必須定義屬性dc,用來表示一個域名的部分,而organization必須定義屬性o,用來表示一個組織的名稱。
  • 根據objectClass的要求,第5、6行分別定義屬性dc和屬性o的值。

2.瞭解objectClass


      LDAP中,一個條目必須包含一個objectClass屬性,且需要賦予至少一個值。每一個值將用作一條LDAP條目進行數據存儲的模板;模板中包含了一個條目必須被賦值的屬性和可選的屬性。
      objectClass有着嚴格的等級之分,最頂層是top和alias。例如,organizationalPerson這個objectClass就隸屬於person,而person又隸屬於top。

 

      objectClass可分爲以下3類:

  • 結構型(Structural):如person和organizationUnit;
  • 輔助型(Auxiliary):如extensibeObject;
  • 抽象型(Abstract):如top,抽象型的objectClass不能直接使用。

在OpenLDAP的schema中定義了很多objectClass,下面列出部分常用的objectClass的名稱。
  ● account
  ● alias
  ● dcobject
  ● domain
  ● ipHost
  ● organization
  ● organizationalRole
  ● organizationalUnit
  ● person
  ● organizationalPerson
  ● inetOrgPerson
  ● residentialPerson
  ● posixAccount
  ● posixGroup

 

3.瞭解Attribute


      屬性(Attribute)類似於程序設計中的變量,可以被賦值。在OpenLDAP中聲明瞭許多常用的Attribute(用戶也可自己定義Attribute)。常見的Attribute含義如下:
  ● c:國家。
  ● cn:common name,指一個對象的名字。如果指人,需要使用其全名。
  ● dc:domain Component,常用來指一個域名的一部分。
  ● givenName:指一個人的名字,不能用來指姓。
  ● l:指一個地名,如一個城市或者其他地理區域的名字。
  ● mail:電子信箱地址。
  ● o:organizationName,指一個組織的名字。
  ● ou:organizationalUnitName,指一個組織單元的名字。
  ● sn:surname,指一個人的姓。
  ● telephoneNumber:電話號碼,應該帶有所在的國家的代碼。
  ● uid:userid,通常指某個用戶的登錄名,與Linux系統中用戶的uid不同。

 

提示:objectClass是一種特殊的Attribute,它包含其他用到的Attribute以及其自身。

 

      對於不同的objectClass,通常具有一些必設屬性值和一些可選屬性值。例如,可使用person這個objectClass來表示系統中一個用戶的條目,對於系統中用戶通常需要有這樣一些信息:姓名、電話、密碼、描述等。如下圖所示,對於person,通過cn和sn設置用戶的名和姓,這是必須設置的,而其他屬性則是可選的。

 

 

下面列出部分常用objectClass要求必設的屬性。
  ● account:userid。
  ● organization:o。
  ● person:cn和sn。
  ● organizationalPerson:與person相同。
  ● organizationalRole:cn。
  ● organizationUnit:ou。
  ● posixGroup:cn、gidNumber。
  ● posixAccount:cn、gidNumber、homeDirectory、uid、uidNumber。

4.創建LDIF文件


      對以上內容有一定了解之後,就可以編寫輸入LDIF文件,編輯需要向目錄數據庫添加的條目了。
      下面根據如下圖所示的結構,創建LDIF文件dlw.com.ldif。

 

 

      對上圖進行分析,該目錄結構分爲3層,有4個結點。根據上圖可創建LDIF文件如下:
提示:每個結點可用一個dn表示,對於每個結點,又可繼續添加新的結點。如在根結點中可添加其他部門ou,在ou=managers結點也可繼續添加其他管理人員的信息。

 

寫道
1: dn:dc=dlw,dc=com
2: objectclass:top
3: objectclass:dcobject
4: objectclass:organization
5: dc:dlw
6: o:dlw,Inc.
7:
8: dn:ou=managers, dc=dlw, dc=com
9: ou:managers
10: objectclass:organizationalUnit
11:
12: dn:cn=dlw,ou=managers,dc=dlw,dc=com
13: cn:dlw
14: sn:dongliwei
15: objectclass:person
16:
17: dn:cn=test,ou=managers,dc=dlw,dc=com
18: cn:test
19: sn:Test User
20: objectclass:person
 

以上文件中各行的含義如下:

 

  • 第1~6行創建根結點,這部分在前面也有介紹,就不再重複了。
  • 第7、11、16行爲空行,用來分隔4個dn條目(4個結點)。
  • 第8~10行定義cn=managers結點的條目,該條目的objectClass爲organizationalUnit,因此需要用ou屬性定義組織名稱。
  • 第12~15行定義cn=dlw結點的條目,該條目使用的objectClass爲person,因此需設置cn和sn兩個屬性值。
  • 第17~20行與第12~15行的意義相同。

 

 

      在以上LDIF文件中,第1、8、12、17行以dn開頭,這部分內容必須唯一,並且在向目錄數據庫添加這些數據時,也要確保這些數據不能與目錄數據庫中已有數據相同,否則,添加操作將中斷。

 

5.從LDIF文件添加到目錄數據庫


      使用OpenLDAP客戶端工具ldapadd命令,可將LDIF文件中的條目添加到目錄數據庫中,該命令的格式如下:
       ldappadd  選項  LDIF文件
      在ldappadd命令中常用的選項如下:

 

  • -x:進行簡單認證。
  • -D:用來綁定服務器的dn。
  • -h:目錄服務的地址。
  • -w:綁定dn的密碼。
  • -f:使用LDIF文件進行條目添加的文件。

 

將前面編寫的LDIF文件的條目數據添加到目錄數據庫中。
具體操作步驟如下:

(1)檢查dlw.com.ldif文件中的內容,需要注意的是,每個冒號後面都需要空一格,而每行結束處不能留有空格字符。
(2)使用以下命令將dlw.com.ldif文件中的條目添加到目錄中:

寫道
# ldapadd -x -D "cn=root,dc=dlw,dc=com" -w secret -f dlw.com.ldif
 

執行以上命令,如果添加操作正常完成,將顯示如下圖所示的提示信息,表示添加了4個條目到目錄數據庫中。

 

 

提示:如果以上命令執行不成功,需要逐個字符檢查dlw.com.ldif文件中的內容,特別注意空格的問題。

 

查詢


      添加到目錄中的條目被保存在目錄數據庫,在Linux命令界面下,可使用OpenLDAP客戶端工具ldapsearch命令來進行查詢。該命令的格式如下:


      ldapsearch  選項  過濾  屬性值


常用的選項有以下幾個:


  ● -x:進行簡單認證。
  ● -D:用來綁定服務器的dn。
  ● -w:綁定dn的密碼。
  ● -b:指定要查詢的根節點。
  ● -H:制定要查詢的服務器。

 

使用ldapsearch命令查詢“dc=dlw, dc=com”下的所有條目,可使用以下命令:

# ldapsearch -x -b "dc=dlw,dc=com"  

# ldapsearch -x -b "dc=dlw,dc=com"
 

執行結果如下圖所示。

 

 

而如果使用以下命令,將查詢顯示sn中以字符wu開頭的條目,將得到如下圖所示的查詢結果,只找到一個條目。

# ldapsearch -x -b 'dc=dlw,dc=com' 'sn=wu*'  

# ldapsearch -x -b 'dc=dlw,dc=com' 'sn=wu*'
 

 

 

修改條目


      使用OpenLDAP客戶端工具ldapmodify命令可對目錄數據庫中的條目進行修改。該命令的格式如下:


      ldapmodify  選項


      該命令的選項也很多,常用選項與ldapadd類似,這裏就不再列出了。
      提示:使用ldapmodify命令不能修改條目的dn,但可以修改其他屬性值。

使用ldapmodify命令修改條目信息可以有兩種方式:一種是交互式進行修改,另一種是通過文件進行修改。

1.交互式修改


      修改前面創建的條目“cn=test, ou=managers, dc=dlw, dc=com”,將其sn屬性修改爲“Test User Modify”,並添加一個description屬性,設置其值爲“add Attribute”。
      首先輸入以下命令,進行修改狀態:

# ldapmodify -x -D "cn=root,dc=dlw,dc=com" -W secret  

# ldapmodify -x -D "cn=root,dc=dlw,dc=com" -W secret
 

執行以上命令後,終端將等候用戶輸入需要修改條目的dn,輸入以下內容:

  1. dn: cn=test, ou=managers, dc=dlw, dc=com  
  2. changetype: modify  
  3. replace: sn  
  4. sn: Test User Modify  
dn: cn=test, ou=managers, dc=dlw, dc=comchangetype: modifyreplace: snsn: Test User Modify
 

      以上輸入內容中,第1行查找需要修改的條目,第2行設置修改模式,第3行設置需要替換的屬性sn,第4行給屬性sn重新設置一個值,替換該屬性原有的值。
      輸入完以上內容之後再按Enter鍵,程序將按以上設置更新數據,然後按Ctrl+C鍵退出修改命令。執行過程如下圖所示。

 

使用以上命令修改條目的數據之後,可使用以下命令查看是否修改成功:

#ldapsearch -x -b 'dc=dlw,dc=com' 'cn=test'  

#ldapsearch -x -b 'dc=dlw,dc=com' 'cn=test'
 

執行以上命令查看test條目的數據如下圖所示,可以看到sn屬性被修改了。

 

 

2.通過文件修改


    通過前面的方式對條目進行修改時,很不方便,如果在交互方式時輸錯了某個字符,只能中斷命令後重新進行修改。因此,更好的修改方法是首先將修改時輸入的文字保存到一個文件中,然後以該文件作爲輸入進行修改。用這種方式進行操作,首先需要創建一個臨時文件,用來保存需要進行的修改操作,下面演示這種方式的修改過程。

【例子】 通過修改命令將前面LDAP數據庫中的信息還原,即將sn屬性由“Test User Modify”修改爲“Test User”。
具體操作步驟如下:
(1)使用vi編輯器創建一個文件modify,在其中輸入以下內容:

  1. dn: cn=test,ou=managers,dc=dlw,dc=com  
  2. changetype: modify  
  3. replace: sn  
  4. sn: Test User  
dn: cn=test,ou=managers,dc=dlw,dc=comchangetype: modifyreplace: snsn: Test User

 從以上輸入內容可看到,與在交互式時輸入的內容完全相同。
技巧:使用文件方式修改條目,可方便修改和檢查,若某個地方有輸入錯誤,可修改後再調用ldapmodify進行修改,減少輸入量。

(2)使用以下命令調用modify的內容進行修改:

 # ldapmodify -x -D "cn=root,dc=dlw,dc=com" -w secret -f modify  

# ldapmodify -x -D "cn=root,dc=dlw,dc=com" -w secret -f modify
 

執行結果如下圖所示。

 

 

刪除條目


      對於目錄數據庫中不用的條目,也可使用ldapdelete命令將其刪除。該命令的格式如下:


      ldapdelete  選項  刪除條目


      該命令使用的選項與ldapadd類似,就不再列出來了。
      刪除目錄數據庫中的“cn=test,ou=managers,dc=dlw,dc=com”條目,具體命令如下:

  1. # ldapdelete -x -D "cn=root,dc=dlw,dc=com" -w secret \  
  2. > "cn=test,ou=managers,dc=dlw,dc=com"  
# ldapdelete -x -D "cn=root,dc=dlw,dc=com" -w secret \> "cn=test,ou=managers,dc=dlw,dc=com"
 

      順利執行以上命令後,終端上將不會有任何信息輸出,表示完成了刪除操作。
      使用ldapdelete命令只能刪除樹形結構中的葉結點條目,如果刪除非葉結點條目,將出現錯誤提示。例如,執行以下命令刪除根結點“dc=dlw,dc=com”,由於根結點下面還有結點,將顯示如下圖所示的錯誤提示信息:

 

 

Python代碼  收藏代碼
  1. # ldapdelete -x -D "cn=root,dc=dlw,dc=com" -w secret "dc=dlw,dc=com"  
# ldapdelete -x -D "cn=root,dc=dlw,dc=com" -w secret "dc=dlw,dc=com"
 

數據導出


      通過ldapadd命令可向目錄數據庫中添加數據,在某些情況下,可能還需要進行反向操作,即將目錄數據庫中的數據導出。
      使用ldapsearch命令對目錄數據庫進行搜索,然後通過重定向將搜索結果保存到一個文件中,可達到導出數據的目的。另外,導出數據更常用的是slapcat命令,該命令的格式如下:


      slapcat  選項


      最常用的選項就是-l,表示導出爲LDIF文件格式。
      如將本章前面例子中創建的目錄數據庫導出爲export.ldif文件,可使用以下命令:

#slapcat -l export.ldif  

#slapcat -l export.ldif
 

      執行以上命令將在當前工作目錄得到文件export.ldif,打開文件將顯示如下圖所示的內容:

 

 

提示:從導出結果可看出,除了使用ldapadd命令添加到目錄數據庫中的條目數據外,還導出了很多其他信息,包括條目錄UUID、時間戳等信息。

 

 

設置主從LDAP服務器


      在某些時候,爲了對LDAP服務器進行負載均衡,可能希望設置多臺LDAP服務器。對於設置多臺LDAP服務器的關鍵問題是數據的同步問題,使用slurpd進程可進行主LDAP服務器向從LDAP服務器複製數據的操作。下面將介紹架設主從LDAP服務器的過程。

 

多臺LDAP服務器工作過程


      對於多臺LDAP服務器,可設置一臺爲主服務器,其他的爲從服務器。本節介紹一臺從服務器的配置,若是多臺從服務器也可按此步驟進行操作。
注意:在進行配置之前應首先確保每個LDAP服務器都已安裝好OpenLDAP服務器程序,並能正確工作。
      通過本節下面介紹的方法配置好主從LDAP服務器之後,在主服務器運行slurpd進程,該進程使用LDAP協議從主服務器的數據庫更新從服務器的數據,具體操作過程如下:


(1)LDAP客戶端向從服務器提交一個LDAP修改請求。
(2)從服務器給LDAP客戶端返回一個指向主服務器的引用。
(3)LDAP客戶端向主服務器提交LDAP修改請求。
(4)主服務器對數據庫中的數據進行修改,並將改變寫入本機的日誌文件。
(5)在主服務器運行的slurpd進程檢查到日誌中有新內容,通過日誌的信息將改變發送給從服務器。
(6)從服務器接收slurpd發來的信息,對本地數據進行修改。


      以上過程就是使用slurpd進程進行數據複製的過程。從以上過程可看出,需要在主服務器的配置文件中設置要向哪些從服務器發送複製信息、主服務器還要設置一個記錄數據改變的日誌文件,而從服務器需要設置一個指向主服務器的鏈接。

複製數據庫


首先,把主從服務器關閉。通過以下三步操作靜態同步主從服務器上的數據:

 

  • 把主服務器上/var/lib/ldap目錄下的所有數據庫文件全部拷貝到從服務器的同目錄中,覆蓋原有文件。
  • 把主服務器上的/etc/ldap/schema目錄下的所有schema文件拷貝到從服務器的同目錄中,覆蓋原有文件。
  • 把主服務器上/etc/ldap/slapd.conf文件拷貝到從服務器的同目錄中,覆蓋原有文件。

 

設置主服務器


配置主服務器上的slapd.conf文件,取消replogfile指令前的註釋符號,取消後的結果如下:

  1. # Replicas of this database  
  2. replogfile      /var/lib/ldap/replog  
# Replicas of this databasereplogfile      /var/lib/ldap/replog
 

增加replica指令,如:

  1. #replace config  
  2. replica uri=ldap://192.168.14.21:389     #指定從服務器主機名和端口號  
  3. binddn="cn=root,dc=dlw,dc=com"         #指定需同步的DN的管理員  
  4. bindmethod=simple credentials=111111  #指定驗證方式和需同步的DN的管理員密碼  
#replace configreplica uri=ldap://192.168.14.21:389     #指定從服務器主機名和端口號binddn="cn=root,dc=dlw,dc=com"         #指定需同步的DN的管理員bindmethod=simple credentials=111111  #指定驗證方式和需同步的DN的管理員密碼
 

設置從服務器


配置從服務器上的slapd.conf文件,增加updatedn指令,如:

  1. updatedn " cn=root,dc=dlw,dc=com"          #與主服務器的binddn對應  
updatedn " cn=root,dc=dlw,dc=com"          #與主服務器的binddn對應
 

在從服務器的配置文件中,不要包含replica和replogfile指令。


測試主從LDAP服務器


經過以上步驟的操作,主從LDAP服務器都已準備好,接下來就可以測試相關操作。


   1.啓動主LDAP服務器
        在主LDAP服務器中啓動slapd進程和slurpd進程。
   2.啓動從LDAP服務器
        在主LDAP服務器中啓動slapd進程。


【例子】測試主從LDAP服務器。
具體操作步驟如下:

(1)在主LDAP服務器中使用以下命令修改一個條目:

  1. #ldapmodify -x -D "cn=root,dc=dlw,dc=com" -w secret  
#ldapmodify -x -D "cn=root,dc=dlw,dc=com" -w secret
 

輸入以下內容,修改cn=dlw條目的內容:

  1. dn: cn=dlw,ou=managers,dc=dlw,dc=com  
  2. changetype: modify  
  3. replace: sn  
  4. sn: dongliwei  
dn: cn=dlw,ou=managers,dc=dlw,dc=comchangetype: modifyreplace: snsn: dongliwei
 

輸入後按Enter鍵完成修改,操作過程如圖5-7所示(將sn修改爲dongliwei)。

 

 

(2)在從LDAP服務器中進行操作,查看主LDAP服務器中的操作是否被複制到從LDAP服務器中來了。在從LDAP服務器中使用以下命令進行查詢:

#ldapsearch -x -b "dc=dlw,dc=com" "cn=dlw"  

#ldapsearch -x -b "dc=dlw,dc=com" "cn=dlw"
 

執行結果如下圖所示,從圖中可看到其中的sn也被修改爲dongliwei了(數據庫中原來的內容爲zhangsan.modi,是前面例子中修改的值),即被主LDAP服務器進行了同步複製。

 

 

 

OpenLDAP在用戶認證的應用


      OpenLDAP經常用在用戶登錄認證方面,通過LDAP的數據複製功能,可讓用戶使用一個賬戶登錄網絡中使用LDAP服務的所有服務器。在主LDAP服務器中設置好用戶賬戶數據,然後通過在網絡中的任意客戶端都可使用設置的賬號進行登錄操作。下面將簡單介紹將用戶認證遷移到LDAP的操作方法。

用戶認證用到的ojbectClass


      在LDAP中用來保存用戶認證條目的objectClass主要有以下3個,分別用來保存組、用戶、密碼等信息到目錄的條目中。

  • posixGroup:可設置屬性cn、userPassword、gidNumber等。
  • posixAccount:可設置屬性cn、gidNumber、uid、uidNumber、homeDirectory、loginShell等。
  • shadowAccount:可設置屬性uid、shadowExpire、shadowFlag、shadowInactive、shadowLastChange、shadowMax、shadowMin、shadowWarning、userPassword等。

提示:從上面列出的屬性的名稱可以很容易地與組、用戶的相關信息聯繫起來。

 

使用遷移工具


      要使用LDAP進行用戶認證,首先應該考慮的就是數據遷移的工作量。如果要操作員從/etc/passwd和/etc/group文件中逐個將信息重新錄入,工作量將非常大。
      OpenLDAP爲用戶考慮到了這些遷移工作,提供了多個遷移工具的腳本程序,這些程序位於/usr/share/openldap/migration/目錄中,在該目錄中有很多擴展名爲pl和sh的腳本文件,通過這些遷移工具,可以很方便地將系統中的用戶遷移到LDAP目錄數據庫中。下面介紹具體的遷移步驟。

【例子】將系統中的用戶信息遷移到LDAP目錄數據庫中。
具體操作步驟如下:
(1)修改/usr/share/openldap/migration/migrate_common.ph文件,在其中查找以下內容:

  1. $DEFAULT_BASE="dc=padl,dc=com";  
$DEFAULT_BASE="dc=padl,dc=com";
 

將其修改爲目錄服務器使用的根,如本章使用的例子要改爲以下形式:

  1. $DEFAULT_BASE="dc=dlw,dc=com";  
$DEFAULT_BASE="dc=dlw,dc=com";
 

保存後退出。

 

 

(2)使用以下命令執行腳本migrate_base.pl,用來創建根項,併爲Hosts、Networks、Group和People等創建低一級的組織單元(執行該命令將生成base.ldif文件):

  1. #./migrate_base.pl > base.ldif  
#./migrate_base.pl > base.ldif
 

(3)由於本章前面已在LDAP服務器中創建了根項“dc=dlw,dc=com”,因此將base.ldif文件中的第1個條目刪除,另外,在用戶認證中只用到組和用戶,也將其他無關條目刪除,只保存以下內容(例子):

  1. dn: ou=People,dc=dlw,dc=com  
  2. ou: People  
  3. objectClass: top  
  4. objectClass: organizationalUnit  
  5.   
  6. dn: ou=Group,dc=dlw,dc=com  
  7. ou: Group  
  8. objectClass: top  
  9. objectClass: organizationalUnit  
dn: ou=People,dc=dlw,dc=comou: PeopleobjectClass: topobjectClass: organizationalUnitdn: ou=Group,dc=dlw,dc=comou: GroupobjectClass: topobjectClass: organizationalUnit
 

(4)使用以下命令將base.ldif文件中的條目導入目錄數據庫:

# ldapadd -x -D "cn=root,dc=dlw,dc=com" -w secret -f  base.ldif  

# ldapadd -x -D "cn=root,dc=dlw,dc=com" -w secret -f  base.ldif
 

執行結果如下圖所示。

 

 

(5)開始遷移組信息。使用以下命令將/etc/group中的組信息保存到臨時文件group.tmp中:

#cat /etc/group > group.tmp  

#cat /etc/group > group.tmp
 

(6)系統組不導入LDAP目錄數據庫中,因此需對group.tmp文件中的信息進行編輯,只保留需要導入LDAP目錄數據庫的組的信息。


(7)使用以下命令將組的數據生成LDIF條目信息:
#./migrate_group.pl group.tmp > group.ldif  

#./migrate_group.pl group.tmp > group.ldif
 

(8)使用cat命令查看group.ldif的內容,可看到已按posixGroup這種objectClass將組的數據組織完成,如下圖所示。

 

 

(9)類似地,使用以下命令導出/etc/passwd中的用戶數據,並刪除不需要的用戶,然後使用migrate_passwd.pl腳本生成LDIF文件:

  1. #cat /etc/passwd > passwd.tmp  
  2. #./migrate_passwd.pl passwd.tmp > passwd.ldif  
  3. #cat passwd.ldif  
#cat /etc/passwd > passwd.tmp#./migrate_passwd.pl passwd.tmp > passwd.ldif#cat passwd.ldif
 

提示:從上面列出的屬性的名稱可以很容易地與組、用戶的相關信息聯繫起來。

 

(10)使用以下命令將組和用戶信息導入目錄數據庫

  1. #ldapadd -x -D "cn=root,dc=dlw,dc=com" -w 111111 -f group.ldif  
  2. #ldapadd -x -D "cn=root,dc=dlw,dc=com" -w 111111 -f passwd.ldif  
#ldapadd -x -D "cn=root,dc=dlw,dc=com" -w 111111 -f group.ldif#ldapadd -x -D "cn=root,dc=dlw,dc=com" -w 111111 -f passwd.ldif
 

執行以上命令的過程如下圖所示。

 

 

(11)使用以下命令查看目錄數據庫中用戶root的信息,用“uid=root”作查詢條件:

  1. #ldapsearch -x -b 'dc=dlw,dc=com' 'uid=root'  
#ldapsearch -x -b 'dc=dlw,dc=com' 'uid=root'
 

查找結果如下圖所示。

 

 

      通過以上的操作,就將需要導入的組和用戶的信息導入到了目錄數據庫中,接下來還需要對客戶端進行設置,使用LDAP進行登錄驗證操作。

 

 

設置客戶端登錄


若客戶端要使用LDAP進行用戶登錄認證,則可使用本地計算機中不存在的用戶名進行登錄操作。
【例子】修改配置文件,設置客戶端使用LDAP進行認證。
具體操作步驟如下:
(1)修改客戶端計算機中的/etc/sysconfig/authconfig文件,將以下項都修改爲yes:

  1. USELDAP=yes  
  2. USELDAPAUTH=yes  
  3. USEMD5=no  
  4. USESHADOW=yes  
  5. USELOCAUTHORIZE=yes  
USELDAP=yesUSELDAPAUTH=yesUSEMD5=noUSESHADOW=yesUSELOCAUTHORIZE=yes
 

(2)修改客戶端計算機中的/etc/openldap/ldap.conf文件,修改內容如下:

  1. host 192.168.14.20  
  2. BASE dc=dlw,dc=com  
  3. ssl off  
host 192.168.14.20BASE dc=dlw,dc=comssl off
 

(3)修改客戶端計算機中的/etc/nsswitch.conf文件,在passwd、shadow、group後面都加上ldap,如下圖所示。

 

 

      經過以上配置以後,在客戶端就可以使用LDAP目錄數據庫中的用戶信息在客戶端進行登錄操作了。登錄操作與使用本地用戶賬號相同,這裏就不再演示了。

 

 

LDAP Schema


      Schema是LDAP的一個重要組成部分,類似於數據庫的模式定義,LDAP的Schema定義了LDAP目錄所應遵循的結構和規則,比如一個 objectclass會有哪些屬性,這些屬性又是什麼結構等等,schema給LDAP服務器提供了LDAP目錄中類別,屬性等信息的識別方式,讓這些可以被LDAP服務器識別。
在LDAP的schema中,有四個重要的元素:

    Objectclass
    objectclass定義了一個類別,這個類別會被不同的目錄(在LDAP中就是一個Entry)用到,它說明了該目錄應該有哪些屬性,哪些屬性是必須的,哪些又是可選的。一個objectclass的定義包括名稱(NAME),說明(DESC),類型(STRUCTURAL或AUXILARY ,表示是結構型的還是輔助型的),必須屬性(MUST),可選屬性(MAY)等信息。

Python代碼  收藏代碼
  1. Objectclass格式:  
  2. objectclass = ( whsp  
  3. numericoid whsp //全局唯一的 OID  
  4. [ "NAME" qdescrs ] //類名稱  
  5. [ "DESC" qdstring ] //類描述  
  6. [ "OBSOLETE" whsp ]  
  7. [ "SUP" oids ] ; //父類  
  8. [ ( "ABSTRACT" / "STRUCTURAL" / "AUXILIARY" ) whsp ]  
  9. [ "MUST" oids ] ; //必填屬性集合  
  10. [ "MAY" oids ] //選填屬性集合  
  11. whsp ")"  
Objectclass格式:objectclass = ( whspnumericoid whsp //全局唯一的 OID[ "NAME" qdescrs ] //類名稱[ "DESC" qdstring ] //類描述[ "OBSOLETE" whsp ][ "SUP" oids ] ; //父類[ ( "ABSTRACT" / "STRUCTURAL" / "AUXILIARY" ) whsp ][ "MUST" oids ] ; //必填屬性集合[ "MAY" oids ] //選填屬性集合whsp ")"
 

例如:

  1. # Object Class Definitions   
  2. objectclass ( 1.3.6.1.4.1.7914.1.2.2.1 NAME 'kunmailUser'   
  3. DESC 'KunMail-LDAP User'   
  4. SUP top   
  5. STRUCTURAL  
  6. MUST(username$cn$vuid$vgid)  
  7. MAY(maildir$home$clearpw$forwardAddr$quota$storeHost$delivery$mailReplyText$active))  
# Object Class Definitions objectclass ( 1.3.6.1.4.1.7914.1.2.2.1 NAME 'kunmailUser' DESC 'KunMail-LDAP User' SUP top STRUCTURALMUST(username$cn$vuid$vgid)MAY(maildir$home$clearpw$forwardAddr$quota$storeHost$delivery$mailReplyText$active))
 

      這裏kunmailUser這種數據,要包含maildir $ home $ clearpw $ forwardAddr $ quota $ storeHost $ delivery $ mailReplyText $ active等可選項,還要包括username $ cn $ vuid $ vgid 必選項。 可選項用MAY()來包含,必選項用MUST()來包含。DESC是說明項。SUP表示父類(有點像面向對象編程啊)top表示沒有父類,他自己是頂級。STRUCTURAL是存儲方式。一般來說每個節點都要包含一個ABSTRACT類("top" or "alias"), 至少一個STRUCTURAL類,0個或者多個AUXILIARY類。AUXILIARY表示輔助型、STRUCTURAL表示結構型(默認)、ABSTRACT表示摘要型。
      下面定義一個允許將myPhoto增加到任何已經存在的條目中的auxiliary對象類:

Python代碼  收藏代碼
  1. objectclass= ( 1.1.2.2.1 NAME 'myPhotoObject'  
  2. DESC 'mixin myPhoto'  
  3. AUXILIARY  
  4. MAY myPhoto )  
objectclass= ( 1.1.2.2.1 NAME 'myPhotoObject'DESC 'mixin myPhoto'AUXILIARYMAY myPhoto )
 

      如果您的組織需要一個私有的結構化對象類來表示用戶,你可以子類化任何一個已經存在的person類,比如inetOrgPerson(RFC2798),然後增加需要的屬性:

  1. objectclass =( 1.1.2.2.2 NAME 'myPerson'  
  2. DESC 'my person'  
  3. SUP inetOrgPerson  
  4. MUST ( 'myUniqueName' $ 'givenName' )  
  5. MAY 'myPhoto' )  
objectclass =( 1.1.2.2.2 NAME 'myPerson'DESC 'my person'SUP inetOrgPersonMUST ( 'myUniqueName' $ 'givenName' )MAY 'myPhoto' )
 

      該對象類從inetOrgPerson中繼承允許的或者必須的屬性,但是,要求myUniqueName和givenName,允許myPhoto。

 

 

Attribute


      attribute就是一個上面objectclass中可能包含的屬性,對其的定義包括名稱,數據類型,單值還是多值以及匹配規則等。後面用具體的例子來說明。

 

Attribute格式:

  1. attributeType ( whsp  
  2. numericoid whsp //全局唯一的 OID  
  3. [ "NAME" qdescrs ] //屬性名稱  
  4. [ "DESC" qdstring ] //屬性描述  
  5. [ "OBSOLETE" whsp ]  
  6. [ "SUP" woid ] //本屬性從其它屬性中派生出來的  
  7. [ "EQUALITY" woid //相等性匹配  
  8. [ "ORDERING" woid//順序匹配  
  9. [ "SUBSTR" woid ] //字符串匹配  
  10. [ "SYNTAX" whsp noidlen whsp ] //字段的數據類型的OID  
  11. [ "SINGLE-VALUE" whsp ] //定義本屬性爲單值(默認多值)  
  12. [ "COLLECTIVE" whsp ] //default not collective  
  13. [ "NO-USER-MODIFICATION" whsp ]//default user modifiable  
  14. [ "USAGE" whsp AttributeUsage ]//default userApplications  
  15. whsp ")"  
  16. AttributeUsage =  
  17. "userApplications" /  
  18. "directoryOperation" /  
  19. "distributedOperation" / ; DSA-shared  
attributeType ( whspnumericoid whsp //全局唯一的 OID[ "NAME" qdescrs ] //屬性名稱[ "DESC" qdstring ] //屬性描述[ "OBSOLETE" whsp ][ "SUP" woid ] //本屬性從其它屬性中派生出來的[ "EQUALITY" woid //相等性匹配[ "ORDERING" woid//順序匹配[ "SUBSTR" woid ] //字符串匹配[ "SYNTAX" whsp noidlen whsp ] //字段的數據類型的OID[ "SINGLE-VALUE" whsp ] //定義本屬性爲單值(默認多值)[ "COLLECTIVE" whsp ] //default not collective[ "NO-USER-MODIFICATION" whsp ]//default user modifiable[ "USAGE" whsp AttributeUsage ]//default userApplicationswhsp ")"AttributeUsage ="userApplications" /"directoryOperation" /"distributedOperation" / ; DSA-shared
 

whsp是空格的意思(' ')。numericoid 是全局唯一的 OID,是帶.的十進制形式 (e.g. 1.1.0), qdescrs有一個或幾個意思, woid 可以使名稱或者是 OID 可選擇的一定長度的後綴(e.g {10})。
例如,屬性類型name和cn在core.schema中如下定義:

Python代碼  收藏代碼
  1. attributeType ( 2.5.4.41 NAME 'name'  
  2. DESC 'name(s) associated with the object'  
  3. EQUALITY caseIgnoreMatch  
  4. SUBSTR caseIgnoreSubstringsMatch  
  5. SYNTAX 1.3.6.1.4.1.1466.115.121.1.15{32768} )  
  6. attributeType ( 2.5.4.3 NAME ( 'cn' $ 'commonName' )  
  7. DESC 'common name(s) assciated with the object'  
  8. SUP name )  
  9. attributetype ( 1.3.6.1.4.1.7914.1.2.1.6 NAME 'quota'   
  10. DESC 'The amount of space the user can use until all further messages get bounced.'   
  11. SYNTAX 1.3.6.1.4.1.1466.115.121.1.44   
  12. SINGLE-value )   
attributeType ( 2.5.4.41 NAME 'name'DESC 'name(s) associated with the object'EQUALITY caseIgnoreMatchSUBSTR caseIgnoreSubstringsMatchSYNTAX 1.3.6.1.4.1.1466.115.121.1.15{32768} )attributeType ( 2.5.4.3 NAME ( 'cn' $ 'commonName' )DESC 'common name(s) assciated with the object'SUP name )attributetype ( 1.3.6.1.4.1.7914.1.2.1.6 NAME 'quota' DESC 'The amount of space the user can use until all further messages get bounced.' SYNTAX 1.3.6.1.4.1.1466.115.121.1.44 SINGLE-value ) 
 

請注意,每一個都定義了屬性的OID,給出了一個短的名稱,以及一個簡短的描述。每一個名稱都是OID的一個別名。Slapd(8)在返回結果的時候,將返回第1個列出的名稱。
      第1個名稱,name,保存了directoryString(UTF-8編碼的Unicode)語法。該語法由OID說明。(1.3.6.1.4.1.1466.115.121.1.15標識了目錄字符串語法)。還說明了一個推薦長度爲32768的選項。服務器應該支持該長度的值,但是,也可以支持更長的值。該域沒有指明長度限制,因此,在服務器上被忽略,並且服務器不會限制其大小。另外,相等和子串匹配使用不區分大小寫的規則。下面是經常使用的語法和匹配規則(OpenLDAP支持這些,以及更多)
      第2個屬性,cn,是name的一個子類型,因此,它繼承了語法,匹配規則,並且使用name.commonName作爲別名。
      兩個屬性都沒有限制到單一值。都可以被用戶應用程序所使用,都不存在過期,都不是集合。
      很多組織爲用戶保留唯一的名字(unique name),雖然用戶可以使用displayName,但是這個屬性(name)依舊由用戶控制。而不是organization。我們可以從 inetorgperson.schema 拷貝displayName ,替換OID,name,和描述(description)。

  1. attributetype ( 1.1.2.1.1 NAME 'myUniqueName'  
  2. DESC 'unique name with my organization'  
  3. EQUALITY caseIgnoreMatch  
  4. SUBSTR caseIgnoreSubstringsMatch  
  5. SYNTAX 1.3.6.1.4.1.1466.115.121.1.15  
  6. SINGLE-VALUE )  
attributetype ( 1.1.2.1.1 NAME 'myUniqueName'DESC 'unique name with my organization'EQUALITY caseIgnoreMatchSUBSTR caseIgnoreSubstringsMatchSYNTAX 1.3.6.1.4.1.1466.115.121.1.15SINGLE-VALUE )
 

但是,如果我們要使name屬性包含一個斷言,這個屬性可以被定義爲name的子屬性。

 

  1. attributetype ( 1.1.2.1.1 NAME 'myUniqueName'  
  2. DESC 'unique name with my organization'  
  3. SUP name )  
attributetype ( 1.1.2.1.1 NAME 'myUniqueName'DESC 'unique name with my organization'SUP name )
 

      很多的組織爲每一個用戶保留一個頭像。myPhoto屬性類型的定義可以用來保存用戶的頭像。當然用戶可以選擇jpegPhoto屬性類型(RFC2798)(或其子類型)來保存頭像。當然你只能在圖片符合JPEG File Interchange Format時使用。
      當然,一個使用八進制語法的屬性類型可以這樣的定義:

 

  1. attributetype ( 1.1.2.1.2 NAME 'myPhoto'  
  2. DESC 'a photo (application defined format)'  
  3. SYNTAX 1.3.6.1.4.1.1466.115.121.1.40  
  4. SINGLE-VALUE )  
attributetype ( 1.1.2.1.2 NAME 'myPhoto'DESC 'a photo (application defined format)'SYNTAX 1.3.6.1.4.1.1466.115.121.1.40SINGLE-VALUE )
 

      在這,語法中並沒有置頂photo的格式(format),這裏假設訪問屬性的應用可以對其值進行處理。
      如果你想支持多種圖片格式,你需要爲每一個格式定義屬性類型。爲圖片添加類型信息的前綴。或者使用ASN.1描述值,和use the ;binary transfer option。
      可以使圖片屬性能夠保存URI,你可以在labeledURI(RFC2079)後創建一個屬性,或者創建一個子類型。

 

  1. attributetype ( 1.1.2.1.3 NAME 'myPhotoURI'  
  2. DESC 'URI and optional label referring to a photo'  
  3. SUP labeledURI )  
attributetype ( 1.1.2.1.3 NAME 'myPhotoURI'DESC 'URI and optional label referring to a photo'SUP labeledURI )
 

Syntax


      syntax是LDAP中的“語法”,其實就是LDAP中會用到的數據類型和數據約束,這個語法是遵從X.500中數據約束的定義的。其定義需要有一個ID(遵從X.500)以及說明(DESP)

 

 

Commonly Used Syntaxes

Name

OID

Description

boolean

1.3.6.1.4.1.1466.115.121.1.7

boolean value

distinguishedName

1.3.6.1.4.1.1466.115.121.1.12

DN

directoryString

1.3.6.1.4.1.1466.115.121.1.15

UTF-8 string

IA5String

1.3.6.1.4.1.1466.115.121.1.26

ASCII string

Integer

1.3.6.1.4.1.1466.115.121.1.27

integer

Name and Optional UID

1.3.6.1.4.1.1466.115.121.1.34

DN plus UID

Numeric String

1.3.6.1.4.1.1466.115.121.1.36

numeric string

OID

1.3.6.1.4.1.1466.115.121.1.38

object identifier

Octet String

1.3.6.1.4.1.1466.115.121.1.40

arbitary octets

Printable String

1.3.6.1.4.1.1466.115.121.1.44

printable string

 

 

Matching Rules


      是用來指定某屬性的匹配規則,實際上就是定義一個特殊的Syntax的別名,讓LDAP服務器可以識別,並對定義的屬性進行匹配。

 

 

Commonly Used Matching Rules

Name

Type

Description

booleanMatch

equality

boolean

octetStringMatch

equality

octet string

objectIdentiferMatch

equality

OID

distinguishedNameMatch

equality

DN

uniqueMemberMatch

equality

Name with optional UID

numericStringMatch

equality

numerical

numericStringOrderingMatch

ordering

numerical

numericStringSubstringsMatch

substrings

numerical

caseIgnoreMatch

equality

case insensitive, space insensitive

caseIgnoreOrderingMatch

ordering

case insensitive, space insensitive

caseIgnoreSubstringsMatch

substrings

case insensitive, space insensitive

caseExactMatch

equality

case sensitive, space insensitive

caseExactOrderingMatch

ordering

case sensitive, space insensitive

caseExactSubstringsMatch

substrings

case sensitive, space insensitive

caseIgnoreIA5Match

equality

case insensitive, space insensitive

caseIgnoreIA5OrderingMatch

ordering

case insensitive, space insensitive

caseIgnoreIA5SubstringsMatch

substrings

case insensitive, space insensitive

caseExactIA5Match

equality

case sensitive, space insensitive

caseExactIA5OrderingMatch

ordering

case sensitive, space insensitive

caseExactIA5SubstringsMatch

substrings

case sensitive, space insensitive

 

      LDAP的schema的主要元素就是這些了,下面列舉出了一些LDAP規定好的或是現在比較通用的schema,一般的LDAP服務器都應該可以識別這些定義。
      這就是一個名爲subschema的objectclass的定義:

 

  1. objectclass=(2.5.20.1 NAME 'subschema'  AUXILIARY  
  2.  MAY ( dITStructureRules $ nameForms $ ditContentRules $  
  3. objectClasses $ attributeTypes $ matchingRules $ matchingRuleUse ) )  
objectclass=(2.5.20.1 NAME 'subschema'  AUXILIARY MAY ( dITStructureRules $ nameForms $ ditContentRules $objectClasses $ attributeTypes $ matchingRules $ matchingRuleUse ) )
 

      首先是ID,這裏是2.5.20.1,接着是NAME,AUXILIARY說明是輔助型,之後是可選屬性的定義,subschema中沒有定義必須屬性,如果需要定義,應該和MAY一樣,將屬性放在MUST()中並用$隔開
      再來看一個屬性定義:

 

  1. attributetype ( 2.5.4.3 NAME 'cn' SUP name EQUALITY caseIgnoreMatch )  
attributetype ( 2.5.4.3 NAME 'cn' SUP name EQUALITY caseIgnoreMatch )
 

      可以看到cn屬性的父屬性是name,它相等性匹配於caseIgnoreMatch(匹配原則爲EQUALITY,還有如SUBSTR是字符串匹配,ORDERING是順序匹配)
      syntax定義一般都比較簡單,如:

 

  1. ( 1.3.6.1.4.1.1466.115.121.1.6  DESC  'String' )  
( 1.3.6.1.4.1.1466.115.121.1.6  DESC  'String' )
 

      這個定義說明,這一串數字1.3.6.1.4.1.1466.115.121.1.5就代表了LDAP中的字符串,這個數字串的定義和X.500相關,包括了它的存儲方式,所佔空間大小等。
      最後看看Matching Rule的例子,前面提到了caseIgnoreMatch,就看他的吧

 

  1. attributetype ( 2.5.13.2 NAME 'caseIgnoreMatch'  
  2.       SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )  
attributetype ( 2.5.13.2 NAME 'caseIgnoreMatch'      SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )
 

      其實1.3.6.1.4.1.1466.115.121.1.15 就是LDAP數據類型Directory String的ID,說明前面的cn需要等於這個數據類型纔有效。
      還有很多常用schema的定義都在了RFC2252中,LDAP服務器都應該支持這些基本的schema。好了,現在基本對LDAP中的schema有個一個大致的說明,可能有不到位或不妥之處,還望大家指正。



發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章