NFS為 Network FileSystem 的簡稱,最早之前是由 Sun 這家公司所發展出來的,他的目的就是想讓不同的機器、不同的作業系統可以彼此分享個別的檔案啦!目前在 Unix Like 當中用來做為 file server 是相當不錯的一個方案喔!基本上, Unix Like 主機連接到另一部 Unix Like 主機來分享彼此的檔案時,使用 NFS 要比 SAMBA 快速且方便的多了!此外, NFS 的設定真的很簡單,幾乎只要記得啟動 Remote Procedure Call 這個咚咚 ( 就是 portmap 這個套件啦! ) 就一定可以架設的起來!真是不錯啊!不過,如果要達成 Windows 與 Linux 之間的溝通,那麼還是以 SAMBA 比較容易啊!無論如何, NFS 還是可以做為小公司或學校單位內部 Unix Like 機器共享 file 的一個 Server 喔! |
例題:
請問我的主機是以 RPM 為套件管理的 Linux distribution ,例如 Red Hat, Mandrake 與 OpenLinux 等版本,那麼我要如何知道我的主機裡面是否已經安裝了 portmap 與 nfs 相關的套件呢? 答: 簡單的使用 rpm -qa | grep nfs 與 rpm -qa | grep portmap 即可知道啦! |
[root@test
root]# vi /etc/exports
[欲分享的目錄] [主機名稱1或IP1(參數1,參數2)] [主機名稱2或IP2(參數3,參數4)] |
[root@test
root]# vi /etc/exports
/tmp *(rw,no_root_squash) |
[root@test
root]# vi /etc/exports
/tmp *(rw,no_root_squash) /home/public 192.168.0.*(rw) *(ro) /home/public 192.168.0.0/24(rw) *(ro) |
[root@test
root]# vi /etc/exports
/tmp *(rw,no_root_squash) /home/public 192.168.0.*(rw) *(ro) /home/test 192.168.0.100(rw) |
[root@test
root]# 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) |
[root@test
root]# 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) |
[root@test
root]# /etc/rc.d/init.d/portmap start<==啟動
portmap !
[root@test root]# /etc/rc.d/init.d/nfs start <==啟動 NFS |
[root@test
root]# vi /var/log/messages
Nov 16 15:04:45 test portmap: portmap startup succeeded Nov 16 15:04:53 test nfs: Starting NFS services: succeeded Nov 16 15:04:54 test nfs: rpc.rquotad startup succeeded Nov 16 15:04:54 test nfs: rpc.mountd startup succeeded Nov 16 15:04:54 test nfs: rpc.nfsd startup succeeded |
語法:
[root@test root]# exportfs [-aruv] 參數說明: -a :全部掛載(或卸載) /etc/exports 檔案內的設定 -r :重新掛載 /etc/exports 裡面的設定,此外,亦同步更新 /etc/exports 及 /var/lib/nfs/xtab 的內容! -u :卸載某一目錄 -v :在 export 的時候,將分享的目錄顯示到螢幕上! 範例: [root@test root]# exportfs -rv <==全部重新 export 一次! exporting 192.168.0.100:/home/test exporting 192.168.0.*:/home/public exporting *.linux.org:/home/linux exporting *:/home/public exporting *:/tmp reexporting 192.168.0.100:/home/test to kernel [root@test root]# exportfs -au <==全部都卸載了! |
[root@test
root]# vi /var/lib/nfs/xtab
/home/test 192.168.0.100(rw,sync,wdelay,hide,secure,root_squash, no_all_squash,subtree_check,secure_locks,mapping=identity,anonuid=-2, anongid=-2) |
語法:
[root@test root]# showmount [-ae] hostname -a :在螢幕上顯示目前主機與 Client 所連上來的使用目錄狀態 -e :顯示 hostname 這部機器的 /etc/exports 裡面的分享目錄! 範例: [root@test root]# showmount -e localhost Export list for localhost: /tmp * /home/linux *.linux.org /home/public (everyone) /home/test 192.168.0.100 |
[root@test
root]# netstat -utln
Active Internet connections (only servers) Proto Recv-Q Send-Q Local Address Foreign Address State tcp 0 0 0.0.0.0:111 0.0.0.0:* LISTEN <==來自 portmap tcp 0 0 0.0.0.0:817 0.0.0.0:* LISTEN <==來自 rpc.xxxx tcp 0 0 0.0.0.0:1266 0.0.0.0:* LISTEN <==來自 rpc.xxxx udp 0 0 0.0.0.0:2049 0.0.0.0:* <==就是 nfs 的 port udp 0 0 0.0.0.0:814 0.0.0.0:* <==來自 rpc.xxxx udp 0 0 0.0.0.0:1327 0.0.0.0:* <==來自 rpc.xxxx udp 0 0 0.0.0.0:111 0.0.0.0:* <==來自 portmap |
語法:
[root@test root]# rpcinfo [-p] hostname(orIP) -p :顯示所有的 port 與 program 的資訊! 範例: [root@test root]# rpcinfo -p test.linux.org program vers proto port 100000 2 tcp 111 portmapper 100000 2 udp 111 portmapper 100011 1 udp 1014 rquotad 100011 2 udp 1014 rquotad 100011 1 tcp 1017 rquotad 100011 2 tcp 1017 rquotad 100003 2 udp 2049 nfs 100003 3 udp 2049 nfs 100021 1 udp 1339 nlockmgr 100021 3 udp 1339 nlockmgr 100021 4 udp 1339 nlockmgr 100005 1 udp 1340 mountd 100005 1 tcp 1271 mountd 100005 2 udp 1340 mountd 100005 2 tcp 1271 mountd 100005 3 udp 1340 mountd 100005 3 tcp 1271 mountd |
OK啦!所以我們得先知道一下我們的主機裡面有什麼?假設我的主機名稱是 test.linux.org ,那麼我要知道裡頭有些什麼藉由 NFS 分享出來的目錄,就給他 showmount 一下囉!
[root@test root]# showmount -e test.linux.org
Export list for localhost:
/tmp *
/home/linux *.linux.org
/home/public (everyone)
/home/test 192.168.0.100
然後呢?假設我要將 /home/public 掛載在我的 /home/nfs/public 底下,那麼我就得先有這個目錄才行呀!然後再利用 mount 這個指令來掛載 /home/public 這個目錄!有點像這樣:
[root@test root]# mkdir -p /home/nfs/public <==建立 public 這個目錄,加 -p 可以持續增加目錄
[root@test root]# mount -t nfs test.linux.org:/home/public /home/nfs/public
掛載的格式:
[root@test root]# mount -t nfs hostname(orIP):/directory /mount/point
[root@test root]# df
Filesystem 1K-blocks Used Available Use% Mounted on
/dev/hda1 1904920 1235380 572776 69% /
/dev/hdb1 976344 115212 810736 13% /backup
test.linux.org:/home/public
1904920 1235376 572776 69% /home/nfs/public <==這個是遠端主機的容量
先注意一下掛載 NFS 檔案的格式範例喔!呵呵!這樣就可以將資料掛載進來啦!請注意喔!以後,只要您進入您的目錄 /home/nfs/public 就等於到了 test.linux.org 那部遠端主機的 /home/public 那個目錄中囉!很不錯吧!那麼如何將掛載的 NFS 目錄卸載呢?就使用 umount 啊!
[root@test root]# umount /home/nfs/public
可能發生的問題:
通常無法掛載的原因有底下這幾個:
- 使用者的權限不符:以上面的例子來說明,我的 /home/test 只能提供 192.168.0.0/24 這個網域,所以,如果我在 test.linux.org 這部機器中,以 localhost 來掛載時,就會無法掛載上,這個權限概念沒問題吧!那麼您可以試試看:
所以囉!如果您發現上面的顯示的訊息時,就表示您的主機權限不能夠進入該目錄囉!如果確定您的 IP 沒有錯誤,那麼請回到 /etc/exports 這個檔案中,針對您自己的 IP 來進行修正吧!
[root @test root]# mount -t nfs localhost:/home/test /home/nfs
mount: localhost:/home/test failed, reason given by server: Permission denied
- 忘記啟動 portmap :
這個最容易被忘記了!就是忘記了啟動 portmap 這個服務啦!如果您發現您的 mount 的訊息是這樣:或者是:
[root@test root]# mount -t nfs localhost:/home/test /home/nfs
mount: RPC: Port mapper failure - RPC: Unable to receive那麼就趕緊將 portmap 啟動吧!!並且也需要將 nfs 重新啟動喔!
[root@test root]# mount -t nfs localhost:/home/test /home/nfs
mount: RPC: Program not registered
[root@test root]# /etc/rc.d/init.d/portmap start
[root@test root]# /etc/rc.d/init.d/nfs restart- 被防火牆擋掉了:
這個也很容易忘記了!那就是重新設定一下您的防火牆,這包含了兩部份,包括 iptables 與 TCP_Wrappers !因為我們啟動了 portmap ,這個東西有兩個資料需要分享出來,一個是 port 111 需要提供出去,因此您的 iptables 規則當中,需要開放這個 port 喔!有點像這樣的幾行字要加入您的 iptables rules 當中:如果您已經開放了這個 port 的連接權限,卻還是無法連接成功,那麼應該就是 TCP_Wrappers 的問題了!檢查一下您的 /etc/hosts.deny 裡頭是否有這行:
iptables -A INPUT -p TCP --dport 111 -j ACCEPT
iptables -A INPUT -p UDP --dport 111 -j ACCEPT果真如此的話,由於 portmap 是由 portmap 這個 daemon 所啟動的,所以您就必須要在 /etc/hosts.allow 裡面加入這一行:
[root@test root]# vi /etc/hosts.deny
ALL: ALL或者是將 ALL 改成您所想要讓他使用 NFS 的網域即可!這樣說可以瞭解了嗎?若想進一步瞭解一下防火牆,請參考前面章節提過的:簡易防火牆建置。
[root@test root]# vi /etc/hosts.allow
portmap: ALL
需要注意的是,由於 NFS 使用的這個 RPC 在 client 端連上主機時,那麼您的主機想要關機,那可就會成為『不可能的任務』!如果您的 Server 上面還有 Client 在連線,那麼您要關機,可能得要等到數個鐘頭才能夠正常的關機成功!嗄!真的假的!不相信嗎?不然您自個兒試試看! ^_^!所以囉,建議您的 NFS Server 想要關機之前,能先『關掉 portmap 與 nfs 』這兩個東西!如果無法正確的將這兩個 daemons 關掉,那麼先以 netstat -utlp 找出 PID ,然後以 kill 將他關掉先!這樣才有辦法正常的關機成功喔!這個請特別特別的注意呢!
好了!一些注意事項講完了之後,再來呢?對了!又是最重要的安全設定方面的問題了!那麼 NFS 可以設定安全的地方有哪裡呢?其實還不少呢?由外而內可以這樣看:防火牆的基本概念請參考『簡易防火牆建置』一文,最好能將該篇文章給他看完,否則還真難瞭解底下在幹嘛∼嗯!假設您已經看完該篇短文了,接著下來我們就得要一步一步的接著建立防火牆囉!
- iptables 防火牆設定;
- TCP_Wrappers 防火牆設定;
- /etc/exports 權限設定。
- 使用 iptables 限制大範圍連線:
假設我們的 NFS 主要是針對內部網路開放而已,而對於外部網路只有對學術網路開放,亦即是 140.0.0.0/8 ,那麼您可以使用這樣的語法:這樣大致上就可以讓 192.168.0.0/24 這個 C Class 的網域與 140.0.0.0/8 這個 A Class 的網域到您的主機裡面來,而其他的連線就視您的原本的 iptables 的狀態而定喔!
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 限制更細的範圍:
事實上,如果您不懂得如何設定 iptables 的話,那也沒關係,我們可以使用 TCP_Wrappers 阿!因為要使用 NFS 就必須要通過 portmap 這一關( 因為要使用 RPC 啦! ),而這個 portmap 可以藉由 TCP_Wrappers 來管理!呵呵!太好了!那麼就將他連線的範圍限制的更小囉!我們可以在 /etc/hosts.allow 裡面規定連上 NFS 主機的主機 IP 與名稱,假設限制中的主機只有 192.168.0.0/24 這個 C class 及 140.116.44.125 這個主機,以及後面接的是 ncku.edu.tw 的網域可以連上我的 NFS 主機,那麼我可以寫成這樣:呵呵!這樣可就設定好囉!很簡單的吧!
[root@test root]# vi /etc/hosts.allow
portmap: 192.168.0.0/255.255.255.0
portmap: 140.116.44.125
portmap: .ncku.edu.tw[root@test root]# vi /etc/hosts.deny
portmap: ALL
- 使用 /etc/exports 設定更安全的權限:
這就牽涉到您的邏輯思考了!怎麼設定都沒有關係,但是在『便利』與『安全』之間,要找到您的平衡點吶!善用 root_squash 及 all_squash 等功能,再利用 anonuid 等等的設定來規範登入您主機的使用者身份!應該還是有辦法提供一個較為安全的 NFS 主機的!通常我們都會約略的建議,不要啟動 NFS Server ,即使要啟動,最好也是針對某個範圍來進行目錄的分享!並且,『要分使用者層級來管理』會比較好一些喔!底下我們就來實際的在您的機器上面搞一個簡單的 NFS server 吧!
- Client 端掛載的問題:
基本上,在 Client 端掛載的時候,為了擔心會不小心剛 NFS 端掛進來的具有 SUID 權限檔案的程式執行!這個很可能會危害到系統的安全呢!因為 SUID 本來就不是很安全的嘛!所以呢,您這個 root 也可以將 NFS 所分享的目錄以較為安全的情況掛載進來!例如:選擇 nosuid 也是一個很不錯的抉擇喔!
[root@test root]# mount -t nfs -o nosuid,ro hostname:/directory /mount/point
假設環境:實地演練:
- 假設我的 Linux 主機為 192.168.0.100 這一部;
- 預計將 /tmp 以可讀寫,並且不限制使用者身份的方式分享給所有 192.168.0.0/24 這個網域中的所有 Linux 工作站;
- 預計開放 /home/nfs 這個目錄,使用的屬性為唯讀,可提供除了網域內的工作站外,向外亦提供資料內容;
- 預計開放 /home/upload 做為 192.168.0.0/24 這個網域的資料上傳目錄,其中,這個 /home/upload 的使用者及所屬群組為 nfs-upload 這個名字,他的 UID 與 GID 均為 210;
- 預計將 /home/andy 這個目錄僅分享給 192.168.0.50 這部 Linux 主機,以提供該主機上面 andy 這個使用者來使用,也就是說, andy 在 192.168.0.50 及 192.168.0.100 均有帳號,且帳號均為 andy ,所以預計開放 /home/andy 給 andy 使用他的家目錄啦!
好了,那麼請您先不要看底下的答案,先自己動筆或者直接在自己的機器上面動手作作看,等到得到您要的答案之後,在看底下的說明吧!整個步驟大致上就是這樣吶!加油喔!
- 首先,就是要建立 /etc/exports 這個檔案的內容囉,您可以這樣寫吧!
大概就是這樣子吧!您可以自行測試看看!
[root @test root]# vi /etc/exports
/tmp 192.168.0.*(rw,no_root_squash)
/home/nfs 192.168.0.*(ro) *(ro,all_squash)
/home/upload 192.168.0.*(rw,all_squash,anonuid=210,anongid=210)
/home/andy 192.168.0.50(rw)
- 再來,就是要建立每個對應的目錄的實際 Linux 權限了!我們一個一個來看:
這樣子一來,權限的問題大概就可以解決囉!
1. /tmp
[root @test root]# ll /
drwxrwxrwt 6 root root 4096 Nov 16 09:07 tmp2. /home/nfs
[root @test root]# mkdir -p /home/nfs <==建立所需要的目錄
[root @test root]# chmod 755 -R /home/nfs <==修改較為嚴格的檔案權限
將目錄與檔案設定成唯讀!不能寫入的狀態,會更保險一點!3. /home/upload
[root @test root]# groupadd -g 210 nfs-upload <==先建立所需要的 210 這個群組
[root @test root]# useradd -g 210 -u 210 -M nfs-upload <==建立需要的使用者名稱
[root @test root]# mkdir -p /home/upload <==建立起目錄了!
[root @test root]# chown -R nfs-upload:nfs-upload /home/upload <==修改擁有者!
如此,則使用者與目錄的權限都設定妥當囉!4. /home/andy
[root @test root]# ll /home
drwx------ 3 andy andy 4096 Oct 28 13:37 andy
- 啟動 portmap 與 nfs 服務:
[root @test root]# /etc/rc.d/init.d/portmap start
[root @test root]# /etc/rc.d/init.d/nfs start- 在 192.168.0.50 這部機器上面演練一下:
1. 確認可用目錄
[andy @linux50 andy]$ showmount -e 192.168.0.100
Export list for 192.168.0.100:
/tmp 192.168.0.*
/home/nfs (everyone)
/home/upload 192.168.0.*
/home/andy 192.168.0.502. 建立掛載點:
[andy @linux50 andy]$ mkdir -p /home/zzz/tmp
[andy @linux50 andy]$ mkdir -p /home/zzz/nfs
[andy @linux50 andy]$ mkdir -p /home/zzz/upload
[andy @linux50 andy]$ mkdir -p /home/zzz/andy3. 實際掛載:
[andy @linux50 andy]$ su <==通常 Linux 只允許 root 來掛載!
[root @linux50 andy]# mount -t nfs 192.168.0.100:/tmp /home/zzz/tmp
[root @linux50 andy]# mount -t nfs 192.168.0.100:/home/nfs /home/zzz/nfs
[root @linux50 andy]# mount -t nfs 192.168.0.100:/home/upload /home/zzz/upload
[root @linux50 andy]# mount -t nfs 192.168.0.100:/home/andy /home/zzz/andy
[root @linux50 andy]# exit
在 LPI 網站 http://www.lpi.org 裡面提到的,關於 NFS 的考試題庫的地方,只有在 LPI level 1 的 102 ,裡面的 topic 113 Networking Services ,第四點當中,簡易的 NFS 設定。強調的是『應試者需瞭解 NFS 的設定、啟動與關閉的關係』至於會考的檔案與指令可能有這些:
- /etc/exports
- /etc/fstab
- mount
- umount