Ubuntu(14.04)OpenLDAP伺服器(官方文件)
輕量目錄訪問協議(LDAP),是一個執行在TCP/IP協議的查詢和修改基於X.500目錄服務的協議。當前LDAP的版本為LDAPv3,定義在RFC4510中,在Ubuntu中的實現是OpenLDAP。
所以LDAP協議訪問LDAP目錄,這裡有一些主要的概念和說明:
- 一個LDAP目錄是樹狀的entries(條目)並且是按性質進行分層的,稱為目錄資訊樹(DIT)。
- 一個條目包含一系列的attributes(屬性)。
- 一個屬性有一個型別描述(名字/描述)並且有一個或多個值。
- 每個屬性必須被至少一個objectClass(物件型別)所定義。
- 屬性和物件型別被定義在schemas(模式)中(一個objectclass被認為是一個特殊的attribute)。
- 每個實體有一個唯一的id:叫做Distinguished Name(DN or dn),它由相對的Distinguished Name(RDN)從父條目依次排列組成。
- 條目的DN不是一個屬性,它不被認為是條目的一部分。
object, container, 和 node這些屬於有一定自己的含義,但是基本上和entry在技術上描述的是同一個東西。
例如,下面我們有一個真實的條目,它由11個屬性組成:
- DN 是 “cn=John Doe,dc=example,dc=com”
- RDN 是 “cn=John Doe”
- 父 DN 是 “dc=example,dc=com”
dn : cn=John Doe,dc=example,dc=com
cn: John Doe
givenName: John
sn: Doe
telephoneNumber: +1 888 555 6789
telephoneNumber: +1 888 555 1232
mail: [email protected]
manager: cn=Larry Smith,dc=example,dc=com
objectClass: inetOrgPerson
objectClass: organizationalPerson
objectClass: person
objectClass : top
以上是LDIF格式(LDAP資料交換格式)的條目。任何你想要傳輸進你的DIT(目錄資訊樹)的資訊也必須是這樣的格式。它被定義在RFC2849。
雖然本指南將介紹如何使用它做中央認證,但是在涉及到大量讀請求、基於屬性(name:value)的後端應用他都很不錯。例子包括一個地址簿,一個電子郵件地址列表,和一個郵件伺服器的配置。
安裝
分別使用slapd和ldap-utils包,來安裝OpenLDAP服務程序和傳統的LDAP管理工具。
slapd的安裝會建立一個工作設定。特別地,它將建立一個數據庫實體用來儲存你的資料。但是,這個例項的字尾(或者叫base DN)將被定義成主機的域名。如果你想它不一樣,配置/etc/hosts並把域名替換成你想要的字尾名。比如,如果你想要字尾名是dc=example,dc=com,那麼你的host檔案應該像這樣:
127.0.1.1 hostname.example.com hostname
你可以恢復這些修改,在包安裝之後。
這次的指導將會使用dc=example,dc=com這個資料庫字尾。
繼續安裝:
sudo apt-get install slapd ldap-utils
從Ubuntu 8.10開始,slapd被設計成在他內部配置,通過建立一個獨立DIT(目錄資訊樹)的來達到這個目的。這就使得我們可以動態地配置slapd而不需要重啟服務。配置資料庫由一系列在/etc/ldap/slapd.d資料夾下的LDIF文字檔案組成。這種工作方式有好幾種名字: slapd-config方式、RTC方式(Real Time Configuration)、或者cn=config方式。你可以仍然實用傳統的flat-file方式(slapd.conf)但是不推薦你這樣。這個功能最後將被淘汰。
tips:Ubuntu 現在使用slapd-config的方式來配置slapd,本指南同樣使用。
在安裝的過程中,你將被提示定義管理憑證。這些是你資料庫實體的rootDN的LDAP-based憑證。預設情況下,使用者的DN是cn=admin,dc=example,dc=com。當然,預設地不會為slapd-config資料庫建立管理帳號。所以你需要從外部認證LDAP來訪問它。我們在接下來的文章中將展示如何做這個認證。
現在一些經典的schemas(cosine, nis, inetorgperson)被內建在slapd中。包括“core”schema,它是其他任何schema工作的先決條件。
安裝後的檢查
安裝過程需要設定兩個DIT。一個是slapd-config另一個是你自己的資料(dc=example,dc=com)。讓我們來看看。
slapd-config資料庫/DIT看起來像這樣。回想一下,這個資料庫是LDIF-based的,並且在/etc/ldap/slapd.d資料夾下:
/etc/ldap/slapd.d/ /etc/ldap/slapd.d/cn=config /etc/ldap/slapd.d/cn=config/cn=module{0}.ldif /etc/ldap/slapd.d/cn=config/cn=schema /etc/ldap/slapd.d/cn=config/cn=schema/cn={0}core.ldif /etc/ldap/slapd.d/cn=config/cn=schema/cn={1}cosine.ldif /etc/ldap/slapd.d/cn=config/cn=schema/cn={2}nis.ldif /etc/ldap/slapd.d/cn=config/cn=schema/cn={3}inetorgperson.ldif /etc/ldap/slapd.d/cn=config/cn=schema.ldif /etc/ldap/slapd.d/cn=config/olcBackend={0}hdb.ldif /etc/ldap/slapd.d/cn=config/olcDatabase={0}config.ldif /etc/ldap/slapd.d/cn=config/olcDatabase={-1}frontend.ldif /etc/ldap/slapd.d/cn=config/olcDatabase={1}hdb.ldif /etc/ldap/slapd.d/cn=config.ldif
tips:不要直接修改slapd-config資料庫。通過LDAP協議(工具)修改。
通過LDAP協議,slapd-config DIT看起來像這樣:
注意,在Ubuntu伺服器14.10或更高的版本,這個命令可能不能使用了,因為這個bug。
sudo ldapsearch -Q -LLL -Y EXTERNAL -H ldapi:/// -b cn=config dn dn: cn=config dn: cn=module{0},cn=config dn: cn=schema,cn=config dn: cn={0}core,cn=schema,cn=config dn: cn={1}cosine,cn=schema,cn=config dn: cn={2}nis,cn=schema,cn=config dn: cn={3}inetorgperson,cn=schema,cn=config dn: olcBackend={0}hdb,cn=config dn: olcDatabase={-1}frontend,cn=config dn: olcDatabase={0}config,cn=config dn: olcDatabase={1}hdb,cn=config
這些條目的解釋:
cn=config: 全域性設定
cn=module{0},cn=config: a dynamically loaded module
cn=schema,cn=config: contains hard-coded system-level schema
cn={0}core,cn=schema,cn=config: the hard-coded core schema
cn={1}cosine,cn=schema,cn=config: the cosine schema
cn={2}nis,cn=schema,cn=config: the nis schema
cn={3}inetorgperson,cn=schema,cn=config: the inetorgperson schema
olcBackend={0}hdb,cn=config: the ‘hdb’ backend storage type
olcDatabase={-1}frontend,cn=config: frontend database, default settings for other databases
olcDatabase={0}config,cn=config: slapd configuration database (cn=config)
olcDatabase={1}hdb,cn=config: your database instance (dc=examle,dc=com)
dc=example,dc=com DIT看起來像這樣:
ldapsearch -x -LLL -H ldap:/// -b dc=example,dc=com dn dn: dc=example,dc=com dn: cn=admin,dc=example,dc=com
實體的解釋:
- dc=example,dc=com: base of the DIT
- cn=admin,dc=example,dc=com: administrator (rootDN) for this DIT (set up during package install)
修改/填充您的資料庫
讓我們介紹下我們的的資料庫的內容。我們將加入如下內容:
1. 一個叫做People的節點(用來存放users)
2. 一個叫做Group的節點(用來存放groups)
3. 一個組叫做miners
4. 一個使用者叫做john
建立下面的LDIF檔案,並叫做add_content.ldif:
dn: ou=People,dc=example,dc=com
objectClass: organizationalUnit
ou: People
dn: ou=Groups,dc=example,dc=com
objectClass: organizationalUnit
ou: Groups
dn: cn=miners,ou=Groups,dc=example,dc=com
objectClass: posixGroup
cn: miners
gidNumber: 5000
dn: uid=john,ou=People,dc=example,dc=com
objectClass: inetOrgPerson
objectClass: posixAccount
objectClass: shadowAccount
uid: john
sn: Doe
givenName: John
cn: John Doe
displayName: John Doe
uidNumber: 10000
gidNumber: 5000
userPassword: johnldap
gecos: John Doe
loginShell: /bin/bash
homeDirectory: /home/john
tips:在你的目錄中的uid和gid的值不與本地值衝突是很重要的。使用比較高的數值範圍,比如從5000開始。通過在ldap中設定較高的uid和gid值,允許你更容易地控制本地使用者和ldap使用者。後面有更多關於它的內容。
新增內容:
ldapadd -x -D cn=admin,dc=example,dc=com -W -f add_content.ldif
Enter LDAP Password: ********
adding new entry "ou=People,dc=example,dc=com"
adding new entry "ou=Groups,dc=example,dc=com"
adding new entry "cn=miners,ou=Groups,dc=example,dc=com"
adding new entry "uid=john,ou=People,dc=example,dc=com"
你使用ldapsearch功能檢查這些資訊是否正確:
ldapsearch -x -LLL -b dc=example,dc=com 'uid=john' cn gidNumber
dn: uid=john,ou=People,dc=example,dc=com
cn: John Doe
gidNumber: 5000
開關的解釋:
-x: “simple” binding; will not use the default SASL method
-LLL: disable printing extraneous information
uid=john: a “filter” to find the john user
cn gidNumber: requests certain attributes to be displayed (the default is to show all attributes)
修改slapd配置資料庫
slapd-config DIT(目錄資訊數)可以被查詢和修改。下面是一些例子。
使用ldapmodify 新增一個”Index” 給你的{1}hdb,cn=config 資料庫(dc=example,dc=com)。用以下內容建立一個檔案,取名叫uid_index.ldif:
dn: olcDatabase={1}hdb,cn=config add: olcDbIndex olcDbIndex: uid eq,pres,sub
然後執行下面的命令:
sudo ldapmodify -Q -Y EXTERNAL -H ldapi:/// -f uid_index.ldif modifying entry "olcDatabase={1}hdb,cn=config"
你可以用以下方式確認變化:
sudo ldapsearch -Q -LLL -Y EXTERNAL -H ldapi:/// -b \ cn=config '(olcDatabase={1}hdb)' olcDbIndex dn: olcDatabase={1}hdb,cn=config olcDbIndex: objectClass eq olcDbIndex: uid eq,pres,sub
讓我們新增一個schema.它首先需要轉換為ldif格式。你可以在/etc/ldap/schema目錄中找到除了已經被轉換的schemas還有未被轉換的schemas。
- 通常不要從slapd-config資料庫刪除schema。在測試系統增加一個schemas進行練習。
在增加任何schema之前,你應該檢查哪些schemas已經被安裝了(顯示是一個預設的輸出框的輸出)。
sudo ldapsearch -Q -LLL -Y EXTERNAL -H ldapi:/// -b \
cn=schema,cn=config dndn: cn=schema,cn=config
dn: cn={0}core,cn=schema,cn=config
dn: cn={1}cosine,cn=schema,cn=config
dn: cn={2}nis,cn=schema,cn=config
dn: cn={3}inetorgperson,cn=schema,cn=config
- 通常不要從slapd-config資料庫刪除schema。在測試系統增加一個schemas進行練習。
建立轉換配置檔案schema_convert.conf包含下面的行:
include /etc/ldap/schema/core.schema include /etc/ldap/schema/collective.schema include /etc/ldap/schema/corba.schema include /etc/ldap/schema/cosine.schema include /etc/ldap/schema/duaconf.schema include /etc/ldap/schema/dyngroup.schema include /etc/ldap/schema/inetorgperson.schema include /etc/ldap/schema/java.schema include /etc/ldap/schema/misc.schema include /etc/ldap/schema/nis.schema include /etc/ldap/schema/openldap.schema include /etc/ldap/schema/ppolicy.schema include /etc/ldap/schema/ldapns.schema include /etc/ldap/schema/pmi.schema
- 建立輸出資料夾ldif_output。
定義schema的index:
slapcat -f schema_convert.conf -F ldif_output -n 0 | grep corba,cn=schema cn={1}corba,cn=schema,cn=config
tips:當slapd提取相同父DN的物件時。它會建立物件的index,index包含在括弧中:{x}。
使用slapcat來執行轉換:
slapcat -f schema_convert.conf -F ldif_output -n0 -H \ ldap:///cn={1}corba,cn=schema,cn=config -l cn=corba.ldif
轉換後的schema現在在cn=corba.ldif中。
編輯Edit cn=corba.ldif來達到以下的屬性:
dn: cn=corba,cn=schema,cn=config ... cn: corba
同時移除底下的如下所示的行:
structuralObjectClass: olcSchemaConfig entryUUID: 52109a02-66ab-1030-8be2-bbf166230478 creatorsName: cn=config createTimestamp: 20110829165435Z entryCSN: 20110829165435.935248Z#000000#000#000000 modifiersName: cn=config modifyTimestamp: 20110829165435Z
你的屬性值可能有不同。
最後,使用ldapadd功能新增新的schema到slapd-config DIT:
sudo ldapadd -Q -Y EXTERNAL -H ldapi:/// -f cn\=corba.ldif adding new entry "cn=corba,cn=schema,cn=config"
確認現在被載入的schemas:
sudo ldapsearch -Q -LLL -Y EXTERNAL -H ldapi:/// -b cn=schema,cn=config dn dn: cn=schema,cn=config dn: cn={0}core,cn=schema,cn=config dn: cn={1}cosine,cn=schema,cn=config dn: cn={2}nis,cn=schema,cn=config dn: cn={3}inetorgperson,cn=schema,cn=config dn: cn={4}corba,cn=schema,cn=config
外部應用程式和客戶端使用LDAP進行身份驗證,都需要特別的配置。詳細內容請參考合適的客戶端文件。
日誌
當實施一個基於OpenLDAP的解決方案時,為slapd做日誌的活動是很有必要的,但是,它需要在軟體安裝之後手動啟動。否則,只有基本的資訊將會出現在log中,就像其他slapd配置,它可以通過slapd-config資料庫啟動。
OpenLDAP有許多日誌子系統(級別),每個級別都包含較弱級別的內容(遞增的)。一個好的級別嘗試是stats。在slapd-config主頁上有關於各個級別的更詳細的說明。
建立logging.ldif檔案,包含下面內容:
dn: cn=config
changetype: modify
replace: olcLogLevel
olcLogLevel: stats
實施這個改變:
sudo ldapmodify -Q -Y EXTERNAL -H ldapi:/// -f logging.ldif
一旦你的系統在生產環境中,這將會產生大量的日誌,你將會想要回到一個更少日誌的級別。當你在這種冗長的模式中,你的主機日誌引擎(rsyslog)可能會比較難維持,並且可能丟失資訊。
rsyslogd-2177: imuxsock lost 228 messages from pid 2547 due to rate-limiting
你將考慮修改rsyslog的配置。在/etc/rsyslog.conf中,輸入:
# Disable rate limiting
# (default is 200 messages in 5 seconds; below we make the 5 become 0)
$SystemLogRateLimitInterval 0
然後重啟rsyslog程序:
sudo service rsyslog restart
複製
LDAP服務變得越來越重要,是因為更多的網路系統開始依賴它。在這樣的環境中,一個標準的實踐是在LDAP中建立冗餘(高可用)來防止LDAP伺服器變得不可響應帶來的浩劫。這通過LDAP複製(replication)來實現。
複製通過Syncrepl引擎完成。這允許使用消費者/生產者模型同步更改。我們將在這次指南中實施的這種特殊方式的備份是下面模式的組合:refreshAndPersist和delta-syncrepl。每當修改產生時,生產者就會推送修改實體給消費者,但是,只有實際的修改才會被髮送,而不是所有的實體。
提供者配置
從配置提供者開始。
建立一個包含以下內容的LDIF檔案,並命名為provider_sync.ldif:
# Add indexes to the frontend db. dn: olcDatabase={1}hdb,cn=config changetype: modify add: olcDbIndex olcDbIndex: entryCSN eq - add: olcDbIndex olcDbIndex: entryUUID eq #Load the syncprov and accesslog modules. dn: cn=module{0},cn=config changetype: modify add: olcModuleLoad olcModuleLoad: syncprov - add: olcModuleLoad olcModuleLoad: accesslog # Accesslog database definitions dn: olcDatabase={2}hdb,cn=config objectClass: olcDatabaseConfig objectClass: olcHdbConfig olcDatabase: {2}hdb olcDbDirectory: /var/lib/ldap/accesslog olcSuffix: cn=accesslog olcRootDN: cn=admin,dc=example,dc=com olcDbIndex: default eq olcDbIndex: entryCSN,objectClass,reqEnd,reqResult,reqStart # Accesslog db syncprov. dn: olcOverlay=syncprov,olcDatabase={2}hdb,cn=config changetype: add objectClass: olcOverlayConfig objectClass: olcSyncProvConfig olcOverlay: syncprov olcSpNoPresent: TRUE olcSpReloadHint: TRUE # syncrepl Provider for primary db dn: olcOverlay=syncprov,olcDatabase={1}hdb,cn=config changetype: add objectClass: olcOverlayConfig objectClass: olcSyncProvConfig olcOverlay: syncprov olcSpNoPresent: TRUE # accesslog overlay definitions for primary db dn: olcOverlay=accesslog,olcDatabase={1}hdb,cn=config objectClass: olcOverlayConfig objectClass: olcAccessLogConfig olcOverlay: accesslog olcAccessLogDB: cn=accesslog olcAccessLogOps: writes olcAccessLogSuccess: TRUE # scan the accesslog DB every day, and purge entries older than 7 days olcAccessLogPurge: 07+00:00 01+00:00
在檔案中修改rootDN來匹配你的目錄的rootDN。
slapd的apparmor檔案將不需要為訪問日誌資料庫做調整,當/etc/apparmor.d/local/usr.sbin.slapd中包含 :
/var/lib/ldap/ r, /var/lib/ldap/** rwk,
建立一個目錄,設定一個數據庫配置檔案,並重新載入apparmor檔案:
sudo -u openldap mkdir /var/lib/ldap/accesslog sudo -u openldap cp /var/lib/ldap/DB_CONFIG /var/lib/ldap/accesslog sudo service apparmor reload
由於apparmor改變,增加新的內容,並重啟程序:
sudo ldapadd -Q -Y EXTERNAL -H ldapi:/// -f provider_sync.ldif sudo service slapd restart
現在,提供者配置好了。
消費者配置
現在,配置消費者。
安裝軟體,參考上面的安裝部分。保證slapd-config資料庫和提供者的是相同的。特別的,確保schemas和數 據庫字尾相同。
建立一個LDIF檔案包含如下內容,並命名為consumer_sync.ldif:
dn: cn=module{0},cn=config changetype: modify add: olcModuleLoad olcModuleLoad: syncprov dn: olcDatabase={1}hdb,cn=config changetype: modify add: olcDbIndex olcDbIndex: entryUUID eq - add: olcSyncRepl olcSyncRepl: rid=0 provider=ldap://ldap01.example.com bindmethod=simple binddn="cn=admin,dc=example,dc=com" credentials=secret searchbase="dc=example,dc=com" logbase="cn=accesslog" logfilter="(&(objectClass=auditWriteObject)(reqResult=0))" schemachecking=on type=refreshAndPersist retry="60 +" syncdata=accesslog - add: olcUpdateRef olcUpdateRef: ldap://ldap01.example.com
保證下面的屬性擁有正確的值:
provider (Provider伺服器的名字 – ldap01.example.com 在本例中中 – 或者IP地址)
binddn (你正在使用的管理員DN)
credentials (管理員DN的密碼)
searchbase (資料庫字尾)
olcUpdateRef (Provider伺服器的主機名或者ip地址)
rid (複製ID, 一個唯一的3為標誌來區別這個複製。每個消費者都應該至少有一個rid)
增加新的內容:
sudo ldapadd -Q -Y EXTERNAL -H ldapi:/// -f consumer_sync.ldif
完成,現在兩個資料庫應該是同步的(字尾:dc=example,dc=com)。
測試
一旦複製開始,你就可以監視它,通過執行:
ldapsearch -z1 -LLLQY EXTERNAL -H ldapi:/// -s base -b dc=example,dc=com contextCSN
dn: dc=example,dc=com
contextCSN: 20120201193408.178454Z#000000#000#000000
在提供者和消費者兩端。一旦輸出(20120201193408.178454Z#000000#000#000000 in the above example) 兩邊 的機器都匹配的話,就表示複製成功了。每次在提供者端資料改變,在消費者端會做出相同的改變。
如果你的連線比較慢,或者(並且)你的ldap資料庫比較大的話,消費者的contextCSN匹配提供者,可能需要花 費一點的時間。但是你將會知道它正在執行,因為消費者的contextCSN將會穩定增長。
一旦消費者的contextCSN丟失,或者沒有匹配提供者,你應該在繼續前停止並找出問題。嘗試檢查消費者主機的 slapd(日誌)和使用者的日誌檔案,檢視是不是消費者的認證成功了或者它的請求資料的請求(他們看起來像很 多ldapsearch報表)沒有錯誤。
訪問控制
使用者應該被賦予什麼樣的許可權(讀,寫等等)的管理被稱為訪問控制。被涉及的配置指令被稱為訪問控制列表或者ACL。
當我們安裝slapd包時,各種ACL已經被自動地設定。我們將看一些重要的預設配置,這樣做,我們將知道ACL是怎麼工作的和我們是如何配置的。
為了獲得一個有效的LDAP查詢使用的ACL,我們需要檢視被查詢的資料庫的ACL實體以及那些特殊的前端資料庫例項。ACL屬於後者作為預設值,假使前者不匹配。前端資料庫是第二個被諮詢的,並且在兩個ACL資源中將被應用的ACL是第一個匹配項(先匹配的生效)。下面的命令將各自給hdb資料庫 (“dc=example,dc=com”)的ACL和那些前端資料庫。
sudo ldapsearch -Q -LLL -Y EXTERNAL -H ldapi:/// -b \
cn=config '(olcDatabase={1}hdb)' olcAccess
dn: olcDatabase={1}hdb,cn=config
olcAccess: {0}to attrs=userPassword,shadowLastChange by self write by anonymous
auth by dn="cn=admin,dc=example,dc=com" write by * none
olcAccess: {1}to dn.base="" by * read
olcAccess: {2}to * by self write by dn="cn=admin,dc=example,dc=com" write by *
read
tips:rootDN總是擁有對他的資料庫的所有許可權。在ACL中包含它確實提供了一個明確的配置,但是它也造成slapd引起效能的損失。
sudo ldapsearch -Q -LLL -Y EXTERNAL -H ldapi:/// -b \
cn=config '(olcDatabase={-1}frontend)' olcAccess
dn: olcDatabase={-1}frontend,cn=config
olcAccess: {0}to * by dn.exact=gidNumber=0+uidNumber=0,cn=peercred,
cn=external,cn=auth manage by * break
olcAccess: {1}to dn.exact="" by * read
olcAccess: {2}to dn.base="cn=Subschema" by * read
最先的ACL是至關重要的:
olcAccess: {0}to attrs=userPassword,shadowLastChange by self write by anonymous
auth by dn="cn=admin,dc=example,dc=com" write by * none
為了更容易消化這可能有不同的表現:
to attrs=userPassword
by self write
by anonymous auth
by dn="cn=admin,dc=example,dc=com" write
by * none
to attrs=shadowLastChange
by self write
by anonymous auth
by dn="cn=admin,dc=example,dc=com" write
by * none
這個混合的ACL(有兩個)強制了下面:
發生初始連結時,匿名認證訪問被userPassword屬性提供。也許是反直覺的,‘匿名認證’是需要的即使你們訪問DIT不需要。一旦遠端終端連線,認證就會發生(見下一點)。
認證可以發生是因為使用者對userPasword屬性有讀(因為“被自己寫”)的許可權。
userPassword屬性對其他使用者來說是沒必要的,除了rootDN,它對這個屬性有完全的許可權。
為了讓使用者更改自己的密碼,使用passwd或其他功能,shadowlastchange屬性需要可訪問一旦使用者被認證。
DIT可以被匿名搜尋因為在ACL中的”read”:
to *
by self write
by dn="cn=admin,dc=example,dc=com" write
by * read
如果這是不必要的那麼你需要更改ACL。你可以選擇性地(或與修改的ACL組合)使用 ‘olcRequire: authc’指令來在繫結請求時強制認證。
如前所述,沒有為slapd-config資料庫建立管理賬戶。但是,有一個SASL身份被授予許可權完全訪問它。它代表了本地主機的超級使用者(root/sudo)。它在這兒:
dn.exact=gidNumber=0+uidNumber=0,cn=peercred,cn=external,cn=auth
下面的命令將顯示slapd-config資料庫的ACL:
sudo ldapsearch -Q -LLL -Y EXTERNAL -H ldapi:/// -b \
cn=config '(olcDatabase={0}config)' olcAccess
dn: olcDatabase={0}config,cn=config
olcAccess: {0}to * by dn.exact=gidNumber=0+uidNumber=0,cn=peercred,
cn=external,cn=auth manage by * break
由於這是一個SASL身份,當呼叫考慮中的LDAP的工具時,我們需要使用SASL機制,並且我們在這本指南中看到它很多次。它是EXTERNAL機制。檢視前面的命令作為一個例子。請注意:
- 你必須使用sudo成為root身份來匹配ACL。
- EXTERNAL機制通過IPC工作(UNIX domain sockets)。這意味著你必須使用ldapi URI格式。
一個簡潔的方式來獲得所有的ACL是這樣的:
sudo ldapsearch -Q -LLL -Y EXTERNAL -H ldapi:/// -b \
cn=config '(olcAccess=*)' olcAccess olcSuffix
關於訪問控制的話題有很多話要說。請看slapd.access手冊頁。
TLS
當對一個OpenLDAP伺服器認證時,最好使用一個加密的session。這裡可以使用傳輸層安全(TLS)來完成。
這裡我們將是我們自己的證書頒發機構,如何建立並簽署我們自己的LDAP伺服器證書,叫做CA。由於slapd使用gnutls庫進行編譯,我們將使用certtool工具來完成這些任務。
安裝gnutls-bin和ssl-cert包:
sudo apt-get install gnutls-bin ssl-cert
為證書頒發機構建立私鑰:
sudo sh -c "certtool --generate-privkey > /etc/ssl/private/cakey.pem"
建立臨時檔案/etc/ssl/ca.info來定義CA:
cn = Example Company ca cert_signing_key
建立自己認證的CA證書:
sudo certtool --generate-self-signed \ --load-privkey /etc/ssl/private/cakey.pem \ --template /etc/ssl/ca.info \ --outfile /etc/ssl/certs/cacert.pem
為伺服器建立一個私鑰:
sudo certtool --generate-privkey \ --bits 1024 \ --outfile /etc/ssl/private/ldap01_slapd_key.pem
把檔名中的ldap01換成你的伺服器名。使用主機和服務來命名證書和金鑰對你清晰地使用它們會很有幫助。
建立/etc/ssl/ldap01.info資訊檔案包含:
organization = Example Company cn = ldap01.example.com tls_www_server encryption_key signing_key expiration_days = 3650
上述證書10年比較好,根據需要調整。
建立伺服器證書
sudo certtool --generate-certificate \ --load-privkey /etc/ssl/private/ldap01_slapd_key.pem \ --load-ca-certificate /etc/ssl/certs/cacert.pem \ --load-ca-privkey /etc/ssl/private/cakey.pem \ --template /etc/ssl/ldap01.info \ --outfile /etc/ssl/certs/ldap01_slapd_cert.pem
建立certinfo.ldif檔案包含下面的內容(根據需要調整,我們的示例假設我們建立的證書使用https://www.cacert.org)
dn: cn=config
add: olcTLSCACertificateFile
olcTLSCACertificateFile: /etc/ssl/certs/cacert.pem
-
add: olcTLSCertificateFile
olcTLSCertificateFile: /etc/ssl/certs/ldap01_slapd_cert.pem
-
add: olcTLSCertificateKeyFile
olcTLSCertificateKeyFile: /etc/ssl/private/ldap01_slapd_key.pem
使用ldapmodify命令來告訴slapd關於我們的TLS通過slapd-config資料庫:
sudo ldapmodify -Y EXTERNAL -H ldapi:/// -f /etc/ssl/certinfo.ldif
與常識相反,你在/etc/default/slapd不需要ldaps://來使用加密,你只需要:
SLAPD_SERVICES="ldap:/// ldapi:///"
在TLS/SSL(ldaps://)上的LDAP反對支援StartTLS。後者關於一個存在的LDAP會話(監聽在TCP 389埠)被TLS/SSL保護。 相反LDAPS,和HTTPS類似,是一個明確一開始就被加密的協議,它執行在TCP636埠。
加強所有權和許可權:
sudo adduser openldap ssl-cert
sudo chgrp ssl-cert /etc/ssl/private/ldap01_slapd_key.pem
sudo chmod g+r /etc/ssl/private/ldap01_slapd_key.pem
sudo chmod o-r /etc/ssl/private/ldap01_slapd_key.pem
重啟OpenLDAP:
sudo service slapd restart
檢查你的主機日誌(/var/log/syslog)看看是不是伺服器正常啟動了。
複製和TLS
如果你已經在兩個伺服器之間配置了複製,常見的做法是在複製傳輸間加密來防止偷聽。這和我們上面所做的使用認證加密是不同的。這節中我們將建立在TLS認證工作。
這裡我們假設你已經設定了消費者和提供者之間的複製,通過“複製”章節,並且配置了TLS認證在提供者,通過“TLS”章節。
如前所述,複製的目的是LDAP服務的高可用。既然我們在提供者上有TLS認證,那麼我們要求消費者同樣擁有。除此之外,但是,我們希望對複製流進行加密。仍然要做的是為消費者建立一個金鑰和證書,然後相應地配置。我們將在提供者上生成金鑰/證書,以避免必須建立另一個證書,然後將必要的材料轉移到消費者。
在提供者上,建立一個持久的目錄(這將用於可能的傳輸)和消費者私鑰:
mkdir ldap02-ssl cd ldap02-ssl sudo certtool --generate-privkey \ --bits 1024 \ --outfile ldap02_slapd_key.pem
建立一個資訊檔案,ldap02.info,為消費者伺服器,根據需求修改它的值:
organization = Example Company cn = ldap02.example.com tls_www_server encryption_key signing_key expiration_days = 3650
建立消費者證書:
sudo certtool --generate-certificate \ --load-privkey ldap02_slapd_key.pem \ --load-ca-certificate /etc/ssl/certs/cacert.pem \ --load-ca-privkey /etc/ssl/private/cakey.pem \ --template ldap02.info \ --outfile ldap02_slapd_cert.pem
複製CA證書:
cp /etc/ssl/certs/cacert.pem .
完成,現在把ldap02-ssl目錄傳輸給消費者。這裡我們使用scp(根據需要調整):
cd .. scp -r ldap02-ssl [email protected]:
在消費者上,配置TLS認證:
sudo apt-get install ssl-cert sudo adduser openldap ssl-cert sudo cp ldap02_slapd_cert.pem cacert.pem /etc/ssl/certs sudo cp ldap02_slapd_key.pem /etc/ssl/private sudo chgrp ssl-cert /etc/ssl/private/ldap02_slapd_key.pem sudo chmod g+r /etc/ssl/private/ldap02_slapd_key.pem sudo chmod o-r /etc/ssl/private/ldap02_slapd_key.pem
建立檔案 /etc/ssl/certinfo.ldif包含下面內容(根據需要調整):
dn: cn=config add: olcTLSCACertificateFile olcTLSCACertificateFile: /etc/ssl/certs/cacert.pem - add: olcTLSCertificateFile olcTLSCertificateFile: /etc/ssl/certs/ldap02_slapd_cert.pem - add: olcTLSCertificateKeyFile olcTLSCertificateKeyFile: /etc/ssl/private/ldap02_slapd_key.pem
配置slapd-config資料庫:
sudo ldapmodify -Y EXTERNAL -H ldapi:/// -f certinfo.ldif
配置 /etc/default/slapd 作為提供者(SLAPD_SERVICES)。
在消費者上,為Consumer-side複製配置TLS。通過在一些TLS選項上增加的方式修改現有的olcSyncrepl屬性。在這樣做時,我們將看到,第一次,如何改變屬性的值。
建立consumer_sync_tls.ldif檔案包含下面內容:
dn: olcDatabase={1}hdb,cn=config replace: olcSyncRepl olcSyncRepl: rid=0 provider=ldap://ldap01.example.com bindmethod=simple binddn="cn=admin,dc=example,dc=com" credentials=secret searchbase="dc=example,dc=com" logbase="cn=accesslog" logfilter="(&(objectClass=auditWriteObject)(reqResult=0))" schemachecking=on type=refreshAndPersist retry="60 +" syncdata=accesslog starttls=critical tls_reqcert=demand
額外的選項指定,分別地,消費者必須使用StartTLS,並且CA證書是需要的來核實提供者的省份。同時改變(‘替代’)屬性值的時候注意LDIF語法。
實施這些改變:
sudo ldapmodify -Y EXTERNAL -H ldapi:/// -f consumer_sync_tls.ldif
並且重啟slapd:
sudo service slapd restart
在提供者上,檢查TLS會話是不是已經被建立。在/var/log/syslog中,提供你的’conns’-level日誌設定,你應該看到類似如下的訊息:
slapd[3620]: conn=1047 fd=20 ACCEPT from IP=10.153.107.229:57922 (IP=0.0.0.0:389) slapd[3620]: conn=1047 op=0 EXT oid=1.3.6.1.4.1.1466.20037 slapd[3620]: conn=1047 op=0 STARTTLS slapd[3620]: conn=1047 op=0 RESULT oid= err=0 text= slapd[3620]: conn=1047 fd=20 TLS established tls_ssf=128 ssf=128 slapd[3620]: