NFS
NFS简介
-
NFS:Network File System 网络文件系统,基于内核的文件系统。Sun公司开发,通过使用NFS,用户和程序可以像访问本地文件一样访问远端系统上的文件,基于RPC(Remote Procedure Call Protocol 远程过程调用)实现
-
RPC采用C/S模式,客户机请求程序调用进程发送一个有进程参数的调用信息到服务进程,然后等待应答信息。在服务器端,进程保持睡眠状态直到调用信息到达为止。当一个调用信息到达,服务器获得进程参数,计算结果,发送答复信息,然后等待下一个调用信息,最后,客户端调用进程接收答复信息,获得进程结果,然后调用执行继续进行
-
NFS优势:节省本地存储空间,将常用的数据,如:/home目录,存放在NFS服务器上且可以通过网络访问,本地终端将可减少自身存储空间的使用
-
RPC 远程过程调用
-
NFS文件系统通信过程
-
NFS工作原理
NFS服务使用随机端口,NFS在启动时将自己使用的端口号发送到RPC服务(portmap)上,protmap服务就记录下来当前NFS服务使用端口。客户端访问NFS时,不会直接访问NFS服务,直接访问portmap服务。
portmap服务的监听端口TCP的111端口。RPC服务在centos系统中称为rpcbind.
==> NFS服务依赖于portmap服务。
-
NFS的理解
- 由于NFS是一个文件系统,文件系统属于内核级的功能,则NFS在内核中有对应的驱动。
- 各种文件系统都有与之对应的驱动模块。
# lsmod | grep nfs 搜索当前系统是否加载NFS驱动模块
如果当前没有使用NFS文件系统,驱动模块将未被加载,
驱动模块支持动态加载,如果使用NFS文件系统将自动加载NFS驱动模块。
# updatedb
# locate nfs.ko
/usr/lib/modules/4.18.0-80.el8.x86_64/kernel/drivers/xen/xenfs/xenfs.ko.xz
/usr/lib/modules/4.18.0-80.el8.x86_64/kernel/fs/nfs/nfs.ko.xz
NFS服务
1.NFS各个版本的对比
- 伪根:NFS共享哪个文件夹,用户就能看到该文件夹的真实路径。通过伪根可以掩饰真实路径。
- NFS一般在局域网使用,端口号过多,也不固定,防护墙不好配置。
2.NFS服务介绍
- 软件包:nfs-utils
- Kernel支持:nfs.ko
- 端口:2049(nfsd), 其它端口由portmap(111)分配
- CentOS6开始portmap进程由rpcbind代替
- 配置文件:/etc/exports,/etc/exports.d/*.exports
- CentOS7不支持同一目录同时用nfs和samba共享,因为使用锁机制不同
- 相关软件包:rpcbind(必须),tcp_wrappers
- NFS服务主要进程:
rpc.nfsd 最主要的NFS进程,管理客户端是否可登录
rpc.mountd 挂载和卸载NFS文件系统,包括权限管理
rpc.lockd 非必要,管理文件锁,避免同时写出错
rpc.statd 非必要,检查文件一致性,可修复文件 - 日志:/var/lib/nfs/
# rpm -ql nfs-utils
/sbin/mount.nfs
/sbin/mount.nfs4
/sbin/osd_login
/sbin/rpc.statd
/sbin/umount.nfs
/sbin/umount.nfs4
/usr/sbin/blkmapd
/usr/sbin/exportfs
/usr/sbin/mountstats
/usr/sbin/nfsdcltrack
/usr/sbin/nfsidmap
/usr/sbin/nfsiostat
/usr/sbin/nfsstat
/usr/sbin/rpc.gssd
/usr/sbin/rpc.idmapd
/usr/sbin/rpc.mountd
/usr/sbin/rpc.nfsd
/usr/sbin/rpcdebug
/usr/sbin/showmount
/usr/sbin/sm-notify
/usr/sbin/start-statd
service文件:
/usr/lib/systemd/system/nfs.service
/usr/lib/systemd/system/nfs-server.service
nfs.service 是nfs-server.service的软链接,centos8上没有nfs.service这个软链接
由于NFS服务依赖rpcbind,在centos6上rpcbind服务未启动将不能启动nfs服务,centos7开始由systemd,systemd可以解决服务启动时的依赖关系。
3.NFS配置防火墙
- 配置防火墙,开放NFS服务:将NFS配置使用固定端口
# vim /etc/sysconfig/nfs
RQUOTAD_PORT=875
LOCKD_TCPPORT=32803
LOCKD_UDPPORT=32769
MOUNTD_PORT=892
STATD_PORT=662
STATD_OUTGOING_PORT=2020
防火墙除开放上述端口,还需开放TCP和UDP的111和2049共4个端口
NFS配置文件
-
配置文件:
/etc/exports.d/filename
/etc/exports -
#开始为注释
-
导出的文件系统的格式:
- /dir 主机1(opt1,opt2) 主机2(opt1,opt2)…
配置文件就两部分:共享目录+共享的对象(共享目录的配置选项)
默认共享目录的配置选项:(sync,wdelay,hide,no_subtree_check,sec=sys,ro,secure,root_squash,no_all_squash)
- /dir 主机1(opt1,opt2) 主机2(opt1,opt2)…
-
主机格式:
- 单个主机:ipv4,ipv6,FQDN
- IP networks:两种掩码格式均支持
- wildcards:主机名通配,例如*.magedu.com,IP不可以
- netgroups:NIS域的主机组,@group_name
- anonymous:表示使用*通配所有客户端
-
每个条目指定目录导出到的哪些主机,及相关的权限和选项
-
默认选项:(ro,sync,root_squash,no_all_squash)
-
ro,rw 只读和读写
-
async 异步,数据变化后不立即写磁盘,性能高
-
sync(1.0.0后为默认)同步,数据在请求时立即写入共享
-
no_all_squash (默认)保留共享文件的UID和GID
-
all_squash 所有远程用户(包括root)都变成nfsnobody
-
root_squash (默认)远程root映射为nfsnobody,UID=65534,早期版本是4294967294 (nfsnobody),centos8是nobody用户,UUID=65534
-
no_root_squash 远程root映射成root用户
-
anonuid和anongid 指明匿名用户映射为特定用户UID和组GID,而非nfsnobody,可配合all_squash使用
-
注:NFS共享目录仅在NFS服务授权但是如果对其目录没有相应的权限也是不能进行对共享目录进行操作的.
-
1.共享目录写权限问题:
# cat /etc/exports
/data/nfs *(rw)
共享目录具有写权限:
1、NFS服务授权
2、共享目录授权远程用户对应的映射用户具有写权限
首先看没有权限的提示:
1、NFS服务未授权时:
# exportfs -v (显示结果省略了一些默认项,上面有说明)
/data/nfs <world>(...ro,root_squash,no_all_squash)
client: 提示此为只读文件系统
# touch f1.txt
touch: cannot touch ‘f1.txt’: Read-only file system
2、NFS服务授权,但是映射用户对目录不具有写权限时:
NFS服务未授权时:
# exportfs -v (显示结果省略了一些默认项,上面有说明)
/data/nfs <world>(...rw,root_squash,no_all_squash)
client: 提示权限被拒绝,说明映射用户对目录没有w权限
# touch f1.txt
touch: cannot touch ‘f1.txt’: Permission denied
2.用户权限是否压缩问题:
- 用户权限是否压缩在于是否映射为NFS server端的nobody/nfsnobody用户。
# exportfs -v
/data/nfs <world>(...root_squash,no_all_squash)
# cat /etc/exports
/data/nfs *(rw,no_root_squash)
-
root_squash:表示root权限压缩,被映射为nobody用户(映射与OS版本有关,上面有相关详细说明)
-
no_root_squash:则表示不压缩root权限,远程主机对共享目录仍保留root权限。
-
no_all_squash:表示普通用户不进行权限压缩
-
all_squash:表示所有用户进行权限压缩。(包括root,即使前面对root设置为no_root_squash)
3.映射用户问题
-
关于上述权限是否压缩问题其实就是映射用户的问题,可能产生如下问题:
普通不压缩权限,如果NFS client和NFS server有一个UID均为1005的用户
NFS client uid=1005(tom)
NFS server uid=1005(Bob)
那么NFS client tom在共享目录创建的文件f1.txt,NFS server端f1.txt的所有者为Bob。(linux上是依靠UID识别用户的)。==>上述问题在生产环境中可能造成的情况是:以web服务为例如下图:
-
如果想自定义映射用户:
将root映射为uid=1000的用户:
NFS server:weirdo:x:1000:1000:weirdo:/home/weirdo:/bin/bash
NFS client:wang:x:1000:1000:wang:/home/wang:/bin/bash
NFS server的配置文件:
# cat /etc/exports
/data/nfs *(rw,anonuid=1000,anongid=1000)
client:root用户创建f2.txt文件
# id
uid=0(root) gid=0(root) groups=0(root)
# touch f2.txt
# ll f2.txt
-rw-r--r-- 1 wang wang 0 Oct 16 14:53 f2.txt
server:查看f2.txt文件
# ll f2.txt
-rw-r--r-- 1 weirdo weirdo 0 Oct 16 14:53 f2.txt
client:wang用户创建f3.txt文件
$ touch f3.txt
$ ll f3.txt
-rw-rw-r-- 1 wang wang 0 Oct 16 14:56 f3.txt
server:查看f3.txt文件
# ll f3.txt
-rw-rw-r-- 1 weirdo weirdo 0 Oct 16 14:56 f3.txt
==>说明在NFS服务的共享目录中:
由于client和server的用户uid不一致,导致共享目录的中权限可能不同。
上述问题:生产环境中因为在各个服务器创建各自的用户造成UID混乱,为解决这种情况:
- 1.规范化:建用户和编译安装的服务在整个环境中同一个用户名UID保持一致。
- 2.LDAP服务:身份验证服务器可以将整个系统环境的用户全部集中于一台服务器,每次验证均在身份验证服务器上进行。
NFS分离共享文件
在上述实验中,编辑的/etc/exports文件将NFS服务的共享文件夹是按照一行一个共享文件夹,但是如果共享文件夹较多,但不同的主机又有不同的授权,可以采取对每个文件夹目录单独文件的方式配置。
- 在此目录下创建文件,对单独的目录进行单独授权/etc/exports.d/*.exports文件
示例:现需要共享/data/{doc,nfs,php}三个目录,而且还需要对不同的主机分别授权
写在/etc/exports一个文件中如下:
# cat /etc/exports
/data/nfs 192.168.38.17(rw,all_squash) *(ro)
/data/doc 192.168.38.17(rw) *(ro)
/home/weirdo 192.168.38.17(rw,anonuid=1000,anongid=1000)
/home/weirdo 192.168.38.16(ro)
查看共享目录:
# showmount -e 192.168.38.8
Export list for 192.168.38.8:
/home/weirdo 192.168.38.16,192.168.38.17
/data/doc (everyone)
/data/nfs (everyone)
因此可以将各种共享目录分离写在/etc/exports.d/{data_doc,data_nfs,home_weirdo}.exports各自的文件中。
windows 支持NFS功能
-
控制面板–> 找到程序和功能 --> 启用或关闭windows功能 --> NFS服务 --> 打开NFS客户端 --> 命令行方式挂载盘符
-
windows10版本以后window支持NFS功能,不过好像我的window7版本也有NFS功能,所以windows也能支持NFS功能。
-
因此一般认为NFS为linux专有服务,windows一般认为不支持NFS服务。
NFS工具
1.rpcinfo
- rpcinfo -p hostname
- rpcinfo –s hostname 查看RPC注册程序
2.exportfs
- –v 查看本机所有NFS共享
- –r 重读配置文件,并共享目录
- –a 输出本机所有共享
- –au 停止本机所有共享
3.showmount
- showmount -e hostname 显示NFS服务器的共享列表
4.mount.nfs 挂载工具
- 使用mount挂载NFS实际上是调用mount.nfs命令
客户端NFS挂载
-
NFS相关的挂载选项:man 5 nfs
- fg(默认)前台挂载,bg后台挂载
- hard(默认)持续请求,soft 非持续请求
- intr 和hard配合,请求可中断
- rsize和wsize 一次读和写数据最大字节数,rsize=32768
- _netdev 无网络不挂载
-
基于安全考虑,建议使用nosuid,nodev,noexec挂载选项
-
示例:开机挂载:/etc/fstab
172.16.0.1:/public /mnt/nfs nfs defaults,_netdev 0 0
NFS常用场景
- NFS常用于家目录的共享