最後更 新日:2010/04/1

OpenLDAP 整合 FreeBSD System Account ( Single Sign-In )
Document made with Nvu


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 ldappasswd: 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 設定檔