[其他] AD的替代品: OpenLDAP 建置與介接
本文最後更新於:2024年5月2日 晚上
此文章同步刊登於哲煜科技的Medium
前言
如果本身是大型組織的IT,或是任職於服務供應商,曾經提供大型客戶客製軟體服務,想必對於微軟的Active Directory(AD)不陌生吧,簡單來講,這個系統的主要目的如下:
用途為以樹狀結構管理組織中的網路物件,物件可以是使用者、群組、電腦、網域控制站、郵件、設定檔、組織單元、樹系等等,只要是在Active Directory結構定義檔(schema)中定義的物件,就可以儲存在Active Directory資料檔中。
– 統整並節錄於維基百科
如上所述,透過AD,可以針對整個網域中的設備派送軟體安裝、執行程式,也可以集中管理員工帳號,利用Single Sign-On(SSO)就可以只用一組AD的帳號密碼,讓每個員工登入作業系統與使用應用程式。
雖然微軟的AD功能完善、只要有Windows Server就能夠架設,但是要錢啊。因此不少企業也選擇了其他的替代方案,例如Novell的eDirectory,或是開源並包含在許多Linux裡的OpenLDAP,而這就是今天要講的主題。
OpenLDAP建置
一、 安裝OpenLDAP
更新安裝包目錄
sudo apt update
下載OpenLDAP
sudo apt install slapd
設定管理者密碼
- 安裝完成
- 使用以下指令確認是否有安裝成功確認389 port正在被監聽中:
sudo netstat -tulnp | grep slapd
二、設定slapd
- 重新產生slapd的設定檔
sudo dpkg-reconfigure slapd
- 選擇「NO」,不忽略OpenLDAP server配置
- 設定domain name
OpenLDAP會根據設定生成該AD之後的base dn(Distinguish Name)
以圖中的ad.hankz.org.tw
為例,產生的base_dn就會是dc=ad,dc=hankz,dc=org,dc=tw
- 設定組織名稱,不影響結構
- 設定管理員密碼
- 設定後端使用資料庫,選擇MDB即可
- 是否要在移除slapd時,清除資料庫
- 是否要備份舊資料庫(預設路徑:
/var/backups/
)
- LDAPv2是過時的,是否禁用LDAPv2(建議禁用)
- 設定完成
- 查詢ldap內容(清單條列,不方便閱讀,後面會介紹GUI工具)
sudo slapcat
ldap常用設定
一、禁用匿名存取(anonymous access)
來源:https://serverfault.com/questions/63916/how-to-disable-anonymous-access-on-ldap
安裝ldap-utils
sudo apt install ldap-utils
建立檔案
sudo vim /usr/share/slapd/ldap_disable_bind_anon.ldif
輸入以下內容後,儲存檔案並退出(重點:
olcDisallows: bind_anon
)dn: cn=config changetype: modify add: olcDisallows olcDisallows: bind_anon dn: cn=config changetype: modify add: olcRequires olcRequires: authc dn: olcDatabase={-1}frontend,cn=config changetype: modify add: olcRequires olcRequires: authc
應用設定
sudo ldapadd -Y EXTERNAL -H ldapi:/// -f /usr/share/slapd/ldap_disable_bind_anon.ldif
結果:
管理工具
一、Softerra LDAP Administrator
當然使用這種command line介面管理實在是不太現實,所以我使用Softerra LDAP Administrator來作為GUI管理介面
下載並安裝軟體後,新增連線
填入連線資訊(Base DN可省略)
切換到Credentials頁籤,選擇Other credentials,輸入使用者dn與密碼
登入後就可以看到整個openLDAP的結構,新增、修改、刪除等等都可以透過這個工具去完成,有興趣的話,讀者可以去研究一下如何使用,這邊就不多做贅述
PHP介接OpenLDAP
身為軟體開發者,比較常遇見的使用場景大概就是介接Single Sign-On(SSO)和撈取資料並進行同步了吧,這邊就用PHP簡單示範一下基本的帳號登入與搜尋資料吧。
一、登入
$host = '[YOUR_LDAP_SERVE_HOST]';
$port = '[YOUR_LDAP_SERVE_PORT]';
$username = '[USER_DN]'; // OpenLDAP與MS AD不同,不是使用帳號欄位進行登入
$password = '[USER_PASSWORD]';
$ldapconn = @ldap_connect($host, $port);
if(!$ldapconn) {
// Host 或 Port 「格式」設定錯誤(這步並沒有對OpenLDAP進行連線)
die();
}
$ldapbind = @ldap_bind($ldapconn, $username, $password); // 真正連線的地方
if($ldapbind) {
// 登入成功
} else {
// 登入失敗
}
二、搜索資料
$host = '[YOUR_LDAP_SERVE_HOST]';
$port = '[YOUR_LDAP_SERVE_PORT]';
$username = '[USER_DN]'; // OpenLDAP與MS AD不同,不是使用帳號欄位進行登入
$password = '[USER_PASSWORD]';
$ldapconn = @ldap_connect($host, $port);
if(!$ldapconn) {
// Host 或 Port 「格式」設定錯誤(請注意這步並沒有對OpenLDAP進行連線)
die();
}
// 如果要使用匿名存取的話,拿掉這行
$ldapbind = @ldap_bind($ldapconn, $username, $password);
// 例如:dc=ad,dc=hankz,dc=org,dc=tw
$base_dn = '';
// 例如:(objectClass=*)
$filter = '[FILTER]';
// 陣列,想取得的屬性名稱,若要全部取得,設定為array('*')
$attributes = array();
// 總取回筆數,0為無限制
$sizeLimit = 0;
// 每次取回筆數
$pageSize = 1000;
// 是否有限制筆數
$limit = $sizelimit > 0;
$data = array();
$cookie = '';
do {
@ldap_control_paged_result($ldapconn, $pageSize, true, $cookie);
$result = @ldap_list($ldapconn, $base_dn, $filter, $attributes, 0, $sizelimit);
if(!$result) {
return array();
}
$entries = ldap_get_entries($ldapconn, $result);
unset($entries['count']);
$data = array_merge($data, $entries);
@ldap_control_paged_result_response($ldapconn, $result, $cookie);
// 扣掉已取得的筆數
if($limit) {
$sizelimit -= $pageSize;
}
// $cookie必須要有值 && (沒有指定筆數 || 還未取完指定筆數)
} while($cookie !== null && $cookie != '' && ($limit == false|| $sizelimit > 0 ));
if(empty($data)) {
// 取得失敗
} else {
// 取得成功
}
環境
Ubuntu 16.04.6 LTS slapd (Ubuntu) (Feb 18 2021 14:23:06)
PHP 7.3.5