分类: 系统运维
2008-03-03 21:39:59
NFS服务器的配置与使用
一,NFS 简介
NFS (Network File System)网络文件系统,是使不同的计算机之间能够通过网络进行文件共享的一种协议,多用于UNIX/LINUX系统中。
NFS是由SUN公司开发,并于1984年推出的一个RPC服务系统,它使我们能够达到文件的共享,在不同的系统间使用,所以它的通信协议设计与主机及操作系统无关。当用户想使用远程文件时只要用“mount”命令就可把远程文件系统挂接在自己的文件系统之下,使远程的文件与使用本地计算机上的文件一样。例如在计算机A上,要把计算机B上的/usr/share挂接到A的/mnt/share只需执行如下命令即可:
NFS的优点:使用NFS可以提高资源的使用率,又可以大大节省客户本地硬盘的空间,同是也便于对资源进行集中管理。
NFS协议本身没有提供数据传输的功能,它必须借助于RPC(远程过程调用)协议来实现数据传输,可以将NFS服务器看成是一个RPC服务器,而且NFS客户端看做是RPC的一个客户端。
用户不但可以mount(挂接)目录,而且可以挂接一个文件。在挂接之后用户只能对文件做读取(或者写入)的操作,而不能在远程计算机上把此文件或目录移动或删除,但是如果挂接 /usr/man后,则不能再挂接 /usr/man底下的目录,否则会发生错误。
NFS就是一种促使servers(服务器)上的文件能被其他的计算机挂接而达到资源共享的网络文件系统,使用这些文件的计算机就可称为Client(客户机),一个客户机可以从服务器上挂接一个文件或者一个层次的目录。然而,事实上任何一台计算机都可以是NFS服务器或NFS客户机,甚至同时为NFS 服务器和NFS客户机。
NFS服务器所共享出来的文件或目录都记录在/etc/exports文件中,当启动NFS服务器时,脚本/etc/rc.d/rc会自动启动exportfs程序,搜索/etc/exports这一个文件是否存在,并且赋予正确的权限给所有共享出去的文件或目录。
但需要注意的是,只有服务器所共享出去的文件或目录,NFS客户机才能够挂接。同样,当启动客户机时,系统会自动去挂接所有服务器共享的目录或文件,而挂接到的所有路径都会记录在/etc/fstab下。当客户机挂接一个目录或文件时,并不是说复制服务器上的这一个目录或文件到本地的计算机上,而是在使用时从服务器上读取文件到本地的内存中,因此,可以用cd进入这一个挂接到的目录,就如同进入本地的目录一样.
2、基本监控程序
-------------------
要顺利运行NFS,至少需要五个Linux服务,它们各有不同的功能,有的负责装载服务,有的保证远程命令指向正确的位置。这些服务通过/etc/rc.d/init.d目录中的nfs,nfslock和portmap脚本启动。下面简单介绍每个监控程序:
(1) 基本NFS
rpc.nfsd是NFS服务器监控程序,它通过/etc/rc.d/init.d目录中的nfs脚本启动,主要功能是管理客户端是否能够登入服务器。NFS监控程序还启动rpc.mountd装载监控程序,并导出共享目录。
(2) RPC装载(rpc.mounted)
它是RPC安装守护进程,主要功能是管理NFS的文件系统.当客户端顺利地通过rpc.nfsd登录NFS服务器后,在使用NFS服务器所提供的文件前,还必须通过文件使用权限的验证,rpc.mounted会读取NFS的配置文件/etc/exports来对比客户端的权限.
(3) 端口映射器
Portmap的主要功能是进行端口映射工作.当客户端尝试连接并使用RPC服务器提供的服务时,portmap会将所管理的与服务对应的端口号提供给客户端,从而使客户端可以通过该端口向服务器请求服务.portmap没有运行,NFS客户端就无法查找从NFS服务器中共享的目录.
(4) 重新启动与statd
当NFS服务需要中断或者重新启动时,rpc.statd监控程序和rpc.lockd在服务器重新启动之后使客户机恢复NFS连接。
(5) 锁定
通过共享NFS目录打开文件时,锁定可以使用户不能覆盖同一个文件。锁定通过nfslock脚本并使用rpc.lockd监控程序启动运行。
二,NFS的安装
NFS服务,至少要以下3个守护进程:
1)rpc.nfsd
它是基于的NFS守护进程,主要功能是管理客户端是否能够登陆服务器.
2)rpc.mountd
它是RPC安装守护进程,主要功能是管理NFS的文件系统。
3)portmap
主要功能是进行端口射功作,是NFS服务必不可少的守护进程.
NFS客户端要安装的软件包:
nfs-common portmap
NFS服务器端要安装的软件包:
nfs-kernel-server nfs-common portmap
要检查NFS服务是否正常运行,可使用rpcinfo –p命令.如果NFS服务运行正常,就可在该命令执行结果中看到关于portmapper nfs 和mounted等守护进程的条目.
三,NFS的配置
1. 主配置文件:/etc/exports 格式如下:
[输出目录] [客户端1(参数1,参数2)] [客户端2(参数3,参数4)]
输出目录是指NFS系统中需要共享给客户端使用的目录.
客户端是指网络中可以访问这个NFS输出目录的计算机
客户端常用的指定方式
192.168.16.20 指定IP地址的主机
192.168.16.0/24(或192.168.16.*) 指定子网中的所有主机
Pc1.gdvcp.net 指定域名的主机
*. gdvcp.net 指定域中的所有主机
* (或缺省) 所有主机
下面是一些NFS共享的常用参数:
ro 只读访问
rw 读写访问
sync 将数据同步写入内存缓冲区与磁盘中,虽然这样效率较低,但
可以保证数据的一致性.
async 将数据先保存在内存缓冲区中,必要时才写入磁盘中
secure 限制客户端只能从1024以下的TCP/IP端口连接NFS服务器
(默认配置)
insecure 允许客户端从1024以上的TCP/IP端口连接NFS服务器
wdelay 检查是否有相关的写操作,如果有则将这些写操作一起执行,
这样可提高效率(默认设置)
no_wdelay 如果多个用户要写入NFS目录,则立即写入,当使用async
时,无需此设置。
hide 在NFS共享目录中不共享其子目录
no_hide 共享NFS目录的子目录
subtree_check 如果共享/usr/bin之类的子目录时,强制NFS检查父目录的
权限(默认)
no_subtree_check 和上面相对,不检查父目录权限
all_squash 将远程访问的所有普通用户及所属的用户组都映射为匿名
用户或用户组(一般为nfsnobody),适合公用目录。
no_all_squash 和上面相对(默认)
root_squash 将root用户及所属用户组都映射为匿名用户或用户组(默
认)
no_root_squas 和上面相对
anonuid=xxx 将远程访问的所有用户都映射为匿名用户,并指定该匿名用
户账号为本地用户(UID=xxx)
anongid=xxx 将远程访问的所有用户组都映射为匿名用户组账号,并指定
该匿名用户组账号为本地用户组(GID=xxx)
2. NFS 服务配置实例
/share 192.168.0.0/24 (rw) *(ro)
/share目录可供子网192.168.0.x中的所有用户进行读写操作,而其他网络中的用户只能读取该目录中的内容.
值得注意的是,当子网192.168.0.x中的某用户访问该共享目录时,能否真正地写入,还要看该目录对该用户有没有开放相应的写入权限.
如果该用户是普通用户,那么只有当该目录对该用户开放了定稿权限时,该用户才可以在该目录下创建子目录及文件,且新建子目录及文件的所有者就是该用户(实际上是该用户的UID)
如果该用户是root用户,由于默认选项中有root_squash,root 被映射成nfsnobody因此只有该目录对nfsnobody开放了写入权限时,该用户才能在共享目录中创建子目录及文件,且所有者将变成nfsnobody
/mnt/cdrom *.abc.com(ro,sync) master.abc.com(rw,sync)
上面的规则代表将/mnt/cdrom目录以只读同步方式共享给*.abc.com域,并且以读写同步方式共享给master.abc.com主机。
/home/share 192.168.102.15(rw,sync) *(ro)
对192.168.102.15赋予读写权限,其他机器仅有只读权限。
3. 维护NFS服务的输出目录列表
每次修改了配置文件后不需要重启nfs服务,这个时候我们就可以用exportfs命令重新扫描/etc/exports文件,来使改动立刻生效。
Exportfs +options
-a: 输出在/etc/exports文件中所设置的所有目录
-r: 重新读取/etc/exports文件中的设置,并使设置立即生效,而不需要重新启动NFS服
务
-u: 停止输出某一目录
-v: 在输出目录时将目录显示到屏幕上.
比如:
# exportfs -au 卸载所有共享目录
# exportfs -rv 重新共享所有目录并输出详细信息
exportfs 命令有软件包 nfs-kernel-server 提供,详细的 exportfs 命令说明请查看:
man exportfs
四. 启动和停止NFS服务
为了使NFS服务能正常工作,需要启动portmap 和nfs这两个服务,并且portmap一定要先于nfs启动
/etc/init.d/portmap start
/etc/init.d/nfs start
/etc/init.d/nfs stop
当完成资源共享, 我们如何知道发布了哪些权限呢?这时我们可以查看 /var/lib/nfs/etab 文件,它是有 exportfs 命令根据 /etc/exports 生成的。
cat /var/lib/nfs/etab
可用showmount在客户机上查看NFS的资源共享情况
# showmount -e 192.168.102.47
使用mount命令即可挂栽共享资源,在客户机 192.168.102.15 上加载共享资源
# mount 192.168.102.47:/home/share /mnt
# cd /mnt
# echo '12345'> 123
即可发现对服务器共享目录可写
# umount /mnt
在客户机 192.168.102.61 上加载共享资源
# mount 192.168.102.47:/home/share /mnt
# cd /mnt
# ls
123
# touch 321
touch: cannot touch `321': Permission denied
# echo '123455' >123
-bash: 123: Permission denied
可能出问题的地方:
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
RPC Server的相关命令
rpcinfo
#rpcinfo -p hostname(orIP)
要注意的问题:
需要注意的是,由于 NFS 使用的这个 RPC 在 client 端连上主机时,那么你的主机想要关机,那可就会成为『不可能的任务』!我还不知道正确的原因是什么,但是,如果你的 Server 上面还有 Client 在联机,那么你要关机,可能得要等到数个钟头才能够正常的关机成功!嗄!真的假的!不相信吗?不然您自个儿试试看! ^_^!所以啰,建议您的 NFS Server 想要关机之前,能更先『关掉 portmap 与 nfs 』这两个东西!如果无法正确的将这两个 daemons 关掉,那么先以 netstat -utlp 找出 PID ,然后以 kill 将他关掉先!这样才有办法正常的关机成功喔!这个请特别特别的注意呢!
安全建议
为了保障网络安全,在使用NFS时最好结合TCP_Wrappers来限制使用范围(如果只希望192.168.5.120 这个C地址,以及IP地址为192.168.5.123的主机挂载我的NFS Server):
# vi /etc/hosts.allow
portmap: 192.168.5.120/255.255.255.248 : allow
portmap: 192.168.5.123 : allow
# vi /etc/hosts.deny
portmap: ALL : deny
除了使用TCP_Wrappers之外,还可以使用iptables防火墙、/etc/exports权限设定来保障安全。
即可发现对服务器共享目录只有读取权限,这与我们在服务器端的权限设置是相符的。
现在我们来查看服务器上有关NFS服务器启动了哪些端口:
0[root@debian-ykj:init.d]# lsof -i|grep rpc
portmap 1528 daemon 3u IPv4 4337 UDP *:sunrpc
portmap 1528 daemon 4u IPv4 4340 TCP *:sunrpc (LISTEN)
rpc.mount 1982 root 6u IPv4 6227 UDP *:886
rpc.mount 1982 root 7u IPv4 6230 TCP *:889 (LISTEN)
rpc.statd 9608 statd 3w IPv4 1696803 UDP *:32889
rpc.statd 9608 statd 6u IPv4 1696793 UDP *:880
rpc.statd 9608 statd 7u IPv4 1696806 TCP *:56837 (LISTEN)
观察激活的端口号
# netstat -utln
Active Internet connections (only SERVERs)
Proto Recv-Q Send-Q Local Address Foreign Address State
tcp
0 0
tcp
0 0
tcp
0 0
udp
0 0
udp
0 0
udp
0 0
udp
0 0
nfs所开启的端口是2049,其它的端口是RPC Server其它程序(例如rpc.mountd、rpc.rquotad、rpc.nfsd... )随机产生的,也就是端口号不会是固定的,每次restart nfs都会得到不一样的端口号。
客户端使用 NFS:
1.查看 NFS 的服务:
client 要查看 Server 有提供哪些 NFS 服务,可以使用 showmount 这个指令
# showmount -e 可看有分享哪些目录
# showmount -a 可看出所有的 mount
2.连接 NFS Server:
要使用 NFS server 上的资源,使用 mount 指令就可以了。
# mount -t nfs hostname:/shared_dir
例:
# mount -t nfs 192.168.1.100:/tmp /mnt/nfs
3.开机时自动连上 NFS:
如果希望开机的时候,系统就自动挂载 NSF,则需要编辑 /etc/fstab 档。
例:
192.168.1.100:/tmp /mnt/nfs nfs defaults 0 0
实例
某公司需要在网络上共享一个文件夹,所有人都只有只读权限,且只有192.168.1.0/24子网的用户可以访问,试通过NFS共享该文件夹。NFS服务器的IP地址是192.168.1.1。
具体操作步骤如下:
(1)以root身份登录,在/目录下创建目录share。
[root@bearzhang /]#mkdir share
(2)编辑/etc/exports文件,在该文件中加入下面的命令行。
/share 192.168.1.0/24(ro,root_squash)
“/share”表示要共享的目录,192.168.1.0/24表示允许访问的主机(这里是一个子网的主机),括号内的ro表示客户机上的用户对该共享目录只有只读权限,root_squash表示当客户机上的root用户访问该共享目录时,映射该用户为匿名用户,即当客户机上的root用户访问该共享目录时相当于服务器上的anonymous(nobody)用户。
(3)在192.168.1.0/24子网上的任意一台客户机上安装共享目录。
[root@bearzhang root]#mount 192.168.1.1:/share /mnt
上面命令行的意思是:将192.168.1.1上的/share目录作为一个分区挂接到本机的/mnt目录下。
(4)测试权限。
进入/mnt目录建立目录test,此时会出现下面的提示
root@bearzhang mnt]#mkdir: cannot create directory `mydir': Permission denied
因为在步骤(2)中的命令行中加了参数ro,任何人对该共享目录都只有只读权限。