一、简单介绍

NFS是网络文件系统,其工作于内核中,通过与Linux的vfs接口向用户输出一个与本地文件系统无差的文件系统。用户首先通过mount命令将远程的NFS文件系统挂载至本地的某个目录上,当进程访问这个目录时,NFS会根据用户请求创建一个TCP/IP的长连接,所有的请求都通过这个链接远程传输给NFS服务器。简单来讲就是将本地文件系统的API转换为能够通过套接字远程调用的API,这个可以远程调用的接口使得客户端在访问时,可以基于协议报文发过来一个请求,而后NFS服务器将其转换为在本地磁盘上所存储的文件,可以将NFS理解为附加在本地文件系统上的虚拟层,有了这个虚拟层之后才使得本地的某个文件系统通过网络能输出给其他主机访问。而这个过程是基于RPC机制实现的

NFS是由Sun公司研发的,它的第一版就从来没有走出过Sun公司,后来公开的是NFS v2版本,早期时候nfs为了高效传输使用的是udp协议,但是udp没有校验功能,所以在NFSv3开始就支持tcp和udp了,不过官方建议及默认设置都是使用tcp进行传输的,其监听在2049/TCP端口,到了NFSv4在UID映射上有了更加苛刻的要求,一般来讲为了避免用户在不使用集中身份认证时出现UID映射错误导致权限混乱,都会把所有用户映射为同一个用户账号,这个映射称为压缩用户权限

二、认证方式

因为NFS是网络文件系统,其本地文件属主、属组等权限映射关系与远程主机的用户映射关系极有可能是不一致的,比如本地UID为1001的用户是Centos,而远程的UID为1001的用户是apache,这就让数据安全存在极大的风险,所以此时就需要一个统一的用户解析认证方式

  • nis:网络信息服务(Network Information Service),一个比较古老的协议,正是Sun公司为了解决双方用户映射关系不一致而研发的。但是nis整个协议是明文的,所以只适合在内网中使用
  • ldap:轻量级目录服务访问协议(Lightweight directory access protocol)

如果只是在内网中简单做一个存储的话,没有太大必要去部署nis和ldap。不管是哪个用户访问,都可以将它们映射为一个统一的来宾账号

三、辅助类服务

客户端在链接nfs服务器时,都会先链接nfsbind进程,其固定监听在111/TCP上,由nfsbind告知客户端其他辅助类服务的监听端口

  • rpc.mountd:帮助nfs检查客户端IP是不是被允许的客户端,因为rpc.mountd是半随机端口,所以客户端需要先向nfsbind请求mountd的端口,而后向rpm.mountd请求,当认证通过后会发送给客户端一个令牌,而后客户端持令牌访问nfs服务
  • rpc.lockd:负责对文件加锁的进程,保证多个客户端不会通过修改同一个文件
  • rpc.statd:负责保存每一个链接的操作状态,一旦某个用户异常断开了,它就会提醒用户上次的操作

四、安装配置

1. 安装

使用命令lsmod | grep nfs查看是否已经装载nfsd模 块,然后nfs-utils包,这个包提供了一些管理命令

2. 配置目录

自建一个目录供客户端远程挂载,并在/etc/exports配置文件中定义访问权限

/etc/exprots文件定义格式:

/path/dir client1(options1,options2,...) client2(options1,options2,...)

client可用参数
ipv4、ipv6、FQDN
network/netmask:网络地址/掩码
主机名称通配:
nis域内的主机组
*:表示通配所有主机 *.busyops.com

options可用参数:
ro:只读
rw:读写
sync:同步读写
async:异步读写
secure:要求客户端端口必须小于1024
insecure:客户端使用任何端口都可以
no wdelay:不可以存在写延迟
crossmnt:服务方提供的nfs服务目录如果是挂载的另一个nfs服务,那么如果想让客户端看到被挂载两次的内容则加上这个选项
root_squash:压缩root权限,只要客户端使用root账号访问,在服务端一律当做来宾,一般映射为nfsnobody
no_root_squash:不压缩root权限
all_squash:把所有人都压缩权限,通通当做来宾
anonuid:指定用户映射的用户
anongid:指定用户映射的组

示例:
/ master(rw) trusty(rw,no_root_squash)
/projects proj*.local.domain(rw)
/usr *.local.domain(ro) @trusted(rw)
/home/joe pc001(rw,all_squash,anonuid=150,anongid=100)
/pub *(ro,insecure,all_squash)
/srv/www -sync,rw server @trusted @external(ro)
/foo 2001:db8:9:e54::/64(rw) 192.0.2.0/24(rw)
/build buildhost[0-9].local.domain(rw)

3. 挂载

使用命令showmount -e Server_ip可以查看远端导出的目录,而后客户端使用mount.nfs Server_ip:/path/dir /local/dir完成挂载

五、命令

1. showmount命令

-e 查看远端主机导出的可挂载目录
-a:在nfs_server上可以查看被挂载的目录

2. exportfs命令

重新导出文件系统,而不要重启nfs服务

exportfs [options]
-r:重新导出
-a:所有文件系统
-v:详细信息
-u:取消导出文件系统

六、小tips

  • 在挂载远程的nfs文件系统后,本地用户是否可以对目录中的文件执行写操作,取决于nfs服务器如何定义的。比如服务器端挂载选项定义为all_squash,那么所有用户都会映射为远端主机的nfsnobody,是否能写取决于nfsnobody在远端主机的权限
  • 如果两端的用户名称不同但是UID相同,那么在不同主机上查看文件的属主与属组也是不同的,但是最终的权限仍然取决远端nfs服务器上的用户权限
  • 如果显示定义了用户的UID和GID,那么在客户端创建的文件权限都会被自动修改为定义的属主、属组