29.5. 輕量級目錄存取協定 (LDAP)

Written by Tom Rhodes.

輕量級目錄存取協定 (Lightweight Directory Access Protocol, LDAP) 是一個利用分散式目錄資訊服務來做到存取、修改與認証物件的應用層通訊協定,可以想像成是一本可以儲存數個階層、同質資訊的電話簿或記錄簿。它用在 Active Directory 及 OpenLDAP 網路,允許使用者利用一個帳號來存取數個階層的內部資訊,例如:電子郵件認証、取得員工聯絡資訊及內部網站的認証皆可使用 LDAP 伺服器資料庫中的單一使用者帳號來存取。

本章節將介紹在 FreeBSD 系統上如何快速的設定一個 LDAP 伺服器。本章節假設管理者已做好規劃,這包含:要儲存何種類型的資訊、這些資訊要來做什麼、那些使用者擁有存取這些資訊的權限以及如何確保這些資訊不會被未經授權存取。

29.5.1. LDAP 術語與結構

LDAP 使用了數個術語在開始設置之前必須先了解。所有的目錄項目由一群屬性 (attributes) 所組成,每個屬性集皆有一個獨特的辨識碼稱為辨識名稱 (Distinguished Name, DN),這個辨識碼會由數個其他的屬性,如:常用或相對辨識名稱 (Relative Distinguished Name, RDN) 所組成,這就像目錄有絕對路徑與相對路徑,可以把 DN 當做絕對路徑,RDN 當做相對路徑。

LDAP 項目的例子如下。這個例子會搜尋指定使用者帳號 (uid)、組織單位 (ou) 及組織的項目 (o):

% ldapsearch -xb "uid=trhodes,ou=users,o=example.com"
# extended LDIF
#
# LDAPv3
# base <uid=trhodes,ou=users,o=example.com> with scope subtree
# filter: (objectclass=*)
# requesting: ALL
#

# trhodes, users, example.com
dn: uid=trhodes,ou=users,o=example.com
mail: trhodes@example.com
cn: Tom Rhodes
uid: trhodes
telephoneNumber: (123) 456-7890

# search result
search: 2
result: 0 Success

# numResponses: 2
# numEntries: 1

這個範例項目會顯示 dn, mail, cn, uid 以及 telephoneNumber 屬性的數值。而 cn 屬性則是 RDN

更多有關 LDAP 以及其術語的資訊可在 http://www.openldap.org/doc/admin24/intro.html 找到。

29.5.2. 設定 LDAP 伺服器

FreeBSD 並未提供內建的 LDAP 伺服器,因此要從安裝 net/openldap24-server 套件或 Port 開始設置。由於 Port 有許多可以設定的選項,建議安裝套件使用預設的選項,若選項必須做修改才改用編譯 Port 的方式安裝,大多數的案例皆可使用預設值。然而,若需要支援 SQL,則必須開啟選項並依 節 4.5, “使用 Port 套件集” 的指示編譯 Port。

接著,建立目錄來儲存資枓以及儲存憑證:

# mkdir /var/db/openldap-data
# mkdir /usr/local/etc/openldap/private

複製資料庫設定檔:

# cp /usr/local/etc/openldap/DB_CONFIG.example /var/db/openldap-data/DB_CONFIG

下一個階段是設定憑証機構 (Certificate authority)。以下指令必須在 /usr/local/etc/openldap/private 執行,這很重要是由於檔案權限須要被限制且使用者不應有這些檔案的存取權限。要建立憑証授權,需先輸人這個指令並依提示作業:

# openssl req -days 365 -nodes -new -x509 -keyout ca.key -out ../ca.crt

提示的輸入項目除了通用名稱 (Common Name) 其他是可以一樣的,這個項目必須使用與系統主機名稱 不同 的名稱。若這是一個自行簽署的憑証 (Self signed certificate),則在憑証機構 CA 的前面加上主機名稱。

接下來的工作是建立一個憑証簽署的請求及私鑰。請輸入以下指令然後依提示操作:

# openssl req -days 365 -nodes -new -keyout server.key -out server.csr

在憑証產生程序的過程中請確認 Common Name 屬性設定正確。完成之後便可簽署金鑰:

# openssl x509 -req -days 365 -in server.csr -out ../server.crt -CA ../ca.crt -CAkey ca.key -CAcreateserial

在憑証產生程序的最後一步是產生並簽署用戶憑証:

# openssl req -days 365 -nodes -new -keyout client.key -out client.csr
# openssl x509 -req -days 3650 -in client.csr -out ../client.crt -CA ../ca.crt -CAkey ca.key

要記得當提示是要使用同樣的 Common Name 屬性。完成之後,請確認執行的指令產生了共 8 個新檔案。若正確無誤,下個步驟便是編輯 /usr/local/etc/openldap/slapd.conf 並加入以下選項:

TLSCipherSuite HIGH:MEDIUM:+SSLv3
TLSCertificateFile /usr/local/etc/openldap/server.crt
TLSCertificateKeyFile /usr/local/etc/openldap/private/server.key
TLSCACertificateFile /usr/local/etc/openldap/ca.crt

接著編輯 /usr/local/etc/openldap/ldap.conf 然後加入下行:

TLS_CACERT /usr/local/etc/openldap/ca.crt
TLS_CIPHER_SUITE HIGH:MEDIUM:+SSLv3

在編輯這個檔案的時候,取消註解以下項目然後設定這些項目使用實際要使用的數值:BASE, URI, SIZELIMITTIMELIMIT。設定 URI 要包含 ldap://ldaps://。然後加入兩個項目指向憑証機構。完成之後,所有的設定項目會如下:

BASE    dc=example,dc=com
URI     ldap:// ldaps://

SIZELIMIT       12
TIMELIMIT       15

TLS_CACERT /usr/local/etc/openldap/ca.crt
TLS_CIPHER_SUITE HIGH:MEDIUM:+SSLv3

給伺服器用的預設密碼應該要更換:

# slappasswd -h "{SHA}" >> /usr/local/etc/openldap/slapd.conf

這個指令會提示輸入密碼,若程序沒有失敗,便會將編碼過的密碼加到 slapd.conf 的最後。支援的編碼格式有許多種,請參考 slappasswd 的操作手冊以取得更多資訊。

接著編輯 /usr/local/etc/openldap/slapd.conf 並加入下行:

password-hash {sha}
allow bind_v2

在這個設定檔的 suffix 必須更新為與在 /usr/local/etc/openldap/ldap.confrootdn 使用的 BASE 相同。rootdn 建議的值為 cn=Manager。在儲存這個檔案之前,將 rootpw 放到由 slappasswd 產生的密碼之前,然後刪除原有的 rootpw。最後的結果應該如下:

TLSCipherSuite HIGH:MEDIUM:+SSLv3
TLSCertificateFile /usr/local/etc/openldap/server.crt
TLSCertificateKeyFile /usr/local/etc/openldap/private/server.key
TLSCACertificateFile /usr/local/etc/openldap/ca.crt
rootpw  {SHA}W6ph5Mm5Pz8GgiULbPgzG37mj9g=

最後,在 /etc/rc.conf 開啟 OpenLDAP 服務並設定 URI

slapd_enable="YES"
slapd_flags="-4 -h ldaps:///"

此時便可啟動並測試伺服器:

# service slapd start

若所有的設定均正確,搜尋目錄應會如此範例顯示成功連線並有一筆回應:

# ldapsearch -Z
# extended LDIF
#
# LDAPv3
# base <dc=example,dc=com> (default) with scope subtree
# filter: (objectclass=*)
# requesting: ALL
#

# search result
search: 3
result: 32 No such object

# numResponses: 1

注意:

若指令失敗且設定看起來沒有問題,可先停止 slapd 服務並開啟除錯選項並重新啟動:

# service slapd stop
# /usr/local/libexec/slapd -d -1

服務有回應之後,便可使用 ldapadd 匯入資料到目錄。在此例中,會先建立一個含有使用者清單的檔案,每位使用者應使用以下格式定義:

dn: dc=example,dc=com
objectclass: dcObject
objectclass: organization
o: Example
dc: Example

dn: cn=Manager,dc=example,dc=com
objectclass: organizationalRole
cn: Manager

要匯入這個檔案,可指定檔案名稱。以下指令會提示輸入先前設定過的密碼然後輸入如下的結果:

# ldapadd -Z -D "cn=Manager,dc=example,dc=com" -W -f import.ldif
Enter LDAP Password:
adding new entry "dc=example,dc=com"

adding new entry "cn=Manager,dc=example,dc=com"

使用 ldapsearch 發出一個查詢到伺服器來確認資料已新增:

% ldapsearch -Z
# extended LDIF
#
# LDAPv3
# base <dc=example,dc=com> (default) with scope subtree
# filter: (objectclass=*)
# requesting: ALL
#

# example.com
dn: dc=example,dc=com
objectClass: dcObject
objectClass: organization
o: Example
dc: Example

# Manager, example.com
dn: cn=Manager,dc=example,dc=com
objectClass: organizationalRole
cn: Manager

# search result
search: 3
result: 0 Success

# numResponses: 3
# numEntries: 2

此時,伺服器應已設定完成並可正常運作。

本文及其他文件,可由此下載: ftp://ftp.FreeBSD.org/pub/FreeBSD/doc/

若有 FreeBSD 方面疑問,請先閱讀 FreeBSD 相關文件,如不能解決的話,再洽詢 <questions@FreeBSD.org>。

關於本文件的問題,請洽詢 <doc@FreeBSD.org>。