/etc/exports 設定檔的語法與參數
啟動 NFS
NFS 的連線觀察
[root@linux ~]# showmount -e 192.168.0.2
Export list for 192.168.0.2:
/tmp *
/home/linux *.linux.org
/home/public (everyone) <==這是等一下我們要掛載的目錄
/home/test 192.168.0.100
在開始 NFS 伺服器的設定之前,您必須要瞭解的是,
NFS 會直接使用到核心功能,所以你的核心必須要有支援 NFS 才行。 萬一如果你的核心版本小於 2.2 版,或者重新自行編譯過核心的話,那麼就得要很注意啦! 因為你可能會忘記選擇 NFS 的核心支援啊!
還好,我們 CentOS 或者是其他版本的 Linux ,預設核心通常是支援 NFS 功能的, 所以你只要確認你的核心版本是目前新的 2.6.x 版,並且使用你的 distribution 所提供的核心, 那應該就不會有問題啦!
至於 NFS 伺服器的架設實在很簡單, 你只要編輯好主要設定檔 /etc/exports 之後, 先啟動 portmap ,然後再啟動 nfs ,你的 NFS 就成功了! 不過這樣的設定能否對用戶端生效?那就得要考慮你權限方面的設定能力了。 廢話少說,我們就直接來看看那個 /etc/exports 應該如何設定吧! 某些 distributions 並不會主動提供 /etc/exports 檔案,所以請您自行手動建立他吧。
您看看,這個設定檔有夠簡單吧!每一行最前面是要分享出來的目錄,注意喔!是以目錄為單位啊! 然後這個目錄可以依照不同的權限分享給不同的主機,像鳥哥上面的例子說明是: 要將 /tmp 分別分享給三個不同的主機或網域的意思。記得主機後面以小括號 () 設計權限參數, 若權限參數不止一個時,則以逗號 (,) 分開。且主機名與小括號是連在一起的喔! 在這個檔案內也可以利用 # 來註解呢。
至於主機名稱的設定主要有幾個方式:
還好,我們 CentOS 或者是其他版本的 Linux ,預設核心通常是支援 NFS 功能的, 所以你只要確認你的核心版本是目前新的 2.6.x 版,並且使用你的 distribution 所提供的核心, 那應該就不會有問題啦!
至於 NFS 伺服器的架設實在很簡單, 你只要編輯好主要設定檔 /etc/exports 之後, 先啟動 portmap ,然後再啟動 nfs ,你的 NFS 就成功了! 不過這樣的設定能否對用戶端生效?那就得要考慮你權限方面的設定能力了。 廢話少說,我們就直接來看看那個 /etc/exports 應該如何設定吧! 某些 distributions 並不會主動提供 /etc/exports 檔案,所以請您自行手動建立他吧。
[root@linux ~]# vi /etc/exports /tmp 192.168.1.0/24(ro) localhost(rw) *.ev.ncku.edu.tw(ro,sync) # [分享目錄] [第一部主機(權限)] [可用主機名] [可用萬用字元] |
至於主機名稱的設定主要有幾個方式:
- 可以使用完整的 IP 或者是網域,例如 192.168.1.10 或 192.168.1.0/24 ,或 192.168.1.0/255.255.255.0 都可以接受!
- 可以使用主機名稱,這個主機名稱要在 /etc/hosts 內或使用 DNS 可以被找到才行啊!重點是可找到 IP 就是了。如果是主機名稱的話,那麼他可以支援萬用字元,例如 * 或 ? 均可接受。
- rw:read-write,可讀寫的權限;
- ro:read-only,唯讀的權限;
- sync:資料同步寫入到記憶體與硬碟當中;
- async:資料會先暫存於記憶體當中,而非直接寫入硬碟!
- no_root_squash:
登入 NFS 主機使用分享目錄的使用者,如果是 root 的話,那麼對於這個分享的目錄來說,他就具有 root 的權限! 這個項目『極不安全』,不建議使用!
- root_squash:
在登入 NFS 主機使用分享之目錄的使用者如果是 root 時,那麼這個使用者的權限將被壓縮成為匿名使用者,通常他的 UID 與 GID 都會變成 nobody(nfsnobody) 那個系統帳號的身份;
- all_squash:
不論登入 NFS 的使用者身份為何, 他的身份都會被壓縮成為匿名使用者,通常也就是 nobody(nfsnobody) 啦!
- anonuid:
anon 意指 anonymous (匿名者) 前面關於 *_squash 提到的匿名使用者的 UID 設定值,通常為 nobody(nfsnobody),但是您可以自行設定這個 UID 的值!當然,這個 UID 必需要存在於您的 /etc/passwd 當中!
- anongid:同 anonuid ,但是變成 group ID 就是了!
- 思考一:讓 root 保有 root 的權限
我想將 /tmp 分享出去給大家使用,由於這個目錄本來就是大家都可以讀寫的,因此想讓所有的人都可以存取。 此外,我要讓 root 寫入的檔案還是具有 root 的權限,那如何設計設定檔?
參考前面的主機名稱設定說明,我們可以利用萬用字元的。這表示無論來自哪裡都可以使用我的 /tmp 這個目錄。 再次提醒,『 *(rw,no_root_squash) 』這一串設定值中間是沒有空白字元的喔!而 /tmp 與 *(rw,no_root_squash) 則是有空白字元來隔開的! 特別注意到那個 no_root_squash 的功能!在這個例子中,如果你是用戶端,而且您是以 root 的身份登入您的 Linux 主機,那麼當您 mount 上我這部主機的 /tmp 之後,您在該 mount 的目錄當中,將具有『root 的權限!』[root@linux ~]# vi /etc/exports # 任何人都可以用我的 /tmp ,用萬用字元來處理主機名稱,重點在 no_root_squash /tmp *(rw,no_root_squash)
- 思考二:同一目錄針對不同範圍開放不同權限
我要將一個公共的目錄 /home/public 公開出去,但是只有限定我的區域網路內 192.168.0.0/24 這個網域可以讀寫,其他人則只能讀取:
上面的例子說的是,當我的 IP 是在 192.168.0.0/24 這個網段的時候,那麼當我在 Client 端掛載了 Server 端的 /home/public 後,針對這個被我掛載的目錄我就具有可以讀寫的權限~ 至於如果我不是在這個網段之內,那麼這個目錄的資料我就僅能讀取而已,亦即為唯讀的屬性啦![root@linux ~]# vi /etc/exports /tmp *(rw,no_root_squash) /home/public 192.168.0.0/24(rw) *(ro) # 繼續累加在後面,注意,我有將主機與網域分為兩段 (用空白隔開) 喔!
需要注意的是,之前鳥哥將主機名稱的萬用字元與 IP 網段搞錯了! 萬用字元僅能用在主機名稱的分辨上面,IP 或網段就只能用 192.168.0.0/24 的狀況, 不可以使用 192.168.0.* 喔!
- 思考三:僅給某個單一主機使用的目錄設定
我要將一個私人的目錄 /home/test 開放給 192.168.0.100 這個 Client 端的機器來使用,那麼我就必需這麼寫:
這樣就設定完成了!而且,只有 192.168.0.100 這部機器才能對 /home/test 這個目錄進行存取喔![root@linux ~]# vi /etc/exports /tmp *(rw,no_root_squash) /home/public 192.168.0.0/24(rw) *(ro) /home/test 192.168.0.100(rw) # 只要設定 IP 正確即可!
- 思考四:開放匿名登入的情況
我要讓 *.linux.org 網域的主機,登入我的 NFS 主機時,可以存取 /home/linux ,但是他們存資料的時候,我希望他們的 UID 與 GID 都變成 40 這個身份的使用者, 假設我 NFS 伺服器上的 UID 40 已經有設定妥當:上面四個案例的權限如果依照前一小節的存取設定權限來思考的話, 那麼權限會是什麼情況呢?讓我們來檢查一下:
特別注意到那個 all_squash 與 anonuid, anongid 的功能!如此一來,當 test.linux.org 登入這部 NFS 主機,並且在 /home/linux 寫入檔案時,該檔案的所有人與所有群組,就會變成 /etc/passwd 裡面對應的 UID 為 40 的那個身份的使用者了![root@linux ~]# vi /etc/exports /tmp *(rw,no_root_squash) /home/public 192.168.0.0/24(rw) *(ro) /home/test 192.168.0.100(rw) /home/linux *.linux.org(rw,all_squash,anonuid=40,anongid=40) # 如果要開放匿名,那麼重點是 all_squash,並且要配合 anonuid 喔!
- 用戶端與主機端具有相同的 UID 與帳號:
假設我在 192.168.0.100 登入這部 NFS (IP 假設為 192.168.0.2) 主機,並且我在 192.168.0.100 的帳號為 dmtsai 這個身份,同時,在這部 NFS 上面也有 dmtsai 這個帳號, 並具有相同的 UID ,果真如此的話,那麼:
- 由於 192.168.0.2 這部 NFS 主機的 /tmp 權限為 -rwxrwxrwt ,所以我 (dmtsai 在 192.168.0.100 上面) 在 /tmp 底下具有存取的權限,並且寫入的檔案所有人為 dmtsai ;
- 在 /home/public 當中,由於我有讀寫的權限,所以如果在 /home/public 這個目錄的權限對於 dmtsai 有開放寫入的話,那麼我就可以讀寫,並且我寫入的檔案所有人是 dmtsai 。但是萬一 /home/public 對於 dmtsai 這個使用者並沒有開放可以寫入的權限時, 那麼我還是沒有辦法寫入檔案喔!這點請特別留意!
- 在 /home/test 當中,我的權限與 /home/public 相同的狀態!還需要 NFS 主機的 /home/test 對於 dmtsai 有開放權限;
- 在 /home/linux 當中就比較麻煩!因為不論您是何種 user ,您的身份一定會被變成 UID=40 這個帳號!所以,這個目錄就必需要針對 UID = 40 的那個帳號名稱,修改他的權限才行!
- 用戶端與主機端的帳號並未相同時:
假如我在 192.168.0.100 的身份為 vbird ,但是 192.168.0.2 這部 NFS 主機卻沒有 vbird 這個帳號時,情況會變成怎樣呢?
- 我在 /tmp 底下還是可以寫入,但是寫入的檔案所有人變成 nobody 了;
- 我在 /home/public 裡面是否可以寫入,還需要視 /home/public 的權限而定,不過,反正我的身份就被變成 nobody 了就是;
- /home/test 的觀點與 /home/public 相同!
- /home/linux 底下,我的身份就被變成 UID = 40 那個使用者就是了!
- 當用戶端的身份為 root 時:
假如我在 192.168.0.100 的身份為 root 呢? root 這個帳號每個系統都會有呀!權限變成怎樣呢?這樣的權限講解之後,您可以瞭解了嗎?這裡是最重要的地方,如果這一關通過了,底下的咚咚就沒有問題啦! ^_^! 當然啦,您還是得要回到前一小節NFS 的檔案存取權限好好的瞧一瞧, 才能解決 NFS 的問題喔!
- 我在 /tmp 裡面可以寫入,並且由於 no_root_squash 的參數,改變了預設的 root_squash 設定值,所以在 /tmp 寫入的檔案所有人為 root 喔!
- 我在 /home/public 底下的身份還是被壓縮成為 nobody 了!因為預設屬性裡面都具有 root_squash 呢!所以,如果 /home/public 有針對 nobody 開放寫入權限時,那麼我就可以寫入,但是檔案所有人變成 nobody 就是了!
- /home/test 與 /home/public 相同;
- /home/linux 的情況中,我 root 的身份也被壓縮成為 UID = 40 的那個使用者了!
啟動 NFS
設定檔搞定後,當然要開始來啟動才行啊!而前面我們也提到過,NFS 的啟動還需要 portmap 的協助才行啊! 所以趕緊來啟動吧!
那個 portmap 根本就不需要設定!只要直接啟動他就可以啦!
啟動之後,會出現一個 port 111 的 sunrpc 的服務,那就是 portmap 啦!至於 nfs 則會啟動至少兩個以上的 daemon 出現!然後就開始在監聽 Client 端的需求啦!你必須要很注意螢幕上面的輸出資訊, 因為如果設定檔寫錯的話,螢幕上會顯示出錯誤的地方喔!
此外,如果妳想要增加一些 NFS 伺服器的資料一致性功能時,可能需要用到 rpc.lockd 及 rpc.statd 等 RPC 服務, 那麼或許妳可以增加一個服務,那就是 nfslock
啟動之後,請趕快到 /var/log/messages 裡面看看有沒有被正確的啟動呢?
在確認沒有問題之後,接下來我們來瞧一瞧那麼 NFS 到底開了哪些埠口?
注意看到上面喔!總共產生了好多的 port 喔!真是可怕!不過主要的埠口是:
仔細瞧瞧,上面出現的資訊當中除了程式名稱與埠口的對應可以與 netstat -tlunp 輸出的結果作比對之外,還需要注意到 NFS 的版本支援!新的 NFS 版本傳輸速度較快, 由上表看起來,我們的 NFS 至少支援到第 3 版,應該還算合理啦! ^_^! 如果妳的 rpcinfo 無法輸出,那就表示註冊的資料有問題啦!可能需要重新啟動 portmap 與 nfs 喔!
[root@linux ~]# /etc/init.d/portmap start # 如果 portmap 本來就已經在執行了,那就不需要啟動啊! [root@linux ~]# /etc/init.d/nfs start # 有時候可能會出現如下的警告訊息: exportfs: /etc/exports [3]: No 'sync' or 'async' option specified for export "192.168.0.100:/home/test". Assuming default behaviour ('sync'). # 上面的警告訊息僅是在告知因為我們沒有指定 sync 或 async 的參數, # 則 NFS 將預設會使用 sync 的資訊而已。妳可以不理他,也可以加入 /etc/exports。 [root@linux ~]# vi /etc/exports /tmp *(rw,no_root_squash,sync) /home/public 192.168.0.0/24(rw,sync) *(ro,sync) /home/test 192.168.0.100(rw,sync) /home/linux *.linux.org(rw,all_squash,anonuid=40,anongid=40,sync) [root@linux ~]# /etc/init.d/nfs restart |
此外,如果妳想要增加一些 NFS 伺服器的資料一致性功能時,可能需要用到 rpc.lockd 及 rpc.statd 等 RPC 服務, 那麼或許妳可以增加一個服務,那就是 nfslock
[root@linux ~]# /etc/init.d/nfslock start
|
[root@linux ~]# vi /var/log/messages
Sep 22 00:01:37 linux nfs: Starting NFS services: succeeded
Sep 22 00:01:37 linux nfs: rpc.rquotad startup succeeded
Sep 22 00:01:37 linux nfsd[1050]: nfssvc_versbits: +2 +3 +4
Sep 22 00:01:37 linux nfs: rpc.nfsd startup succeeded
Sep 22 00:01:37 linux nfs: rpc.mountd startup succeeded
Sep 22 00:01:37 linux rpcidmapd: rpc.idmapd -SIGHUP succeeded
|
[root@linux ~]# netstat -ultn
Active Internet connections (only servers)
Proto Recv-Q Send-Q Local Address Foreign Address State PID/Program name
tcp 0 0 0.0.0.0:2049 0.0.0.0:* LISTEN -
tcp 0 0 0.0.0.0:803 0.0.0.0:* LISTEN 1047/rpc.rquotad
tcp 0 0 0.0.0.0:111 0.0.0.0:* LISTEN 32503/portmap
tcp 0 0 0.0.0.0:819 0.0.0.0:* LISTEN 1064/rpc.mountd
udp 0 0 0.0.0.0:2049 0.0.0.0:* -
udp 0 0 0.0.0.0:800 0.0.0.0:* 1047/rpc.rquotad
udp 0 0 0.0.0.0:816 0.0.0.0:* 1064/rpc.mountd
udp 0 0 0.0.0.0:111 0.0.0.0:* 32503/portmap
|
- portmap 啟動的 port 在 111;
- NFS 啟動的 port 在 2049;
- 其他 rpc.daemons 啟動的 port 則是隨機產生的,因此需向 port 111 註冊。
[root@linux ~]# rpcinfo [-p] [IP|hostname] 參數: -p :顯示出所有的 port 與 porgram 的資訊; 範例一:顯示出目前這部主機的 RPC 狀態 [root@linux ~]# rpcinfo -p localhost program vers proto port 100000 2 tcp 111 portmapper 100000 2 udp 111 portmapper 100011 1 udp 800 rquotad 100011 2 udp 800 rquotad 100011 1 tcp 803 rquotad 100011 2 tcp 803 rquotad 100003 2 udp 2049 nfs 100003 3 udp 2049 nfs 100003 2 tcp 2049 nfs 100003 3 tcp 2049 nfs 100005 1 udp 816 mountd 100005 1 tcp 819 mountd 100005 2 udp 816 mountd 100005 2 tcp 819 mountd 100005 3 udp 816 mountd 100005 3 tcp 819 mountd # NFS版本 埠口 服務名稱 |
NFS 的連線觀察
在妳的 NFS 伺服器設定妥當之後,我們可以先自我測試一下是否可以連線喔! 就是利用 showmount 這個指令來查閱!
很簡單吧!所以,當您要掃瞄某一部主機他提供的 NFS 分享的目錄時,就使用 showmount -e IP (或hostname) 即可!非常的方便吧!這也是 NFS client 端最常用的指令喔!
事實上 NFS 關於目錄權限設定的資料非常之多!我們可以檢查一下 /var/lib/nfs/etab 就知道了!
上面僅僅是一個小範例,只是....怎麼 anonuid 會是 -2 啊? 其實那個數值是 65536-2 啦!所以得到 65534 ,比對 /etc/passwd , 會發現 CentOS 出現的是 nfsnobody 啦!這個帳號在不同的版本都可能會不一樣的! 另外,
如果有其他用戶端掛載了妳的 NFS 檔案系統時, 那麼該用戶端與檔案系統資訊就會被記錄到 /var/lib/nfs/xtab 裡頭去的!
另外,如果妳想要重新處理 /etc/exports 檔案,當重新設定完 /etc/exports 後需不需要重新啟動 nfs ? 不需要啦!如果重新啟動 nfs 的話,要得要向 RPC 註冊!很麻煩~ 這個時候我們可以透過 exportfs 這個指令來幫忙喔!
要熟悉一下這個指令的用法喔!這樣一來,就可以直接重新 exportfs 我們的記錄在 /etc/exports 的目錄資料
[root@linux ~]# showmount [-ae] [hostname|IP] 參數: -a :顯示目前主機與用戶端的 NFS 連線分享的狀態; -e :顯示某部主機的 /etc/exports 所分享的目錄資料。 範例一:請顯示出剛剛我們所設定好的相關 exports 資訊 [root@linux ~]# showmount -e localhost Export list for localhost: /tmp * /home/linux *.linux.org /home/public (everyone) /home/test 192.168.0.100 |
事實上 NFS 關於目錄權限設定的資料非常之多!我們可以檢查一下 /var/lib/nfs/etab 就知道了!
[root@linux ~]# tail /var/lib/nfs/etab /home/public *(ro,sync,wdelay,hide,nocrossmnt,secure,root_squash,no_all_squash, subtree_check,secure_locks,mapping=identity,anonuid=-2,anongid=-2) # 上面是同一行,可以看出除了 ro, sync, root_squash 等等, # 其實還有 anonuid 及 anongid 等等的設定! /tmp *(rw,sync,wdelay,hide,nocrossmnt,secure,no_root_squash,no_all_squash,subtr ee_check,secure_locks,mapping=identity,anonuid=-2,anongid=-2) # 同樣的,在 /tmp 也有很多的權限相關的參數喔! |
另外,如果妳想要重新處理 /etc/exports 檔案,當重新設定完 /etc/exports 後需不需要重新啟動 nfs ? 不需要啦!如果重新啟動 nfs 的話,要得要向 RPC 註冊!很麻煩~ 這個時候我們可以透過 exportfs 這個指令來幫忙喔!
[root@linux ~]# exportfs [-aruv] 參數: -a :全部掛載(或卸載) /etc/exports 檔案內的設定 -r :重新掛載 /etc/exports 裡面的設定,此外,亦同步更新 /etc/exports 及 /var/lib/nfs/xtab 的內容! -u :卸載某一目錄 -v :在 export 的時候,將分享的目錄顯示到螢幕上! 範例一:重新掛載一次 /etc/exports 的設定 [root@linux ~]# exportfs -arv exporting 192.168.0.100:/home/test exporting 192.168.0.0/24:/home/public exporting *.linux.org:/home/linux exporting *:/home/public exporting *:/tmp 範例二:全部都卸載 [root@linux ~]# exportfs -auv |
[root@linux ~]# showmount -e 192.168.0.2
Export list for 192.168.0.2:
/tmp *
/home/linux *.linux.org
/home/public (everyone) <==這是等一下我們要掛載的目錄
/home/test 192.168.0.100
[root@linux ~]#
mkdir -p /home/nfs/public
[root@linux ~]#
mount -t nfs -o nolock 192.168.0.2:/home/public /home/nfs/public
# 注意一下掛載的語法!『 -t nfs 』指定檔案系統類型,
# IP:/dir 則是指定某一部主機的某個提供的目錄!
# 注意一下掛載的語法!『 -t nfs 』指定檔案系統類型,
# IP:/dir 則是指定某一部主機的某個提供的目錄!
[root@linux ~]# df
Filesystem 1K-blocks Used Available Use% Mounted on
....中間省略....
192.168.0.2:/home/public
10080512 2135072 7433344 23% /home/nfs/public
Filesystem 1K-blocks Used Available Use% Mounted on
....中間省略....
192.168.0.2:/home/public
10080512 2135072 7433344 23% /home/nfs/public
[root@linux ~]# umount /home/nfs/public