2016年11月20日 星期日

ldap 披荊斬棘白話入門

如果你管理了好幾部 linux 與 windows 伺服器, 而你們公司的每一位同仁 (或每一位客戶, 或你的每一位學生) 可能同時在上述伺服器當中的好幾部都各有一個帳號, 那麼帳號密碼管理就成了頭痛的問題: 要怎樣才能讓用戶使用方便, 只改一次密碼就可以自動讓所有伺服器上同一個帳號的密碼都同步更新? 這個問題, 在 unix 世界, 以前採用的是 NIS 技術; 不過 windows (及它的 active directory) 興起之後, 好像很少人在用 NIS。 現在業界多半都採用 ldap。

可是 ldap 是我所認真學過的開放技術當中, 投資報酬率最低的技術之一。 學語法及爬文的過程, 有一種跟政府官員打交道的感覺: 這個社群中的大部分高手似乎不喜歡用簡單白話的方式溝通 -- 不論是語法或是討論串皆然。 結果就是: 為了解決一個小問題, 新手必須四處碰壁撞滿頭包 (如果他夠幸運的話) 才會找到答案。 工程師已經夠辛苦了, 為何還要遭受這種對待呢! (淚) 貴哥的使命就是要改變這種悲慘的狀況。

[2017/9/12] 有現成的 openldap docker 可用; 不過我這篇的重點是講觀念, 所以還是值得參考。

一、 基本觀念

以下說明會用到這個範例:

dn:  cn=foxmosa,dc=moztw,dc=org
cn:  foxmosa 
uid:  foxmosa
objectclass:  inetOrgPerson
sn:  狐耳
givenName:  摩莎
userPassword:  {CRYPT}$6$abc123...
preferredLanguage:  Traditional Chinese

如果可以重來一次, 我會先準備好以下基本觀念, 再開始爬文:

  1. 入門使用者可以把 ldap 簡單想成是公司的通訊目錄加財產清冊, 內含每一位員工/各階層每一個部門/每一部裝置 (電腦/印表機/冷氣機/空氣清淨機/...) 的姓名或名稱、 電話、 帳號名稱、 密碼、 裝置序號、 財產編號、 ... 等等。
  2. 但它的儲存方式不是傳統的關聯式資料庫, 而是一個樹狀結構。
  3. 每位員工或每個部門或每部裝置有一個獨一無二的 distinc name (dn), 就像是他的/它的身份證字號一樣。 但是它的語法很囉嗦: 像上面的 cn=foxmosa,dc=moztw,dc=org 就是狐耳摩莎的 dn。 讀者可以看出這類似要表達 「moztw.org 組織裡的 foxmosa」 這樣的概念。
  4. 每位員工的一筆記錄當中, 除了 dn 屬性 (attribute) 之外, 還可以有 cn (姓名/名稱)、 sn (姓氏)、 givenName (名)、 objectclass (類別)、 ... 等等其他更多屬性。 雖然 cn 可以填中文, 但它會出現在 dn 裡面, 所以我偏好把它當成類似 uid 在用, 也就是只用英文文數字。 我把中文姓名寫在 sn 跟 givenName 裡面。
  5. 一筆記錄裡面到底可以含有哪些屬性? 要看它是哪種類型的記錄而定。 例如 「(網路組織當中的)人」 (inetOrgPerson) 才會有 「偏好講哪種語言」 的屬性 (preferredLanguage)、 「企業組織」 (organization) 才會有 「註冊地址」 的屬性 (registeredAddress)。 常用屬性列表詳見 Common LDAP schemas。 但其實每位系統管理員可以修改 schema, 所以還是要下指令查詢比較準確。 另文詳談。
  6. 前述的 objectclass 屬性定義了一筆記錄的類型。 又, 一筆記錄可以包含好幾個 objectclass 屬性, 也就是說, 一個人或一個組織可以同時屬於好幾種類型。

二、 安裝與試車

本文在 Ubuntu 16.04.1 LTS 底下實作。 (嚴格來說, 是在 lxc container 裡面。)

  1. apt-get install slapd ldap-utils: slapd 是伺服器端的套件; ldap-utils 則提供客戶端增刪查改的指令。 slapd 的管理員密碼可以隨便打, 反正等一下要重新設定。
  2. dpkg-reconfigure slapd ==>
    1. Omit OpenLDAP server configuration? ==> No
    2. DNS domain name: ==> 你的 domain, 例如 moztw.org 或 my.com.tw 或 im.cyut.edu.tw
    3. Organization name: ==> Chaoyang University of Technology [現在不適合打中文, 因為中文會變成亂碼。 之後再改。]
    4. 輸入新密碼, 兩次
    5. Database backend to use: ==> MDB
    6. Do you want the database to be removed when slapd is purged? ==> yes (反正我們目前並沒有任何舊資料需要保留)
    7. Move old database? ==> yes
    8. Allow LDAPv2 protocol? ==> no (反正我並不需要跟既有的 Windows Active Directory 或其他舊程式整合)
  3. ldapsearch -x ==> 錯誤: 您要在哪一棵樹底下搜尋資料呀?
  4. ldapsearch -x -b 'dc=im,dc=cyut,dc=edu,dc=tw' 這個 -b 選項指定查詢指令的 base, 類似 find /tw/edu/cyut/im 指令的後面的參數, 也就是查詢的起點/最上層。 這會印出兩筆資料: 一筆是本公司/本機構, 也就是 -b 參數後面的那個物件; 另一筆是本公司/本機構的管理員 cn=admin,... (後面是本公司/本機構的 dn)。
  5. 為減少囉嗦, 請編輯 /etc/ldap/ldap.conf , 在裡面加一句 BASE dc=im,dc=cyut,dc=edu,dc=tw 之類的, 從此以後就可以直接下 ldapsearch -x 而不必給後面的 -b 'dc=...' 。 注意: 不需要重新啟動 slapd。 也就是說, /etc/ldap/ldap.conf 裡面的這個指令所影響的是 ldapsearch、 ldapadd、 ldapdelete、 ldapmodify、 ... 等等 (來自 ldap-utils 的) 客戶端增刪查改指令。

更多參考資料: 安裝 ldap-utils 使用

三、 新增/刪除用戶

建立一個文字檔 users.ldif , 內含三位用戶的資訊:

dn:  cn=ckhung,dc=im,dc=cyut,dc=edu,dc=tw
cn:  ckhung
objectclass:  inetOrgPerson
sn:  洪
givenName:  朝貴

dn:  cn=snoopy,dc=im,dc=cyut,dc=edu,dc=tw
cn:  snoopy
objectclass:  inetOrgPerson
sn:  史
givenName:  奴比

dn:  cn=foxmosa,dc=im,dc=cyut,dc=edu,dc=tw
cn:  foxmosa
objectclass:  inetOrgPerson
sn:  狐耳
givenName:  摩莎
  1. ldapadd -x < users.ldif ==> 你是哪根蔥啊? 沒有權限新增用戶!
  2. 用 admin 的身份再試一次: ldapadd -x -D 'cn=admin,dc=im,dc=cyut,dc=edu,dc=tw' < users.ldif ==> 你是 admin? 那密碼咧?
  3. ldapadd -x -D 'cn=admin,dc=im,dc=cyut,dc=edu,dc=tw' -W < users.ldif ==> 輸入密碼後, 成功加入三位新用戶!
  4. ldapsearch -x ==> 看到三位新用戶。 可是為什麼中文姓名都變成亂碼啊?
  5. 原來雙冒號的屬性 (sn:: 跟 givenName:: 5pGp6I6O) 表示後面是二進位資料, 已被施以 base64 encoding。 詳見 FAQ。 用 perl 把它解回來: perl -MMIME::Base64 -MEncode=decode -n -00 -e 's/\n //g; s/(?<=:: )(\S+)/decode("UTF-8",decode_base64($1))/eg;print' (可能需要先安裝 libmime-base64-urlsafe-perl 套件)
  6. 可以在 ~/.bashrc 裡面加上一句 alias base64de='perl -MMIME::Base64 -MEncode=decode -n -00 -e '"'"'s/\n //g; s/(?<=:: )(\S+)/decode("UTF-8",decode_base64($1))/eg;print'"'" 這樣下次再登入時, 查詢指令就可簡寫為: ldapsearch -x | base64de 。 以上解法抄自 這裡; 多層單引號的處理改自 這裡 [我覺得應該要順便把兩個冒號改成一個會更好, 這樣輸出就符合 ldif 檔案格式; 不過現在暫時沒力氣研究]
  7. 查詢時可指定條件, 例如: ldapsearch -x 'cn=foxmosa'ldapsearch -x 'objectClass=inetOrgPerson' 。 更多指定條件的方式, 請見 這一篇
  8. 刪除一位用戶: ldapdelete -x -D 'cn=admin,dc=im,dc=cyut,dc=edu,dc=tw' -W 'cn=foxmosa,dc=im,dc=cyut,dc=edu,dc=tw'
  9. 再用 ldapsearch -x 查詢, 確認 foxmosa 已經消失了。

四、 密碼

如果覺得每次要用 admin 的身份做事就要打一次密碼很麻煩, 可以把密碼寫在一個文字檔內, 再用 -y 指定從檔案讀取密碼:

echo -n 'admin的密碼' > admin.pwd ; chmod og-rwx admin.pwd
ldapdelete -x -D 'cn=admin,dc=im,dc=cyut,dc=edu,dc=tw' -y admin.pwd 'cn=snoopy,dc=im,dc=cyut,dc=edu,dc=tw'
ldapdelete -x -D 'cn=admin,dc=im,dc=cyut,dc=edu,dc=tw' -y admin.pwd 'cn=ckhung,dc=im,dc=cyut,dc=edu,dc=tw'

這樣就不會一直被問密碼了。 但是要注意: 密碼檔內不可有任何多餘字元, 連換列字元都不可以! 上面的 echo -n ... 就是要求 echo 不要在最後面加上換列字元。 可以用 xxd admin.pwd 檢查確認。 試完後, 再用剛剛的 users.ldif 把三個測試用戶加回去。

再來要幫 foxmosa 改密碼:

echo -n '狐耳摩莎的密碼' > foxmosa.pwd ; chmod og-rwx foxmosa.pwd
ldappasswd -x -D 'cn=admin,dc=im,dc=cyut,dc=edu,dc=tw' -y admin.pwd -T foxmosa.pwd 'cn=foxmosa,dc=im,dc=cyut,dc=edu,dc=tw'
ldapsearch -x > old.ldif
ldapsearch -x -D 'cn=admin,dc=im,dc=cyut,dc=edu,dc=tw' -y admin.pwd > new.ldif
diff old.ldif new.ldif

注意到兩件事: (1) foxmosa 的資料裡, 多出了 userPassword 這個屬性。 (2) 必須要用 admin 的身份查詢, 才看得見這個屬性。 又, 這個做法適合批次改密碼; 如果只是要改一位用戶的密碼, 不想建立 foxmosa.pwd , 也可以直接用 -S 取代 -T foxmosa.pwd , 這樣系統會問你新密碼。

然後改用 foxmosa 的身份查詢我們的主目錄: ldapsearch -x -D 'cn=foxmosa,dc=im,dc=cyut,dc=edu,dc=tw' -W 這時就必須輸入正確的密碼才能看見資料了。 至於 ckhung 跟 ruby 兩位用戶, 因為還沒有密碼, 所以無法用他們的身份下去查詢。 當然啦, 這個實驗看起來有點多此一舉, 因為不要指定身份, 反而可以查詢。 不過若是用戶想要修改自己的資訊, 或是 (slapd 的) 站長把 「開放路人甲查詢」 的功能關掉, 那就非得用自己的帳密連線不可。

如果是 foxmosa 想要改自己的密碼, 可以這樣下: ldappasswd -x -D 'cn=foxmosa,dc=im,dc=cyut,dc=edu,dc=tw' -W -S 系統會先問你新密碼 (兩次), 再問你舊密碼。 下面小結一下 ldappasswd 改密碼的重要參數及選項; 更完整教學請見 這篇

  1. 不指定要改誰的密碼, 就會改到自己的密碼
  2. 用 -D 表達下指令者的身份 (admin 或 foxmosa), 並且要用以下其中一種方式向系統驗證我的身份 (這個動作叫做 bind):
    1. 詢問我: -W
    2. 從檔案讀: -y me.pwd
    3. 直接打在命令列上 (會在 .bash_history 留下記錄!): -w '被看光光的密碼'
  3. 同樣地, 要從以下三種方式當中選一種來指定新密碼: (1) 詢問我: -S (2) 從檔案讀: -T foxmosa.pwd (3) 直接打在命令列上: -s '被看光光的新密碼'

用 base64de 解碼後, 會看到密碼欄長得類似這樣: {SSHA}uDY7...。 前面的 {SSHA} 表示這個密碼所採用的 hashing algorithm。 除了預設的 SSHA 之外, 還可以有 MD5、 SMD5、 SHA、 CRYPT 等等不同的 algorithms, 詳見 手冊

另一種改密碼的方式: 建立一個文字檔 chpwd.ldif, 內含:

dn: cn=foxmosa,dc=im,dc=cyut,dc=edu,dc=tw
changetype: modify
replace: userPassword
userPassword: 新密碼

然後用 ldapmodify 指令修改密碼: ldapmodify -x -D 'cn=admin,dc=im,dc=cyut,dc=edu,dc=tw' -y admin.pwd < chpwd.ldif 。 改好後請 (用 admin 或 foxmosa 的身份) 再次 ldapsearch 查看密碼屬性, 發現採用這樣的寫法, 密碼就不會被 hash, 比較不理想。 根據 這一篇, 請把 slappasswd -s '新密碼' 的輸出貼到 chpwd.ldif 檔的 userPassword: 屬性去, 類似這樣: userPassword: {SSHA}uDY7... , 再用 ldapmodify 修改一次, 並用 ldapsearch 查看密碼屬性, 這就跟前一種做法所產生的格式類似了。 (但即使密碼相同, 出來的 hash 值也很可能不一樣 -- 這就是 SSHA 的特性) 又, slappasswd -s 的寫法適合批次處理, 但會在 .bash_history 裡面留下記錄, 比較不安全。 若是 admin 更改自己的密碼, 建議不要用 -s 。

一般的建議是採用預設的 SSHA 比較安全; 但如果希望產生一個通用於 slapd 跟 /etc/shadow 的 hash, 那就必須採用 CRYPT 格式。 根據 這個解答, 請安裝 whois 套件, 然後 mkpasswd -m sha-512 產生類似這樣的輸出: $6$JB/AsjtVxB$h... 然後把它貼到 chpwd.ldif 檔案裡的 userPassword 屬性, 前面還要加上 {CRYPT}, 類似這樣: userPassword:: {CRYPT}$6$JB/AsjtVxB$h...

五、 admin 有第二個密碼!

腳踏車會落鏈; 管理員會忘記密碼。 忘記 admin 的密碼時, 該怎麼辦? 這一節讓你看到 ldap 世界的地形有多麼地崎嶇詭異。 初學者可略過此節, 不影響後面的理解。

假設你剛剛已成功地用正常的方式更改過 admin 的密碼, 並且已經測試過新密碼可用。 現在請用當初 dpkg-reconfigure slapd 所設定的 (舊) 密碼再試一次... 還是可以用! 驚! 這是怎麼一回事?

先前說的修改密碼的方式, 修改的是資料庫裡面的密碼 -- admin 跟 foxmosa 跟其他所有用戶一樣, 在資料庫裡各佔一席之地。 資料庫檔在 /var/lib/ldap 底下。 用 strings /var/lib/ldap/data.mdb 可以看到先前建立的用戶、 SSHA 處理過的密碼等等資訊。 但是似乎沒有工具可以直接編輯這個二進位檔。

還好, admin 另有一個 (特權!) 密碼, 放在系統設定檔 /etc/ldap/slapd.d/cn\=config/olcDatabase\=\{1\}mdb.ldif 裡面, 用 ldappasswd 改不到這個密碼。 而 slapd 似乎會允許用戶使用這兩個密碼之中的任何一個作為通關密語。

那麼系統設定檔裡的這個密碼該如何修改呢? dpkg-reconfigure slapd 是一個方法。 另一個方法是拿出落鏈自己修的精神 -- 密碼徒手改。

  1. 編輯設定檔, 修改裡面的 olcRootPW: 欄位, 最後變成類似這樣: olcRootPW: {SSHA}/uDY7...。 其中密碼的部分一樣按照先前的方式用 slappasswd 產生。 注意: 因為我們沒有用 base64 encoding, 所以 olcRootPW 後面放一個冒號就好!
  2. perl -ne 'print unless $.<=2' /etc/ldap/slapd.d/cn\=config/olcDatabase\=\{1\}mdb.ldif > backup.ldif (效果是製造設定檔的備份, 但扣除最前面兩列註解)。
  3. crc32 backup.ldif 然後把印出來的一個八位數的十六進位數字貼到原始設定檔第二列的 "# CRC32 " 後面, 取代原先的數值。 (可能需要先安裝 libarchive-zip-perl 套件, 才有 crc32 指令可用。)
  4. 用這種方式修改密碼, 需要重新啟動 slapd 才會生效! service slapd restart

如果沒有做 2、3 兩步的話, 後續再下 slapcat 之類的指令時 (後詳), 會出現 ... ldif_read_file: checksum error ... 之類的錯誤。 設定檔最上面的註解叫你別手動編輯, 就是這個意思。 詳見 這一頁

「忘記管理員密碼、 需要重設」 這件事很常發生, 但是在 ldap 的世界卻很難搜尋到簡單明瞭的文章。 (比較容易搜尋到修改 「第二個管理員」 的密碼的文章。 下詳。) 艱澀隱晦的神秘知識逼新手們繞遠路、 甚至走到錯誤的道路去; 沒有人用白話文簡單解釋基本觀念, 這種現象在 ldap 的世界裡面是家常便飯啊! 我寫這篇文章真是功德無量 :-)

六、 客戶端可以在遠方; 伺服器可以耍特權

這一節以 「查詢」 為例, 來談兩個重要的使用情境: 遠方的客戶端, 和伺服器本機帳戶的特權。

先前所有指令都是在 slapd 伺服器底下。 假設那部伺服器的 IP 是 10.12.24.252 現在請開第二部 lxc 容器 (或第二部 ubuntu 電腦), 並且安裝 ldap-utils 套件, 然後下這個指令: ldapsearch -H ldap://10.12.24.252:389/ -b 'dc=im,dc=cyut,dc=edu,dc=tw' 這裡比先前多了以下兩串:

  1. -H ldap://10.12.24.252:389/ 指定伺服器的位址及埠號。 用 grep ldap /etc/services 可看出 ldap 服務的預設 port 就是 389, 所以上面的 :389 其實可以省略。
  2. -b 'dc=im,dc=cyut,dc=edu,dc=tw' 指定查詢的起點 base, 也就是查詢起始點/最上層。

為減少命令列的囉嗦, 可以在客戶端的 /etc/ldap/ldap.conf 檔裡面加上這兩句:

BASE dc=im,dc=cyut,dc=edu,dc=tw
URI  ldap://10.12.24.252

從此以後客戶端也就不需要額外多打上面那兩串囉。

儘管客戶端的指令可以跟伺服器端一樣簡潔; 但是伺服器端就是有一些特權是客戶端所沒有的。 在伺服器端, 以下三個指令效果類似:

  1. ldapsearch -x
  2. ldapsearch -Y EXTERNAL -H ldapi:///
  3. sudo slapcat

你可以把輸出存檔, 用 diff 比較三者的差異。 其中第三種句型利用 root 的身份直接到後臺撈資料, 會多印出一些底層資料。 用 dpkg -L slapd | grep -P '/usr/s?bin' 可以看到還有 slappasswd、 slapadd 等等指令, 這些指令是伴隨著 slapd 一起安裝的, 當你變身成 root, 就可以不必登入 ldap 帳號、 用它們直接管理後臺。 當前兩種句型因為某些奇怪的原因而失敗、 當你煩到快要去撞牆時, 可以用第三種方法繞到牆後面的後臺。 這個問答 解釋前端系列指令 (ldap*) 跟後端系列指令 (slap*) 的差異, 想要寫 cron 備份資料時, 特別值得一讀。 又, 例如第五節所說的 「checksum error」, 可以這樣觀察: slapcat > /dev/null (更正設定檔內 CRC32 後面的數字之前、 之後比較一下。)

七、 圖形介面

我是命令列控, 通常不太學 GUI 的軟體。 不過 ldap 的指令實在太囉嗦, 特別是 ldapmodify, 想拿它來隨便改一個屬性, 竟然必須先建一個 ldif 檔! 在 ldap 的世界, 就連我這個命令列控都無法抵擋 GUI 的誘惑: apt-get install jxplorer

jxplorer 建立連線 啟動後, 按 「檔案」 下方的 「連結到 DSA」 按鈕, 然後如圖填入主機 IP、 基底 (就是 /etc/ldap/ldap.conf 裡的 BASE 參數)、 「層級」 (驗證身份的方式) 選 「使用者+密碼」、 使用者 DM、 密碼等等參數。 按 「確定」 之前, 建議先按 「儲存」 並且幫這組連線參數取個名字, 這樣以後就可以用選的就好。 但是它不會存密碼。 還有, 名字裡不能含有句點字元。

視窗左側顯示一棵 Directory Information Tree (DIT)。 通常管理員 (你) 可能會根據公司的部門組織樹來建構這棵樹。 詳見 1 2 這兩篇觀念解釋文。 可以點選想要查看的物件 (某個人、 某個單位); 左側可以選擇用 HTML 的方式還是用表格的方式檢視或修改。 如果只是要修改幾個值, 用 jxplorer 比用命令列方便多了。

用 jxplorer 編輯密碼 修改其他欄位很簡單; 但修改密碼值得特別提一下。 先在左側點選人, 再到右側的表格編輯器點一下 userPassword 的 「非字串資料」, 選擇 「無格式」、 填入新密碼兩次、 按確定、 按送出。 密碼要填的是 hash 值, 而不是 (使用者記得的) 原始密碼。 採用 「無格式」 的方式填密碼, 彈性最大。 但是在 hash 值前面還要加上 hash 演算法名稱 (放在大括弧內), 也就是說, 真正填進 「非字串資料」 裡面的東西必須長得像這樣: {CRYPT}$6$JB/AsjtVxB$h... 。 如果密碼以 SSHA 的方式 hash, 那麼也可以改選 SSHA (而不要選 「無格式」), 這樣就可少打 {SSHA} 這幾個字元。

八、 太上皇管理員 cn=config

現在終於可以向你解釋你一個秘密: 在 openldap 裡面, 還有另一個管理員, 叫做 cn=config。 驚! 驚! cn=admin 管人員/部門/設備等等普通資料; cn=config 管設定檔, 也管 cn=admin。 這說來話長, 從後臺說起比較簡單:

slapcat > data1.ldif
slapcat -b cn=config > meta1.ldif
grep '^dn:' data1.ldif
grep '^dn:' meta1.ldif

第一個熟悉的指令查看人員/單位/設備目錄; 第二個指令則是查看系統設定。 你可以用編輯器打開這兩個檔案研究一下它們的內容 (差很多, 完全不相關); 不過更簡單的方式是用後面兩個指令撈出其中的 dn, 會看到 data1.ldif 裡面存的, 是熟悉的 admin、 ckhung、 snoopy、 foxmosa; 而 meta1.ldif 裡面存的, 則是系統設定資料, 包含幾筆名稱包含 cn=schema 的資料, 還有幾筆名稱包含 olcDatabase=* 的資料, 而每一筆的結尾都是 cn=config。

現在改用 ldapsearch 指令重做一次:

ldapsearch -Y EXTERNAL -H ldapi:/// > data2.ldif
ldapsearch -Y EXTERNAL -H ldapi:/// -b cn=config > meta2.ldif
grep '^dn:' data2.ldif
grep '^dn:' meta2.ldif

可以看到 data2.ldif 的內容大致跟 data1.ldif 的內容相同; 而 meta2.ldif 的內容大致跟 meta1.ldif 的內容相同。

以上都是在伺服器上才有的特權指令 (感謝 這個問答); 但如果想從客戶端查詢/修改系統設定, 那就應該類似這樣下指令: ldapsearch -x -D 'cn=config' -b cn=config -W 唯一的問題是: 我們不知道 cn=config 的密碼。 事實上你從 meta1.ldif 或 meta2.ldif 裡面可以看出來: 在 cn=config 那筆記錄底下, 並沒有一個 olcRootPW 欄位, 也就是說, cn=config 並沒有預設的密碼。 所以, 對於暫時還拿不掉 jxplorer 奶嘴的 ldap 新手 (我) 來說, 如果想要拿它來修改系統設定, 就必須乖乖回到命令列, 先設定 cn=config 的密碼。 先建立一個 change-config-pwd.ldif 文字檔, 內容如下:

dn: olcDatabase={0}config,cn=config
changetype: modify
replace: olcRootPW
olcRootPW: {SSHA}uDY7...

其中 {SSHA}uDY7... 那一串是由 slappasswd 指令產生的。 跟先前一樣, 因為我們沒有用 base64 encoding, 所以 olcRootPW 後面放一個冒號就好。 然後設定 cn=config 的密碼: ldapmodify -Y EXTERNAL -H ldapi:/// < change-config-pwd.ldif 再回到那一句查詢: ldapsearch -x -D 'cn=config' -b cn=config -W, 終於成功!

用 cn=config 的身份更改 admin 的密碼 再到 jxplorer 新增連線, 「基底 DN」 (base DN) 填 cn=config, 「使用者 DN」 也填 cn=config, 終於可以用圖形介面從客戶端查詢系統設定。 從左半部可以看到好幾個資料庫。 點選 {1}mdb 然後在右半部找到熟悉的 olcRootDN 跟 olcRootPW。 在這裡, 你甚至可以直接修改 admin 的密碼, 不需要自己手動修改 checksum。 (所以我說 cn=config 其實才是權力最大的太上皇。) 還有, 從此以後爬文看到高手輕鬆地說: 「只要改某某設定值就好了」, 你終於可以不需要再像無頭蒼蠅一樣又用設定值名稱去上天下海搜尋如何寫 ldif 檔以及下很長的 ldapmodify 指令, 你終於可以用 奶嘴 jxplorer 直接修改設定檔就好! 感動到眼淚都快掉下來了~~~

九、 感言

這個問答 的提問者說爬了很多文都還是找不到要領; 好幾位電腦高手都抱怨 openldap 很難設定 這篇修改設定教學文 也在抱怨; 這位大大的文章 說要改 admin 的密碼, 但其實他改到 cn=config 的密碼。 即使是不太正確或不太完整的文章, 在 google 的排名還是很前面, 而且對我們這些新手還是幫了很多忙。 你可以想像我爬了多少文 (通常是對話; 教學文比較少)、 花了多少力氣, 才能夠寫得這麼清楚嗎? (搖頭嘆氣)

大部分時候小格的文章能對中文世界有貢獻就不錯了; 這篇文章我可以很有信心地說: 就連英文世界也找不到這麼有系統的類似教學文 :-) 可惜小格並沒有英文讀者。 如果有讀者正好已加入某個 wiki/部落格/文件社群, 拜託推薦我也加入, 我很樂意再花幾個星期的時間把它翻成英文, 去拯救全球各地那些在 ldap 世界裡走不出迷宮的工程師 :-)

ps. 本篇完全還沒談到資安保護的部分, 例如傳輸加密以避免被中間人攻擊、 用 fail2ban 阻擋暴力破解等等。 現在你的 openldap 伺服器算是仍然處於裸奔的狀態。

6 則留言:

  1. 老師真是功德無量啊! 想我當初學openldap也是到處撞牆! 老師加油,把 master/slave 也一起介紹吧!

    回覆刪除
  2. 真是複雜的命令,一點都不smart/clear

    回覆刪除
  3. 架完LDAP後,也正常運作了。隔天回頭看,還是一頭霧水。這文章真是功德無量阿~

    回覆刪除
  4. 你好, 多謝老師的解說, 超級新手有些概念還未弄清
    首先, 這個OPENLDAP已經是一個SERVER了嗎?? 那如何跟WINDOW 的AD / database 的user 去配合作驗證呢??
    如果有一個C# program,只需透過System.DirectoryServices.Protocols 就可以連結LDAP SERVER嗎?
    謝謝老師

    回覆刪除
    回覆
    1. 抱歉, 今天才看到留言。 奇怪, 現在 blogspot 不會用 e-mail 通知站長有留言了...?

      呵呵 c# 我完全沒概念耶。 總之你就把 openladp 當成一個 active directory 就對了。 是的。 它就是一個 AD server。

      刪除

因為垃圾留言太多,現在改為審核後才發佈,請耐心等候一兩天。