最後更
新日:2010/04/1
OpenLDAP 整合 FreeBSD System Account ( Single Sign-In )

Description :
這邊記錄了我最近玩 OpenLDAP 的設定方式,使用 OpenLDAP 取代過去的 NIS ( Network Information Service ) 服務,讓 OpenLDAP 整合 FreeBSD User 帳號及密碼,達成統一管理 ( Single Sign In ) 的簡易管理機智,套一句我們老師常說的話『我們資訊人就是要化繁為簡』Single Sign-In 的機智確實達到化繁為簡了,使用者只要一組帳號密碼就大小通吃真的是很方便。
Environment :
硬體:i386 PC
Intel P4 2.0
記憶體網卡:512M RAM + Intel 網卡
作業系統:FreeBSD 8.0
Release
Setp
1.
1-1. OpenLDAP Server 端的安裝及相關設定:
# cd /usr/ports/net/openldap-server24 # 最新 openlda24-server 版
# make install clean ; rehash # 選擇想要的,未來有需要用到其他的可透過 make config 再加選再 make install
# vi /etc/rc.conf # 加入開機自動啟動
slapd_enable="YES"
slapd_flags='-h "ldapi://%2fvar%2frun%2fopenldap%2fldapi/ ldap://0.0.0.0/"'
slapd_sockets="/var/run/openldap/ldapi"
# vi /usr/local/etc/openldap/slapd.conf # 編輯 Server 主設定檔
# 載入 openldap 內所定義的 schema
include /usr/local/etc/openldap/schema/core.schema
include /usr/local/etc/openldap/schema/corba.schema
include /usr/local/etc/openldap/schema/cosine.schema
include /usr/local/etc/openldap/schema/misc.schema
include /usr/local/etc/openldap/schema/inetorgperson.schema
include /usr/local/etc/openldap/schema/openldap.schema
include /usr/local/etc/openldap/schema/nis.schema
# 運作的 pid 存放位置
pidfile /var/run/openldap/slapd.pid
argsfile /var/run/openldap/slapd.args
# 動態載入後端的 modules
modulepath /usr/local/libexec/openldap
moduleload back_bdb
# 設定 ldap 使用權限,讓 userPassword 這個屬性的使用者可寫
access to attrs=userPassword
by self write
by anonymous auth
by dn.base="cn=root,dc=ntut,dc=idv,dc=tw" write
by * none
# 開放 anonymous 可讀,不過只限制在 IP 127.0.0.1 本機及網段 10.99.99.0/24
access to *
by self write
by users read
by anonymous peername.IP=127.0.0.1 read
by anonymous peername.IP=10.99.99.0%255.255.255.0 read
by dn.base="cn=root,dc=ntut,dc=idv,dc=tw" write
by * none
# DBD 資料庫定義及設定 Base DN 及 base DN 管理帳號 root
database bdb
suffix "dc=ntut,dc=idv,dc=tw"
rootdn "cn=root,dc=ntut,dc=idv,dc=tw"
rootpw secret
# openldap 資料庫存放目錄
directory /var/db/openldap-data
# 設定索引
index objectClass eq
index ou,cn,sn,mail,mobile,givenName eq,pres,sub
index uid,uidNumber,gidNumber,loginShell eq,pres
# chown -R ldap:ldap /var/db/openldap-data # 修改 openldap 資料目錄擁有者為 ldap
# cp /usr/local/etc/openldap/DB_CONFIG.example /var/db/openldap-data/DB_CONFIG # 替 Berkeley DB 製作設定檔 DB_CONFIG
# vi /etc/syslog.conf # 修改系統 log 讓 ldap 可產生 ldap.log
local4.* /var/log/ldap.log
# vi /etc/newsyslog.conf # ldap 的資料量蠻大的所以要設定 freebsd 定期壓縮 ldap.log
/var/log/ldap.log
640 7 * @TOO
JC
# touch /var/log/ldap.log # 手動產生 ldap.log 檔
# /etc/rc.d/syslogd restart # 重新啟動 syslogd
# /etc/rc.d/newsyslog restart # 重新啟動 newsyslog
# /usr/local/etc/rc.d/slapd start # 啟動 openldap
# ps -ax | grep slapd # 確認 ldap 的 process 是否啟動
71692 ?? Ss 0:00.06 /usr/local/libexec/slapd -h ldapi://%2fvar%2frun%2fop
71720 p0 S+ 0:00.01 grep slapd
# netstat -na |grep LISTEN # 確認 389 Service 服務是否開啟
tcp4
0 0
*.389
*.*
LISTEN
1-2. 新增 OpenLDAP 名錄的內容
# mkdir /usr/local/etc/openldap/data # 建立一個存放 *.ldif 文字檔目錄
# vi /usr/local/etc/openldap/ldif/bdn.ldif # 編寫一個基本 bdn 值,包含 Group 及 People 兩個 ou
# Base DN ntut.idv.tw
dn: dc=ntut,dc=idv,dc=tw
dc: ntut
objectClass: top
objectClass: domain
# Group
dn:ou=Group, dc=ntut,dc=idv,dc=tw
objectclass: top
objectclass: organizationalUnit
ou: Group
# People
dn:ou=People, dc=ntut,dc=idv,dc=tw
objectclass: top
objectclass: organizationalUnit
ou: People
# ldapadd -x -D "cn=root,dc=ntut,dc=idv,dc=tw" -W -f bdn.ldif # 加入基本 bdn 值
Enter LDAP Password:
adding new entry "dc=ntut,dc=idv,dc=tw"
adding new entry "ou=Group, dc=ntut,dc=idv,dc=tw"
adding new entry "ou=People, dc=ntut,dc=idv,dc=tw"
# slappasswd -h "{CRYPT}" # 一般 Unix 用的加密格式為 {CRYPT}
New password:
Re-enter new password:
{CRYPT}qEe2Nd4v/adTc # 將這一串加密後的亂數值貼到 userPassword 後
# vi /usr/local/etc/openldap/data/user.ldif # 編寫一個 Unix User 的物件屬性值內容值
# test account
dn: uid=test,ou=People,dc=ntut,dc=idv,dc=tw
uid: test
cn: test
objectClass: top
objectClass: account
objectClass: posixAccount
userPassword: {CRYPT}qEe2Nd4v/adTc
uidNumber: 18000
gidNumber: 18000
homeDirectory: /home/test
loginShell: /usr/local/bin/bash
gecos: Test User
# ldapadd -x -D "cn=root,dc=ntut,dc=idv,dc=tw" -W -f user.ldif # 加入一個 test 帳號的基本資料
Enter LDAP Password:
adding new entry "uid=test,ou=People,dc=ntut,dc=idv,dc=tw"
# vi /usr/local/etc/openldap/data/group.ldif # 編寫一個 Unix Group 的物件屬性值內容值
# Group by wheel
dn: cn=wheel,ou=Group,dc=ntut,dc=idv,dc=tw
objectClass: posixGroup
objectClass: top
cn: wheel
userPassword: {crypt}*
gidNumber: 0
memberUid: test
memberUid: root
# ldapadd -x -D "cn=root,dc=ntut,dc=idv,dc=tw" -W -f group.ldif # 加入一個系統群組 wheel 的基本資料
Enter LDAP Password:
adding new entry "cn=wheel,ou=Group,dc=ntut,dc=idv,dc=tw"
# ldapsearch -x -b "uid=test,ou=People,dc=ntut,dc=idv,dc=tw" # 用 ldapsearch 可查看剛才新增的 test user 資料
# test, People, ntut.idv.tw
dn: uid=test,ou=People,dc=ntut,dc=idv,dc=tw
uid: test
cn: test Lin
objectClass: top
objectClass: account
objectClass: posixAccount
uidNumber: 18000
gidNumber: 18000
homeDirectory: /home/test
loginShell: /usr/local/bin/bash
gecos: Test User
# ldapdelete -x -W -D "cn=root,dc=ntut,dc=idv,dc=tw" "uid=test,ou=People,dc=ntut,dc=idv,dc=tw" # 刪除某節點 (leaf node)
# ldapdelete -D "cn=root,dc=ntut,dc=idv,dc=tw" -w secret -x -r -v "ou=Group,dc=ntut,dc=idv,dc=tw" # 刪除整個 ou=Group 子樹
ldap_initialize( <DEFAULT> )
deleting entry "ou=Group,dc=ntut,dc=idv,dc=tw"
deleting children of: ou=Group,dc=ntut,dc=idv,dc=tw
deleting children of: cn=wheel,ou=Group,dc=ntut,dc=idv,dc=tw
removing cn=wheel,ou=Group,dc=ntut,dc=idv,dc=tw
cn=wheel,ou=Group,dc=ntut,dc=idv,dc=tw removed
# ldapmodrdn -D "cn=root,dc=ntut,dc=idv,dc=tw" -w secret -x "cn=user1,ou=People,dc=ntut,dc=idv,dc=tw" "cn=user2" # 將 cn=user1 變成 cn=user2
Setp 2.
2-1. OpenLDAP Client 端安裝測試
# cd /usr/ports/net/nss_ldap/ # 安裝取得使用者帳號、群組的 nss_ldap 模組
# make install clean
# cd /usr/ports/security/pam_ldap # 安裝使用者的認證、授權機制的可抽換式模組
# make install clean
# cd /usr/ports/security/pam_mkhomedir # 安裝幫使用者自動產生家目錄的軟體
# make install clean
# cp /usr/local/etc/ldap.conf.dist ldap.conf # 複製 nss_ldap 的設定檔
# vi /usr/local/etc/ldap.conf # 設定 nss_ldap 設定檔
host 10.99.99.8
base dc=ntut,dc=idv,dc=tw
uri ldap://10.99.99.8
binddn cn=root,dc=ntut,dc=idv,dc=tw
bindpw secret
rootbinddn cn=root,dc=ntut,dc=idv,dc=tw
bind_policy soft
pam_filter objectclass=posixAccount
pam_login_attribute uid
nss_base_passwd ou=People,dc=ntut,dc=idv,dc=tw?one
nss_base_shadow ou=People,dc=ntut,dc=idv,dc=tw?one
nss_base_group ou=Group,dc=ntut,dc=idv,dc=tw?one
# cd /usr/local/etc # 切換目錄
# ln -s nss_ldap.conf ldap.conf # 把 ldap.conf 及 nss_ldap.conf 聯結在一起
# vi /usr/local/etc/ldap.secret # 填入管理密碼
secret
# chmod 400 ldap.secret # 因為此檔為明碼修改權限
#vi /etc/nsswitch.conf # 設定 nsswitch 加入 Mark 4 個值在加入 group: files ldap 及 passwd: files ldap
#group: compat
#group_compat: nis
hosts: files dns
networks: files
#passwd: compat
#passwd_compat: nis
shells: files
group: files ldap
passwd: files ldap
services: compat
services_compat: nis
protocols: files
rpc: files
# id test # 查詢有無 test 帳號
uid=18000(test) gid=18000 groups=18000,0(wheel)
# vi /etc/pam.d/login # 增加下面兩行,當一個 User login 到 Server 時即會透過 ldap 認證並且建立一個家目錄
auth
sufficient
/usr/local/lib/pam_ldap.so
no_warn try_first_pass
session
required
/usr/local/lib/pam_mkhomedir.so
# vi /etc/pam.d/sshd # 改變 sshd 經由 pam 透過 ldap 認證,加入下面兩行
auth
sufficient
/usr/local/lib/pam_ldap.so
no_warn try_first_pass
session
required
/usr/local/lib/pam_mkhomedir.so
# ssh test@10.99.99.8 # 測試 ssh 透過 ldap 認證
Password:
Last login: Thu Apr 1 11:43:16 2010 from localhost
Copyright (c) 1980, 1983, 1986, 1988, 1990, 1991, 1993, 1994
The Regents of the University of California. All rights reserved.
FreeBSD 8.0-RELEASE-p2 (MYBSD) #0: Mon Mar 29 17:17:53 CST 2010
Welcome to FreeBSD!
# vi /etc/pam.d/ftp # 同樣 ftp 要透過 ldap 認證也只要加這一行
auth
sufficient
/usr/local/lib/pam_ldap.so
no_warn try_first_pass
# ftp test@10.99.99.8 # 測試 ftp 是否透過 ldap 認證
# vi telnetd # 同樣 telnet 若要透過 ldap 認證也只要加這一行
auth
sufficient
/usr/local/lib/pam_ldap.so
no_warn try_first_pass
# telnet 10.99.99.8 # 測試 telnet 是否透過 ldap 認證
# su - test # 切換使用者,用意在於建立 mail 的存放目錄
$ maildirmake Maildir # 手動產生 Maildir
$ exit # 離開
# telnet 10.99.99.8 110 # 測試 pop3 是否透過 ldap 認證
Trying 10.99.99.8...
Connected to 10.99.99.8.
Escape character is '^]'.
+OK Hello there.
user test
+OK Password required.
pass 1234
+OK logged in.
quit
+OK Bye-bye.
Connection closed by foreign host.
References.
http://www.weithenn.idv.tw
http://www.google.com
http://www.freebsd.org/doc/en/articles/ldap-auth/ldap.html
http://mail.lsps.tp.edu.tw/~gsyan/freebsd2001/pam_ldap.html
To Add.
※ 物件類別 ( objectclass ) 說明:
於 LDAP 中 Unix 在帳號管理會比 Linux 單純,因為我們用到的 posixAccount 這個物件類別(objectclass),Linux 中帳號管理上比較複雜,它必須要包括了 /etc/password、/etc/shadow、/etc/group 等三個物件。
posixAccount >> 屬性:必要: cn、uid、uidNumber、gidNumber、homeDirectory 選用: userPassword、loginShell、gecos、description
shadowAccount >> 屬性:uid、userPassword 、shadowLastChange 、shadowMin 、shadowMax 、shadowWarning 、shadowExpire 、shadowInactive 、shadowFlag
posixGroup >> 屬性:選用: userPassword、memberUid、description
※ FreeBSD 系統帳號轉移程式:
#cd /root # 運用轉移程式將原本系統帳戶轉為 ldap 格式
#fetch http://www.padl.com/download/MigrationTools.tgz # 取得 MigrationTools 的 perl 程式
#tar -xzvf MigrationTools.tgz # 解開 MigrationTools
#cd MigrationTools-47
#vi migrate_common.ph # 修改 migrate_common.ph 檔
$DEFAULT_MAIL_DOMAIN = "ntut.idv.tw";
$DEFAULT_BASE = "dc=ntut,dc=idv,dc=tw";
#vi migrate_passwd.pl # 修改 migrate_passwd.pl 檔 , 因為 FreeBSD User 欄位關係必須減掉上面那行改為下面那行
- local($user, $pwd, $uid, $gid, $gecos, $homedir, $shell) = split(/:/);
+ local($user, $pwd, $uid, $gid, $class, $change, $expired, $gecos, $homedir, $shell) = split(/:/);
#./migrate_passwd.pl /etc/master.passwd /root/user.ldif # 執行 user 轉換
#./migrate_group.pl /etc/group /root/group.ldif # 執行 group 轉換
# ldapadd -x -D "cn=root,dc=ntut,dc=idv,dc=tw" -W -f user.ldif # 新增使用者
# ldapsearch -x -b "uid=john,ou=People,dc=ntut,dc=idv,dc=tw" # 可查看 john 這個使用者有無新增進去
※ 刪除整個 LDAP 資料重作:
# /usr/local/etc/rc.d/slapd stop # 停止 ldap service
# rm -rf /var/db/openldap-data/* # 清空整個 LDAP DB 資料
# /usr/local/etc/rc.d/slapd start # 重新啟動 ldap service
Starting slapd.
# cp /usr/local/etc/openldap/DB_CONFIG.example /var/db/openldap-data/DB_CONFIG # copy LDAP DB 設定檔