作者:陳柏菁 E-mail
第十五章 架 設 NFS 及 NIS Server

索引:
15.1 架設 NFS Server
  15.1.1 NFS 概述
  15.1.2 安裝 NFS 套件及瀏覽套件內容
  15.1.3 設定 NFS --- 設定 /etc/exportsexportfs
  15.1.4 Client 掛載 NFS ---
showmountClient 掛載 NFS 的語法設定開機時自動掛載
使用一般 user 身分執行掛載 ( sudo )
  15.1.5 對分享目錄做進一步的限定
15.2 架設 NIS Server
  15.2.1 NIS 使用時機
  15.2.2 安裝 NIS Server 套件及瀏覽套件內容
  15.2.3 設定 NIS Server
  15.2.4 設定 NIS Client ---
Client 端測試NIS Client 查詢 NIS Server 相關資訊的指令
  15.2.5 NIS 與 NFS 的整合
  15.2.6 設定 Slave NIS Server


15.1 架設 NFS Server

15.1.1 NFS 概述


NFS 全名為 Network File System ( 網路檔案系統 ),主要是讓 Unix-Like 主機之間,能透過掛載的方式來存取對方所分享出來的資源,也就是說 NFS Client 是將 NFS Server 所提供的分享目錄掛載至本地端主機下,就好比是在本機操作般一樣。

Windows 本身是不支援 NFS 檔案系統的,除非您額外的加裝一些軟體,不過這並不是本章所要探討的範圍,因此我們這裡的重心還是擺在 Unix-Like 上頭。

NFS 早期是由 SUN 這間公司所發展的,其主要是使用 RPC ( Remote Procedure Call:遠端程序呼叫 ) 機制來運作。所謂的 RPC 就是讓用戶端電腦上所執行的程式可以呼叫遠端電腦的程式來幫其執行相關服務,然後再將結果傳回給用戶端。

負責 RPC 服務的一支關鍵 daemon 叫 portmap,當 NFS Server 啟動後,portmap 就會動態分配 port number 給那些提供 NFS 服務的相關 daemon。因此當 Client 端在對 NFS Server 提出服務請求時,必須先通過 portmap ( 監聽 111 port ) 這一關,讓 portmap 來將 NFS 服務相關 daemon 的 port 告知,然後 Client 才曉得要跟哪些 port 做溝通,爾後也才能建立起與 NFS Server 的連線。一般有使用到 RPC 機制的伺服器,就可稱之為 RPC Server。

NFS Server 的執行主程式

˙ /usr/sbin/rpc.nfsd
此 daemon 可以用來識別 NFS Client 端的登入身分 ID。
˙ /usr/sbin/rpc.mountd :
當接收到 Client 端的掛載請求時rpc.mountd 會依據 /etc/exports 檔案 (其實真正參考的檔案是 /var/lib/nfs/etab) 來檢查此來源端是否允許掛載,及掛載後該使用者的相關權限為何。另外每次 Server 收到 Client 的掛載需求時rpc.mountd 會將這個紀錄記載在 /var/lib/nfs/rmtab 內,俟收到卸載請求後,才又將這個紀錄從 rmtab 中移除。
˙

/usr/sbin/rpc.rquotad
如果 NFS Server 本身有限定 quota 限額時,才會使用到這個 daemon。

15.1.2 安裝 NFS 套件及瀏覽套件內容

※ 檢查相關套件有無安裝

suselinux:~ # rpm -qa | grep nfs
nfs-utils-1.0.6-103.7 ← NFS 的主要套件囉。

suselinux:~ # rpm -qa | grep portmap
portmap-5beta-728.1 ← 這個套件一般預設都會安裝,不過還是查一下吧。

※查詢 nfs-utils 套件清單

suselinux:~ # rpm -ql nfs-utils
/etc/init.d/nfsserver 管理 NFS 服務的 script。
/usr/sbin/exportfs 維護 export list 的指令。架設 NFS Server 的目的,就是要設定一些分享目錄來給特定的來源端掛載,而當您打算把這些目錄分享出來並提供給 Client 端做存取的這個行為就叫做 export (輸出)。因此 export list 簡單的說,就是指提供給 Client 端做存取的分享資源一覽表的意思。
/usr/sbin/rcnfsserver 連結至 /etc/init.d/nfsserver 的符號連結檔。
/usr/sbin/rpc.mountd 參考上一小節的說明。
/usr/sbin/rpc.nfsd 參考上一小節的說明。
/usr/sbin/showmount 顯示 NFS Server 的掛載資訊。
/var/lib/nfs/etab etab 就是 export table 之意。NFS 的主要設定檔為 /etc/exports,當您第一次啟動 NFS 時,就會把 /etc/exports 的內容寫入 /var/lib/nfs/etab 之中,爾後 /etc/exports 做了修改並重新 export 時,也會同時更新 etab 的資料。要是哪天您發覺 exports 與 etab 這兩個檔案的內容有出入,那有可能您曾經修改過 /etc/exports,但忘了重新 export ; 也有可能是使用 exportfs 指令來修改過。

NFS 的主要設定檔 /etc/exports,其不屬於 nfs-utils 套件,而是存放在 netcfg 套件內。另外 rpc.rquotad 則是屬於 quota 套件。

※設定下次開機時啟動 NFS 服務

suselinux:~ # chkconfig nfsserver 35

15.1.3 設定 NFS

以下我們會以兩台 Linux 來實做,一台做 NFS Server (192.168.1.111),一台做 NFS Client (192.168.1.197)。不過在還沒正式開始設定之前,先做個基本的檢查動作:

1. NFS Server 及 NFS Client 先互 ping 看看,以確保雙方都能夠通訊。如果有一方不通時,請先找出問題來,看看是不是防火牆或其他網路因素所造成的,等解決了之後再進行下一步。
Client:~ # ping 192.168.1.111
PING 192.168.1.111 (192.168.1.111) 56(84) bytes of data.
64 bytes from 192.168.1.111: icmp_seq=1 ttl=64 time=0.371 ms
64 bytes from 192.168.1.111: icmp_seq=2 ttl=64 time=0.355 ms

Server:~ # ping 192.168.1.197
PING 192.168.1.197 (192.168.1.197) 56(84) bytes of data.
64 bytes from 192.168.1.197: icmp_seq=1 ttl=64 time=3.52 ms
64 bytes from 192.168.1.197: icmp_seq=2 ttl=64 time=0.342 ms
   
2. NFS Server 及 NFS Client 雙方都要啟動 RPC 機制,可使用 rpcinfo 指令來做測試。至於 rpcinfo 的用法請參考以下說明:

rpcinfo:report RPC information.

 
指令語法 rpcinfo -p [Hostname | Address]
rpcinfo -u [Hostname | Address] [program-name]

參數說明
-p 偵測主機的 portmapper,並列出有向 RPC 登記 (註冊) 的所有程式。
-u,-t 使用 RPC 來呼叫特定主機上的程式,並回報是否有正確收到對方程式的回應。-u:UDP,-t:TCP。

了解大致用法後,接著可以在 Client 或 Server 上作測試:
Client:~ # rpcinfo -p localhost ← 測試本機的 portmapper。只要有出現 111 port 就 ok 的啦。
program
vers
proto
port
 
100000
2
tcp
111
portmapper
 
100000
2
udp
111
portmapper
 

Client:~ # rpcinfo -p 192.168.1.111 ← 測試 Server 的 portmapper。
program
vers
proto
port
 
100000
2
tcp
111
portmapper
 
100000
2
udp
111
portmapper
 

確認以上執行都沒問題之後,就可以開始設定 NFS 了。

設定 /etc/exports

 

先說明這個檔案的設定格式:

分享目錄 允許存取的來源端主機名稱或 IP 位址(權限參數 1, 權限參數 2,…) …

說明:如只打算分享一個目錄,就設定那麼一行便可搞定,夠簡單吧 !

 

在來源端的部分,可以使用 machine name,如 *.paching.com.tw,這表示此 domain 內的主機 (xx.paching.com.tw) 皆允許存取 ; 那要是以 IP Address 來設定的話,則可使用如 192.168.1.0/24 或 192.168.1.0/255.255.255.0 這類的表示法 ; 來源端設定成 " * ",就表示允許 所有來源端。另外對於同一個分享目錄來說,您可以針對不同的來源端而制定不同的權限參數。

緊接著之後是接一個 ( ),中間不要留任何空白字元,至於 ( ) 裡邊就是權限的相關設定,權限參數之間使用 " , " 做區隔即可。權限設定是 NFS 最重要的地方,這裡若能搞定的話,那後面就沒有什麼了。接著就來看看可以設定哪些權限參數:

ro 預設值。表示 client 端對此目錄的權限為 read-only。當設定成 ro 時,使用者縱使對該分享目錄擁有寫入權限亦無濟於事。
rw 允許 client 端對該目錄具有讀寫權限,不過前提是使用者原本就需對此目錄具有讀寫的權限才行。
root_squash 預設值。表示 client 端若以 root 身分來掛載分享目錄時,會將其身分 squash ( 壓制 ) 成 anonymous account ( ID 為 65534),也就是說使用者以 (UID,GID) = (0,0) 的身分來存取分享目錄時,其身分會被轉換成 (UID,GID) = (65534,65534),當然此時對該目錄所實際擁有的權限,就是以 ID 65534 為主囉 ! 系統以此作為預設,顯然是為了安全的考量,畢竟 root 的權限太大了。 
SuSE 裡頭,UID、GID 65534 所代表的分別是 nobody 及 nogroup。
no_root_squash 不把 root 身分轉換成 anonymous,所以當 client 端以 root 來掛載分享目錄後,會真正擁有 root 的權限。
all_squash 不論任何人 (包含 root 在內) 在存取分享目錄時,其身分都會被轉換成 anonymous。當 no_root_squash 及 all_squash 都設定時,是會以 all_squash 為主的。
no_all_squash 預設值。不會把所有人的身分都壓制成 anonymous,所以當 client 端以一個 (UID,GID) = (500,600) 的使用者身分執行掛載後,對該目錄所擁有的權限是以 Sever 上 (UID,GID) = (500,600) 的權限為主。比如使用者 barry 在 Client 端主機的 UID 為 500,而很巧的在 Server 端主機上也存在著 barry 帳號,但其 UID 為 550,此時當 Client 端的 barry 掛載目錄後,對該目錄的權限是以 Server 端 UID 為 500 的使用者權限為主。
anonuid 預設為 65534。當 Client 端的使用者被 squash 成 anonymous 時,此 anonymous 的 UID 要設定為多少。預設為 65534,當然您也可對其做修改,比如 anonuid = 3000。
anongid 預設為 65534。與上面的意思一樣,只不過是針對 anonymous 的 GID 做設定罷了,不再贅述。
sync 預設值。同步 I/O,也就是在資料異動時,會同步寫入記憶體與磁碟之中。
async 非同步 I/O,也就是將異動的資料先暫存至 cache,再伺機回存磁碟。設定這個參數可以提昇效能,但容易造成資料的遺失。

設定檔的內容就大致如此,應該不難吧 !

設定範例說明

  範例一
Server:~ # mkdir /home/nfsdir ← 建立分享目錄。
Server:~ # chmod 777 /home/nfsdir  讓所有人皆具寫入權限。

Server:~ # vi /etc/exports

# See the exports(5) manpage for a description of the syntax of this file.
# This file contains a list of all directories that are to be exported to
# other computers via NFS (Network File System).
# This file used by rpc.nfsd and rpc.mountd. See their manpages for details
# on how make changes in this file effective.


/home/nfsdir 192.168.1.0/24(rw,sync) *(all_squash,sync)

說明
設定分享目錄為 /home/nfsdir,允許從 192.168.1.0/24 這個網路段來的主機進行掛載,並對此目錄具有讀寫的權限 ; 另外如果是以 root 身分進行存取,則其身分會被轉換成 anonymous,其他人則不會。
至於除了192.168.1.0/24 這個網路段以外的其他所有來源端主機在進行存取時,無論任何人,其身分都會被轉換成 anonymous,且只具有唯讀的權限。

範例二
Server:~ # mkdir /tmp/sharedir
Server:~ # chmod 777 /tmp/sharedir
Server:~ # vi /etc/exports

/tmp/sharedir *(rw,all_squash,anonuid=2000,anongid=1500,sync) 


說明
允許所有來源端掛載 /tmp/sharedir,並具有讀寫的權限,且無論使用任何身分執行掛載後,皆會被轉換成 anonymous,此時 anonymous 的 UID 指定為 2000,GID 為 1500。

範例三

Server:~ # mkdir /home/reportdir
Server:~ # chmod 1777 /home/reportdir
Server:~ # vi /etc/exports

/home/reportdir 192.168.1.197(rw,no_root_squash,sync)


說明

允許 192.168.1.197 的來源端進行掛載,若執行掛載的身分為 root,則掛載後對 reportdir 所具有的權限就是 root 的權限 ; 如是其他使用者進行存取,則其真正擁有的權限就看 Client 端使用者的 UID、GID 為何 ? 比如 Client 端若是以 UID、GID 皆為 1500 來進行掛載,則對於 reportdir 所擁有的權限,便是以 Server 上 UID、GID 1500 為主。


範例四:將以上設定結合起來,再加上一個 CDROM 分享的設定。
Server:~ # mkdir /mnt/cdrom → 先建立 cdrom 的掛載點。
Server:~ # mount /dev/cdrom /mnt/cdrom → 掛載 cdrom。
Server:~ # vi /etc/exports

/home/nfsdir 192.168.1.0/24(rw,sync) *(all_squash,sync)
/tmp/sharedir *(rw,all_squash,anonuid=2000,anongid=1500,sync) 
/home/reportdir 192.168.1.197(rw,no_root_squash,sync)

/mnt/cdrom 192.168.1.0/24(ro,sync)

說明
最後面那個 cdrom 的分享應該沒問題吧 ! 只要記得先把 cdrom 掛載起來後再進行分享的設定就好了。

設定完成後請啟動 NFS:

Server:~ # rcnfsserver start
Starting kernel based NFS server        done

接著您可使用 rpcinfo 或 netstat 去確認 nfs 相關 daemon 的執行狀態:
Server:~ # rpcinfo -p localhost
Server:~ # netstat -anp

將來要是修改了 /etc/exports 之後,可以不需重新啟動 NFS,而直接使用 exportfs 指令即可。接著就介紹這個指令:

exportfs: maintain list of NFS exported file systems.

  維護 NFS Server 上的 export table。

指令語法 exportfs [-o options,..] [client:/path ..]
exportfs [-aruv]
exportfs  -u [client:/path ..]

參數說明
-a export 或 unexport 所有的分享目錄。當配合 -u 參數一起使用時,就會把所有的分享目錄做 unexport。
-r 根據 /etc/exports 來 reexport (重新輸出) 所有的分享目錄。
-u unexport 一個或多個分享目錄。
-v 顯示 export 或 unexport 的結果在螢幕上。
-o 指定在 export 分享目錄時,所使用的權限參數。

補充 一下指令語法中的 [client:/path ..],client 是針對來源端的指派,可以是 IP 位址或主機名稱 ; path 是 NFS 所分享目錄的實際路徑。當您要對 /etc/exports 中沒設定到的分享目錄做 export,或對已設定的分享目錄做新增來源端或修改相同來源端的權限時,這個 exportfs 指令就很好用了,也就是說這個指令可以用來修改 export table ( /var/lib/nfs/etab ) 啦。以下的例子會以範例四做基礎,來看看如何使用 exportfs:

範例說明
1. 修改 /tmp/sharedir:將所有來源端 (*) 的權限修改成唯讀:

Server:~ # exportfs -o ro *:/tmp/sharedir  也可加上 -v 參數,來將執行結果輸出至螢幕。

Server:~ # cat /var/lib/nfs/etab | grep sharedir ← 做個確認。

/tmp/sharedir *(ro,sync,wdelay,hide,nocrossmnt,secure,root_squash,all_squash,
subtree_check,secure_locks,acl,mapping=identity,anonuid=2000,anongid=1500)

2. 修改 /home/reportdir:新增來源端 192.168.1.200,並將 all user 身分轉換成 anonymous,且只具唯讀權限

Server:~ # exportfs -o ro,all_squash 192.168.1.200:/home/reportdir

Server:~ # cat /var/lib/nfs/etab | grep report

/home/reportdir 192.168.1.200(ro,sync,wdelay,hide,nocrossmnt,secure,root_squash,all_squash,
subtree_check,secure_locks,acl,mapping=identity,anonuid=65534,anongid=65534)

/home/reportdir 192.168.1.197(rw,sync,wdelay,hide,nocrossmnt,secure,no_root_squash,no_all_squash,
subtree_check,secure_locks,acl,mapping=identity,anonuid=65534,anongid=65534)

3. 新增分享目錄 /tmp/testdir:允許存取的來源端為 192.168.2.0/24,並採用預設的權限

Server:~ # exportfs 192.168.2.0/24:/tmp/testdir

Server:~ # cat /var/lib/nfs/etab | grep testdir

/tmp/testdir 192.168.2.0/24(ro,sync,wdelay,hide,nocrossmnt,secure,root_squash,no_all_squash,
subtree_check,secure_locks,acl,mapping=identity,anonuid=65534,anongid=65534)

4. 將分享給 192.168.2.0/24 的 /tmp/testdir 及 * 的 /home/nfsdir 做 unexport

Server:~ # exportfs -uv 192.168.2.0/24:/tmp/testdir *:/home/nfsdir
unexporting 192.168.2.0/24:/tmp/testdir
unexporting *:/home/nfsdir

以上是使用 exportfs 指令來修改 export table。接著下來您可嘗試執行以下的指令:
Server:~ # exportfs -rv

這樣將會把 /etc/exports 的設定內容重新做一次輸出 (reexport),結果當然就是更新 /var/lib/nfs/etab 囉,所以剛剛使用 exportfs 去做的修改,都會從 /var/lib/nfs/etab 中消失。

如果平常您只針對 /etc/exports 在做設定,並無額外使用 exportfs 指令來修改 export table 的話,那麼只要 /etc/exports 異動後,就可以執行 " exportfs -rv " 來讓新的設定值生效。

一般人往往搞不清楚 exportfs 指令中 -a -r 參數的差別,簡單的說,使用 -r 能夠將 /etc/exports 與 export table 做同步更新,而 -a (未搭配 -u 使用時) 則是把 /etc/exports 所有設定的分享目錄輸出至 export table 而已,如果之前已經存在於 export table 內的資料紀錄還是會存在,所以 -a 參數並不能讓 export table 與 /etc/exports 的設定內容取得完全的一致性。假使剛剛您不是執行 " exportfs -rv " 而是執行 " exportfs -av ",就可以很明顯的看出兩者之間的差異。

15.1.4 Client 掛載 NFS

這裡我們還是以上一小節的範例四做為 NFS Server 的設定內容,來看看在 NFS Client 端如何執行掛載。不過在此之前,先學學showmount 指令的用法:

  showmount:show mount information for an NFS server.

  顯示 NFS Server 上的掛載資訊。

指令語法showmount -e [ hostname | IP Address ]

  -e 可使用 --exports 來代替,是用來顯示 NFS Server 上 export table 的簡要資訊,那當然其後就是接 NFS Server 的主機名稱或 IP 位址。這對 Client 端想了解 Server 分享什麼目錄時是非常好用的。

Client:~ # showmount -e 192.168.1.111
Export list for 192.168.1.111:
/tmp/sharedir (everyone)
/mnt/cdrom 192.168.1.0/24
/home/nfsdir (everyone)
/home/reportdir 192.168.1.197

  了解了 Server 分享哪些目錄後,接著 NFS Client 就可以進行掛載囉。



Client 端掛載 NFS 的語法

  mount [NFS Server 的主機名稱或 IP]:[分享目錄的路徑] [掛載點]

範例說明
Client:~ # mkdir /mnt/nfs ← 建立掛載點
Client:~ # mount 192.168.1.111:/home/nfsdir /mnt/nfs ← 掛載成功後,可使用 df 或 mount 指令去做個確認。

Client:~ # cd /mnt/nfs
Client:/mnt/nfs # touch file1
Client:/mnt/nfs # ls -l
total 0
-rw-r--r-- 1 nobody nogroup 0 Nov 12 2005 file1

雖然您是以 root 的身分執行掛載,但由於掛載之後身分已被轉換成 anonymous,因此所建立檔案的 owner 及 group id 皆為預設的 65534。如要執行卸載,請先切離目前掛載點後再執行 umount:

Client:/mnt/nfs # cd
Client:~ # umount /mnt/nfs

Client:~ # mount 192.168.1.111:/tmp/sharedir /mnt/nfs
Client:~ # cd /mnt/nfs
Client:/mnt/nfs # touch file2
Client:/mnt/nfs # ls -l file2
total 0
-rw-r--r-- 1 2000 1500 0 Nov 12 2005 file2

由於 /tmp/sharedir 這個分享目錄的設定中,有指定 anonuid=2000 及 anongid=1500,所以才會看到這樣的結果。至於為何是顯示 id number,理由很簡單,因為在 Client 端主機上的 /etc/passwd 及 /etc/group 中找不到這兩個 id number 所對應的名稱,如果找得到的話,就會顯示 username 及 groupname 了。

Client:/mnt/nfs # cd
Client:~ # umount /mnt/nfs

Client:~ # mount 192.168.1.111:/home/reportdir /mnt/nfs
Client:~ # cd /mnt/nfs
Client:/mnt/nfs # touch file3
Client:/mnt/nfs # ls -l
total 0
-rw-r--r-- 1 root root 0 Nov 12 2005 file3

注意到沒,file3 的 owner 及 group 皆為 root,這就是 no_root_squash 所發揮的效用啦。




設定開機時自動掛載

  若要系統於開機時自動掛載 nfs 的檔案系統,可於 Client 端的 /etc/fstab 做如下設定:
Client:~ # vi /etc/fstab

192.168.1.111:/home/reportdir   /mnt/nfs nfs defaults 0 0



使用一般 user 身分執行掛載


  剛剛在 Client 端的測試都是使用 root 來進行掛載,如果改成以一般使用者身分來執行的話又如何呢 ?
barry@Client:~> mkdir nfs
barry@Client:~> mount 192.168.1.111:/home/nfsdir nfs
mount: only root can do that

這時候可以考慮在 Client 端安裝 sudo 套件來解決這個問題:
Client:~ # rpm -qa | grep sudo
sudo-1.6.7p5-117.1

查無此套件的話,採光碟安裝即可。

安裝了這個套件並做好相關設定後,一般使用者只要在欲執行的指令之前加上 sudo,就能以 root ( 當然也可以是其他 user ) 的身分來執行這個指令,如此便可解決一般 user 無法 mount 的問題。

接著來看一下 sudo 設定檔 (/etc/sudoers) 的內容:
Client:~ # visudo ← 也可用 vi 去編輯 /etc/sudoers。

# Defaults specification
Defaults targetpw # ask for the password of the target user i.e. root
# 執行 sudo 指令時,會要求輸入目標使用者的密碼。也就是當您變換成另一個使用者來執行指令
# 時,需輸入那個使用者的密碼才行。


%users ALL=(ALL) ALL # WARNING! Only use this together with 'Defaults targetpw'!
# 在 % 符號後接的是群組名稱。此行設定是說允許 users 群組成員,能夠執行 sudo 來以任何 user 的身分
# 任何的 command。如果您將上面那行設定 " Default targetpw " 註解起來的話,則在以另一個 user
# 身分執行指令時,只需輸入自己的密碼,而非目標使用者的密碼。這可是個危險動作啊,因要是
#
users 的成員,當其變換成 root 身分執行指令時,只需輸入自己密碼就可取得 root 的執行權限。

# User privilege specification

root ALL=(ALL) ALL

先看個簡單的範例:

barry@Client:~> cat /var/log/messages
cat: /var/log/messages : Permission denied

→ 一般 user 不具有瀏覽 /var/log/messages 的權限。

barry@Client:~> ls -l /var/log/messages
-rw-r----- 1 root root 471056 Nov 12 15:13 /var/log/messages

barry@Client:~> sudo cat /var/log/messages ← 在程式之前加上個 sudo 指令 (不加參數),就表示要以 root 的身分來執行。
Password:  ← 請輸入目標使用者 root 的密碼。
Nov 11 12:08:12 suselinux kernel: eth0: no IPv6 routers present
Nov 12 11:08:38 suselinux SuSEfirewall2: Warning: ip6tables does not support state matching.
Nov 12 11:08:38 suselinux syslog-ng[2621]: STATS: dropped 0
Nov 12 11:08:38 suselinux SuSEfirewall2: Firewall rules unloaded.
            :略

如想要以指定的 user 身分執行 command,請加上 -u 參數:

barry@Client:~> sudo -u mary touch ~mary/maryfile
Password: ← 請輸入目標使用者 mary 的密碼。

barry@Client:~> ls -l ~mary/maryfile
-rw-r--r-- 1 mary users 0 Nov 12 15:26 /home/mary/maryfile


有些時候,您會希望只授權給少數使用者能以 root 的身分執行一些工作,但又不希望這些 user 能知道 root 的密碼,這時候就得調整一下 sudoers :
Client:~ # visudo

# Defaults targetpw ← 註解起來。
# %users ALL=(ALL) ALL ← 這一行也要註解起來。

%authgrp ALL=(ALL) ALL
barry ALL=(ALL) ALL
# 這樣一來,就只有authgrp 群組成員及使用者 barry ,可以執行 sudo 來以 root 或其他 user 的身分執行 command,
# 且輸入的是自己的密碼。

了解了 sudo 的用法後,再來就直接以一般 user 身分進行掛載及卸載 NFS:
barry@Client:~> sudo mount 192.168.1.111:/home/reportdir nfs
Password: ← 如果以剛剛修改過的 /etc/sudoers 為主的話,那這裡需輸入 barry 的密碼。

barry@Client:~> touch nfs/barryfile
barry@Client:~> ls -l nfs/barryfile
-rw-r--r-- 1 barry users 0 Nov 12 2005 nfs/barryfile

現在請回到 Server 上,觀察一下 barryfile 的長格式:

Server:~ # ls -l /home/reportdir/barryfile
-rw-r--r-- 1 3000 users 0 Nov 12 22:12 /home/reportdir/barryfile

咦,奇怪,怎麼在 Server 端所看到 barryfile,其擁有者為 id 3000 ? 因為這個 id 在 Server 上找不到所對應的 username 啦。


最後 Client 端要卸載時,也請加上 sudo 指令:

barry@Client:~> sudo umount nfs

15.1.5 對分享目錄做進一步的限定

我們直接以範例來說明比較快。首先在 NFS Server 上建立一分享目錄 /secretdir,並做以下的規劃:
 
1. 設定允許存取的來源端為 192.168.1.197。
2. 新增一 UID 為 5000 的使用者 admin ,並讓 admin 對此目錄擁有最大權限。
3. 新增一 GID 為 5000 的群組 secretgrp,並讓該群組成員 (barry 及 mary) 對此分享目錄具有唯讀權限,其他人 (包括 root) 則不具任何權限。

Server 端的設定
1. 建立分享目錄:

Server:~ # mkdir /secretdir
Server:~ # cat > /secretdir/secretfile ← 先建立一個檔案,以方便等會兒實驗用。
It is a secret file.

2. 新增帳號及群組:

Server:~ # useradd -u 5000 -m admin 
新增 UID 為 5000 的帳號 admin。
Server:~ # passwd admin
Changing password for admin.
New password:
Re-enter new password:
Password changed.

Server:~ # groupadd -g 5000 secretgrp 
新增 GID 為 5000 的群組 secretgrp。

3. 修改檔案目錄相關屬性:


Server:~ # chown -R admin:secretgrp /secretdir
Server:~ # chmod 750 /secretdir ; chmod 640 /secretdir/secretfile

Server:~ # ls -ld /secretdir
drwxr-x--- 2  admin secretgrp 80 Nov 12 23:39 /secretdir
Server:~ # ls -l /secretdir
-rw-r----- 1 admin secretgrp 21 Nov 12 23:39 secretfile

4. 設定 /etc/exports:

Server:~ # vi /etc/exports

/secretdir 192.168.1.197(rw,root_squash,sync)

Server:~ # exportfs -rv

Client 端的設定及掛載
1. 新增 id 皆為 5000 的使用者及群組:

Client:~ # useradd -u 5000 -m admin
Client:~ # passwd admin
Changing password for admin.
New password:
Re-enter new password:
Password changed.

Client:~ # groupadd -g 5000 secretgrp

2. 將使用者 barry 及 mary 加入 secretgrp 群組:

Client:~ # vi /etc/group

secretgrp : ! : 5000 : barry , mary

3. Client 掛載測試:請先在 /etc/sudoers 中做好相關設定。

barry
@Client:~> sudo mount 192.168.1.111:/secretdir nfs 
barry@Client:~> cd nfs
barry@Client:~/nfs> cat secretfile
It is a secret file.

barry@Client:~/nfs> touch barryfile
touch: cannot touch `barryfile': Permission denied

admin@Client:~> mkdir nfs
admin@Client:~> sudo mount 192.168.1.111:/secretdir nfs
admin@Client:~> touch nfs/adminfile
admin@Client:~> ls -l nfs
-rw-r--r-- 1 admin users 0 Nov 13 2005 adminfile

Client:~ # mount 192.168.1.111:/secretdir /mnt/nfs
Client:~ # cd /mnt/nfs
-bash: cd: /mnt/nfs: Permission denied

以上分別使用 barry、admin 及 root 做測試,應該看得懂吧。

15.2 架設 NIS Server

15.2.1 NIS 的使用時機

假使您是個系統管理人員,平常手邊所管理的 Linux 主機有好幾部,這時候可能會希望每一台主機上的帳號密碼都是相同的,因為這樣就能夠使用同一組帳號密碼來分別登入不同的主機。此時所直接想到的處理方式可能就是土法煉鋼法,也就是到每一部 Linux 主機上去設定帳號密碼,當然如果主機只有兩三部且帳號數也不多時,只要您願多花一點時間,相信是一定可以搞定的 ; 那萬一管理的主機有個十來部,且使用者帳號有上百個甚至更多,難道還是想一部部來做設定嗎 ? 當然不想啊,是吧 ! 所以這時候您可能會有個想法,看看能不能把所有的帳號密碼都集中在一部 Linux 主機上就好,而其他主機上的使用者在登入時則透過這台主機來做認證的工作。真是個 good idea,但是想歸想,要怎麼實現呢 ? 架設 NIS Server 就能滿足您的要求啦。

NIS 全名為 Network Information System,顧名思義就是提供網路資訊的一個服務,也是 SUN 這家公司所發展的一套軟體,一樣是運用 RPC 機制來管理。在 NIS 網域裡,可以存在著一台以上的 NIS 伺服器,而這些 Server 就專門負責使用者在登入 NIS Client 端時的認證工作。

由以上說明不難發現 NIS Server 的重要性。如果您網域裡只存在一台 NIS Server,那萬一這台 Server 出狀況,則其他靠 NIS 做認證的使用者,會全部無法登入 NIS Client,因此最好還是存在著至少一台的 Slave NIS。至於其架構圖請參考以下:


針對這個圖稍微做個說明。首先在 NIS Domain 裡存在著兩部 NIS Server,一部做 Master,提供給四台的 NIS Client 做登入時的認證,另外一部做 Slave,提供給兩台的 NIS Client 做認證。如果 Master NIS 出問題時,那四部 NIS Client 會轉而向 Slave NIS 做認證,反過來說,如果 Slave 出問題時,則那兩部 NIS Client 會轉而向 Master 做認證,當然在所有 NIS Client 的主機上,必須要把這兩部 NIS Server 都設定進去,這樣 Client 才曉得要查詢的優先順序為何。

因為 NIS 與 NFS 相同,都是使用 RPC 來管理,所以等一下在設定 NIS 之前,請先將 Server 與 Client 端的 portmap 啟動。這部分在以下的範例中就不再提了。

15.2.2 安裝 NIS Server 套件及瀏覽套件內容

NIS Server 及 NIS Client 端各有其所需安裝的套件,所以在實做的過程,您需要分別對扮演著不同角色的主機做個別的設定。而這一小節主要是針對 NIS Server 來做說明。

確認 NIS Server 套件的安裝及檢視套件清單
Server:~ # rpm -q ypserv
ypserv-2.12.1-44.2 NIS Server 的主要套件。

Server:~ # rpm -ql ypserv

/etc/ypserv.conf NIS Server 的主要設定檔。
/usr/sbin/ypserv 提供 NIS 服務的 daemon。
/usr/sbin/rpc.yppasswdd 當使用者在 NIS Client 端執行 yppasswd 指令來變更密碼時,就是靠這個 daemon 先去比對 client 所輸入的舊密碼是否相符,符合後才允許更新密碼。
/usr/sbin/rpc.ypxfrd 啟動這個 daemon,可以加速 NIS Slave 在大量複製 NIS Master 資料庫時的執行效率。
/etc/init.d/ypserv 管理 NIS 服務的 script。
/etc/init.d/yppasswdd 管理 yppasswd 這個 daemon 的 script。
/usr/sbin/rcypserv 連結至 /etc/init.d/ypserv 的符號連結檔。
/usr/sbin/rcyppasswdd 連結至 /etc/init.d/yppasswdd 的符號連結檔。
/usr/lib/yp/ypinit 安裝及建立 NIS 資料庫的程式。
/var/yp NIS 的資料庫就是放在這個目錄下。
/var/yp/securenets 如想要對存取 NIS Server 的來源端做限制,就可以設定在這個檔案內。

yp 就是 yellow page 之意,也就是所謂的黃頁。黃頁其實指的是一些工商名錄,如地址簿與電話簿之類的,因此透過 yellow page 的查詢,可以讓我們很快速的找到所需的資訊。NIS 就是類似 yp 這樣的一個功能,所以您會注意到 NIS 的相關套件、檔案、程式名稱之前,幾乎都會加上 yp,這樣應該能夠理解吧 !

15.2.3 設定 NIS Server

請您參考以下的步驟做相關的設定:

1. 首先在 /etc/hosts 檔內,將 NIS Server 的主機名稱與 IP 位址的對應關係設定進去
Server:~ # vi /etc/hosts

192.168.1.111 Server.paching.com.tw Server
   
2. 設定 NIS domain name
Server:~ # nisdomainname paching

您亦可使用 ypdomainname 這個指令來做設定,而這兩個指令都是屬於 yp-tools 套件。如只單純的執行 nisdomainname 指令,則會顯示目前 NIS 的 domain name 為何。另外請注意,此處的 domain name 與 DNS 並無直接的關聯性。

Server:~ # vi /etc/defaultdomain

paching

這裡的設定主要是讓系統在下次開機時,能自動幫我們指定好 NIS Domain Name。
   
3. 設定 ypserv.conf
Server:~ # vi /etc/ypserv.conf

# Host : Domain : Map : Security
# 限定的來源端
開放的網域
對應的資料庫類型 安全性
* : * : shadow.byname : port
* : * : passwd.adjunct.byname : port
說明
Security 的部分可設定成 deny (全部拒絕存取)、none (無任何限制,表示皆可存取)、port (允許小於 1024 port 的來源端作存取)。若無特殊考量,這個地方採用系統預設值即可。但如您考慮到安全性的話,則可做如下的修改:

Server:~ # vi /etc/ypserv.conf

127.0.0.0/255.0.0.0 : * : * : port
192.168.1. : * : * : port
* : * : * : deny
說明
來源端 " 192.168.1. ",代表的就是 192.168.1.0/255.255.255.0。也就是說除了這個來源端允許存取以外,拒絕其他所有的來源端。
   
4. 設定 /etc/netgroup
這個檔案主要是用來設定信任的網路群組,其設定格式如下:
netgroup (host,user,domain) (host,user,domain) ..

netgroup 是您的群組名稱,而緊接著在 ( ) 內的 host 表示來源端主機,user 表示 username,domain 就是 NIS 網域名稱。筆者在這個地方是沒做任何的設定,這就表示所有的主機、使用者及網域都信任的意思。
   
5. 初次啟動 ypserv 及 yppasswdd
Server:~ # rcypserv start
Starting ypserv              done
                    
Server:~ # rcyppasswdd start
Starting rpc.yppasswdd             done
   
6. 確認 RPC 有收到程式正確的回應
Server:~ # rpcinfo -u localhost ypserv
program 100004 version 1 ready and waiting
program 100004 version 2 ready and waiting

Server:~ # rpcinfo -u localhost yppasswdd
program 100009 version 1 ready and waiting

如果您執行的結果不是輸出這樣的訊息,表示 RPC 收不到程式的回應。請您務必要看到正確的回應訊息後,再繼續進行下個步驟。
   
7. 建立 NIS 資料庫
suselinux:~ # /usr/lib/yp/ypinit -m

At this point, we have to construct a list of the hosts which will run NIS servers.
Server.paching.com.tw is in the list of NIS server hosts. Please continue to add
the names for the other hosts, one per line. When you are done with the list,
type a <control D>.
  next host to add: Server.paching.com.tw
  next host to add:  ← 這個地方請按下 Ctrl - D。
The current list of NIS servers looks like this:

Server.paching.com.tw

Is this correct? [y/n: y] y ← 沒問題的話,就輸入 y 囉 !
We need a few minutes to build the databases...
Building /var/yp/paching/ypservers...
Running /var/yp/Makefile...
gmake[1]: Entering directory `/var/yp/paching'
Updating passwd.byname...
Updating passwd.byuid...
Updating group.byname...
Updating group.bygid...
Updating rpc.byname...
Updating rpc.bynumber...
Updating services.byname...
Updating services.byservicename...
Updating netid.byname...
gmake[1]: Leaving directory `/var/yp/paching'

Server.paching.com.tw has been set up as a NIS master server.

Now you can run ypinit -s Server.paching.com.tw on all slave server.


這樣就很輕鬆的建立起 NIS 資料庫了。您可至 /var/yp 中看到一個 paching 的目錄及 ypservers 的檔案,paching 目錄這就是存放資料庫檔案之處,至於 ypservers 檔案則是記載著這台 NIS 的主機名稱。

另外在剛剛那輸出內容的最後兩行是告知您 Server.paching.com.tw 這台主機已經被設定成 NIS Master Server 了,如還要設定 NIS Slave,就在 Slave 主機上執行:" ypinit -s Server.paching.com.tw "。

將來您要是在 NIS Server 上去新增帳號或修改帳號密碼相關資訊後,請記得更新資料庫:
Server:~ # make -C /var/yp

Server 部分的設定就是如此。另外想讓下次開機時自動啟動 NIS 相關服務,請執行:

Server:~ # chkconfig ypserv 35
Server:~ # chkconfig yppasswdd 35

15.2.4 設定 NIS Client


按照慣例,先查詢套件有無安裝及套件內容:
Client:~ # rpm -qa | egrep 'ypbind|yp-tools'
yp-tools-2.8-188.1 ← NIS Client 查詢 NIS Server 相關資訊時所使用的指令就在這個套件內。
ypbind-1.17.3-1.2  ← NIS Client 的主要套件。

Client:~ # rpm -ql ypbind

/etc/yp.conf ypbind 的主要設定檔。
/usr/sbin/ypbind NIS Client 執行的主程式 (daemon),他會找尋 domain 裡的 NIS Server,並取得其相關資訊。
/etc/init.d/ypbind 管理 ypbind 的 script。
/usr/sbin/rcypbind 連結至 /etc/init.d/ypbind 的符號連結檔。

Client:~ # rpm -ql yp-tools

/bin/nisdomainname 設定或顯示 NIS Domain Name 的指令。
/bin/ypdomainname 同上。
/usr/bin/ypcat 瀏覽 NIS Server 上資料庫檔案內容的指令。
/usr/bin/ypmatch 此指令可用來顯示資料庫檔案的部分內容。
/usr/bin/yppasswd NIS Client 可使用這個指令來修改 NIS Server 上的密碼。
/usr/bin/ypwhich 顯示 NIS Server 的主機名稱或資料庫檔案名稱。



NIS Client 的設定步驟


  1. 於 hosts 檔內,將 NIS Server 的資料設定進去
Client:~ # vi /etc/hosts

192.168.1.111 Server.paching.com.tw Server
     
  2. 設定 NIS domain name
Client:~ # nisdomainname paching
Client:~ # vi /etc/defaultdomain
paching
     
  3. 設定 yp.conf
Client:~ # vi /etc/yp.conf

# 指定 NIS Domain Name。
domain paching

# 指定 Client 端要使用的 NIS Server。
ypserver Server.paching.com.tw
     
  4. 設定 Client 端查詢的順序
Client:~ # vi /etc/nsswitch.conf

passwd : files nis
shadow : files nis
group : files nis
hosts : files nis dns
說明
passwd 有關帳號資訊的查詢,是先查本機的 /etc/passwd,查詢不到再向 NIS Server 查詢。
shadow 有關密碼的查詢,是先查詢本機的 /etc/shadow,查詢不到再向 NIS Server 查詢。
group 有關群組的查詢,是先查本機的 /etc/group,查詢不到再向 NIS Server 查詢。
hosts 有關主機名稱的查詢,先查詢本機的 /etc/hosts 檔,查詢不到再向 NIS Server 查詢,若連 NIS 也查詢不到,再根據本機 /etc/resolv.conf 的設定,向預設的名稱伺服器做查詢。
     
  5. 修改 /etc/passwd
Client:~ # vi /etc/passwd
      :略
mysql : x : 60 : 103 : MySQL database admin : /var/lib/mysql : /bin/bash
dhcpd : x : 102 : 65534 : DHCP server daemon : /var/lib/dhcp : /bin/false
pop : x : 67 : 100 : POP admin : /var/lib/pop : /bin/false
+ : : : : : : ← 加上這行。

# 補上這一行的用意,是表示相關資訊在本機查不到時,可以引導 process 到 NIS 去查詢。
# 請注意此行設定中," + " 及其後的六個 " : " 中間無任何空白字元。
     
  6. 初次啟動 ypbind
Client:~ # rcypbind start
Starting ypbind           done

Client:~ # rpcinfo -u localhost ypbind
program 100007 version 1 ready and waiting
program 100007 version 2 ready and waiting

設定下次開機時,啟動 ypbind:
Client:~ # chkconfig ypbind 35



Client 端測試

  若一切 ok 的話,接著就可以使用一個 Server 上存在但 Client 端不存在的帳號,來看看能否順利從 Client 端登入:
Client login : vivian
Password: ← 請輸入 Server 上使用者 vivian 的密碼。
Last login: Sat Nov 12 14:29:53 2005
Have a lot of fun...
No directory /home/vivian !
vivian@Client: / >

由於 Client 端主機並不存在 vivian 這個帳號,而是經由 NIS 認證來登入的,因此 Client 端主機當然不會有 vivian 這個家目錄存在。要解決這個問題很容易,只要把 NIS 與 NFS 做個整合即可,這部分等一下馬上會說明。



NIS Client 查詢 NIS Server 相關資訊的指令

  以下要介紹的這些指令,請參考 15.2.2 小節的說明,這裡直接以範例來介紹:
Client:~ # ypwhich -x
Client:~ # ypcat -x
Client:~ # ypmatch -x
Use "ethers"   for map "ethers.byname"
Use "aliases"   for map "mail.aliases"
Use "services"   for map "services.byname"
Use "protocols"   for map "protocols.bynumber"
Use "hosts"   for map "hosts.byname"
Use "networks"   for map "networks.byaddr"
Use "group"   for map "group.byname"
Use "passwd"   for map "passwd.byname"

以上三個指令的執行結果是相同的,都是用來顯示 NIS Server 上的資料庫檔案。若單純的使用 ypwhich 指令,不加任何參數,則會顯示 NIS Server 的主機名稱:

Client:~ # ypwhich
Server.paching.com.tw

Client:~ # ypcat passwd.byname
 

→ 列出 UID 1000 以上的使用者帳號資訊。亦可使用 passwd 來代替 passwd.byname:


Client:~ # ypcat passwd

Client:~ # ypmatch vivian barry passwd.byname ← 顯示 vivian 及 barry 的帳號資訊。
vivian : $2a$10$a5XgYTu9OcTm8b1dU:5001 : 100 : : /home/vivian : /bin/bash
barry : $2a$10$po3qlJbOZ4ckiDAwfd6E : 1000 : 1001 : : /home/barry : /bin/bash

Client:~ # ypmatch 1000 passwd.byuid ← 顯示
UID 1000 的帳號資訊。
barry : $2a$10$po3qlJbOZ4ckiDAwfd6E : 1000 : 1001 : : /home/barry : /bin/bash

15.2.5 NIS 與 NFS 的整合


剛剛從 Client 端做測試時,雖可經由 NIS 認證而成功登入,但美中不足之處就是使用者沒家目錄可用,這時候您只要在 NIS Server 上再去架設 NFS Server,並將 /home 分享出來,然後 Client 端再把 /home 掛載進來就行了:

NIS Server:

 
Server:~ # vi /etc/exports

/home 192.168.1.0/24(rw,sync)

Server:~ # rcnfsserver start ← 如果 NFS 已是啟動狀態,則執行 " exportfs -rv " 即可。

NIS Client:
 
Client:~ # mount 192.168.1.111:/home /home

Client:~ # df | grep home ← 做個確認。
192.168.1.111:/home 514048 33280 480768 7% /home

如要設定 Client 端在下次開機時能自動掛載家目錄,請至 /etc/fstab 做設定:


Client:~ # vi /etc/fstab

192.168.1.111:/home  /home  nfs  defaults  0 0

NIS Client 成功掛載後,您可以用剛剛那個帳號再登入一次,這回應該就有家目錄可用了。

另外也可嘗試於 NIS Client 的主機上頭去啟動 telnet 服務,然後由另一部電腦對此 NIS Client 做遠端連線,看看能否認證成功。

15.2.6 設定 Slave NIS Server

NIS Server 所扮演的角色非常重要,萬一掛點了,那平常透過 NIS 作認證來存取相關服務的功能就全部停擺,其影響可說是非同小可,所以為了防止有這種事情發生,架設一台以上的 Salve NIS 就有其必要性。Master 與 Slave 角色的扮演就跟 DNS 一樣,Slave 除了可做備援外,亦可分擔 Master 的負擔


目前我們的 Master NIS 為 Sever.paching.com.tw,那 Slave NIS 就假設為 Slave.paching.com.tw。首先請把 Master 的主機紀錄於 Slave 的 /etc/hosts 檔:

Slave:~ # vi /etc/hosts

192.168.1.111 Server.paching.com.tw Server

再來重複 15.2.3 小節的 2 ~ 6 步驟。如果都沒問題的話,就可以開始與 Master 做資料同步了:

Slave:~ # /usr/lib/yp/ypinit -s Server.paching.com.tw

完成後請檢查您的 /var/yp 目錄下有沒有多一個 paching 的目錄,如果有的話,那代表 Master 的資料庫都已經成功傳送至您 Slave 主機了。

目前在我的環境裡,已經存在一台 Master 與一台 Slave NIS,不過先前
NIS Client 尚未將 Slave 設定進去,那就趕快補上去吧:

Client:~ # vi /etc/hosts

192.168.1.111 Server.paching.com.tw Server
192.168.1.112 Slave.paching.com.tw Slave

Client:~ # vi /etc/yp.conf

domain paching
ypserver Server.paching.com.tw
ypserver Slave.paching.com.tw ← 補上這筆設定即可。

最後再重新啟動 ypbind :
Client:~ # rcypbind restart

剩下的測試工作就留給各位囉 !

copyright © 2005 by barry ( 柏青哥 )