1. 准备工作
2. NFS的由来与其功能
2.1 什么是NFS ( Network FileSystem )
2.2 什么是RPC ( Remote Procedure Call )
2.3 NFS启动的RPC daemons
2.4 NFS的文件存取权限
3. NFS Server 端的设定
3.1 所需要的套件
3.2 NFS的套件结构
3.3 /etc/exports 配置文件的语法与参数
3.4 NFS服务的启动:rpcinfo
3.5 NFS的连接观察: showmount, /var/lib/nfs/etab, exportfs
3.6 NFS的安全性
4. NFS 客户端的设定
4.1 远端NFS服务器的挂载
4.2 客户端可处理的挂载参数与开机挂载
4.3 无法挂载的原因分析
4.4 自动挂载 autofs 的使用
5. 案例演练
6. 参考资料
1、准备工作
NFS 这个借由网路分享文件系统的服务在架设的时候是很简单的,不过,他最大的问题在于『权限』方面的概念!因为在客户端与服务器端可能必须要具备相同的账号才能够存取某些目录或档案。 另外,NFS的启动需要透过所谓的远端程序呼叫 (RPC),也就是说,我们并不是只要启动NFS就好了,还需要启动RPC这个服务才行!
2、 NFS的由来与其功能
2.1 什么是 NFS (Network FileSystem)
NFS(Network File System)是一种分布式文件系统,允许网络中的安装不同操作系统的计算机间共享文件和外设,所以它的通讯协定设计与主机及操作系统无关. 它是由SUN公司于1984年推出,使得可以本地机一样的使用另一台联网计算机的文件和外设。NFS在文件传送或信息传送过程中依赖于RPC协议。
图一、NFS 主机分享目录与 Client 挂载示意图
就如同上面的图示一般,当我们的NFS Server设定好共享出来的/home/sharefile这个目录后,其他的NFS Client端就可以将这个目录挂载到自己系统上面的某个挂载点(挂载点可以自定义),例如前面图示中的NFS client 1与NFS client 2挂载的目录就不相同。我只要在 NFS client 1系统中进入/home/data/sharefile内,就可以看到 NFS Server系统内的/home/sharefile目录下的所有资料了 (当然,权限要足够)。这个 /home/data/sharefile 就好像 NFS client 1自己机器里面的一个 partition。只要权限对了,那么您可以使用 cp, cd, mv, rm... 等等磁盘或文件相关的命令。
好的,既然NFS是通过网络来进行文件的传输,那么经由socket pair的概念你会知道NFS应该会使用一些port吧?那么NFS使用哪个 port来进行传输呢?答案是....不知道?因为NFS用来传输的port是随机选择小于1024以下的端口来使用的。那客户端怎么知道你服务器端使用那个port呢?此时就得要远程过程调用(Remote Procedure Call, RPC)的协议来辅助,下面我们就来谈谈什么是 RPC?
2.2 什么是 RPC (Remote Procedure Call)
RPC, 远程过程调用 (remote procedure call)是能使客户端执行其他系统中程序的一种机制。由于使用 RPC 的程序不必了解支持通信的网络协议的情况,因此 RPC 提高了程序的互操作性。常用于分布式客户端/服务器模型,发出请求的程序是客户程序,而提供服务的程序是服务器。
因为NFS支持的功能相当的多,而不同的功能都会使用不同的程序来启动,每启动一个功能就会启用一些 port 来传输文件,因此, NFS 的功能所对应的 port 才没有固定, 而是采用随机取用一些未被使用的小于 1024 的端口来作为传输之用。但如此一来又造成客户端想要连上服务器时的困拢, 因为客户端得要知道服务器端的相关端口才能够连接!
此时我们就得需要远程过程调用(RPC) 的服务,RPC 最主要的功能就是在指定每个 NFS 功能所对应的 port number ,并且返回给客户端,让客户端可以连结到正确的端口上去。 那 RPC 又是如何知道每个 NFS 的端口呢?这是因为当服务器在启动 NFS 时会随机取用数个端口,并主动的向 RPC 注册,因此 RPC 可以知道每个端口对应的 NFS 功能,然后 RPC 又是固定使用 port 111 来监听客户端的需求并返回客户端正确的端口。
注:在启动 NFS 之前,RPC 就要先启动了,否则NFS会无法向 RPC 注册。 另外,RPC若重新启动时,原来注册的资料会不见,因此RPC重新启动后,它管理的所有程序都需要重新启动以重新向RPC注册。
图二、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 的一种。 此外,由图二你也会知道,不论是客户端还是服务器端,要使用 NFS 时,两者都需要启动 RPC 才行。
更多的 NFS 相关协议信息你可以参考下面网页:
http://www.faqs.org/rfcs/rfc1094.html
http://www.tldp.org/HOWTO/NFS-HOWTO/index.html
2.3 NFS启动的RPC daemons
我们现在知道NFS服务器在启动的时候就得要向RPC注册,所以NFS服务器也被称为RPC server之一。那么NFS服务器主要的任务是进行文件系统的共享,文件系统的共享则与权限有关。 所以 NFS 服务器启动时至少需要两个 daemons ,一个管理client端是否能够登入的问题,一个管理client端能够取得的权限。如果你还想要管理quota的话,那么NFS还得要再载入其他的RPC程序。我们以较单纯的NFS主机来说:
rpc.nfsd:
这个 daemon 主要的功能就是在管理 Client 是否能够登入主机的权限,其中还包含这个登入者的 ID 的判别。
rpc.mountd
这个daemon主要的功能,则是在管理NFS的文件系统,当Client端顺利的通过rpc.nfsd而登入主机之后,在他可以使用NFS服务器提供的文件之前,还会经过文件使用权限 (就是那个-rwxrwxrwx与owner, group那几个权限)的认证程序!它会去读NFS的配置文件/etc/exports 来比对Client的权限,当通过这一关之后Client就可以取得使用NFS文件的权限(注:这个也是我们用来管理NFS共享之目录的使用权限与安全设定的地方)
rpc.lockd (非必要)
这个玩意儿可以用在管理文件的锁定(lock)用途。为何文件需要『锁定』呢?因为既然分享的NFS文件可以让客户端使用,那么当多个客户端同时尝试写入某个文件时,就可能对于该文件造成一些问题啦!这个rpc.lockd则可以用来克服这个问题。 但rpc.lockd必须要同时在客户端与服务器端都开启才行,此外,rpc.lockd也常与rpc.statd 同时启用。
rpc.statd (非必要)
可以用来检查文件的一致性,与rpc.lockd有关!若发生因为客户端同时使用同一文件造成文件可能有所损毁时, rpc.statd 可以用来检测并尝试回复该文件。与 rpc.lockd同样的,这个功能必须要在服务器端与客户端都启动才会生效。
2.4 NFS的文件存取权限
不知道你有没有想过这个问题,在图一的环境下,假如我在NFS client 1上面以dmtsai这个使用者身份想要去存取 /home/data/sharefile/这个来自NFS server所提供的文件系统时,请问NFS server所提供的文件系统会让我以什么身份去存取?是 dmtsai 还是?
为什么会这么问呢?这是因为NFS本身的服务并没有进行身份登入的识别,所以说,当你在客户端以dmtsai的身份想要存取服务器端的文件系统时,服务器端会以客户端的使用者UID与GID等身份来尝试读取服务器端的文件系统。这时有个有趣的问题就产生啦!那就是如果客户端与服务器端的使用者身份并不一致怎么办?
我们以下面这个图示来说明一下:
图三、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 ,我们的RHEL4则取名为nfsnobody 。
如果使用者身份是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这一个可以确认客户端与服务器端身份一致的服务搭配使用,以避免身份的错乱
3、NFS Server 端的设定
既然要使用NFS的话,就得要安装NFS所需要的套件,下面让我们查询一下系统有无安装所需要的套件, NFS套件的架构以及如何设定 NFS主机。^
3.1 所需要的套件
以RHEL 4为例的话,要设定好NFS服务器我们必须要有两个套件才行,分别是:
NFS 主程序:nfs-utils
RPC 主程序:portmap
portmap
就如同刚刚提的到,我们的NFS其实可以被视为一个RPC程序,而要启动任何一个RPC程序之前,我们都需要做好port的对应 (mapping) 的工作才行,这个工作其实就是『portmap』这个服务所负责的!也就是说, 在启动任何一个RPC server之前,我们都需要启动portmap才行!
nfs-utils
就是提供 rpc.nfsd 及 rpc.mountd 这两个 NFS daemons 与其他相关 documents 与说明文件、执行档等的套件!这个就是 NFS 的主要套件。
判断系统中是否已安装NFS相关包
RHEL4 系统的情况;其它版本的Redhat及Fedora的系统和这相似;
#rpm -qa | grep nfs
nfs-utils-1.0.6-65.EL4
#rpm -qa | grep portmap
portmap-4.0-63
3.2 NFS的套件结构
/etc/exports
这个文件就是NFS的主要配置文件。系统可能没有预设,所以这个文件不一定会存在,您可能必须要使用 vi 主动的建立这个文件。
/usr/sbin/exportfs
这个是维护NFS共享资源的命令,我们可以利用这个命令重新共享 /etc/exports 变更的目录资源、将NFS Server分享的目录卸载或重新分享等等,这个指令是NFS系统里面相当重要的。至于指令的用法我们在下面会再介绍。
/usr/sbin/showmount
这是另一个重要的NFS命令。exportfs是用在NFS Server端,而showmount则主要用在Client端。这个showmount可以用来察看NFS共享出来的目录资源。
/var/lib/nfs/*tab
在NFS服务器的登录档都放置到/var/lib/nfs/目录里面,在该目录下有两个比较重要的登录档,一个是etab ,主要记录了 NFS 所分享出来的目录的完整权限设定值;另一个xtab则记录曾经连结到此NFS主机的相关客户端资料。
/var/lib/nfs/rmtab
状态文件,列出了挂接导出文件的远程客户机清单。
3.3 /etc/exports配置文件的语法与参数
在开始NFS服务器的设置之前,您必须要了解的是,NFS会直接使用到内核功能,所以你的内核必须要有支持NFS才行。 万一如果你的内核版本小于2.2版,或者重新自行编译过内核的话,那么就得要很注意, 因为你可能会忘记选择NFS的核心支持。
还好,我们RHEL4或者是其他版本的Linux ,预设内核通常是支援NFS功能的, 所以你只要确认你的内核版本是目前新的2.6.x版,并且使用你的distribution所提供的核心,那应该就不会有问题。
至于NFS服务器的架设实在很简单,你只要编辑好主要配置文件/etc/exports之后, 先启动portmap ,然后再启动nfs ,你的NFS就成功了!不过这样的设定能否对客户端生效?那就得要考虑你权限方面的设定能力了。 我们就直接来看看/etc/exports 应该如何配置,某些 distributions并不会主动提供 /etc/exports 文件,所以请您自行手动建立。
例如:
# vi /etc/exports
/tmp 192.168.1.0/24(ro) localhost(rw) *.ev.ncku.edu.tw(ro,sync)
[分享目录] [第一个主机(权限)] [可用主机名] [可用域名]
这个文件的内容非常简单,每一行由共享路径,客户端列表以及每个客户端后紧跟的访问选项构成:
[共享的目录] [主机名或IP(参数,参数)]
其中参数是可选的,当不指定参数时,nfs将使用默认选项。默认的共享选项是 sync,ro,root_squash,no_delay。
当主机名或IP地址为空时,则代表共享给任意客户机提供服务。
当将同一目录共享给多个客户机,但对每个客户机提供的权限不同时,可以这样:
[共享的目录] [主机名1或IP1(参数1,参数2)] [主机名2或IP2(参数3,参数4)]
下面是一些NFS共享的常用参数:
ro: read-only,只读访问权限
rw: read-write,可读写的权限
sync: 资料同步写入到内存与硬盘中
async: 资料会先暂存于内存中,而非直接写入硬盘
secure: NFS通过1024以下的安全TCP/IP端口发送
insecure: NFS通过1024以上的端口发送
wdelay: 如果多个客户要写入NFS目录,则归组写入(默认)
no_wdelay: 如果多个客户要写入NFS目录,则立即写入,当使用async时,无需此设置。
hide: 在NFS共享目录中不共享其子目录
no_hide: 共享NFS目录的子目录
subtree_check: 如果共享/usr/bin之类的子目录时,强制NFS检查父目录的权限(默认)
no_subtree_check: 和上面相对,不检查父目录权限
no_all_squash: 保留共享文件的UID和GID(默认)
all_squash
不论登入 NFS 的使用者身份为何, 他的UID和GID映射匿名客户anonymous(通常也就是 nobody(nfsnobody)),适合公用目录。
root_squash
在登入NFS主机使用共享之目录的使用者如果是root时,那么这个使用者的权限将被映射成为匿名使用者,通常他的 UID 与 GID 都会变成nobody(nfsnobody) 那个系统账号的身份的权限;(默认)
no_root_squas
登入NFS主机使用共享目录的使用者,如果是root的话,那么对于这个共享的目录来说,他就具有root的权限!这个项目『极不安全』,不建议使用!
anonuid=xxx: 指定NFS服务器/etc/passwd文件中匿名客户的UID
anongid=xxx: 指定NFS服务器/etc/passwd文件中匿名客户的GID
/etc/exports 中client的书写规则
(1)单个主机
可以用短名及完全限定名,或者用IP地址,例如student01、student01.flying.com.cn或者192.168.10.1都是合法的主机名。
(2)Net-Group
可以列出/etc/netgroup文件中或NFS网组映射中定义的整组主机。网组名以@开头。
(3)通配符主机
.discuz.net *.*.comsenz.com
(4)掩码
192.168.1.0/255.255.255.0
接下来我们利用上述的几个参数来实际思考一下几个有趣的小习题:
思考一:让root保有root的权限
我想将/tmp共享出去给大家使用,由于这个目录本来就是大家都可以读写的,因此想让所有的人都可以存取。 此外,我要让root写入的文件还是具有root的权限,那如何设计配置文件?
# vi /etc/exports
# 任何人都可以用我的 /tmp ,用通配字符(*)来处理主机名称,重点在no_root_squash
/tmp *(rw,no_root_squash)
参考前面的主机名称设定说明,我们可以利用通配字符(*)。这表示无论来自哪里都可以使用我的/tmp这个目录。 再次提醒,『 *(rw,no_root_squash)』这一串设定值中间是没有空格的,而/tmp与*(rw,no_root_squash)则是有空格来隔开的。特别注意到 no_root_squash的功能!在这个例子中,如果你是客户端,而且您是以 root 的身份登入您的Linux主机,那么当您mount上我这部主机的 /tmp 之后,您在该mount的目录当中,将具有『root 的权限』
思考二:同一目录针对不同范围开放不同权限
我要将一个公共的目录/home/public公开出去,但是只有限定我的局域网内192.168.0.0/24这个网段可以读写,其他人则只能读取:
# vi /etc/exports
/tmp *(rw,no_root_squash)
/home/public 192.168.0.0/24(rw) *(ro)
# 继续加在后面,注意,我有将主机与网域分为两段(用空格隔开)
上面的例子说的是,当我的IP是在192.168.0.0/24 这个网段的时候,那么当我在Client端挂载了Server 端的/home/public后,针对这个被我挂载的目录我就具有可以读写的权限,至于如果我不是在这个网段之内,那么这个目录的文件我就只能读取而已,亦即为只读的属性。
需要注意的是,通配字符仅能用在主机名称的分辨上面,IP或网段就只能用192.168.0.0/24的状况,不可以使用192.168.0.*
思考三:仅给某个单一主机使用的目录设置
我要将一个私人的目录 /home/test 开放给192.168.0.100这个Client端的机器来使用,那么我就必需这么写:
# 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 正确即可!
这样就设定完成了!而且,只有192.168.0.100这部机器才能对/home/test这个目录进行存取。
思考四:开放匿名登入的情况
我要让*.linux.org网域的主机,登入我的NFS主机时,可以存取 /home/linux,但是他们存资料的时候,我希望他们的UID与GID 都变成40这个身份的使用者, 假设我NFS服务器上的UID 40已经有设定妥当:
# 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
特别注意到那个all_squash与anonuid,anongid 的功能!如此一来,当 test.linux.org 登入这部 NFS 主机,并且在 /home/linux 写入文件时,该文件的所有人与所有群组,就会变成/etc/passwd 里面对应的UID为40的那个身份的使用者。
上面四个案例的权限如果依照前一小节的存取设定权限来思考的话,那么权限会是什么情况呢?让我们来检查一下:
客户端与主机端具有相同的UID与账号:
假设我在192.168.0.100登入这个NFS(IP假设为192.168.0.2)主机,并且我在192.168.0.100的账号为dmtsai这个身份,同时,在这个NFS上面也有dmtsai这个账号,并具有相同的UID,果真如此的话,那么:
a) 由于192.168.0.2这个NFS主机的/tmp权限为-rwxrwxrwt,所以我 (dmtsai在192.168.0.100上面)在/tmp底下具有存取的权限,并且写入的文件所有人为dmtsai;
b) 在/home/public当中,由于我有读写的权限,所以如果在/home/public这个目录的权限对于dmtsai有开放写入的话,那么我就可以读写,并且我写入的文件所有人是dmtsai。但是万一/home/public对于dmtsai这个使用者并没有开放可以写入的权限时,那么我还是没有办法写入文件(这点请特别留意);
c) 在/home/test当中,我的权限与/home/public相同的状态,还需要NFS主机的/home/test对于dmtsai有开放权限;
d) 在/home/linux当中就比较麻烦,因为不论您是何种user ,您的身份一定会被变成UID=40这个账号!所以,这个目录就必需要针对UID = 40的那个账号名称,修改他的权限才行。
客户端与主机端的账号并未相同时:
假如我在192.168.0.100的身份为vbird ,但是192.168.0.2这部NFS主机却没有vbird这个账号时,情况会变成怎样呢?
a) 我在/tmp 底下还是可以写入,但是写入的文件所有人变成 nobody 了;
b) 我在/home/public里面是否可以写入,还需要视/home/public的权限而定,不过,反正我的身份就被变成nobody了就是;
c) /home/test 的观点与/home/public相同!
d) /home/linux 底下,我的身份就被变成 UID=40那个使用者呢!
当客户端的身份为 root 时:
假如我在192.168.0.100的身份为root,root这个账号每个系统都会有,权限变成怎样呢?
a) 我在/tmp里面可以写入,并且由于no_root_squash的参数,改变了预设的root_squash设定值,所以在/tmp写入的文件所有者为 root
b) 我在/home/public底下的身份还是被压缩成为nobody,因为预设属性里面都具有root_squash,所以,如果/home/public 有针对 nobody开放写入权限时,那么我就可以写入,但是文件所有者变成nobody
c) /home/test与/home/public相同;
d) /home/linux 的情况中,我root的身份也被压缩成为UID=40的那个使用者
这样的权限讲解之后,您可以了解了吗?这里是最重要的地方,如果这一关通过了,下面的就没有问题啦! 当然,您还是得要回到前一小节NFS 的文件存取权限好好的瞧一瞧, 才能解决NFS的问题。
3.4 NFS服务的启动
NFS的启动还需要portmap的协助,所以需先启动。
# /etc/init.d/portmap start
# 如果 portmap 本来就已经在执行了,那就不需要启动啊!
# /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。
# 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)
# /etc/init.d/nfs restart
portmap不需要设定,只要直接启动就行,启动之后,会出现一个port 111的sunrpc的服务,那就是portmap啦!至于nfs则会启动至少两个以上的daemon出现!然后就开始在监听Client端的请求。你必须要很注意屏幕上面的输出资讯, 因为如果配置文件写错的话,屏幕上会显示出错误。
此外,如果你想要增加一些NFS服务器的文件一致性功能时,可能需要用到rpc.lockd及rpc.statd等RPC服务, 那么或许你可以增加一个服务,那就是nfslock
# /etc/init.d/nfslock start
启动之后,请赶快到 /var/log/messages 里面看看有没有被正确的启动呢?
# 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
在确认没有问题之后,接下来我们来看一看NFS到底开了哪些端口?
# netstat -ultn
Active Internet connections (only servers)
Proto Recv-Q Send-Q Local Address State PID/Program name
tcp 0 0 0.0.0.0:2049 LISTEN -
tcp 0 0 0.0.0.0:803 LISTEN 1047/rpc.rquotad
tcp 0 0 0.0.0.0:111 LISTEN 32503/portmap
tcp 0 0 0.0.0.0:819 LISTEN 1064/rpc.mountd
udp 0 0 0.0.0.0:2049 -
udp 0 0 0.0.0.0:800 1047/rpc.rquotad
udp 0 0 0.0.0.0:816 1064/rpc.mountd
udp 0 0 0.0.0.0:111 32503/portmap
注意看到上面,总共产生了好多的port,真是可怕!不过主要的端口是:
portmap启动的 port 在 111;
NFS启动的port在2049;
其它rpc.daemons启动的port则是随机产生的,因此需向port 111注册。
好了,那我怎么知道每个RPC服务的注册状况?你可以使用 rpcinfo 来处理的。
# rpcinfo [-p] [IP|hostname]
参数:
-p :显示出所有的 port 与 porgram 的信息;
范例一:显示出目前这部主机的 RPC 状态
# 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版本 端口 服务名称
上面出现的信息当中除了程序名称与端口的对应可以与netstat -tlunp输出的结果作比对之外,还需要注意到NFS版本支持!新的NFS 版本传输速度较快,由上表看起来,我们的NFS至少支持到第3版,应该还算合理,如果你的rpcinfo无法输出,那就表示注册的资料有问题,可能需要重新启动portmap与nfs。
3.5 NFS的连接观察
在你的NFS服务器设定好之后,我们可以先自我测试一下是否可以连接?
showmount [-ae] [hostname|IP]
参数:
-a :这个参数是一般在NFS SERVER上使用,是用来显示已经mount上本机nfs目录的cline机器
-e :显示主机的 /etc/exports 所共享的目录。
范例一:请显示出刚刚我们所设定好的相关exports信息
# showmount -e localhost
Export list for localhost:
/tmp *
/home/linux *.linux.org
/home/public (everyone)
/home/test 192.168.0.100
很简单吧!所以,当您要查看某一台主机提供的NFS共享的目录时,就使用 showmount -e IP (或hostname)即可!非常的方便吧!这也是 NFS client 端最常用的指令。
事实上NFS关于目录权限设定的资料非常之多!我们可以检查一下/var/lib/nfs/etab就知道了!
# 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也有很多的权限相关的参数
上面仅仅是一个小范例,只是....怎么anonuid会是-2?其实那个数值是65536-2,所以得到65534,比对/etc/passwd,会发现RHEL4出现的是nfsnobody,这个账号在不同的版本都可能会不一样。 另外,如果有其他客户端挂载了你的NFS文件系统时,那么该客户端与文件系统信息就会被记录到/var/lib/nfs/xtab。
另外,如果你想要重新处理/etc/exports文件,是不是我们每次修改了配置文件都需要重启nfs服务呢?这个时候我们就可以用exportfs命令重新扫描/etc/exports文件,来使改动立刻生效。
exportfs [-aruv]
参数:
-a :全部挂载(或卸载)/etc/exports文件内的设置
-r :重新挂载/etc/exports里面的设置,此外,亦同步更新/etc/exports及/var/lib/nfs/xtab 的内容!
-u :卸载某一目录
-v :在export的时候,将分享的目录显示到屏幕上!
范例一:重新挂载一次 /etc/exports的设置
# 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
范例二:全部卸载
# exportfs -auv
3.6 NFS的安全性
在NFS的安全性上面,有些地方是你必须知道的!下面我们分别来看一看:
a) 利用iptables做大范围连接的限制:
假设我们的NFS主要是针对内部网路开放而已,而对于外部网路只有对140.116.0.0/16这个网段 ,那么你可以在iptables.allow内增加如下的语法:
# vi /usr/local/virus/iptables/iptables.allow
iptables -A INPUT -i $EXTIF -p TCP -s 192.168.0.0/24 --dport 111 -j ACCEPT
iptables -A INPUT -i $EXTIF -p UDP -s 192.168.0.0/24 --dport 111 -j ACCEPT
iptables -A INPUT -i $EXTIF -p TCP -s 140.116.0.0/16 --dport 111 -j ACCEPT
iptables -A INPUT -i $EXTIF -p UDP -s 140.116.0.0/16 --dport 111 -j ACCEPT
这样大致上就可以让 192.168.0.0/24 这个C Class的网域与140.116.0.0/16这个 B Class的网段到您的主机里面来,而其它的连接就视您的原本的iptables的状态而定。
那为什么是限制port 111而不是每个RPC server所开启的端口呢?因为RPC server所开启的端口都是随机产生的,要对他开放实在是... 而且客户端想要连上NFS服务器之前,都是透过port 111来向NFS服务器询问连接的端口的,所以当然先就port 111来进行限制。
b) 利用 TCP Wrappers 限制
但是不同的 RPC 毕竟提供的服务不一样,如果你想要针对某些服务来阻止的话,那可以透过TCP Wrappers这个根据 program name来阻止网路包,还记得我们刚刚使用过rpcinfo这个指令,不是会输出很多的RPC program name吗?没错!你可以这样做:
# vi /etc/hosts.allow
# 让来自 140.116.44.0/255.255.255.0 的主机可以使用 mountd
mountd: 140.116.44.0/255.255.255.0
# vi /etc/hosts.deny
# 让所有人都不能使用 mountd
mountd: ALL
为什么使用的是mountd呢?去到前一小节的rpcinfo指令处看一下, 你就会知道为何需要使用到mountd。
c) 使用/etc/exports 设定更安全的权限
这就牵涉到您的逻辑思考了!怎么设置都没有关系,但是在『便利』与『安全』之间,要找到您的平衡点。善用root_squash 及 all_squash 等功能,再利用anonuid等等的设定来规范登入您主机的使用者身份!应该还是有办法提供一个较为安全的NFS主机的!
另外,当然啦,你的NFS服务器的文件系统之权限设定也需要很留意!不要随便设定成为-rwxrwxrwx ,这样会造成你的系统『很大的困扰』。
d) 更安全的 partition 规划:
如果您的工作环境中,具有多部的 Linux 主机,并且预计彼此共享出目录时,那么在安装 Linux 的时候,最好就可以规划出一块 partition作为预留之用。因为『NFS可以针对目录来分享』,因此,您可以将预留的partition挂载在任何一个挂载点,再将该挂载点 (就是目录)由/etc/exports的设定中分享出去,那么整个工作环境中的其他Linux主机就可以使用该NFS主机的那块预留的 partition。所以,在主机的规划上面,主要需要留意的只有partition而已。此外,由于共享的partition可能较容易被入侵,最好可以针对该partition设定比较严格的参数在/etc/fstab当中。
e) NFS服务器关机前的注意事项:
需要注意的是,由于NFS使用的这个RPC在client端连上服务器时,那么您的服务器想要关机,那可就会成为『不可能的任务』!如果您的Server上面还有Client在连接,那么您要关机,可能得要等到数个钟头才能够正常的关机成功!真的假的?不相信吗?不然您自已试试看!
所以,建议您的NFS Server想要关机之前,能先『关掉portmap与nfs』。如果无法正确的将这两个daemons关掉,那么先以netstat -utlp找出PID ,然后以kill将他杀掉先,这样才有办法正常的关机成功。请特别的注意!
当然,你也可以利用showmount -a localhost查出来那个客户端还在连接,或者是查阅/var/lib/nfs/rmtab或xtab等文件来检查亦可。找到这些客户端后,可以直接call他们啊!让他们能够帮帮忙先!
事实上,客户端以NFS连接到服务器端时,如果他们可以下达一些比较不那么『硬』的挂载参数时,就能够减少这方面的问题。相关的安全性可以参考下一小节的客户端可处理的挂载参数与开机挂载。
4、NFS 客户端的设定
既然NFS服务器最主要的工作就是共享文件系统给网路上其他的客户端,所以客户端当然得要挂载这个玩意儿!此外,主机端可以加设防火墙来保护自己的文件系统,那么客户端挂载该文件系统后,难道不需要保护自己? 所以下面我们要来谈一谈几个NFS客户端。
4.1 远端NFS服务器的挂载
你要如何挂载NFS服务器所提供的文件系统?基本上,可以这样做:
a) 确认本地端已经启动了portmap服务!
b) 查看NFS服务器共享的目录有哪些,并了解我们是否可以使用(showmount);
c) 在本地端建立预计要挂载的挂载点目录(mkdir);
d) 利用mount将远端主机直接挂载到相关目录。
好,现在假设客户端在192.168.0.100这部机器上,而服务器是192.168.0.2,那么赶紧来检查一下我们是否已经有portmap的启动,另外远端主机有什么可用的目录!
# /etc/init.d/portmap start
# /etc/init.d/nfslock start
# 一般来说,系统预设会启动 portmap
# 另外,如果服务器端有启动nfslock的话,客户端也要启动才能生效!
# 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
接下来我想要将远端主机的/home/public挂载到本地端主机的 /home/nfs/public,所以我就得要在本地端主机先建立起这个挂载点目录才行啊!然后就可以用mount这个命令直接挂载NFS的文件系统!
# mkdir -p /home/nfs/public
# mount -t nfs 192.168.0.2:/home/public /home/nfs/public
# 注意一下挂载的语法!『 -t nfs 』指定文件系统类型
# IP:/dir 则是指定某一部主机的某个提供的目录!
# df
Filesystem 1K-blocks Used Available Use% Mounted on
....中间省略....
192.168.0.2:/home/public
10080512 2135072 7433344 23% /home/nfs/public
4.2 客户端可处理的挂载参数与开机挂载
如果你刚刚挂载到本机/home/nfs/public的文件系统当中,含有一个 script,且这个script的内容为『 rm -rf / 』且该文件权限为555,如果你因为好奇给它执行下去,整个系统都会被删掉!
所以说,除了NFS服务器需要保护之外,我们取用人家的NFS文件系统也需要自我保护才行。 那要如何自我保护啊?可以透过mount的指令参数!包括底下这些主要的参数可以尝试加入:
suid、nosuid
如果挂载的partition上面有任何suid的binary程序时,你只要使用nosuid就能够取消SUID的功能。
系统预设值:suid
rw、ro
你可以指定该partition是只读(ro)或可读写。
系统预设值:rw
dev、nodev
是否可以保留装置文件的特殊功能。一般来说只有/dev才会有特殊的装置,因此你可以选择nodev。
系统预设值:dev
exec、noexec
是否具有执行binary file的权限。如果你想要挂载的仅是资料区(例如/home),那么可以选择noexec。
系统预设值:exec
user、nouser
是否允许使用者进行文件的挂载与卸载功能。如果要保护文件系统,最好不要提供使用者进行挂载与卸载。
系统预设值:nouser
auto
noauto
这个auto指的是『mount -a』时,会不会被挂载的项目。如果你不需要这个partition随时被挂载,可以设定为noauto。
系统预设值:auto
一般来说,如果你的NFS服务器所提供的只是类似/home下面的个人资料,应该不需要可执行、SUID与装置文件,因此当你在挂载的时候,可以这样挂载:
# mount -t nfs -o nosuid,noexec,nodev,rw 192.168.0.2:/home/public /home/nfs/public
# mount
192.168.0.2:/home/public on /home/nfs/public type nfs (rw,noexec,nosuid,nodev,addr=192.168.0.2)
这样一来你所挂载的这个文件系统就只能作为文件存取之用,相对来说,对于客户端是比较安全一些的。
关于NFS特殊的挂载参数
除了上述的mount参数之外,其实针对NFS服务器,Linux 还提供不少有用的额外参数。因为NFS使用的是RPC服务,这个RPC必须要客户端与服务器端两者都有启动RPC才能运作。在一般的模式下面,你想要在客户端挂载服务器端的NFS文件系统时,一次命令只能挂载一次, 如果该次挂载由于某些问题 (例如服务器未开机、RPC忘记开等等)导致无法顺利挂载时,你只能等到连接超时(time out)后,才能够继续工作。
另外,当建立连接后,RPC会不断的在客户端与服务器两者之间进行呼叫,此时如果有一个主机失去连接,那么RPC将会持续不断的呼叫,直到服务器或客户端恢复连接为止。此一行为将导致RPC服务出现延迟问题,结果常常就造成你在执行df或者是mount等命令时,出现『等等等等』的情况。
为了避免这些困扰,我们还有一些额外的NFS挂载参数可用。例如:
fg、bg
当执行挂载时,该挂载的行为会在前台(fg)还是在后台(bg)执行? 若在前台执行时,则mount会持续尝试挂载,直到成功或 time out 为止,若为后台执行,则mount会在后台持续多次进行mount,而不会影响到前台的程序操作。如果你的网路连接有点不稳定,或是服务器常常需要开关机,那建议使用bg比较妥当。
预设参数:fg
soft
hard
上面不是谈到挂载时会使用RPC呼叫,如果是hard的情况,则当两者之间有任何一个主机离线,则RPC会持续的呼叫,直到对方恢复连接为止。 如果是soft的话,那RPC会在time out后『重复』呼叫,而非『持续』呼叫, 因此系统的延迟会比较不这么明显。同上,如果你的服务器可能开开关关,建议用soft
预设参数: hard
intr
当你使用上面提到的hard方式挂载时,若加上intr这个参数, 则当RPC持续呼叫中,该次的呼叫是可以被中断的 (interrupted)。
预设参数:无
rsize
wsize
读出(rsize)与写入(wsize)的区块大小(block size)。这个设定值可以影响客户端与服务器端传输资料的缓存记忆容量。一般来说,如果在局域网路内(LAN),并且客户端与服务器端都具有足够的内存,那这个值可以设置大一点,比如说8192 (bytes)等,提升缓存记忆区块将可提升NFS文件系统的传输能力。但要注意设定的值也不要太大,最好是达到网路能够传输的最大值为限。举例来说,如果你的MTU可达9000,那设定成 8192 才会有意义。
预设参数:rsize=1024
wsize=1024
更多的参数可以参考 man nfs ,通常如果你的NFS是用在高速运作的环境当中的话,那么可以建议加上这些参数:
# mount -t nfs -o nosuid,noexec,nodev,rw,bg,soft,rsize=8192,wsize=8192 192.168.0.2:/home/public /home/nfs/public
则当你的 192.168.0.2这个服务器因为某些因素离线时,你的NFS可以继续在后台中重复的呼叫!直到NFS服务器再度上线为止。这对于系统的持续操作还是有帮助的, rsize与wsize的大小则需要依据你的实际网路环境而定。
启动时自动挂载NFS
修改客户机的 /etc/fstab文件,加入类似如下行:
# vi /etc/fstab
192.168.0.2:/home/public /home/nfs/public nfs nosuid,noexec,nodev,rw,bg,soft,rsize=8192,wsize=8192 0 0
# 注意!上面的设定是同一行
4.3 自动挂载 autofs 的使用
在传统的 NFS 文件系统的使用中,如果客户端要使用服务器端所提供的NFS文件系统时:
1、在 /etc/fstab 当中设定开机时挂载,
2、要手动利用mount来挂载。 此外,客户端得要预先手动的建立好挂载点目录。
不过有个小问题,我们知道NFS服务器与客户端的连接或许可能不会永远存在, 而RPC这个服务,如果挂载了NFS服务器后,任何一方离线都可能造成另外一方老是在等待超时。
换个思考的角度:
可不可以让客户端在有使用到NFS文件系统的需求时才挂载?
并且不需要事先建立挂载点?
另外,当NFS文件系统使用完毕后,可不可以让NFS自动卸载,以避免可能的 RPC 错误?
在现在的Linux环境下采用autofs服务是可以达成。
autofs使用automount守护进程来管理你的挂载点,它只在文件系统被访问时才动态地挂载它们。 autofs查询主配置文件 /etc/auto.master来决定要定义哪些挂载点。然后,它使用适用于各个挂载点的参数来启动automount进程。主配置中的每一行都定义一个挂载点,然后用单独的配置文件定义在该挂载点下要挂载的文件系统。
autofs可以预先定义好客户端『预计挂载来自服务器端的上层目录』,以及其相关的对应NFS服务器共享目录。至于在该目录下面的对应目录则可以不需要额外设置。让我们看看下面的图示:
图四、自动挂载的设定档内容
如上图所示,我们的autofs主要设定档为 /etc/auto.master,这个文件的内容很简单, 如上所示,我只要定义出最上层目录 (/home/nfs) 即可,至于后续的文件则是该目录底下各次目录的对应。 在etc/auto.nfs (这个文件的文件名可自定义) 里面则可以定义出每个次目录所欲挂载的远端服务器目录。 然后:『当我们在客户端要使用 /home/nfs/public 的资料时,此时 autofs 才会去 192.168.0.2 挂载/home/public』且『当隔了5分钟没有使用该目录下的文件后,则/home/nfs/public 将会主动的卸载』。
建立主要配置文件 /etc/auto.master
这个主要配置文件的内容很简单,只要有预设目录及『资料对应文件』即可。 那个资料对应文件的文件名是可以自行定义的,在这个例子当中我使用 /etc/auto.nfs 来命名。
# vi /etc/auto.master
/home/nfs /etc/auto.nfs
# mkdir /home/nfs
# 注意!此时 /home/nfs 内并没有其他的目录存在
建立资料对应文件内的挂载资讯
刚刚我们所指定的/etc/auto.nfs是自行设定的,所以这个文件是不存在的。该文件的格式:
[本地端目录] [-挂载参数] [服务器所提供的目录]
参数:
本地端目录:指的就是在 /etc/auto.master 内指定的目录之次目录
-挂载参数 :就是前一小节提到的 rw,bg,soft 等等的参数;
服务器所提供的目录 :例如 192.168.0.2:/home/public 等
# vi /etc/auto.nfs
public -rw,bg,soft,rsize=8192,wsize=8192 192.168.0.2:/home/public
testing -rw,bg,soft,rsize=8192,wsize=8192 192.168.0.2:/home/test
temp -rw,bg,soft,rsize=8192,wsize=8192 192.168.0.2:/tmp
# 参数部分,只要最前面加个 - 符号即可!
这样就可以建立对应了!要注意的是,那些 /home/nfs/public 是不需要事先建立的。(public目录是由 automount 动态地创建的,它不应该在客户机器上实际存在。)
实际运作与观察
配置文件配置好后,启动autofs
# /etc/init.d/autofs start
假设你目前并没有挂载任何来自192.168.0.2这个NFS服务器的目录, 让我们实际来看看,如果我要进入 /home/nfs/public 时,文件系统会如何变化呢?
# mount; df
# 你不会看到任何跟192.168.0.2这个主机有关的NFS挂载信息。
# cd /home/nfs/public
# mount; df
192.168.0.2:/home/public on /home/nfs/public type nfs (rw,bg,soft,rsize=8192,wsize=8192,addr=140.116.44.179)
# 上面的输出是同一行
Filesystem 1K-blocks Used Available Use% Mounted on
192.168.0.2:/home/public
10080488 2144288 7424136 23% /home/nfs/public
# 文件的挂载也出现没错!
# pwd
/home/nfs/public
# 应当注意public目录是由 automount 动态地创建的,它不应该在客户机器上实际存在。
4.4 无法挂载的原因分析
使用者或客户端身份权限不符:
以上面的例子来说明,我的/home/test只能提供 192.168.0.0/24 这个网域,所以如果我在 192.168.0.2 这部服务器中,以 localhost (127.0.0.1) 来挂载时,就会无法挂载上,这个权限概念没问题吧! 那么您可以试试看:
# mount -t nfs localhost:/home/test /home/nfs
mount: localhost:/home/test failed, reason given by server: Permission denied
服务器或客户端某些服务未启动:
如果您发现您的mount的讯息是这样,说明未启动portmap或服务器nfs这个服务。
# mount -t nfs localhost:/home/test /home/nfs
mount: RPC: Port mapper failure - RPC: Unable to receive
# mount -t nfs localhost:/home/test /home/nfs
mount: RPC: Program not registered
被防火墙阻挡
这个原因很多人都忽视了,在有严格要求的网络环境中,我们一般会关闭linux上的所有端口,当需要使用哪个端口的时候才会去打开。而NFS默认是使用111端口,所以我们先要检测是否打开了这个端口,另外也要检查TCP_Wrappers的设定。
5、案例演练
假设环境:
假设我的 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 使用他的家目录啦!
实地演练:
(1)、首先,就是要建立/etc/exports这个文件的内容,您可以这样写:
# 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)
(2)、再来,就是要建立每个对应的目录的实际Linux权限:
a. /tmp
# ll -d /tmp
drwxrwxrwt 5 root root 20480 Sep 22 22:52 /tmp
b. /home/nfs
# mkdir -p /home/nfs
# chmod 755 -R /home/nfs
# 修改较为严格的文件权限将目录与文件设定成只读!不能写入的状态,会更保险一点!
c. /home/upload
# groupadd -g 210 nfs-upload
# useradd -g 210 -u 210 -M nfs-upload
# 先建立对应的账号与群组名称及UID
# mkdir -p /home/upload
# chown -R nfs-upload:nfs-upload /home/upload
# 修改拥有者!如此,则使用者与目录的权限都设定妥当!
(3)、启动 portmap 与 nfs 服务:
# /etc/init.d/portmap start
# /etc/init.d/nfs start
# /etc/init.d/nfslock start
(4)、在 192.168.0.50 这部机器上面测试一下:
a. 确认远端服务器的可用目录:
# /etc/init.d/portmap start
# /etc/init.d/nfslock start
# 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.50
b. 建立挂载点:
# mkdir -p /home/zzz/tmp
# mkdir -p /home/zzz/nfs
# mkdir -p /home/zzz/upload
# mkdir -p /home/zzz/andy
c. 实际挂载:
# mount -t nfs 192.168.0.100:/tmp /home/zzz/tmp
# mount -t nfs 192.168.0.100:/home/nfs /home/zzz/nfs
# mount -t nfs 192.168.0.100:/home/upload /home/zzz/upload
# mount -t nfs 192.168.0.100:/home/andy /home/zzz/andy
整个步骤大致上就是这样。
6、参考资料
http://debian.linuxsir.org/doc/inthedebianway/nfs/
http://www.gd-linux.org/bbs/showthread.php?t=3902
http://fanqiang.chinaunix.net/a1/b1/20010607/110001424.html
http://linux.vbird.org/linux_server/0330nfs.php#What_NFS_NFS
http://x.discuz.net/65438/viewspace_19518.html
http://www.gbunix.com/htmldata/2004_07/1/3/article_159_1.html