LDAP(輕量目錄訪問協定, Lightweight Directory Access Protocol)定義了目錄服務(Directory Service)的資料如何被存取,以及資料在目錄服務被賦予的意義。其採用目錄結構的方式來存取資料,資料之間存在著父子或是兄弟的關係。實作了LDAP的軟體程式可以被視為是專門用來讀取資料的資料庫(資料可能經常被讀取,但不常被變動),經常用來儲存姓名、電子郵件、電話、地址等人事資料,或是拿來做使用者權限的驗證。



安裝slapd

OpenLDAP是LDAP的開源實作專案,提供了LDAP的伺服器程式─slapd,還有一些函式庫及工具。

要在Ubuntu Server上安裝slapd來架設出LDAP伺服器,可以直接在終端機中執行以下指令:

sudo apt install slapd

ubuntu-server-18-04-ldap

在安裝slapd時需要設定LDAP的管理員密碼。這邊可以先隨便設定沒關係,等等會使用比較好的方式來重設。

ubuntu-server-18-04-ldap

ubuntu-server-18-04-ldap

LDAP使用的TCP連接埠為389,可以使用以下指令來查看slapd是否有確實安裝成功。

sudo ss -tlnp | grep slapd

ss指令可以顯示出Socket相關的資訊。-l參數可以只顯示正在監聽中的連線。若使用ss指令時都沒給任何參數的話,會忽略掉監聽中的連線。-t參數可以只顯示TCP連線。-n參數可以讓連接埠數字直接被輸出,而不是用一個名稱代替。-p參數可以顯示佔用連線的行程。

ubuntu-server-18-04-ldap

如上圖,如果有看到TCP有在監聽連接埠389,就表示slapd安裝成功了!

設定slapd

slapd的設定檔位於/etc/ldap/slapd.d目錄,副檔名為.ldif,通常在這個目錄下,一個.ldif檔案只會有一筆物件(object),或稱為「條目」(entry)的資料,方便分類,且檔名會使用該物件的DN(識別名稱, Distinguish Name),方便辨識。

slapd預設會有以下兩個自動產生的檔案:

  • cn=config這個是slapd在執行時會產生並持續維護的設定檔目錄,裡面也會存放多個.ldif設定檔。
  • cn=config.ldif這個檔案表示用來管理整個LDAP伺服器的物件,算是權限等級最高的物件,這個物件又稱為OLC。

以下是預設的cn=config.ldif的內容:

dn: cn=config
objectClass: olcGlobal
cn: config
olcArgsFile: /var/run/slapd/slapd.args
olcLogLevel: none
olcPidFile: /var/run/slapd/slapd.pid
olcToolThreads: 1                                                          
structuralObjectClass: olcGlobal
entryUUID: 85abc3f4-ba64-1038-86dd-6f3eb19fd214
creatorsName: cn=config
createTimestamp: 20190201115907Z
entryCSN: 20190201115907.291875Z#000000#000#000000
modifiersName: cn=config
modifyTimestamp: 20190201115907Z

可以看出一筆物件資料會有很多個欄位,格式如下:

欄位名稱: 欄位值

其中,dn即為該物件的DN(識別名稱, Distinguish Name),算是最重要的欄位,稍候會詳細介紹。而objectClass欄位則是指這個物件的「類別」(class),用來表示指定這個物件所代表的意義,以及它必須要有的欄位,或是可能會有的欄位。可以使用多個objectClass欄位,來指定該物件屬於多個類別,進而擴充其可以使用的欄位。

物件的類別定義在/etc/ldap/schema這個目錄中的設定檔內。但是cn=config這個物件的類別olcGlobal,是特殊的類別,只能用在OLC物件。olcGlobal類別定義了一些以「olc」為開頭的欄位,可以用來設定整個LDAP伺服器。

前面提到LDAP經常用來儲存人事資料,在/etc/ldap/schema/core.ldif(/etc/ldap/schema/core.schema)中,我們可以找到person這個類別,這也就是人事資料所使用的類別。類別定義如下:

olcObjectClasses ( 2.5.6.6 NAME 'person'                            
    DESC 'RFC2256: a person'                                   
    SUP top STRUCTURAL                                         
    MUST ( sn $ cn )                                              
    MAY ( userPassword $ telephoneNumber $ seeAlso $ description ) )

先看到SUP這個設定項目,這個欄位用來定義該類別的父類別和其類別的類型。父類別定義的「必須欄位(MUST)」和「可能會有的欄位(MAY)」都會被子類別繼承下來。一個子類別可以擁有多個父類別,需使用(類別名稱1 $ 類別名稱2 $ 類別名稱3)這樣的格式來隔開多個父類別名稱。而類別的類型則有「結構型類別(STRUCTURAL)」、「抽象型類別(ABSTRACT)」和「輔助型類別(AUXILIARY)」這幾種,一個物件必須要在objectClass欄位中指定剛好一個結構型類別,而其餘的objectClass欄位則可以指定為不同的輔助型類別。抽象型類別則專門用於被所有類型的類別繼承。繼承結構型類別或是輔助型類別的子類別,其類型必須要等於其父類別的類型。

根據設定檔,person這個類別的父類別為top這個類別,top類別是LDAP預設的頂層類別,沒有定義有任何的必須要有或是可能會有的欄位。MUST這個設定項目定義了person這個類別必須要有sn(surname)和cn(common name)欄位;MAY這個設定項目定義了person這個類別也可以有userPasswordtelephoneNumberseeAlsodescription欄位。

RDN和DN

在介紹DN之前,先來了解一下什麼是RDN(Relative Distinguished Name)。根據目錄服務的定義(X.500),常用的目錄節點(node)的屬性類型(AttributeType)如下:

  • CN(Common Name):通用名稱。
  • L(Locality Name):地方名稱。
  • ST(State Or Province Name):洲、省名稱。
  • O(Organization Name):組織名稱。
  • OU(Organization Unit Name):組織單位名稱。
  • C(Country Name):國家名稱。
  • STREET(Street Name):街道名稱。
  • DC(Domain Component):網域部件。如google.com,有comgoogle兩個部件。
  • UID(User ID):使用者的ID。

依照目錄節點的屬性類型,RDN可以寫成cn=PeterO=GoogleC=USA,一個節點會有一個RDN。但是LDAP中的條目是直接使用DN,而不是RDN。DN就是該節點條目其所在目錄以及所有上層目錄的「RDN」串接,並以,字元將各個RDN分開。如此一來所形成的DN是獨一無二的,於是乎我們可以透過DN,直接明確定位到這個目錄結構下的某個節點。

如下圖:

ubuntu-server-18-04-ldap

底下是一個人員的條目範例:

dn:           cn=Ron,dc=magiclen,dc=org
cn:           Ron 
objectclass:  organizationalPerson
sn:           Li
description:  The master of magiclen.org.
title:        Master

重新產生slapd的設定檔

在終端機執行以下指令,可以重新產生slapd的設定檔:

sudo dpkg-reconfigure slapd

透過這個指令,能以更方便的文字介面重新設定管理員使用者和其它項目。

ubuntu-server-18-04-ldap

一開始要先選擇No,不忽略OpenLDAP伺服器的配置。

ubuntu-server-18-04-ldap

接著要設定基本的DN(Base DN)。

ubuntu-server-18-04-ldap

然後是組織名稱。這個雖然是在設定O欄位,但它不會被當成dn的一部份,純粹記錄用。

ubuntu-server-18-04-ldap

再來是管理員的密碼。

ubuntu-server-18-04-ldap

ubuntu-server-18-04-ldap

資料庫後端就用設定腳本建議的MDB即可。

ubuntu-server-18-04-ldap

ubuntu-server-18-04-ldap

這個設定是決定LDAP資料庫是否要在乾淨移除(purge)slapd時也跟著被移除。

ubuntu-server-18-04-ldap

再來決定是否要備份舊的LDAP資料庫,備份檔會被放在/var/backups/目錄中。

ubuntu-server-18-04-ldap

slapcat

slapcat這個指令可以將目前slapd資料庫有的資料輸出,產生出LDIF檔案。LDIF檔案可以再透過slapadd指令來輸入至slapd資料庫中。

使用以下指令,可以查看目前slapd資料庫中的資料。

sudo slapcat

ubuntu-server-18-04-ldap

加上-l參數並指定一個檔案路徑,可以將輸出的資料儲存成檔案。

如果要篩選資料,可以使用-a參數,並設定要篩選的方式。例如:

sudo slapcat -a "entryDN:dnSubtreeMatch:=dc=magiclen,dc=org"

以上指令,可以只輸出dc=magiclen,dc=org節點和其子節點的資料。

slapadd

slapadd指令可以新增資料到slapd資料庫中。加上-l參數並指定一個LDIF檔案路徑,可以將該檔案的LDAP條目加進slapd資料庫中。

LDAP客戶端

安裝LDAP客戶端

要在Ubuntu Server上安裝能存取LDAP伺服器的客戶端程式,可以直接在終端機中執行以下指令:

sudo apt install ldap-utils

ubuntu-server-18-04-ldap

ldapadd─增

ldapadd指令可以將資料寫進LDAP資料庫中。用法如下:

ldapadd -h 192.168.56.103 -W -D "cn=admin,dc=magiclen,dc=org" -f 'cn=Ron,dc=magiclen,dc=org.ldif'

-h參數可以指定LDAP伺服器位址。-W參數可以指定要使用簡易驗證機制,且密碼是在執行指令後才輸入。如果要直接在指令中輸入密碼,需用-w參數;如果要從檔案中讀取密碼,需用-y參數。-D參數可以指定「Bind DN」,也就是管理員的DN。-f可以指定一個LDIF檔來匯入。

ldapsearch─查

ldapsearch指令可以查詢LDAP資料庫中的資料。用法如下:

ldapsearch -h 192.168.56.103 -x -b "dc=magiclen,dc=org"

-x參數可以指定要使用簡易驗證機制。-b參數可以指定「Base DN」,也就是要從哪開始查起的節點。

ubuntu-server-18-04-ldap

最後一個參數可以指定一個表達式,來篩選查詢結果,例如:

ldapsearch -h 192.168.56.103 -x -b "dc=magiclen,dc=org" "(!(cn=admin))"

ldapmodify─改

ldapmodify指令可以修改LDAP資料庫中的資料。用法如下:

ldapmodify -h 192.168.56.103 -W -D "cn=admin,dc=magiclen,dc=org" -f 'cn=Ron,dc=magiclen,dc=org.v2.ldif'

上面的cn=Ron,dc=magiclen,dc=org.v2.ldif檔案,如果不是要用來新增條目的話,必須要定義已經存在於LDAP資料庫中的DN,也就是要修改的DN。另外還需要使用replace欄位來宣告要修改的欄位、add欄位來宣告要增加的欄位或是delete欄位來宣告要刪除的欄位。檔案內容範例如下:

dn:           cn=Ron,dc=magiclen,dc=org
changeType:   modify
replace:      title 
title:        admin

上面這個例子中的changeType欄位有沒有寫都無所謂。

ubuntu-server-18-04-ldap

不過如果是要新增條目的話,changeType欄位就必須要設定為add。如果是要移除條目,changeType欄位就必須要設定為delete

ldapmodify指令加上-a參數的話就是ldapadd指令。

ldapdelete─刪

ldapdelete指令可以刪除LDAP資料庫中的資料。用法如下:

ldapdelete -h 192.168.56.103 -W -D "cn=admin,dc=magiclen,dc=org" 'cn=Ron,dc=magiclen,dc=org'

ubuntu-server-18-04-ldap

ldappasswd─修改密碼

ldappasswd指令可以修改LDAP資料庫中能夠代表使用者的條目的密碼。像是person類別、simpleSecurityObject類別等的條目都可以使用userPassword欄位。用法如下:

ldappasswd -h 192.168.56.103 -W -S -D "cn=admin,dc=magiclen,dc=org" 'cn=Ron,dc=magiclen,dc=org'

-S參數可以在執行指令後才輸入要設定到userPassword欄位的密碼。如果要從檔案中讀取新密碼,需用-T參數。如果不使用參數來指定新密碼的讀取方式,則會自動產生隨機的密碼。

ubuntu-server-18-04-ldap