1. 程式人生 > >Ubuntu(14.04)OpenLDAP伺服器(官方文件)

Ubuntu(14.04)OpenLDAP伺服器(官方文件)

輕量目錄訪問協議(LDAP),是一個執行在TCP/IP協議的查詢和修改基於X.500目錄服務的協議。當前LDAP的版本為LDAPv3,定義在RFC4510中,在Ubuntu中的實現是OpenLDAP。

所以LDAP協議訪問LDAP目錄,這裡有一些主要的概念和說明:

  1. 一個LDAP目錄是樹狀的entries(條目)並且是按性質進行分層的,稱為目錄資訊樹(DIT)。
  2. 一個條目包含一系列的attributes(屬性)。
  3. 一個屬性有一個型別描述(名字/描述)並且有一個或多個值。
  4. 每個屬性必須被至少一個objectClass(物件型別)所定義。
  5. 屬性和物件型別被定義在schemas(模式)中(一個objectclass被認為是一個特殊的attribute)。
  6. 每個實體有一個唯一的id:叫做Distinguished Name(DN or dn),它由相對的Distinguished Name(RDN)從父條目依次排列組成。
  7. 條目的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)。讓我們來看看。

  1. 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協議(工具)修改。

  2. 通過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

    這些條目的解釋:

    1. cn=config: 全域性設定

    2. cn=module{0},cn=config: a dynamically loaded module

    3. cn=schema,cn=config: contains hard-coded system-level schema

    4. cn={0}core,cn=schema,cn=config: the hard-coded core schema

    5. cn={1}cosine,cn=schema,cn=config: the cosine schema

    6. cn={2}nis,cn=schema,cn=config: the nis schema

    7. cn={3}inetorgperson,cn=schema,cn=config: the inetorgperson schema

    8. olcBackend={0}hdb,cn=config: the ‘hdb’ backend storage type

    9. olcDatabase={-1}frontend,cn=config: frontend database, default settings for other databases

    10. olcDatabase={0}config,cn=config: slapd configuration database (cn=config)

    11. olcDatabase={1}hdb,cn=config: your database instance (dc=examle,dc=com)

  3. 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

    實體的解釋:

    1. dc=example,dc=com: base of the DIT
    2. 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 

開關的解釋:

  1. -x: “simple” binding; will not use the default SASL method

  2. -LLL: disable printing extraneous information

  3. uid=john: a “filter” to find the john user

  4. cn gidNumber: requests certain attributes to be displayed (the default is to show all attributes)

修改slapd配置資料庫

slapd-config DIT(目錄資訊數)可以被查詢和修改。下面是一些例子。

  1. 使用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
    
  2. 讓我們新增一個schema.它首先需要轉換為ldif格式。你可以在/etc/ldap/schema目錄中找到除了已經被轉換的schemas還有未被轉換的schemas。

    1. 通常不要從slapd-config資料庫刪除schema。在測試系統增加一個schemas進行練習。
      1. 在增加任何schema之前,你應該檢查哪些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

下面的例子中,我們將新增CORBA schema。
  1. 建立轉換配置檔案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
  2. 建立輸出資料夾ldif_output。
  3. 定義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}。

  4. 使用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中。

  5. 編輯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

    你的屬性值可能有不同。

  6. 最後,使用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"
  7. 確認現在被載入的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。每當修改產生時,生產者就會推送修改實體給消費者,但是,只有實際的修改才會被髮送,而不是所有的實體。

提供者配置

從配置提供者開始。

  1. 建立一個包含以下內容的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。

  2. 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
    
  3. 由於apparmor改變,增加新的內容,並重啟程序:

    sudo ldapadd -Q -Y EXTERNAL -H ldapi:/// -f provider_sync.ldif
    sudo service slapd restart

現在,提供者配置好了。

消費者配置

現在,配置消費者。

  1. 安裝軟體,參考上面的安裝部分。保證slapd-config資料庫和提供者的是相同的。特別的,確保schemas和數 據庫字尾相同。

  2. 建立一個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
    

    保證下面的屬性擁有正確的值:

    1. provider (Provider伺服器的名字 – ldap01.example.com 在本例中中 – 或者IP地址)

    2. binddn (你正在使用的管理員DN)

    3. credentials (管理員DN的密碼)

    4. searchbase (資料庫字尾)

    5. olcUpdateRef (Provider伺服器的主機名或者ip地址)

    6. rid (複製ID, 一個唯一的3為標誌來區別這個複製。每個消費者都應該至少有一個rid)

  3. 增加新的內容:

    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(有兩個)強制了下面:

  1. 發生初始連結時,匿名認證訪問被userPassword屬性提供。也許是反直覺的,‘匿名認證’是需要的即使你們訪問DIT不需要。一旦遠端終端連線,認證就會發生(見下一點)。

  2. 認證可以發生是因為使用者對userPasword屬性有讀(因為“被自己寫”)的許可權。

  3. userPassword屬性對其他使用者來說是沒必要的,除了rootDN,它對這個屬性有完全的許可權。

  4. 為了讓使用者更改自己的密碼,使用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機制。檢視前面的命令作為一個例子。請注意:

  1. 你必須使用sudo成為root身份來匹配ACL。
  2. 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工具來完成這些任務。

  1. 安裝gnutls-bin和ssl-cert包:

    sudo apt-get install gnutls-bin ssl-cert
  2. 為證書頒發機構建立私鑰:

    sudo sh -c "certtool --generate-privkey > /etc/ssl/private/cakey.pem"
  3. 建立臨時檔案/etc/ssl/ca.info來定義CA:

    cn = Example Company
    ca
    cert_signing_key
    
  4. 建立自己認證的CA證書:

    sudo certtool --generate-self-signed \
    --load-privkey /etc/ssl/private/cakey.pem \ 
    --template /etc/ssl/ca.info \
    --outfile /etc/ssl/certs/cacert.pem
  5. 為伺服器建立一個私鑰:

    sudo certtool --generate-privkey \
    --bits 1024 \
    --outfile /etc/ssl/private/ldap01_slapd_key.pem

    把檔名中的ldap01換成你的伺服器名。使用主機和服務來命名證書和金鑰對你清晰地使用它們會很有幫助。

  6. 建立/etc/ssl/ldap01.info資訊檔案包含:

    organization = Example Company
    cn = ldap01.example.com
    tls_www_server
    encryption_key
    signing_key
    expiration_days = 3650
    

    上述證書10年比較好,根據需要調整。

  7. 建立伺服器證書

    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認證,那麼我們要求消費者同樣擁有。除此之外,但是,我們希望對複製流進行加密。仍然要做的是為消費者建立一個金鑰和證書,然後相應地配置。我們將在提供者上生成金鑰/證書,以避免必須建立另一個證書,然後將必要的材料轉移到消費者。

  1. 在提供者上,建立一個持久的目錄(這將用於可能的傳輸)和消費者私鑰:

    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]:
    
  2. 在消費者上,配置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)。

  3. 在消費者上,為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
  4. 在提供者上,檢查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]: