LDAP(輕量目錄訪問協定, Lightweight Directory Access Protocol)定義了目錄服務(Directory Service)的資料如何被存取,以及資料在目錄服務被賦予的意義。其採用目錄結構的方式來存取資料,資料之間存在著父子或是兄弟的關係。實作了LDAP的軟體程式可以被視為是專門用來讀取資料的資料庫(資料可能經常被讀取,但不常被變動),經常用來儲存姓名、電子郵件、電話、地址等人事資料,或是拿來做使用者權限的驗證。
安裝slapd
OpenLDAP是LDAP的開源實作專案,提供了LDAP的伺服器程式─slapd,還有一些函式庫及工具。
要在Ubuntu Server上安裝slapd來架設出LDAP伺服器,可以直接在終端機中執行以下指令:
在安裝slapd時需要設定LDAP的管理員密碼。這邊可以先隨便設定沒關係,等等會使用比較好的方式來重設。
LDAP使用的TCP連接埠為389,可以使用以下指令來查看slapd是否有確實安裝成功。
ss
指令可以顯示出Socket相關的資訊。-l
參數可以只顯示正在監聽中的連線。若使用ss
指令時都沒給任何參數的話,會忽略掉監聽中的連線。-t
參數可以只顯示TCP連線。-n
參數可以讓連接埠數字直接被輸出,而不是用一個名稱代替。-p
參數可以顯示佔用連線的行程。
如上圖,如果有看到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
這個類別也可以有userPassword
、telephoneNumber
、seeAlso
、description
欄位。
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
,有com
和google
兩個部件。 - UID(User ID):使用者的ID。
依照目錄節點的屬性類型,RDN可以寫成cn=Peter
、O=Google
或C=USA
,一個節點會有一個RDN。但是LDAP中的條目是直接使用DN,而不是RDN。DN就是該節點條目其所在目錄以及所有上層目錄的「RDN」串接,並以,
字元將各個RDN分開。如此一來所形成的DN是獨一無二的,於是乎我們可以透過DN,直接明確定位到這個目錄結構下的某個節點。
如下圖:
底下是一個人員的條目範例:
dn: cn=Ron,dc=magiclen,dc=org cn: Ron objectclass: organizationalPerson sn: Li description: The master of magiclen.org. title: Master
重新產生slapd的設定檔
在終端機執行以下指令,可以重新產生slapd的設定檔:
透過這個指令,能以更方便的文字介面重新設定管理員使用者和其它項目。
一開始要先選擇No
,不忽略OpenLDAP伺服器的配置。
接著要設定基本的DN(Base DN)。
然後是組織名稱。這個雖然是在設定O
欄位,但它不會被當成dn
的一部份,純粹記錄用。
再來是管理員的密碼。
資料庫後端就用設定腳本建議的MDB即可。
這個設定是決定LDAP資料庫是否要在乾淨移除(purge)slapd時也跟著被移除。
再來決定是否要備份舊的LDAP資料庫,備份檔會被放在/var/backups/
目錄中。
slapcat
slapcat
這個指令可以將目前slapd資料庫有的資料輸出,產生出LDIF檔案。LDIF檔案可以再透過slapadd
指令來輸入至slapd資料庫中。
使用以下指令,可以查看目前slapd資料庫中的資料。
加上-l
參數並指定一個檔案路徑,可以將輸出的資料儲存成檔案。
如果要篩選資料,可以使用-a
參數,並設定要篩選的方式。例如:
以上指令,可以只輸出dc=magiclen,dc=org
節點和其子節點的資料。
slapadd
slapadd
指令可以新增資料到slapd資料庫中。加上-l
參數並指定一個LDIF檔案路徑,可以將該檔案的LDAP條目加進slapd資料庫中。
LDAP客戶端
安裝LDAP客戶端
要在Ubuntu Server上安裝能存取LDAP伺服器的客戶端程式,可以直接在終端機中執行以下指令:
ldapadd
─增
ldapadd
指令可以將資料寫進LDAP資料庫中。用法如下:
-h
參數可以指定LDAP伺服器位址。-W
參數可以指定要使用簡易驗證機制,且密碼是在執行指令後才輸入。如果要直接在指令中輸入密碼,需用-w
參數;如果要從檔案中讀取密碼,需用-y
參數。-D
參數可以指定「Bind DN」,也就是管理員的DN。-f
可以指定一個LDIF檔來匯入。
ldapsearch
─查
ldapsearch
指令可以查詢LDAP資料庫中的資料。用法如下:
-x
參數可以指定要使用簡易驗證機制。-b
參數可以指定「Base DN」,也就是要從哪開始查起的節點。
最後一個參數可以指定一個表達式,來篩選查詢結果,例如:
ldapmodify
─改
ldapmodify
指令可以修改LDAP資料庫中的資料。用法如下:
上面的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
欄位有沒有寫都無所謂。
不過如果是要新增條目的話,changeType
欄位就必須要設定為add
。如果是要移除條目,changeType
欄位就必須要設定為delete
。
ldapmodify
指令加上-a
參數的話就是ldapadd
指令。
ldapdelete
─刪
ldapdelete
指令可以刪除LDAP資料庫中的資料。用法如下:
ldappasswd
─修改密碼
ldappasswd
指令可以修改LDAP資料庫中能夠代表使用者的條目的密碼。像是person
類別、simpleSecurityObject
類別等的條目都可以使用userPassword
欄位。用法如下:
-S
參數可以在執行指令後才輸入要設定到userPassword
欄位的密碼。如果要從檔案中讀取新密碼,需用-T
參數。如果不使用參數來指定新密碼的讀取方式,則會自動產生隨機的密碼。