## 13.1 NFS 的由來與其功能
NFS 這個藉由網絡分享文件系統的服務在架設的時候是很簡單的,不過,它最大的問題在于『權限』方面的概念! 因為在客戶端與服務器端可能必須要具備相同的賬號才能夠存取某些目錄或檔案。 另外,NFS 的啟動需要透過所謂的遠程過程調用 (RPC),也就是說,我們并不是只要啟動 NFS 就好了, 還需要啟動 RPC 這個服務才行啊!
因此,在開始進行 NFS 的設定之前,我們得先來了解一下,什么是 NFS 呢?不然講了一堆也沒有用,對吧! ^_^! 底下就來談一談什么是 NFS ,且 NFS 的啟動還需要什么樣的協議啊!
* * *
### 13.1.1 什么是 NFS (Network FileSystem)
NFS 就是 **N**etwork **F**ile**S**ystem 的縮寫,最早之前是由 [Sun](http://www.oracle.com/us/sun/index.html) 這家公司所發展出來的 ([注1](#ps1))。 它最大的功能就是可以透過網絡,讓不同的機器、不同的操作系統、可以彼此分享個別的檔案 (share files)。所以,你也可以簡單的將他看做是一個文件服務器 (file server) 呢!這個 NFS 服務器可以讓你的 PC 來將網絡遠程的 NFS 服務器分享的目錄,掛載到本地端的機器當中, 在本地端的機器看起來,那個遠程主機的目錄就好像是自己的一個磁盤分區槽一樣 (partition)!使用上面相當的便利!

圖 13.1-1、NFS 服務器分享目錄與 Client 掛載示意圖
就如同上面的圖示一般,當我們的 NFS 服務器設定好了分享出來的 /home/sharefile 這個目錄后,其他的 NFS 客戶端就可以將這個目錄掛載到自己系統上面的某個掛載點 (掛載點可以自定義),例如前面圖示中的 NFS client 1 與 NFS client 2 掛載的目錄就不相同。我只要在 NFS client 1 系統中進入 /home/data/sharefile 內,就可以看到 NFS 服務器系統內的 /home/sharefile 目錄下的所有數據了 (當然,權限要足夠啊!^_^)!這個 /home/data/sharefile 就好像 NFS client 1 自己機器里面的一個 partition 喔!只要權限對了,那么你可以使用 cp, cd, mv, rm... 等等磁盤或檔案相關的指令!真是他 X 的方便吶!
好的,既然 NFS 是透過網絡來進行數據的傳輸,那么經由[第二章談到的 socket pair](http://linux.vbird.org/linux_server/0110network_basic.php#tcpip_transfer_tcp_socket) 的概念你會知道 NFS 應該會使用一些埠口吧?那么 NFS 使用哪個埠口來進行傳輸呢?基本上 NFS 這個服務的埠口開在 2049 ,但是由于文件系統非常復雜,因此 NFS 還有其他的程序去啟動額外的端口,但這些額外的端口啟動的號碼是? 答案是....不知道! @_@ !因為預設 NFS 用來傳輸的埠口是隨機選擇小于 1024 以下的埠口來使用的。咦!那客戶端怎么知道你服務器端使用那個埠口啊?此時就得要 遠程過程調用 (Remote Procedure Call, RPC) 的協定來輔助啦!底下我們就來談談什么是 RPC?
* * *
### 13.1.2 什么是 RPC (Remote Procedure Call)
因為 NFS 支持的功能相當的多,而不同的功能都會使用不同的程序來啟動, 每啟動一個功能就會啟用一些端口來傳輸數據,因此, NFS 的功能所對應的端口才沒有固定住, 而是隨機取用一些未被使用的小于 1024 的埠口來作為傳輸之用。但如此一來又造成客戶端想要連上服務器時的困擾, 因為客戶端得要知道服務器端的相關埠口才能夠聯機吧!
此時我們就得需要遠程過程調用 (RPC) 的服務啦!RPC 最主要的功能就是在指定每個 NFS 功能所對應的 port number ,并且回報給客戶端,讓客戶端可以連結到正確的埠口上去。 那 RPC 又是如何知道每個 NFS 的埠口呢?這是因為當服務器在啟動 NFS 時會隨機取用數個埠口,并主動的向 RPC 注冊,因此 RPC 可以知道每個埠口對應的 NFS 功能,然后 RPC 又是固定使用 port 111 來監聽客戶端的需求并回報客戶端正確的埠口, 所以當然可以讓 NFS 的啟動更為輕松愉快了!
**Tips:** 所以你要注意,要啟動 NFS 之前,RPC 就要先啟動了,否則 NFS 會無法向 RPC 注冊。 另外,RPC 若重新啟動時,原本注冊的數據會不見,因此 RPC 重新啟動后,它管理的所有服務都需要重新啟動來重新向 RPC 注冊。


圖 13.1-2、NFS 與 RPC 服務及文件系統操作的相關性
如上圖所示,當客戶端有 NFS 檔案存取需求時,他會如何向服務器端要求數據呢?
1. 客戶端會向服務器端的 RPC (port 111) 發出 NFS 檔案存取功能的詢問要求;
2. 服務器端找到對應的已注冊的 NFS daemon 埠口后,會回報給客戶端;
3. 客戶端了解正確的埠口后,就可以直接與 NFS daemon 來聯機。
由于 NFS 的各項功能都必須要向 RPC 來注冊,如此一來 RPC 才能了解 NFS 這個服務的各項功能之 port number, PID, NFS 在服務器所監聽的 IP 等等,而客戶端才能夠透過 RPC 的詢問找到正確對應的埠口。 也就是說,NFS 必須要有 RPC 存在時才能成功的提供服務,因此我們稱 NFS 為 RPC server 的一種。事實上,有很多這樣的服務器都是向 RPC 注冊的,舉例來說,NIS (Network Information Service) 也是 RPC server 的一種呢。此外,由圖 13.1-2 你也會知道,不論是客戶端還是服務器端,要使用 NFS 時,兩者都需要啟動 RPC 才行喔!
更多的 NFS 相關協議信息你可以參考底下網頁:
* RFC 1094, NFS 協議解釋 [http://www.faqs.org/rfcs/rfc1094.html](http://www.faqs.org/rfcs/rfc1094.html)
* Linux NFS-HOWTO:[http://www.tldp.org/HOWTO/NFS-HOWTO/index.html](http://www.tldp.org/HOWTO/NFS-HOWTO/index.html)
* * *
### 13.1.3 NFS 啟動的 RPC daemons
我們現在知道 NFS 服務器在啟動的時候就得要向 RPC 注冊,所以 NFS 服務器也被稱為 RPC server 之一。 那么 NFS 服務器主要的任務是進行文件系統的分享,文件系統的分享則與權限有關。 所以 NFS 服務器啟動時至少需要兩個 daemons ,一個管理客戶端是否能夠登入的問題, 一個管理客戶端能夠取得的權限。如果你還想要管理 quota 的話,那么 NFS 還得要再加載其他的 RPC 程序就是了。我們以較單純的 NFS 服務器來說:
* rpc.nfsd:
最主要的 NFS 服務器服務提供商。這個 daemon 主要的功能就是在管理客戶端是否能夠使用服務器文件系統掛載信息等, 其中還包含這個登入者的 ID 的判別喔!
* rpc.mountd
這個 daemon 主要的功能,則是在管理 NFS 的文件系統哩!當客戶端順利的通過 rpc.nfsd 而登入服務器之后,在他可以使用 NFS 服務器提供的檔案之前,還會經過檔案權限 (就是那個 -rwxrwxrwx 與 owner, group 那幾個權限啦) 的認證程序!他會去讀 NFS 的配置文件 /etc/exports 來比對客戶端的權限,當通過這一關之后客戶端就可以取得使用 NFS 檔案的權限啦!(注:這個也是我們用來管理 NFS 分享之目錄的權限與安全設定的地方哩!)
* rpc.lockd (非必要)
這個玩意兒可以用在管理檔案的鎖定 (lock) 用途。為何檔案需要『鎖定』呢? 因為既然分享的 NFS 檔案可以讓客戶端使用,那么當多個客戶端同時嘗試寫入某個檔案時, 就可能對于該檔案造成一些問題啦!這個 rpc.lockd 則可以用來克服這個問題。 但 rpc.lockd 必須要同時在客戶端與服務器端都開啟才行喔!此外, rpc.lockd 也常與 rpc.statd 同時啟用。
* rpc.statd (非必要)
可以用來檢查檔案的一致性,與 rpc.lockd 有關!若發生因為客戶端同時使用同一檔案造成檔案可能有所損毀時, rpc.statd 可以用來檢測并嘗試回復該檔案。與 rpc.lockd 同樣的,這個功能必須要在服務器端與客戶端都啟動才會生效。
上述這幾個 RPC 所需要的程序,其實都已經寫入到兩個基本的服務啟動腳本中了,那就是 nfs 以及 nfslock 啰! 亦即是在 /etc/init.d/nfs, /etc/init.d/nfslock,與服務器較有關的寫入在 nfs 服務中,而與客戶端的 rpc.lockd 之類的,就設定于 nfslock 服務中。
* * *
### 13.1.4 NFS 的檔案訪問權限
不知道你有沒有想過這個問題,在[圖 13.1-1](#fig13.1-1) 的環境下,假如我在 NFS client 1 上面以 dmtsai 這個使用者身份想要去存取 /home/data/sharefile/ 這個來自 NFS server 所提供的文件系統時, 請問 NFS server 所提供的文件系統會讓我以什么身份去存取?是 dmtsai 還是?
為什么會這么問呢?這是因為 NFS 本身的服務并沒有進行身份登入的識別, 所以說,當你在客戶端以 dmtsai 的身份想要存取服務器端的文件系統時, 服務器端會以客戶端的使用者 UID 與 GID 等身份來嘗試讀取服務器端的文件系統。這時有個有趣的問題就產生啦! 那就是如果客戶端與服務器端的使用者身份并不一致怎么辦? 我們以底下這個圖示來說明一下好了:

圖 13.1-3、NFS 的服務器端與客戶端的使用者身份確認機制
當我以 dmtsai 這個一般身份使用者要去存取來自服務器端的檔案時,你要先注意到的是: 文件系統的 inode 所記錄的屬性為 UID, GID 而非賬號與群組名。 那一般 Linux 主機會主動的以自己的 /etc/passwd, /etc/group 來查詢對應的使用者、組名。 所以當 dmtsai 進入到該目錄后,會參照 NFS client 1 的使用者與組名。 但是由于該目錄的檔案主要來自 NFS server ,所以可能就會發現幾個情況:
* NFS server/NFS client 剛好有相同的賬號與群組
則此時使用者可以直接以 dmtsai 的身份進行服務器所提供的文件系統之存取。
* NFS server 的 501 這個 UID 賬號對應為 vbird
若 NFS 服務器上的 /etc/passwd 里面 UID 501 的使用者名稱為 vbird 時, 則客戶端的 dmtsai 可以存取服務器端的 vbird 這個使用者的檔案喔!只因為兩者具有相同的 UID 而已。這就造成很大的問題了!因為沒有人可以保證客戶端的 UID 所對應的賬號會與服務器端相同, 那服務器所提供的數據不就可能會被錯誤的使用者亂改?
* NFS server 并沒有 501 這個 UID
另一個極端的情況是,在服務器端并沒有 501 這個 UID 的存在,則此時 dmtsai 的身份在該目錄下會被壓縮成匿名者, 一般 NFS 的匿名者會以 UID 為 65534 為其使用者,早期的 Linux distributions 這個 65534 的賬號名稱通常是 nobody ,我們的 CentOS 則取名為 nfsnobody 。但有時也會有特殊的情況,例如在服務器端分享 /tmp 的情況下, dmtsain 的身份還是會保持 501 但建立的各項數據在服務器端來看,就會屬于無擁有者的資料。
* 如果使用者身份是 root 時
有個比較特殊的使用者,那就是每個 Linux 主機都有的 UID 為 0 的 root 。 想一想,如果客戶端可以用 root 的身份去存取服務器端的文件系統時,那服務器端的數據哪有什么保護性? 所以在預設的情況下, root 的身份會被主動的壓縮成為匿名者。
總之,客戶端使用者能做的事情是與 UID 及其 GID 有關的,那當客戶端與服務器端的 UID 及賬號的對應不一致時, 可能就會造成文件系統使用上的困擾,這個就是 NFS 文件系統在使用上面的一個很重要的地方! 而在了解使用者賬號與 UID 及文件系統的關系之后,要實際在客戶端以 NFS 取用服務器端的文件系統時, 你還得需要具有:
* NFS 服務器有開放可寫入的權限 (與 /etc/exports 設定有關);
* 實際的檔案權限具有可寫入 (w) 的權限。
當你滿足了 (1)使用者賬號,亦即 UID 的相關身份; (2)NFS 服務器允許有寫入的權限; (3)文件系統確實具有 w 的權限時,你才具有該檔案的可寫入權限喔! 尤其是身份 (UID) 確認的環節部分,最容易搞錯啦!也因為如此, 所以 NFS 通常需要與 [NIS (十四章)](http://linux.vbird.org/linux_server/0430nis.php) 這一個可以確認客戶端與服務器端身份一致的服務搭配使用,以避免身份的錯亂啊! ^_^
**Tips:** 老實說,這個小節的數據比較難懂~尤其是剛剛接觸到 NFS server 的朋友。因此,你可以先略過 13.1.4 這個小節。 但是,在你讀完與做完本章后續所有的實作之后,記得回到這個小節來再查閱一次文章內容,相信會有進一步的認識的!

* * *
- 鳥哥的Linux私房菜:服務器架設篇 第三版
- 第一部份:架站前的進修專區
- 作者序
- 第一章、架設服務器前的準備工作
- 1.1 前言: Linux 有啥功能
- 1.2 基本架設服務器流程
- 1.3 自我評估是否已經具有架站的能力
- 1.4 本章習題
- 第二章、基礎網絡概念
- 2.1 網絡是個什么玩意兒
- 2.2 TCP/IP 的鏈結層相關協議
- 2.3 TCP/IP 的網絡層相關封包與數據
- 2.4 TCP/IP 的傳輸層相關封包與數據
- 2.5 連上 Internet 前的準備事項
- 2.6 重點回顧:
- 2.7 本章習題
- 2.8 參考數據與延伸閱讀
- 第三章、局域網絡架構簡介
- 3.1 局域網絡的聯機
- 3.2 本書使用的內部聯機網絡參數與通訊協議
- 第四章、連上 Internet
- 4.1 Linux 連上 Internet 前的注意事項
- 4.2 連上 Internet 的設定方法
- 4.3 無線網絡--以筆記本電腦為例
- 4.4 常見問題說明
- 4.5 重點回顧
- 4.6 本章習題
- 4.7 參考數據與延伸閱讀
- 第五章、 Linux 常用網絡指令
- 5.1 網絡參數設定使用的指令
- 5.2 網絡偵錯與觀察指令
- 5.3 遠程聯機指令與實時通訊軟件
- 5.4 文字接口網頁瀏覽
- 5.5 封包擷取功能
- 5.6 重點回顧
- 5.7 本章習題
- 5.8 參考數據與延伸閱讀
- 第六章、 Linux 網絡偵錯
- 6.1 無法聯機原因分析
- 6.2 處理流程
- 6.3 本章習題
- 6.4 參考數據與延伸閱讀
- 第二部分:主機的簡易資安防護措施
- 第七章、網絡安全與主機基本防護:限制端口, 網絡升級與 SELinux
- 7.1 網絡封包聯機進入主機的流程
- 7.2 網絡自動升級軟件
- 7.3 限制聯機埠口 (port)
- 7.4 SELinux 管理原則
- 7.5 被攻擊后的主機修復工作
- 7.6 重點回顧
- 7.7 課后練習
- 7.8 參考數據與延伸閱讀
- 第八章、路由觀念與路由器設定
- 8.1 路由
- 8.2 路由器架設
- 8.3 動態路由器架設:quagga (zebra + ripd)
- 8.4 特殊狀況:路由器兩邊界面是同一個 IP 網段: ARP Proxy
- 8.5 重點回顧
- 8.6 本章習題
- 8.7 參考數據與延伸閱讀
- 第九章、防火墻與 NAT 服務器
- 9.1 認識防火墻
- 9.2 TCP Wrappers
- 9.3 Linux 的封包過濾軟件:iptables
- 9.4 單機防火墻的一個實例
- 9.5 NAT 服務器的設定
- 9.6 重點回顧
- 9.7 本章習題
- 9.8 參考數據與延伸閱讀
- 第十章、申請合法的主機名
- 10.1 為何需要主機名
- 10.2 注冊一個合法的主機名
- 10.3 重點回顧
- 10.4 本章習題
- 10.5 參考數據與延伸閱讀
- 第三部分:局域網絡內常見的服務器架設
- 第十一章、遠程聯機服務器SSH / XDMCP / VNC / RDP
- 11.1 遠程聯機服務器
- 11.2 文字接口聯機服務器: SSH 服務器
- 11.3 最原始圖形接口: Xdmcp 服務的啟用
- 11.4 華麗的圖形接口: VNC 服務器
- 11.5 仿真的遠程桌面系統: XRDP 服務器
- 11.6 SSH 服務器的進階應用
- 11.7 重點回顧
- 11.8 本章習題
- 11.9 參考數據與延伸閱讀
- 第十二章、網絡參數控管者: DHCP 服務器
- 12.1 DHCP 運作的原理
- 12.2 DHCP 服務器端的設定
- 12.3 DHCP 客戶端的設定
- 12.4 DHCP 服務器端進階觀察與使用
- 12.5 重點回顧
- 12.6 本章習題
- 12.7 參考數據與延伸閱讀
- 第十三章、文件服務器之一:NFS 服務器
- 13.1 NFS 的由來與其功能
- 13.2 NFS Server 端的設定
- 13.3 NFS 客戶端的設定
- 13.4 案例演練
- 13.5 重點回顧
- 13.6 本章習題
- 13.7 參考數據與延伸閱讀
- 第十四章、賬號控管: NIS 服務器
- 14.1 NIS 的由來與功能
- 14.2 NIS Server 端的設定
- 14.3 NIS Client 端的設定
- 14.4 NIS 搭配 NFS 的設定在叢集計算機上的應用
- 14.5 重點回顧
- 14.6 本章習題
- 14.7 參考數據與延伸閱讀
- 第十五章、時間服務器: NTP 服務器
- 15.1 關于時區與網絡校時的通訊協議
- 15.2 NTP 服務器的安裝與設定
- 15.3 客戶端的時間更新方式
- 15.4 重點回顧
- 15.5 本章習題
- 15.6 參考數據與延伸閱讀
- 第十六章、文件服務器之二: SAMBA 服務器
- 16.1 什么是 SAMBA
- 16.2 SAMBA 服務器的基礎設定
- 16.3 Samba 客戶端軟件功能
- 16.4 以 PDC 服務器提供賬號管理
- 16.5 服務器簡單維護與管理
- 16.6 重點回顧
- 16.7 本章習題
- 16.8 參考數據與延伸閱讀
- 第十七章、區網控制者: Proxy 服務器
- 17.1 什么是代理服務器 (Proxy)
- 17.2 Proxy 服務器的基礎設定
- 17.3 客戶端的使用與測試
- 17.4 服務器的其他應用設定
- 17.5 重點回顧
- 17.6 本章習題
- 17.7 參考數據與延伸閱讀
- 第十八章、網絡驅動器裝置: iSCSI 服務器
- 18.1 網絡文件系統還是網絡驅動器
- 18.2 iSCSI target 的設定
- 18.3 iSCSI initiator 的設定
- 18.4 重點回顧
- 18.5 本章習題
- 18.6 參考數據與延伸閱讀
- 第四部分:常見因特網服務器架設
- 第十九章、主機名控制者: DNS 服務器
- 19.1 什么是 DNS
- 19.2 Client 端的設定
- 19.3 DNS 服務器的軟件、種類與 cache only DNS 服務器設定
- 19.4 DNS 服務器的詳細設定
- 19.5 協同工作的 DNS: Slave DNS 及子域授權設定
- 19.6 DNS 服務器的進階設定
- 19.7 重點回顧
- 19.8 本章習題
- 19.9 參考數據與延伸閱讀
- 第二十章、WWW 伺服器
- 20.1 WWW 的簡史、資源以及伺服器軟體
- 20.2 WWW (LAMP) 伺服器基本設定
- 20.3 Apache 伺服器的進階設定
- 20.4 登錄檔分析以及 PHP 強化模組
- 20.5 建立連線加密網站 (https) 及防砍站腳本
- 20.6 重點回顧
- 20.7 本章習題
- 20.8 參考資料與延伸閱讀
- 第二十一章、文件服務器之三: FTP 服務器
- 21.1 FTP 的數據鏈路原理
- 21.2 vsftpd 服務器基礎設定
- 21.3 客戶端的圖形接口 FTP 聯機軟件
- 21.4 讓 vsftpd 增加 SSL 的加密功能
- 21.5 重點回顧
- 21.6 本章習題
- 21.7 參考數據與延伸閱讀
- 第二十二章、郵件服務器: Postfix
- 22.1 郵件服務器的功能與運作原理
- 22.2 MTA 服務器: Postfix 基礎設定
- 22.3 MRA 服務器: dovecot 設定
- 22.4 MUA 軟件:客戶端的收發信軟件
- 22.5 郵件服務器的進階設定
- 22.6 重點回顧
- 22.7 本章習題
- 22.8 參考數據與延伸閱讀