目前,研究者们开发了许多网络服务和协议来完成资源共享的功能。对于网络用户和管理员来说,他们希望得到免费和高效的服务,而这种需求的最好选择莫过于当前开源的操作系统Linux下的产品了。本专题从多个应用服务层面着重向读者们推荐几种实用的用于资源共享的技术及其软件。
本文是继samba之后的第2篇文章,详细介绍NFS。专题的完整内容,请参见:
Linux下的文件共享服务全攻略 http://os.51cto.com/art/201010/231947.htm
在Linux下实现文件共享有多种方式,NFS就是其中之一。网络文件系统(NFS)协议是由Sun MicroSystem在20世纪80年代为了提供对共享文件的远程访问而设计和实现的。该协议采用Client/Server模型,通过使用Sun开发的远程过程调用协议(RPC Protocol)来实现运行在一台计算机上的程序来调用在另一台远程机器上运行的子程序,并且,它提供的外部数据表示(XDR)可以使得数据在不同平台上的计算机上进行交换。该协议可以在TCP协议或者是UDP协议上运行,而在此基础上,NFS在数据的传送过程中需要RPC命令得到确认,而且在需要的时候将会重传。
1、NFS原理
NFS比较复杂,包括很多组件,通过特殊的协议进行交互。不同的组件在操作系统当中都使用不同的配置文件以及状态文件。下图说明了NFS的主要组件及配置文件。
NFS分为服务器和客户机两部分,每个主机都有自己的内核级服务:外部数据表示(XDR,eXternal Data Representation)、远程过程调用(RPC,Remote Procedure Call)、I/O监控程序和锁监控程序。每个主机还有自己的用户级服务。内核级服务和用户级服务都依赖于主机的功能:NFS客户机或者是NFS服务器。当然,还要依赖于每个主机使用的不同功能的配置文件(如果是服务器,则用的是/etc/exports配置文件,如果是客户机,则用的是/etc/fstab配置文件)。如果一台主机既是服务器又是客户机,那么它需要运行两个部分的服务。
在服务器端,portmap、 mountd、 nfsd三个监控程序将在后台运行。portmap监控程序用来注册基于rpc的服务。当一个RPC的监控程序启动的时候,它告诉portmap监控程序它在哪一个端口进行侦听,并且它在进行什么样的RPC服务。当一个客户机向服务器提出一个RPC请求,那么它就会和portmap监控程序取得联系以确定RPC消息应该发往的端口号。而Mountd监控程序的功能是来读取服务器端的/etc/exportfs文件并且创建一个将服务器的本地文件系统导出的主机和网络列表,因而客户机的挂接(mount)请求都被定位到mountd监控程序(daemon)。当验证了服务器确实具有挂接所请求的文件系统的权限以后,mountd为请求的挂接点返回一个文件句柄。而nfsd监控程序则被服务器用来处理客户机端发过来的请求,由于服务器需要同时处理多个客户机的请求,所以在缺省情况下,在Linux当中将会自动启动八个nfsd线程。当然,如果NFS服务器特别忙的时候,系统有可能根据实际情况启动三十个线程。
2、NFS安装
在网络环境下,使用yum安装NFS的命令如下:
#yum –y install nfs
3、NFS配置和使用
在安装好NFS后,需要对其进行配置才能正常使用,主要包括服务器配置和客户机配置两个步骤,下面详细对它们加以说明。
服务器配置
编辑/etc/exports,在文件中列出,要共享的目录。书写规则是:共享目录主机(参数)。并且每条规则占据一行。例如:
/mnt/mp3 192.168.10.168(ro,sync, no_root_squash)
上面的规则代表将/mnt/mp3目录以读写同步方式共享给主机192.168.10.168。如果登陆到NFS主机的用户是root,那么该用户就具有NFS主机的root用户的权限。
具体的可选参数如下所示:
- rw:可读写的权限
- ro:只读的权限
- no_root_squash:登入到NFS主机的用户如果是ROOT用户,他就拥有ROOT的权限
- root_squash:在登入NFS主机使用目录的使用者如果是root时,那么这个使用者的权限将被压缩成为匿名使用者,通常他的UID与GID都会变成nobody那个身份
- all_squash:不管登陆NFS主机的用户是什么都会被重新设定为nobody
- anonuid:将登入NFS主机的用户都设定成指定的userid,此ID必须存在于/etc/passwd中
- anongid:同anonuid,但是变成groupID就是了
- sync资料同步写入存储器中
- async:资料会先暂时存放在内存中,不会直接写入硬盘
- insecure允许从这台机器过来的非授权访问
客户机配置
客户机配置相对简单,只需要使用下述命令mount NFS文件系统即可:
#mount -t nfs 192.168.10.168:/home /mnt/mp3
上述命令将远程的共享目录挂接到本地的/home目录下,用户可以直接对该目录进行操作,从而获取远程的共享资源。
启动NFS服务
#service portmap start # service nfs start
下面通过一个具体的例子来介绍NFS的安全性配置。假设在某个网站上有某个目录名为/popgame目录可以开放给NFS客户机来进行下载共享等工作,而这台服务器的IP地址为:202.168.10.8,它可以开放目录给的主机的IP地址为202.168.10.10、202.168.10.13(当然可以提供给更多的服务器,而且他们的IP地址也可以各式各样,现在举的例子有点像局域网中的情况,不过原理相同)。那么我们首先就需要对服务器端的/etc/exports文件进行编写:
我们先进入目录/etc,然后vi exports,那么就会进入到该文件的编辑界面,我们输入如下的内容:
/popgame 202.168.10.10(ro) 202.168.10.13(ro)
我们可以清楚的看到,目录/popgame只能导出到IP地址为上述的客户机上,而且他们的权限也只能是只读,因为他们只是需要简单的共享下载游戏的功能,并不需要具备创建目录、修改文件的功能,而且如果提供了的话,那将会出现安全隐患。下面接着配置客户机的/etc/fstab文件,进入该文件你将需要加入如下的内容,原文件上已经有的内容不要随意更改,否则会影响系统配置,影响文件系统:
202.168.10.8: /popgame /mnt/game nfs ro 0 0
其中的/mnt/game目录是你要将服务器上的/popgame目录挂接到你的客户机上的本地目录,也就是说,当共享了NFS文件系统以后,你可以通过访问本地目录/mnt/game来访问共享的文件。因为现在有两台客户机,所以每一台上都要如上配置。
配置完成以后,就需要在客户机上将服务器的NFS挂接到本地客户机上了,命令如下所示:
mount –t nfs 202.168.10.8: /popgame /mnt/game
特别需要注意的是:在执行命令之前,你必须先要关掉本地客户机上的防火墙,否则也不会挂接成功。原因是防火墙将会阻碍远程过程调用。现在你就可以放心的使用远程的网络资源了。
最后,我们介绍一下使用中需要注意的安全问题。
4、使用中需要注意的安全问题
通常来说,我们要保护好NFS,首先就要关闭最大的漏洞。在操作系统当中,当系统启动的时候,将会有很多的后台系统服务程序在运行,而且有些端口是缺省打开的。如果不对这种情况进行处理的话,一方面会不必要的消耗大量系统资源,另一方面则会给我们的系统带来安全隐患。因此,我们要保护NFS,必须解决好如下问题:
◆要考虑好总体的安全,拒绝所有的访问,只有在需要的时候才提供访问。也就是说,不要把NFS导出到任何主机,而只应该将它导出到所需要的主机,尤其是避免将文件系统导出到不信任的主机。并且要尽量使用只读(ro)权限导出文件系统,尽量不要使用(rw)或者是(no_root_squash)权限;
◆不要提供太多的根用户账号。特别要注意保证任何用户都没有NFS客户机的根用户账号,因为如果具有的话,那么该客户机将会具有最高的权限,将会引起很大的安全问题,它可以修改任何它想修改的东西,这显然是不安全的。而且应该在NFS服务器上使用(root_squash)和(ro)选项;
◆尽量使用限制性的NFS客户机方挂接选项,用只读(ro)选项挂接文件系统,除非确实有必要,要不然不要允许设置UID二进制文件(nosuid)、设备(nodev)和执行文件(noexec)。
◆要严格地控制好导出的目录文件。这主要包括导出的数量以及导出的安全选项。导出的数量依据实际情况而定,避免到处过多的和不必要的选项。另外,要严格地控制好导出的安全选项,安全选项就是上面所描述的只读(ro)、可写(rw)、根用户挤压(root_squash)等选项,这样做就可以使得每个目录都有各自的访问权限,而通常情况下这样也是很合理的,因为所有要导出的目录访问权限都是一样的,这几乎是不可能的。比如说,现在NFS服务器上有三个目录需要导出,一个是/popmusic,一个是/doc,而一个是/digest。这三个目录当中,第一个目录和第三个目录不但允许客户机共享,而且允许客户机上载自己的文件,但是第二个只允许读取,这样第一个和第三个目录的访问权限就要设为rw,而第二个则只能设为ro。
◆在导出的文件系统下的目录的设置过程当中应当要注意一些控制的问题。通常情况下,应该要将访问权限一致的目录和文件作为父目录、子目录,而访问权限不一致的就另开一个目录进行导出,这实际上就是一个管理的粒度问题。举个例子,现有四个目录要进行导出,它们依次是 /direct1 、/direct2 、/direct3 、/direct4 。其中前两个目录的访问权限是只读,而后面两个是可读写,那么,我们在导出的时候可以这样做,将 /direct2作为 /direct1的子目录,放入/direct1中进行导出,然后设置共享权限为只读,同样的,可以将 /direct4 作为/direct3的子目录,设置它的共享权限为可读写,然后导出。这样,客户机在访问服务器数据的时候就不会出现,在一个目录当中,整个父目录的权限与子目录的访问权限不相同。解决了这个设置的问题,共享起来也比较方便,而且便于管理。
本文转自samsunglinuxl51CTO博客,原文链接: http://blog.51cto.com/patterson/412516,如需转载请自行联系原作者