Linux網絡服務——NFS全攻略

一、NFS簡介
1.什麼是NFS(Network FileSystem)
NFS 就是 Network FileSystem 的縮寫,最早之前是由 Sun 所發展出來的。他最大的功能就是可以透過網絡,讓不同的機器、不同的操作系統、可以彼此分享個別的檔案 ( share file ),所以,也可以簡單的將他看做是一個 file server,這個 NFS Server 可以讓你的 PC 來將網絡遠程的 NFS 主機分享的目錄,掛載到本地端的機器當中,所以,在本地端的機器看起來,那個遠程主機的目錄就好象是自己的 partition 一般!
雖然 NFS 有屬於自己的協議與使用的 port number ,但是在資料傳送或者其它相關訊息傳遞的時候, NFS 使用的則是一個稱爲遠程過程調用( Remote Procedure Call, RPC )的協議來協助 NFS 本身的運作!

2.RPC
當我們在使用某些服務來進行遠程聯機的時候,有些信息,例如主機的IP、服務的端口、與對應到的服務的PID 等等,都需要管理與對應!這些管理 port 的對應與服務相關性的工作,就是這個 Remote Procedure Call, RPC 的任務了

NFS 本身的服務並沒有提供資料傳遞的協議,但是 NFS 卻能讓我們進行檔案的分享,這其中的原因,就是 NFS 使用到一些其它相關的傳輸協議!而這些傳輸的協議,就是使用到這個所謂的 RPC 的功能!
也就是說, NFS 本身就是使用 RPC 的一個 program 就是了!所以只要用到NFS的地方都要啓動RPC服務,不論是NFS SERVER或者NFS CLIENT。這樣SERVER和CLIENT才能通過RPC來實現PROGRAM PORT的對應。可以這麼理解RPC和NFS的關係:NFS是一個文件系統,而RPC是負責負責信息的傳輸。這樣 Server 端與 Client 端才能藉由 RPC 的協議來進行 program port 的對應喔!NFS 主要在管理分享出來的目錄,而至於資料的傳遞,就直接將他丟給 RPC 的協議來運作就是了!


二、各NFS協議版本的主要區別 更多內容可以參閱http://www.networkdictionary.cn/protocols/nfs.php
V3相對V2的主要區別:
1、文件尺寸
V2最大隻支持32BIT的文件大小(4G),而NFS V3新增加了支持64BIT文件大小的技術。
2、文件傳輸尺寸
V3沒有限定傳輸尺寸,V2最多隻能設定爲8k,可以使用-rsize and -wsize 來進行設定。
3、完整的信息返回
V3增加和完善了許多錯誤和成功信息的返回,對於服務器的設置和管理能帶來很大好處。
4、增加了對TCP傳輸協議的支持
V2只提供了對UDP協議的支持,在一些高要求的網絡環境中有很大限制,V3增加了對TCP協議的支持
*5、異步寫入特性
6、改進了SERVER的mount性能
7、有更好的I/O WRITES 性能。
9、更強網絡運行效能,使得網絡運作更爲有效。
10、更強的災難恢復功能。
異步寫入特性(v3新增加)介紹:
NFS V3 能否使用異步寫入,這是可選擇的一種特性。NFS V3客戶端發發送一個異步寫入請求到服務器,在給客戶端答覆之前服務器並不是必須要將數據寫入到存儲器中(穩定的)。服務器能確定何時去寫入數據或者將多個寫入請求聚合到一起並加以處理,然後寫入。客戶端能保持一個數據的copy以防萬一服務器不能完整的將數據寫入。當客戶端希望釋放這個copy的時候,它會向服務器通過這個操作過程,以確保每個操作步驟的完整。異步寫入能夠使服務器去確定最好的同步數據的策略。使數據能儘可能的同步的提交何到達。與V2比較來看,這樣的機制能更好的實現數據緩衝和更多的平行(平衡)。而NFS V2的SERVER在將數據寫入存儲器之前不能再相應任何的寫入請求。
V4相對V3的改進:
1:改進了INTERNET上的存取和執行效能
2:在協議中增強了安全方面的特性
3:增強的跨平臺特性

三、NFS所需要的軟件

NFS需要有兩個套件才行,分別是:
nfs-utils
就是提供 rpc.nfsd 及 rpc.mountd 這兩個 NFS daemons 與其它相關 documents 與說明文件、執行檔等的套件!這個就是 NFS 的主要套件
portmap
就如同剛剛提的到,我們的 NFS 其實可以被視爲一個 RPC server program,而要激活任何一個 RPC server program 之前,我們都需要做好 port 的對應 ( mapping ) 的工作才行,這個工作其實就是portmap這個服務所負責的!也就是說,在激活任何一個 RPC server 之前,我們都需要激活 portmap 才行呢!那麼這個 portmap 到底在幹嘛呢?就如同這個服務的名稱,哈哈!就是作 port 的 mapping 啊!
舉個例子來說:當 Client 端嘗試來使用 RPC server 所提供的服務時,由於 Client 需要取得一個可以連接的 port 才能夠使用 RPC server 所提供的服務,因此, Client 首先就會去跟 portmap 聯繫一個port number ,好讓Client可以跟 RPC 聯絡,這個時候 portmap 就自動的將自己管理的 port mapping 告知 Client ,好讓他可以連接上來 server!所以說:在激活 NFS 之前,要先激活portmap

運行nfs所需要的後臺進程:
rpcinfo -p 127.0.0.1

rpc.nfsd管理clinet是否有權限登錄,以及判別登錄者的uid等;
rpc.mountd讀取/etc/exports的權限,對文件訪問權限進行控制;
rpc.lockd文件的互斥鎖,保證文件在同一時間只有一個人訪問,需要nfslockd服務;
rpc.statd檢查文件的一致性,需要nfslockd服務。


四、CLIENT和SERVER的具體操作和設置

(一)NFS server端的設定:
1.配置文件參數
a)./etc/exports
分享的目錄 主機名稱1或IP1(參數1,參數2) 主機名稱2或IP2(參數3,參數4)
b).參數
可以設定的參數主要有以下這些:
rw:read & write,可讀可寫;
ro:read only,只讀;
sync:數據同步寫入;
async:數據先暫時放於內存,而非直接寫入硬盤;
no_root_squash:使用nfs時,如果用戶是root,不進行權限壓縮,即root用戶在nfs上創建的文件 屬組和屬主仍然是root(既不安全,不建議使用);
root_squash:使用nfs時,如果用戶是root,則進行權限壓縮,即把root用戶在nfs上創建的文件 屬組和屬主修改爲nfsnobody;
all_squash:所有的用戶使用nfs都將使用權限壓縮;
anonuid:anon即anonymous(匿名者),前面關於*_squash提到的匿名用戶的uid的設置值,通常爲 nobody或者nfsnobody,使用這個參數可以自行設定這個uid值,這個uid必須存 在於/etc/passwd;
anonuid:anon即anonymous(匿名者),前面關於*_squash提到的匿名用戶的gid的設置值,通常爲 nobody或者nfsnobody,使用這個參數可以自行設定這個gid值,這個gid必須存在 於/etc/passwd。
insecure 允許從這臺機器過來的非授權訪問。

2.設置的實例:
a). /tmp *(rw,no_root_squash) //*號表示所有的IP都可以訪問
b). /tmp *(rw)
/home/public 192.168.0.*(rw) *(ro) //下面兩行作用一樣
/home/public 192.168.0.0/24(rw) *(ro)
c). /home/test 192.168.0.100(rw) //只對某部機器設置權限
d). /home/linux *.linux.org(rw,all_squash,anonuid=40,anongid=40) //當*.linux.org登陸此NFS主機,並且在/home/linux下面寫入檔案時,該檔案的所有人與所有組,就會變成/etc/passwd 裏面對應的UID爲40的那個身份的使用者了.

3.權限問題
假設/etc/exports裏面的內容爲
#vi /etc/exports
/tmp *(rw,no_root_squash)
/home/public 192.168.0.*(rw) *(ro)
/home/test 192.168.0.100(rw)
/home/linux *.linux.org(rw,all_squash,anonuid=40,anongid=40)

假設我們在192.168.0.100這個client端登陸此NFS主機(192.168.0.2),那麼

情況一:在192.168.0.100的帳號爲test這個身份,同時,NFS主機上也有test這個帳號
a).由於NFS主機的/tmp權限爲-rwxrwxrwt,所以我(test在192.168.0.100上)在/tmp下面具有存取的權限,並且寫入檔案的所有人爲test.
b).在/home/public中,由於我有讀寫的權限,如果NFS主機在/home/public這個目錄的權限對於test開放寫入的話,那麼就可以讀寫,並且寫入檔案的所有人是test。如果NFS主機的/home/public對於test這個使用者並沒有開放寫入權限時,那就無法寫入,雖然 /etc/exports裏面是rw,也不起作用.
c).在/home/test中,權限與/home/public有相同的狀態,需要NFS主機的/home/test對於test有開放的權限.
d).在/home/linux當中,不論是何種的user,身份都會被變成UID=40的這個帳號

情況二:如果我們在192.168.0.100的身份爲test2,但是NFS主機卻沒有test2這個帳號時
a).在/tmp下還是可以寫入,但是寫入的檔案所有人變成nobody.
b).在/home/public與/home/test裏面是否可以寫入,還需要看/home/public的權限而定,不過身份就被變成nobody了
c)/home/linux下的身份還是變成UID=40的帳號.
情況三:在192.168.0.100的身份爲root
a).在/tmp裏面可以寫入,但是由於no_root_squash的參數,改變了預設的root_squash的設定值,所以在/tmp寫入檔案的所有人爲root了.
b).在/home/public底下的身份被壓縮成了nobody,因爲預設的屬性都具有root_squash,所以檔案所有人就變成了nobody.
c)./home/test情況與/home/public相同.
d)./home/linux中,root的身份也被壓縮成UID=40的那個使用者了.

4.啓動服務portmap,nfs

#/etc/init.d/portmap start
#/etc/init.d/nfs start
#/etc/init.d/nfslock start

可以到/var/log/messages裏面查看是否正確激活

在客戶端連接使用nfs:
#/etc/init.d/portmap start
#/etc/init.d/nfslock start
# showmount -e 192.168.0.228

 


5.exportfs的用法
如果我們修改了/etc/exports後,並不需要重啓nfs服務,只要用exportfs重新掃描一次/etc/exports,並且重新加載即可
語法: exportfs [-aruv]
-a :全部mount或者unmount /etc/exports中的內容
-r :重新mount /etc/exports中分享出來的目錄
-u :umount 目錄
-v :在 export 的時候,將詳細的信息輸出到屏幕上。


#exportfs -rv //重新export一次
#exportfs -au //全部卸載
#exporting 192.168.0.100:/home/test
#exporting 192.168.0.*:/home/public
#exporting *.the9.com:/home/linux
#exporting *:/home/public
#exporting *:/tmp
#reexporting 192.168.0.100:/home/test to kernel

6./var/lib/nfs/etab裏面可以查看每個目錄的分享權限如:
/nfs *(rw,sync,wdelay,hide,nocrossmnt,secure,root_squash,no_all_squash,no_subtree_check,secure_locks,acl,mapping=identity,anonuid=65534,anongid=65534)
對照一下 /etc/passwd ,你就會發現,65534這個UID的用戶是nfsnobody

7.showmount命令
語法: showmount [-ae] hostname(IP)
-a :這個參數是一般在NFS SERVER上使用,是用來顯示已經mount上本機nfs目錄的cline機器。
-e :顯示指定的NFS SERVER上export出來的目錄。

 

(二)NFS客戶端的設定
#mount -t nfs hostname(orIP):/directory /mountpoint
爲了擔心會不小心將 NFS 端掛進來的具有 SUID 權限檔案的程序執行,root可以將NFS 所分享的目錄以較爲安全的情況掛載進來,可以
#mount -t nfs -o nosuid,ro hostname:/directory /mountponit

mount nfs的其它可選參數: (當然這也可以把這些參數寫入/etc/fastab,下面有關於FSTAB的說明)
soft #當服務器端沒回應時,會在timeout後重新連接,傳回錯誤信息
hard #當服務器端沒回應時持續在後臺嘗試連接
intr #當正在進行 NFS 請求時,允許用鍵盤中斷
nointr #當正在進行 NFS 請求時,不允許用鍵盤中斷
timeo #請求過期時間,單位爲秒
bg #當第一次請求不成功,第二次的mount將放到後臺執行
fg #一直在前臺發送請求
proto=tcp|udp #修改使用TCP協議還是UDP協議來傳輸nfs的數據
default #hard和nointr
rsize #讀操作的塊大小,這個設置影響服務器和客戶端的nfs緩存大小,如果有充足的內存和網 絡帶寬,可以設置高些,如32768(bytes);
wsize #寫操作的塊大小,這個設置影響服務器和客戶端的nfs緩存大小,如果有充足的內存和網 絡帶寬,可以設置高些,如32768(bytes)。


autofs 能夠自動掛載卸載nfs和文件系統,並且在空閒的時候能夠關閉nfs連接,降低系統負載。使用autofs要先關閉netfs服務,並註釋掉/etc/fstab裏關於nfs的內容。

下面是如何使用autofs來自動掛載nfs服務:

#chkconfig --level 35 autofs on
/etc/init.d/autofs start
vi /etc/auto.master
/nfs /etc/auto.nfs --timeout=60
vi /etc/auto.nfs
public -ro,soft,intr 192.168.0.228:/data
reboot
cd /nfs
# ls
# mount
/dev/hda1 on / type ext3 (rw)
proc on /proc type proc (rw)
sysfs on /sys type sysfs (rw)
devpts on /dev/pts type devpts (rw,gid=5,mode=620)
tmpfs on /dev/shm type tmpfs (rw)
/dev/hda2 on /web type ext3 (rw)
none on /proc/sys/fs/binfmt_misc type binfmt_misc (rw)
sunrpc on /var/lib/nfs/rpc_pipefs type rpc_pipefs (rw)
# cd public
# mount
/dev/hda1 on / type ext3 (rw)
proc on /proc type proc (rw)
sysfs on /sys type sysfs (rw)
devpts on /dev/pts type devpts (rw,gid=5,mode=620)
tmpfs on /dev/shm type tmpfs (rw)
/dev/hda2 on /web type ext3 (rw)
none on /proc/sys/fs/binfmt_misc type binfmt_misc (rw)
sunrpc on /var/lib/nfs/rpc_pipefs type rpc_pipefs (rw)
192.168.0.228:/data on /nfs/public type nfs (ro,soft,intr,addr=192.168.0.228)


同時使用多個參數的方法:mount -t nfs -o timeo=3,udp,hard 192.168.0.30:/tmp /nfs
請注意,NFS客戶機和服務器的選項並不一定完全相同,而且有的時候會有衝突。比如說服務器以只讀的方式導出,客戶端卻以可寫的方式mount,雖然可以成功mount上,但嘗試寫入的時候就會發生錯誤。一般服務器和客戶端配置衝突的時候,會以服務器的配置爲準。

 


五、/etc/fstab的設定方法

要開機掛載nfs文件系統還需要開啓netfs服務,並且把掛載項寫入到/etc/fstab。
/etc/fstab的格式如下:
fs_spec   fs_file  fs_type   fs_options  fs_dump fs_pass 
fs_spec:該字段定義希望加載的文件系統所在的設備或遠程文件系統,對於nfs這個參數一般設置爲這樣:192.168.0.1:/NFS
fs_file:本地的掛載點
fs_type:對於NFS來說這個字段只要設置成nfs就可以了
fs_options:掛載的參數,可以使用的參數可以參考上面的mount參數。
fs_dump - 該選項被"dump"命令使用來檢查一個文件系統應該以多快頻率進行轉儲,若不需要轉儲就設置該字段爲0
fs_pass - 該字段被fsck命令用來決定在啓動時需要被掃描的文件系統的順序,根文件系統"/"對應該字段的值應該爲1,其他文件系統應該爲2。若該文件系統無需在啓動時掃描則設置該字段爲0 。

 

六、與NFS有關的一些命令介紹
nfsstat:
查看NFS的運行狀態,對於調整NFS的運行有很大幫助

rpcinfo -p hostname(orIP):
查看rpc執行信息,可以用於檢測rpc運行情況的工具。

 

七、可能出問題的地方:
1.權限的設定不符合
2.忘記了激活portmap,此時會報錯:
mount: RPC: Port mapper failure - RPC: Unable to receive 或者
mount: RPC: Program not registered
那麼,啓動portmap,並且重新啓動nfs
#service portmap start
#service nfs restart
3.被防火牆搞掉
重新設置防火牆,包括iptables與TCP_Wrappers,因爲激活了portmap,所以port 111必須提供出去.因此在iptables rules中,要增加:
iptables -A INPUT -p TCP --dport 111 -j ACCEPT
iptables -A INPUT -p UDP --dport 111 -j ACCEPT

如果還不行,那就是TCP_Wrappers的問題,檢查/etc/hosts.deny,如果有一行是:
ALL: ALL: deny

那就必須在/etc/hosts.allow中增加:

portmap: ALL: allow

如果我們的NFS針對內部網絡開發,對於外部網絡只對學術網絡開發(140.0.0.0/8),可以:
iptables -A INPUT -i eth0 -p TCP -s 192.168.0.0/24 --dport 111 -j ACCEPT
iptables -A INPUT -i eth0 -p UDP -s 192.168.0.0/24 --dport 111 -j ACCEPT
iptables -A INPUT -i eth0 -p TCP -s 140.0.0.0/8 --dport 111 -j ACCEPT
iptables -A INPUT -i eth0 -p UDP -s 140.0.0.0/8 --dport 111 -j ACCEPT

還可以使用TCP_Wrappers,在/etc/hosts.allow裏面規定連上 NFS 主機的主機 IP 與名稱,例如
#vi /.etc/hosts.allow
portmap: 192.168.0.0/255.255.255.0 :allow
portmap: 140.113.23.23 :allow
portmap: .sdu.edu.cn :allow

4、cant contact portmapper: RPC: Remote system error - Connection refused
出現這個錯誤信息是由於SEVER端的PORTMAP沒有啓動。
5、mount clntudp_create: RPC: Program not registered
NFS沒有啓動起來,可以用showmout -e host命令來檢查NFS SERVER是否正常啓動起來。
6、mount: localhost:/home/test failed, reason given by server: Permission denied
這個提示是當client要mount nfs server時可能出現的提示,意思是說本機沒有權限去mount nfs server上的目錄。解決方法當然是去修改NFS SERVER咯。

 

八、NFS安全
NFS的不安全性主要體現於以下4個方面:
1、新手對NFS的訪問控制機制難於做到得心應手,控制目標的精確性難以實現
2、NFS沒有真正的用戶驗證機制,而只有對RPC/Mount請求的過程驗證機制
3、較早的NFS可以使未授權用戶獲得有效的文件句柄
4、在RPC遠程調用中,一個SUID的程序就具有超級用戶權限.
加強NFS安全的方法:
1、合理的設定/etc/exports中共享出去的目錄,最好能使用anonuid,anongid以使MOUNT到NFS SERVER的CLIENT僅僅有最小的權限,最好不要使用root_squash。
2、使用IPTABLE防火牆限制能夠連接到NFS SERVER的機器範圍
iptables -A INPUT -i eth0 -p TCP -s 192.168.0.0/24 --dport 111 -j ACCEPT
iptables -A INPUT -i eth0 -p UDP -s 192.168.0.0/24 --dport 111 -j ACCEPT
iptables -A INPUT -i eth0 -p TCP -s 140.0.0.0/8 --dport 111 -j ACCEPT
iptables -A INPUT -i eth0 -p UDP -s 140.0.0.0/8 --dport 111 -j ACCEPT
3、爲了防止可能的Dos攻擊,需要合理設定NFSD 的COPY數目。
4、修改/etc/hosts.allow和/etc/hosts.deny達到限制CLIENT的目的
/etc/hosts.allow
portmap: 192.168.0.0/255.255.255.0 : allow
portmap: 140.116.44.125 : allow
/etc/hosts.deny
portmap: ALL : deny
5、改變默認的NFS 端口
NFS默認使用的是111端口,但同時你也可以使用port參數來改變這個端口,這樣就可以在一定程度上增強安全性。
6、使用Kerberos V5作爲登陸驗證系統

 

要注意的問題:


關機時如果NFS Server上面還有Client聯機,建議NFS Server關機之前,要先關掉portmap與nfs這兩個系統服務。如果無法正確地將這兩個系統服務關掉,那麼先以netstat -utlp找出PID,然後使用kill殺掉進程,這樣才能正常關機。

如果要載Windows系統中使用NFS共享目錄,需要使用 Omini Lite 軟件,這個我沒有測試,大家有興趣的,可以安裝上來試試。

 

【案例1】架設一臺NFS服務器,並按照以下要求配置輸出目錄

(1)開放/nfs/shared目錄,供所有用戶查閱資料。

(2)開放/nfs/upload目錄作爲192.168.85.0/24網段的數據上傳目錄,並將所有用戶及所屬的用戶組都映射爲nfs-upload,其UID與GID均爲210。

(3)將/home/tom目錄僅共享給192.168.85.129這臺主機,並且只有用戶tom可以完全訪問該目錄。

# mkdir -p /nfs/shared
# mkdir -p /nfs/upload
# chmod 777 /nfs/upload
# useradd tom
# useradd -u 600 test

# vim /etc/exports
/nfs/shared *(ro)
/nfs/upload 192.168.85.0/24(rw,all_squash,anonuid=210,anongid=210)
/home/tom 192.168.85.128(rw)

注意一點:這裏要注意tom兩邊的UID必需要一致否則不能實現第3個要求

發佈了37 篇原創文章 · 獲贊 1 · 訪問量 3萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章