1. 程式人生 > >penLDAP學習筆記

penLDAP學習筆記

LDAP協議

 

      目錄是一組具有類似屬性、以一定邏輯和層次組合的資訊。常見的例子是通訊簿,由以字母順序排列的名字、地址和電話號碼組成。
目錄服務是一種在分散式環境中發現目標的方法。目錄具有兩個主要組成部分:

 

  • 第一部分是資料庫,資料庫是分散式的,且擁有一個描述資料的規劃。
  • 第二部分則是訪問和處理資料的各種協議。

      目錄服務其實也是一種資料庫系統,只是這種資料庫是一種樹形結構,而不是通常使用的關係資料庫。目錄服務與關係資料庫之間的主要區別在於:二者都允許對儲存資料進行訪問,只是目錄主要用於讀取,其查詢的效率很高,而關係資料庫則是為讀寫而設計的。
提示:目錄服務不適於進行頻繁的更新,屬於典型的分散式結構。

 
      LDAP是一個目錄服務協議,目前存在眾多版本的LDAP,而最常見的則是V2和V3兩個版本,它們分別於1995年和1997年首次釋出。

LDAP的基本模型


      LDAP的基本模型是建立在“條目”(Entry)的基礎上。一個條目是一個或多個屬性的集合,並且具有一個全域性唯一的“可區分名稱”(用dn表示)。與關係型資料(後面簡稱資料庫)進行類比,一個條目相當於資料庫中的一條記錄,而dn相當於資料庫中記錄的關鍵字,屬性相當於資料庫中的欄位。
提示:dn必須是全域性唯一的。

 
      LDAP中,將資料組織成一個樹形結構,這與現實生活中的很多資料結構可以對應起來,而不像設計關係型資料庫的表,需要進行多種變化。例如,圖1-1所示就是一個樹形結構的資料。

 

 

      在圖1-1所示的樹形結構中,樹的根結點是一個組織的域名(dlw.com),其下分為3個部分,分別是managers、people和group,可將這3個組看作組織中的3個部門,如managers用來管理所有管理人員,people用來管理登入系統的使用者,group用來管理系統中的使用者組。當然,在該圖中還可繼續增加其他分支。
      對於圖1-1所示的樹形結構,使用關係資料庫來儲存資料的話,需要設定多個表,一層一層分別儲存,當需要查詢某個資訊時,再逐層進行查詢,最終得到結果。
      若使用目錄來儲存該圖中的資料,則更直觀。圖中每個結點用一個條目來儲存,不同型別的結點需要儲存的資料可能不同,在LDAP中通過一個稱為objectClass的型別來控制不同結點需要的資料(稱為屬性)。
      對於目錄中的資料怎樣進行引用呢?前面提到過,每一個條目都有一個dn,因為dn是唯一的,因此就可找到需要結點的資料。dn的構造方式如下:
      首先得到條目自己的名稱(rdn,稱為相對dn),然後開始向上逐級查詢父結點,一直到根項為止。例如,對於圖1-1中最右下方的結點,其dn為:

Python程式碼  
  1. dn: cn=ldap, ou=group, o=dlw.com  

 

      通過這樣的方式,即可唯一標識每一個結點。
      在現實生活中,有很多這種樹形結構的資料,如計算機檔案系統的目錄結構、Internet中的域名等。這些型別的資料,只要不需要頻繁的更新,都適合用目錄來儲存。

LDAP的功能


在LDAP的功能模型中定義了一系列利用LDAP協議的操作,主要包含以下4部分:

 

  • 查詢操作 :允許查詢目錄和取得資料,其查詢效能比關係資料庫好。
  • 更新操作 :目錄的更新操作沒關係資料庫方便,更新效能較差,但也同樣允許進行新增、刪除、修改等操作。
  • 複製操作 :前面也提到過,LDAP是一種典型的分散式結構,提供複製操作,可將主伺服器的資料的更新複製到設定的從伺服器中。
  • 認證和管理操作 :允許客戶端在目錄中識別自己,並且能夠控制一個會話的性質。

 

LDAP協議的特點

 

  • LDAP是一種目錄服務,儲存在特殊的資料庫中,資料的讀取速度遠高於寫入速度。
  • LDAP對查詢做了優化,讀取速度優於普通關係資料庫。
  • LDAP不支援事務、不能進行回滾,需要進行這些操作的應用只有選擇關係資料庫。
  • LDAP採用伺服器/客戶端模式,支援分散式結構。
  • LDAP中的條目以樹形結構組織和儲存。
  • LDAP基於Internet協議,直接執行在簡單和通用的TCP/IP或其他可靠的傳輸協議層上,使連線的建立和包的處理簡單、快捷,對於網際網路和企業網應用都很方便。
  • LDAP協議簡單,通過使用查詢操作實現列表操作和讀操作。
  • LDAP通過引用機制實現分散式訪問,通過客戶端API實現分散式操作(對於應用透明),平衡了負載。
  • LDAP實現具有低費用、易配置和易管理的特點,並提供了滿足應用程式對目錄服務所需求的特性。

 

安裝OpenLDAP


      在RHEL 5的安裝光碟中提供了OpenLDAP 2.3.27軟體包,通過OpenLDAP軟體可實現LDAP服務。OpenLDAP程式包括客戶端、伺服器、開發工具包等軟體包,本節將介紹安裝這些程式包的具體過程。

 

      可以先通過rpm命令查詢系統中是否已安裝OpenLDAP伺服器程式,若未安裝該伺服器程式,再使用rpm命令從RHEL光碟中安裝該程式。
從RHEL 5安裝光碟中找到OpenLDAP伺服器程式,並安裝到當前系統中。
具體操作步驟如下:
(1)在進行安裝以前,首先使用以下命令建立管理OpenLDAP的使用者和組。

 

Python程式碼  
  1. # groupadd ldap  
  2. # useradd -g ldap ldap  
  3. # passwd ldap  

 

(2)執行以下命令,查詢系統中是否已安裝openldap-servers程式。

 

Python程式碼  
  1. # rpm -qa openldap-servers  

 若無任何輸出,則表示當前系統中未安裝openldap-servers伺服器程式。

 

(3)使用以下命令將RHEL安裝光碟掛載到系統中:

 

Python程式碼  
  1. # mount /dev/cdrom /mnt/cdrom  

 

(4)執行以下命令安裝openldap-servers程式的依賴程式包libtools-ltdl:

 

Python程式碼  
  1. # rpm -ivh /mnt/cdrom/Server/libtool-ltdl-1.5.22-6.1.i386.rpm  

 若不執行上面的命令,直接執行下一步的安裝命令,將提示有依賴程式未安裝。

 

(5)執行以下命令安裝openldap-servers程式:

 

Python程式碼  
  1. # rpm -ivh /mnt/cdrom/Server/openldap-servers-2.3.27-5.i386.rpm  

 

這樣就將openldap-servers伺服器程式安裝到系統中了。整個安裝過程如下圖所示。

 

 

 

(6)使用以下命令修改儲存資料的目錄/var/lib/ldap/及其檔案的所有者,並修改許可權,只有ldap使用者才對資料有讀寫許可權:

 

Python程式碼  
  1. # chown ldap.ldap /var/lib/ldap  
  2. # chmod -R 600 /var/lib/ldap  

 

在光碟中還有以下與openldap有關的軟體包,也可使用類似命令進行安裝,這裡不再逐個介紹。
  ● openldap-clients-2.3.27-5.i386.rpm:客戶端操作的相關程式。
  ● openldap-devel-2.3.27-5.i386.rpm:開發包。

 

測試安裝正確性


      安裝完成後,將在/var/lib/目錄中建立一個子目錄ldap來儲存資料,同時在/etc/目錄中也將建立一個子目錄openldap來儲存配置檔案。而openldap的守護程序slapd則儲存在/usr/bin/目錄中。
提示:如果是通過原始碼進行編譯安裝的openldap,這些程式檔案放置的位置可能不同。

1.啟動服務程序 
      要檢查安裝是否正確,可直接執行守護程序,這裡將使用預設的配置。
      啟動OpenLDAP伺服器可使用以下命令之一:

 

Python程式碼  
  1. # server ldap start  
  2. # /etc/rc.d/init.d/ldap  
  3. # /usr/sbin/slapd  

 

使用第1條命令來啟動ldap服務程序的過程如下圖所示。

 

 

 

提示:使用/usr/sbin/slapd命令啟動服務程式是最好的一種方式,如果用前兩條命令啟動openldap服務程式失敗,可使用最後一條命令試一下。

 

      從上圖可看出,啟動的是slapd程序,並有一個提示資訊,提示沒有DB_CONFIG檔案。可通過以下命令將DB_CONFIG檔案複製到/var/lib/ldap/目錄中:

 

Python程式碼  
  1. # cp /etc/openldap/DB_CONFIG.example /var/lib/ldap/DB_CONFIG  

 

另外,由於使用的是預設配置檔案,提示希望使用字尾“dc=my-domain, dc=com”。下節將介紹修改配置檔案的操作。

 

2.檢視監聽埠 
      OpenLDAP使用的監聽埠是389,通過netstat命令檢視該埠是否處於監聽狀態,可瞭解slapd程序是否在工作。具體命令如下:

 

Python程式碼  
  1. # netstat –tnlp | grep 389  

 

執行結果如下圖所示,可以看出,389埠處於監聽狀態,表示slapd程序正在工作。

 

 

 

3.搜尋測試 
      slapd服務程序啟動後,可使用OpenLDAP客戶端的一個搜尋命令進行一次搜尋,以檢查服務的配置是否正確。
      使用以下命令進行搜尋:

 

Python程式碼  
  1. # ldapsearch -x -b '' -s base '(objectclass=*)'  

 

注意:-b後面是兩個單引號,用來阻止特殊字元被Shell解析。

 

      由於還未向LDAP伺服器中新增任何資料,因此,系統中應該只有“根”這個條目,執行以上搜索的結果如下圖所示。

 

 

從以上測試可看出,OpenLDAP已經正確安裝到系統中,接下來就需要修改配置檔案,設定LDAP的根目錄了。

 

 

配置OpenLDAP

 

      在上面的例子中的搜尋結果可看出,在配置檔案中是以預設的“dc=my-domain, dc=com”作為字尾,需要對其進行修改,當然也還需要修改其他的一些配置。下面將介紹對配置檔案的修改操作。

slapd.conf


      OpenLDAP的配置檔案位於/etc/openldap/目錄中,名稱為slapd.conf。該檔案內容較多,通常只需要修改幾個地方即可,包括修改後綴、管理員及其密碼。其初始內容如下:

 

Python程式碼  
  1. #######################################################################  
  2. # ldbm and/or bdb database definitions  
  3. #######################################################################  
  4.   
  5. database        bdb  
  6. suffix          "dc=my-domain,dc=com"  
  7. rootdn          "cn=Manager,dc=my-domain,dc=com"  
  8. # Cleartext passwords, especially for the rootdn, should  
  9. # be avoided.  See slappasswd(8) and slapd.conf(5) for details.  
  10. # Use of strong authentication encouraged.  
  11. # rootpw                secret  
  12. # rootpw                {crypt}ijFYNcSNctBYg  

 

其中各語句的含義如下:
  ● 以符號“#”開始的行是註釋行,第1~3行、第8~12行都是。
  ● 第5行設定資料庫,可使用ldbm或bdb。
  ● 第6行設定字尾。
  ● 第7行設定超級管理員的名稱,與Linux系統中的root類似。在配置時用該使用者,配置完成後,建議將其刪除。
  ● 第11行設定超級管理員的密碼,預設狀態是被註釋了的。這行的密碼是明文狀態。
  ● 第12行也是設定超級管理員的密碼,這行是以加密方式設定的(預設狀態也是被註釋了的)。
根據實際情況,修改第6、7、11行即可,具體如下:

Python程式碼  
  1. #######################################################################  
  2. # ldbm and/or bdb database definitions  
  3. #######################################################################  
  4.   
  5. database        bdb  
  6. suffix          "dc=dlw,dc=com"  
  7. rootdn          "cn=root,dc=dlw,dc=com"  
  8. # Cleartext passwords, especially for the rootdn, should  
  9. # be avoided.  See slappasswd(8) and slapd.conf(5) for details.  
  10. # Use of strong authentication encouraged.  
  11. rootpw  secret  
  12. # rootpw  {crypt}ijFYNcSNctBYg  

 

      以上內容中,第6行將字尾修改為“dc=dlw,dc=com”,同時第7行的超級管理員的字尾部分也需要隨之修改。將第11行的註釋取消,設定超級管理員的密碼為MD5密碼secret。
      修改密碼時需要注意rootpw前面不要有空格,以及rootpw與密碼之間使用Tab鍵分割。 
      經過以上修改,儲存後退出,接著使用以下命令重啟slapd程序:

 

Python程式碼  
  1. # service ldap restart  

 

瞭解schema


      對於LDAP目錄中儲存的資訊,可以使用LDIF(LDAP Interchange Format)格式來儲存。這是一種標準文字檔案格式,使用這種格式儲存得的LDAP伺服器資料庫中的資料可方便讀取和修改,這也是其他大多數服務配置檔案所採取的格式。
      LDIF檔案常用來向目錄匯入或更改記錄資訊,這些資訊需要按照LDAP中schema的格式進行組織,並會接受schema的檢查,不符合其要求的格式將會出現報錯資訊。有關LDIF檔案的格式和建立將在第4章進行介紹,這裡簡單介紹一下組織LDAP資料格式的schema檔案。
      在LDAP中,schema用來指定一個目錄中所包含的物件(objects)的型別(objectClass),以及每一個型別(objectClass)中必須提供的屬性(Atrribute)和可選的屬性。可將schema理解為面向物件程式設計中的類,通過類定義一個具體的物件。LDIF中的資料條目可理解為是一個具體的物件,是通過schema來規劃建立的。因此,schema是一個數據模型,用來決定資料按什麼方式儲存,並定義儲存在不同的條目(Entry)下的資料之間的關係。schema需要在主配置檔案slapd.conf中指定,以用來決定在目錄中可以使用哪些objectClass。
      在/etc/openldap/schema/目錄中提供了許多schema檔案,只需要在配置檔案slapd.conf中使用include命令將需要使用的schema包含即可。例如,配置檔案預設包含了以下schema檔案:

 

寫道 include /etc/openldap/schema/core.schema
include /etc/openldap/schema/cosine.schema
include /etc/openldap/schema/inetorgperson.schema
include /etc/openldap/schema/nis.schema

 

提示:通常使用系統提供的schema就可解決大部分應用。管理員也可以自己設計制定schema,一般包括屬性定義(AttributeDefinition)、類定義(ClassDefinition)以及語法定義(SyntaxDefinition)等部分。這裡就不介紹具體的設計方法了。

 

管理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”下的所有條目,可使用以下命令:

Python程式碼  
  1. # ldapsearch -x -b "dc=dlw,dc=com"  

 

執行結果如下圖所示。

 

 

 

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

 

Python程式碼  
  1. # 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”。
      首先輸入以下命令,進行修改狀態:

Python程式碼  
  1. # ldapmodify -x -D "cn=root,dc=dlw,dc=com" -W secret  

 

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

 

Python程式碼  
  1. dn: cn=test, ou=managers, dc=dlw, dc=com  
  2. changetype: modify  
  3. replace: sn  
  4. sn: Test User Modify  

 

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

 

 

使用以上命令修改條目的資料之後,可使用以下命令檢視是否修改成功:

 

Python程式碼  
  1. #ldapsearch -x -b 'dc=dlw,dc=com' 'cn=test'  

 

執行以上命令檢視test條目的資料如下圖所示,可以看到sn屬性被修改了。

 

 

 

2.通過檔案修改


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

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

Python程式碼  
  1. dn: cn=test,ou=managers,dc=dlw,dc=com  
  2. changetype: modify  
  3. replace: sn  
  4. sn: Test User  

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

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

 

Python程式碼  
  1. # ldapmodify -x -D "cn=root,dc=dlw,dc=com" -w secret -f modify  

 

執行結果如下圖所示。

 

 

 

刪除條目


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


      ldapdelete  選項  刪除條目


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

 

Python程式碼  
  1. # ldapdelete -x -D "cn=root,dc=dlw,dc=com" -w secret \  
  2. > "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"  

 

資料匯出


      通過ldapadd命令可向目錄資料庫中新增資料,在某些情況下,可能還需要進行反向操作,即將目錄資料庫中的資料匯出。
      使用ldapsearch命令對目錄資料庫進行搜尋,然後通過重定向將搜尋結果儲存到一個檔案中,可達到匯出資料的目的。另外,匯出資料更常用的是slapcat命令,該命令的格式如下:


      slapcat  選項


      最常用的選項就是-l,表示匯出為LDIF檔案格式。
      如將本章前面例子中建立的目錄資料庫匯出為export.ldif檔案,可使用以下命令:

 

Python程式碼  
  1. #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指令前的註釋符號,取消後的結果如下:

Python程式碼  
  1. # Replicas of this database  
  2. replogfile      /var/lib/ldap/replog  

 

增加replica指令,如:

 

Python程式碼  
  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的管理員密碼  

 

設定從伺服器


配置從伺服器上的slapd.conf檔案,增加updatedn指令,如:

 

Python程式碼  
  1. updatedn " cn=root,dc=dlw,dc=com"          #與主伺服器的binddn對應  

 

在從伺服器的配置檔案中,不要包含replica和replogfile指令。

 

測試主從LDAP伺服器


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


   1.啟動主LDAP伺服器
        在主LDAP伺服器中啟動slapd程序和slurpd程序。
   2.啟動從LDAP伺服器
        在主LDAP伺服器中啟動slapd程序。


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

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

 

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

 

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

 

Python程式碼  
  1. dn: cn=dlw,ou=managers,dc=dlw,dc=com  
  2. changetype: modify  
  3. replace: sn  
  4. sn: dongliwei  

 

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

 

 

 

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

 

Python程式碼  
  1. #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檔案,在其中查詢以下內容:

Python程式碼  
  1. $DEFAULT_BASE="dc=padl,dc=com";  

 

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

 

Python程式碼  
  1. $DEFAULT_BASE="dc=dlw,dc=com";  

 

儲存後退出。

 

 

(2)使用以下命令執行指令碼migrate_base.pl,用來建立根項,併為Hosts、Networks、Group和People等建立低一級的組織單元(執行該命令將生成base.ldif檔案):

 

Python程式碼  
  1. #./migrate_base.pl > base.ldif  

 

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

 

Python程式碼  
  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  

 

(4)使用以下命令將base.ldif檔案中的條目匯入目錄資料庫:

 

Python程式碼  
  1. # ldapadd -x -D "cn=root,dc=dlw,dc=com" -w secret -f  base.ldif  

 

執行結果如下圖所示。

 

 

 

(5)開始遷移組資訊。使用以下命令將/etc/group中的組資訊儲存到臨時檔案group.tmp中:

 

Python程式碼  
  1. #cat /etc/group > group.tmp  

 

(6)系統組不匯入LDAP目錄資料庫中,因此需對group.tmp檔案中的資訊進行編輯,只保留需要匯入LDAP目錄資料庫的組的資訊。


(7)使用以下命令將組的資料生成LDIF條目資訊:

Python程式碼  
  1. #./migrate_group.pl group.tmp > group.ldif  

 

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

 

 

 

(9)類似地,使用以下命令匯出/etc/passwd中的使用者資料,並刪除不需要的使用者,然後使用migrate_passwd.pl指令碼生成LDIF檔案:

 

Python程式碼  
  1. #cat /etc/passwd > passwd.tmp  
  2. #./migrate_passwd.pl passwd.tmp > passwd.ldif  
  3. #cat passwd.ldif  

 

提示:從上面列出的屬性的名稱可以很容易地與組、使用者的相關資訊聯絡起來。

 

(10)使用以下命令將組和使用者資訊匯入目錄資料庫:

 

Python程式碼  
  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  

 

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

 

 

 

(11)使用以下命令檢視目錄資料庫中使用者root的資訊,用“uid=root”作查詢條件:

 

Python程式碼  
  1. #ldapsearch -x -b 'dc=dlw,dc=com' 'uid=root'  

 

查詢結果如下圖所示。

 

 

 

      通過以上的操作,就將需要匯入的組和使用者的資訊匯入到了目錄資料庫中,接下來還需要對客戶端進行設定,使用LDAP進行登入驗證操作。

 

 

設定客戶端登入


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

 

Python程式碼  
  1. USELDAP=yes  
  2. USELDAPAUTH=yes  
  3. USEMD5=no  
  4. USESHADOW=yes  
  5. USELOCAUTHORIZE=yes  

 

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

 

Python程式碼  
  1. host 192.168.14.20  
  2. BASE dc=dlw,dc=com  
  3. ssl 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 ")"  

 

例如:

 

Python程式碼  
  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))  

 

      這裡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 )  

 

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

 

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

 

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

 

 

Attribute


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

 

Attribute格式:

 

Python程式碼  
  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  

 

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 )   

 

請注意,每一個都定義了屬性的OID,給出了一個短的名稱,以及一個簡短的描述。每一個名稱都是OID的一個別名。Slapd(8)在返回結果的時候,將返回第1