輕量級目錄存取協定 (Lightweight Directory Access Protocol, LDAP) 是一個利用分散式目錄資訊服務來做到存取、修改與認証物件的應用層通訊協定,可以想像成是一本可以儲存數個階層、同質資訊的電話簿或記錄簿。它用在 Active Directory 及 OpenLDAP 網路,允許使用者利用一個帳號來存取數個階層的內部資訊,例如:電子郵件認証、取得員工聯絡資訊及內部網站的認証皆可使用 LDAP 伺服器資料庫中的單一使用者帳號來存取。
本章節將介紹在 FreeBSD 系統上如何快速的設定一個 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
找到。
FreeBSD 並未提供內建的 LDAP 伺服器,要開始設定前請先安裝 net/openldap-server 套件或 Port:
#
pkg install openldap-server
在套件中已開啟了許多的預設選項,可以透過執行 pkg info openldap-server
來查看已開啟的選項,若有不足的地方 (例如需要開啟 SQL 的支援),請考慮使用適當的方式重新編譯該 Port。
安裝程序會建立目錄 /var/db/openldap-data
來儲存資料,同時需要建立儲存憑證的目錄:
#
mkdir /usr/local/etc/openldap/private
接下來是設定憑証機構 (Certificate authority)。以下指令必須在 /usr/local/etc/openldap/private
下執行,這很重要是由於檔案權限須要被限制且其他使用者不應有這些檔案的存取權限,更多有關憑証的詳細資訊以及相關的參數可在 節 13.6, “OpenSSL” 中找到。要建立憑証授權,需先輸人這個指令並依提示操作:
#
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
屬性設定正確。憑証簽署請求 (Certificate Signing Request) 必須經過憑証機構簽署後才會成為有效的憑証:
#
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 個新檔案。
OpenLDAP 伺服器所執行的 Daemon 為 slapd
,OpenLDAP 是透過 slapd.ldif
來做設定, OpenLDAP 官方已停止採用舊的 slapd.conf
格式。
這裡有些 slapd.ldif
的 設定檔範例 可以使用,同時您也可以在 /usr/local/etc/openldap/slapd.ldif.sample
找到範例資訊。相關可用的選項在 slapd-config(5) 文件會有說明。slapd.ldif
的每個段落,如同其他 LDAP 屬性設定一樣會透過獨一無二 DN 來辨識,並請確保 dn:
描述與其相關屬性之間沒有空行。以下的範例中會實作一個使用 TLS 的安全通道,首先是全域的設定:
#
# See slapd-config(5) for details on configuration options.
# This file should NOT be world readable.
#
dn: cn=config
objectClass: olcGlobal
cn: config
#
#
# Define global ACLs to disable default read access.
#
olcArgsFile: /var/run/openldap/slapd.args
olcPidFile: /var/run/openldap/slapd.pid
olcTLSCertificateFile: /usr/local/etc/openldap/server.crt
olcTLSCertificateKeyFile: /usr/local/etc/openldap/private/server.key
olcTLSCACertificateFile: /usr/local/etc/openldap/ca.crt
#olcTLSCipherSuite: HIGH
olcTLSProtocolMin: 3.1
olcTLSVerifyClient: never
這個檔案中必須指定憑証機構 (Certificate Authority)、伺服器憑証 (Server Certificate) 與伺服器私鑰 (Server Private Key),建議可讓客戶端決定使用的安全密碼 (Security Cipher),略過 olcTLSCipherSuite
選項 (此選項不相容 openssl
以外的 TLS 客戶端)。選項 olcTLSProtocolMin
讓伺服器可要求一個安全等級的最低限度,建議使用。伺服器有進行驗証的必要,但客戶端並不需要,因此可設定 olcTLSVerifyClient: never
。
第二個部份是設定後端要採用的模組有那些,可使用以下方式設定:
#
# Load dynamic backend modules:
#
dn: cn=module,cn=config
objectClass: olcModuleList
cn: module
olcModulepath: /usr/local/libexec/openldap
olcModuleload: back_mdb.la
#olcModuleload: back_bdb.la
#olcModuleload: back_hdb.la
#olcModuleload: back_ldap.la
#olcModuleload: back_passwd.la
#olcModuleload: back_shell.la
第三個部份要載入資料庫所需的 ldif
綱要 (Schema),這個動作是必要的。
dn: cn=schema,cn=config
objectClass: olcSchemaConfig
cn: schema
include: file:///usr/local/etc/openldap/schema/core.ldif
include: file:///usr/local/etc/openldap/schema/cosine.ldif
include: file:///usr/local/etc/openldap/schema/inetorgperson.ldif
include: file:///usr/local/etc/openldap/schema/nis.ldif
接下來是前端設定的部份:
# Frontend settings
#
dn: olcDatabase={-1}frontend,cn=config
objectClass: olcDatabaseConfig
objectClass: olcFrontendConfig
olcDatabase: {-1}frontend
olcAccess: to * by * read
#
# Sample global access control policy:
# Root DSE: allow anyone to read it
# Subschema (sub)entry DSE: allow anyone to read it
# Other DSEs:
# Allow self write access
# Allow authenticated users read access
# Allow anonymous users to authenticate
#
#olcAccess: to dn.base="" by * read
#olcAccess: to dn.base="cn=Subschema" by * read
#olcAccess: to *
# by self write
# by users read
# by anonymous auth
#
# if no access controls are present, the default policy
# allows anyone and everyone to read anything but restricts
# updates to rootdn. (e.g., "access to * by * read")
#
# rootdn can always read and write EVERYTHING!
#
olcPasswordHash: {SSHA}
# {SSHA} is already the default for olcPasswordHash
再來是設定後端的部份,之後唯一能夠存取 OpenLDAP 伺服器設定的方式是使用全域超級使用者。
dn: olcDatabase={0}config,cn=config
objectClass: olcDatabaseConfig
olcDatabase: {0}config
olcAccess: to * by * none
olcRootPW: {SSHA}iae+lrQZILpiUdf16Z9KmDmSwT77Dj4U
預設的管理者使用者名稱是 cn=config
,可在 Shell 中輸入 slappasswd
,決定要使用的密碼並將其產生的編碼放到 olcRootPW
欄位中。若這個選項在這時沒有設定好,在匯入 slapd.ldif
之後將沒有任何人有辦法修改全域的設定。
最後一個部份是有關資料庫後端的設定:
#######################################################################
# LMDB database definitions
#######################################################################
#
dn: olcDatabase=mdb,cn=config
objectClass: olcDatabaseConfig
objectClass: olcMdbConfig
olcDatabase: mdb
olcDbMaxSize: 1073741824
olcSuffix: dc=domain,dc=example
olcRootDN: cn=mdbadmin,dc=domain,dc=example
# Cleartext passwords, especially for the rootdn, should
# be avoided. See slappasswd(8) and slapd-config(5) for details.
# Use of strong authentication encouraged.
olcRootPW: {SSHA}X2wHvIWDk6G76CQyCMS1vDCvtICWgn0+
# The database directory MUST exist prior to running slapd AND
# should only be accessible by the slapd and slap tools.
# Mode 700 recommended.
olcDbDirectory: /var/db/openldap-data
# Indices to maintain
olcDbIndex: objectClass eq
這裡指定的資料庫即實際用來保存 LDAP 目錄的資料,也可以使用 mdb
以外的項目,資料庫的超級使用者可在這裡設定 (與全域的超級使用者是不同的東西):olcRootDN
需填寫使用者名稱 (可自訂),olcRootPW
需填寫該使用者編碼後的密碼,將密碼編碼可使用 slappasswd
如同前面所述。
這裡有個檔案庫內有四個 slapd.ldif
的範例,要將現有的 slapd.conf
轉換成 slapd.ldif
格式,可參考此頁 (注意,這裡面的說明也會介紹一些不常用的選項)。
當設定完成之後,需將 slapd.ldif
放在一個空的目錄當中,建議如以下方式建立:
#
mkdir /usr/local/etc/openldap/slapd.d/
匯入設定資料庫:
#
/usr/local/sbin/slapadd -n0 -F /usr/local/etc/openldap/slapd.d/ -l /usr/local/etc/openldap/slapd.ldif
啟動 slapd
Daemon:
#
/usr/local/libexec/slapd -F /usr/local/etc/openldap/slapd.d/
選項 -d
可以用來除錯使用,如同 slapd(8) 中所說明的,若要檢驗伺服器是否正常執行與運作可以:
#
ldapsearch -x -b '' -s base '(objectclass=*)' namingContexts
# extended LDIF
#
# LDAPv3
# base <> with scope baseObject
# filter: (objectclass=*)
# requesting: namingContexts
#
#
dn:
namingContexts: dc=domain,dc=example
# search result
search: 2
result: 0 Success
# numResponses: 2
# numEntries: 1
伺服器端仍必須受到信任,若在此之前未做過這個動作,請依照以下指示操作。安裝 OpenSSL 套件或 Port:
#
pkg install openssl
進入 ca.crt
所在的目錄 (以這邊使用的例子來說則是 /usr/local/etc/openldap
),執行:
#
c_rehash .
現在 CA 與伺服器憑証可以依其用途被辨識,可進入 server.crt
所在的目錄執行以下指令來檢查:
#
openssl verify -verbose -CApath . server.crt
若 slapd
已正在執行,就重新啟動它。如同 /usr/local/etc/rc.d/slapd
所述,要讓 slapd
開機時可正常執行,須要加入以下行到 /etc/rc.conf
:
lapd_enable="YES"
slapd_flags='-h "ldapi://%2fvar%2frun%2fopenldap%2fldapi/
ldap://0.0.0.0/"'
slapd_sockets="/var/run/openldap/ldapi"
slapd_cn_config="YES"
開機啟動 slapd
並不會提供除錯的功能,您可以檢查 /var/log/debug.log
, dmesg -a
及 /var/log/messages
檢確認是否有正常運作。
以下範例會新增群組 team
及使用者 john
到 domain.example
LDAP 資料庫,而該資料庫目前是空的。首先要先建立 domain.ldif
檔:
#
cat domain.ldif
dn: dc=domain,dc=example
objectClass: dcObject
objectClass: organization
o: domain.example
dc: domain
dn: ou=groups,dc=domain,dc=example
objectClass: top
objectClass: organizationalunit
ou: groups
dn: ou=users,dc=domain,dc=example
objectClass: top
objectClass: organizationalunit
ou: users
dn: cn=team,ou=groups,dc=domain,dc=example
objectClass: top
objectClass: posixGroup
cn: team
gidNumber: 10001
dn: uid=john,ou=users,dc=domain,dc=example
objectClass: top
objectClass: account
objectClass: posixAccount
objectClass: shadowAccount
cn: John McUser
uid: john
uidNumber: 10001
gidNumber: 10001
homeDirectory: /home/john/
loginShell: /usr/bin/bash
userPassword: secret
請查看 OpenLDAP 說明文件取得更詳細的資訊,使用 slappasswd
來將純文字的密碼 secret
更改為已編碼的型式來填寫 userPassword
欄位。在 loginShell
所指定的路徑,必須在所有可讓 john
登入的系統中存在。最後是使用 mdb
管理者修改資料庫:
#
ldapadd -W -D "cn=mdbadmin,dc=domain,dc=example" -f domain.ldif
要修改全域設定只能使用全域的超及使用者。例如,假設一開始採用了 olcTLSCipherSuite: HIGH:MEDIUM:SSLv3
選項,但最後想要把它移除,可以建立一個有以下內容的檔案:
#
cat global_mod
dn: cn=config
changetype: modify
delete: olcTLSCipherSuite
然後套用修改內容:
#
ldapmodify -f global_mod -x -D "cn=config" -W
當提示輸入密碼時,提供當時在設定後端一節所設定的密碼,在這裡無須填寫使用者名稱,cn=config
代表要修改資料庫資料的位置。也可以使用 ldapmodify
刪除其中一行屬性,或是 ldapdelete
刪除整筆資料。
若有問題無法正常執行,或是全域的超級使用者無法存取後端的設定,可以刪除並重建整個後端設定:
#
rm -rf /usr/local/etc/openldap/slapd.d/
可以修改 slapd.ldif
後再重新匯入一次。請注意,這個步驟只在沒有其他方式可用時才使用。
本章節的設定說明只針對伺服器端的部份,在同一台主機中也可以同時有安裝 LDAP 客戶端但需要額外做設定。
本文及其他文件,可由此下載: ftp://ftp.FreeBSD.org/pub/FreeBSD/doc/。
若有 FreeBSD 方面疑問,請先閱讀
FreeBSD 相關文件,如不能解決的話,再洽詢
<questions@FreeBSD.org>。
關於本文件的問題,請洽詢
<doc@FreeBSD.org>。