NFS服务及RPC协议

发布时间 2023-12-02 14:41:54作者: yysjdys

NFS服务及RPC协议

FTP和NFS的区别

文件系统类型 FTP是一种基于客户端-服务器的协议,用于文件传输。NFS则是一种分布式文件系统协议,作为本地操作系统和远程文件系统之间的桥梁,可以实现跨平台文件共享。

传输速度和效率 由于FTP是基于客户端-服务器的协议,所以需要进行连接的建立和关闭,因此相对于NFS,FTP传输的速度较慢,效率也较低。而NFS则是通过一些标准和规定管理远程文件系统的,直接访问远程文件系统,传输速度和效率更高

安全性 FTP协议的安全性比较差,数据传输时通常不加密,可能会被非法获取。而NFS使用一些安全机制来实现远程文件系统的访问和传输,因此相对于FTP,NFS更加安全可靠

传输方式 FTP协议是通过FTP客户端和FTP服务器进行文件传输。而NFS通过共享文件系统的方式使用本地文件系统来挂载远程文件系统,实现文件共享

支持的平台 FTP协议是一种常见的文件传输协议,广泛应用于所有操作系统平台。而NFS多用于UNIX和Linux中,虽然现在也有一些移植到其他平台的版本,但是还是没有FTP使用广泛。

RPC 远程过程调度

  • NFS 协议本身并没有网络传输功能,而是基于远程过程调用协议实现的
  • 提供一个面向过程的远程服务的接口
  • 可以通过网络从远程主机程序上请求服务,而不需要了解底层网络技术的协议
  • 工作在 OSI 模型的会话层,它可以为遵从 RPC 协议应用层协议提供端口注册功能
  • 事实上,有很多服务(NFS 和 NIS 等)都可以向 RPC 注册端口
  • RPC 使用网络端口 111 来监听客户端的请求

RPC机制

  • 基于 rpc 的服务(此处是指 nfs 服务,在别处有可能是代表其他服务)在启动时向 portmapper 注册端口
  • 基于 rpc 的客户端联系服务端 portmapper 询问服务的端口号
  • portmapper 告知客户端基于 rpc 服务使用的端口号
  • 基于 rpc 的客户端访问被告知基于 rpc 服务的端口
  • 基于 rpc 的服务响应客户端的请求

工作原理

NFS服务器可以让PC将网络中的NFS服务器共享的目录挂载到本地端的文件系统中,而在本地端的系统中来看,那个远程主机的目录就好像是自己的一个磁盘分区一样,在使用上相当便利;

NFS工作流程

1.首先服务器端启动RPC服务,并开启111端口
2.服务器端启动NFS服务,并向RPC注册端口信息
3.客户端启动RPC(portmap服务),向服务端的RPC(portmap)服务请求服务端的NFS端口
4.服务端的RPC(portmap)服务反馈NFS端口信息给客户端。
5.客户端通过获取的NFS端口来建立和服务端的NFS连接并进行数据的传输。

挂载原理

当我们在NFS服务器设置好一个共享目录/opt后,其他的有权访问NFS服务器的NFS客户端就可以将这个目录挂载到自己文件系统的某个挂载点,这个挂载点可以自己定义,如上图客户端A与客户端B挂载的目录就不相同。并且挂载好后我们在本地能够看到服务端/opt的所有数据。

NFS服务部署

安装rpcbind

[root@node2 ~]# yum -y install rpcbind
//rpcbind为NFS中用来消息通知的服务

rpcbind工具可以将RPC程序号码和通用地址互相转换。要让某主机能向远程主机的服务发起RPC调用, 则该主机上的rpcbind必须处于已运行状态。
当RPC服务启动后,它会告诉rpcbind它监听在哪个地址上,还会告诉它为服务准备好提供的PRC程序 号码。当客户端要向某个给定的程序号码发起RPC调用时,它首先会联系服务端的rpcbind以确定RPC 请求应该发送到哪个地址上。
rpcbind工具应该在所有RPC管理的服务(rpc service)启动之前启动。一般来说,标准的rpc服务由端 口监视器来启动,因此rpcbind必须在端口监视器被调用之前已经启动完成。
当rpcbind工具已经启动后,它会检查特定的name-to-address的转换调用功能是否正确执行。如果失 败,则网络配置数据库会被认为过期,由于RPC管理的服务在这种情况下无法正确运行,rpcbind会输 出这些信息并终止。
另外,rpcbind工具只能由super-user启动

安装 nfs 服务

[root@node2 ~]# yum -y install nfs-utils
# 其实直接装 nfs-utils 也会以依赖的方式自动装上 rpcbind
[root@node2 ~]# systemctl status rpcbind.socket
[root@node2 ~]# systemctl start nfs-server
[root@node2 ~]# systemctl enable nfs-server

比较 nfs 启动前后的 rpcbind 的状态

[root@node2 ~]# systemctl status rpcbind.socket
# nfs 启动前,只是监听 111 端口,但是并没有启动对应的服务
● rpcbind.socket - RPCbind Server Activation Socket
   Loaded: loaded (/usr/lib/systemd/system/rpcbind.socket; enabled; vendor preset: enabled)
   Active: active (running) since 二 2023-07-11 14:03:33 CST; 12h ago
   Listen: /var/run/rpcbind.sock (Stream)
   
   7月 11 14:03:33 localhost.localdomain systemd[1]: Listening on RPCbind Server Activa....
Hint: Some lines were ellipsized, use -l to show in full.
[root@node2 ~]# systemctl status rpcbind
# nfs 启动后,可以看到 rpcbind 自动启动了,也说明了 nfs 对 rpc 的依赖
● rpcbind.service - RPC bind service
   Loaded: loaded (/usr/lib/systemd/system/rpcbind.service; enabled; vendor preset: enabled)
   Active: active (running) since 二 2023-07-11 14:03:34 CST; 12h ago
 Main PID: 1163 (rpcbind)
   CGroup: /system.slice/rpcbind.service
           └─1163 /sbin/rpcbind -w

7月 11 14:03:33 localhost.localdomain systemd[1]: Starting RPC bind service...
7月 11 14:03:34 localhost.localdomain systemd[1]: Started RPC bind service.

查看已经监听的端口,在重启 nfs 之后,端口号会随机变化,所以需要 rpc 做注册

[root@localhost ~]# ss -ntulp//监听命令
//重启服务前端口号为323
 users:(("rpcbind",pid=1163,fd=9))
udp   UNCONN     0      0          [::1]:323                     [::]:*     
//重启后端口号改变了
 users:(("rpcbind",pid=1163,fd=10))
udp   UNCONN     0      0           [::]:2049                    [::]:*
udp   UNCONN     0      0           [::]:111                     [::]:*           
[root@localhost ~]# rpcinfo -p
//查看注册后的端口号为2049
    100003    3   tcp   2049  nfs
    100003    4   tcp   2049  nfs
    100227    3   tcp   2049  nfs_acl
    100003    3   udp   2049  nfs
    100003    4   udp   2049  nfs
    100227    3   udp   2049  nfs_acl

NFS 软件介绍

软件包 nfs-utils
相关软件包 rpcbind(必须),tcp_wrappers kernel

rpcbind是一个系统服务,它提供远程过程调用(RPC)端口映射。它允许客户端应用程序通过网络连接到服务器上运行的RPC服务。rpcbind会监听特定的端口(默认是111),并将客户端请求转发到相应的RPC服务。

tcp_wrappers kernel是一种基于主机的访问控制系统,它通过检查传入网络连接的源IP地址、目标IP地址和请求服务的名称来决定是否允许或拒绝连接。它使用名为hosts.allow和hosts.deny的配置文件来定义访问规则。

这两个组件通常一起使用,以提供更强大的网络访问控制和安全性。rpcbind是必需的,因为它是RPC服务的端口映射器,而tcp_wrappers kernel可以在其上实施访问控制规则。

支持 nfs.ko
端口 2049(nfsd), 其它端口由 portmap(111)分配
//说明: CentOS 6 开始 portmap 进程由 rpcbind 代替

NFS 服务主要进程

rpc.nfsd 最主要的 NFS 进程, 管理客户端是否可登录 rpc.mountd 挂载和卸载 NFS 文件系统,包括权限管理
rpc.lockd 非必要,管理文件锁,避免同时写出错
rpc.statd 非必要, 检查文件一致性, 可修复文件

日志 /var/lib/nfs

NFS 配置文件

/etc/exports

/etc/exports.d/*.exports

NFS 共享配置文件格式

/dir          主机1    (opt1,opt2)                           主机 2(opt1,opt2)
//<输出目录>  //客户端1 选项(如访问权限、用户映射)               //客户端2选项(..)
//输出目录指的是NFS系统中需要共享给客户机使用的目录

常用命令

rw							  //允许读写
ro							  //只读
sync						  //同步写入
async	                      //先写入缓冲区,必要时才写入磁盘,速度快,但会丢数据(异步)
subtree_check	              //若输出一个子目录,则nfs服务将检查其父目录权限
no_subtree_check	          //若输出一个字目录,不检查父目录,提高效率
no_root_squash	              //客户端以root登录时,赋予其本地root权限
root_squash	                  //客户端以root登录时,将其映射为匿名用户
all_squash	                  //将所有用户映射为匿名用户
no_all_squash                 //保留共享文件的 UID 和 GID (默认)
anonuid 和 anongid            //所有远程用户(包括 root)都变成 nfsnobody,Centos8 为 nobody

配置案例

1.准备要共享的文件夹
[root@localhost ~]# mkdir /public
[root@localhost ~]# mkdir /protected
2.配置NFS共享
[root@localhost ~]#vim /etc/exports
/public 192.168.28.0/256(ro)
/protected 192.168.28.0/256(rw,no_root_squash)
//网段内用户对/public文件夹只读,protected文件夹可读可写且登录用户为root时具有root的所有权限
3.启动系统服务nfs-server
[root@localhost ~]#  systemctl restart nfs-server
[root@localhost ~]# systemctl enable nfs-server

NFS工具

rpcinfo

rpcinfo 工具可以查看 RPC 相关信息

查看注册在指定主机的 RPC 程序

rpcinfo -p hostname

查看 rpc 注册程序

rpcinfo -s hostname

exportfs

可用于管理 NFS 导出的文件系统

常见选项
-v:查看本机所有 NFS 共享
-r:重读配置文件,并共享目录
-a:输出本机所有共享
-au:停止本机所有共享

showmount

常见用法
showmount -e hostname

mount.nfs

客户端 NFS 挂载

相关挂载选项
fg                 //(默认)前台挂载
bg                 //后台挂载
hard               //(默认)持续请求
soft               //非持续请求
intr 和 hard 配合   //请求可中断
rsize 和 wsize     //一次读和写数据最大字节数,rsize=32768
_netdev           //无网络不挂载

提示:基于安全考虑,建议使用nosuid,_netdev,noexec挂载选项

范例:临时挂载 NFS 共享
mount -o rw,nosuid,fg,hard,intr 192.168.28.30:/test/dir /mnt/nfs
范例:开机挂载
vim /etc/fstab
192.168.28.30:/myshare    /mnt/nfs    nfs    defaults,_netdev  0 0

自动挂载

可使用autofs服务按需要挂载外围设备,NFS共享等,并在空闲5分钟后后自动卸载,设备一直挂载可能比较耗费资源

相关包和文件

软件包: autofs
服务文件: /usr/lib/systemd/system/autofs.service
配置文件: /etc/auto.master

配置文件格式

参看帮助: man 5 autofs

自动挂载资源有两种格式

相对路径法:将mount point路径分成dirname和basename分别配置,可能会影响现有的目录结构
绝对路径法:直接匹配全部绝对路径名称,不会影响本地目录结构

相对路径法

  • /etc/auto.master`格式
挂载点的dirname    指定目录的配置文件路径
  • 指定目录的配置文件格式
挂载点的basename    挂载选项    选项设备
案例

相对路径法为支持通配符

客户端

[root@localhost ~]# vim /etc/auto.master
/misc    /etc/auto.misc
[root@localhost ~]# mkdir /misc 
[root@localhost ~]# vim /etc/auto.misc
//表示/misc下面的子目录和nfs共享/export目录的子目录同名
* -fstype=nfs,vers=3 192.168.175.19:/myshare/&
[root@localhost ~]# systemctl restart autofs

服务端

[root@localhost myshare]# mkdir -p dir/dir1

客户端

[root@localhost ~]# df -h
[root@localhost misc]# ll /misc
总用量 0
[root@localhost misc]# cd /misc/dir
[root@localhost dir]# ll
总用量 0
drwxr-xr-x 2 root root 6 7月  17 19:10 dir1
[root@localhost dir]# df -h

绝对路径法

  • /etc/auto.master格式
/-      指定配置文件路径
  • 指定配置文件格式
绝对路径      挂载选项      选项设备
案例
[root@localhost dir]# vim /etc/auto.misc
#* -fstype=nfs,vers=3 192.168.175.19:/myshare/&
//把之前挂载的注释掉,防止重复挂载出问题
[root@localhost dir]# vim /etc/auto.master
/-      /etc/auto.direct
//添加一行,/-表示直接挂在根目录下
[root@localhost dir]# vim /etc/auto.direct
/nfsdir -fstype=nfs 192.168.175.19:/myshare
[root@localhost dir]# mkdir /nfsdir
[root@localhost dir]# systemctl restart autofs
[root@localhost dir]# df -h
[root@localhost ~]# cd /nfsdir/
[root@localhost ~]# df -h

实际案例

将NFS的共享目录,通过autofs 发布出来,做为远程主机用户的家目录

环境准备

将node1中的用户家目录共享出来,node2在登陆这个用户的到时候,看到家目录下的文件是一致的

步骤

1.NFS服务器创建用户和相应的目录,将用户user的家目录共享

[root@NFSserver ~]# mkdir /data
[root@NFSserver ~]# useradd -d /data/user user
[root@NFSserver ~]# id user
uid=1000(user) gid=1000(user) 组=1000(user)
[root@NFSserver ~]# vim /etc/exports
#/myshare 192.168.28.0/256(rw,sync,no_root_squash,all_squash)
/data/user    *(rw,sync,anonuid=1000,anongid=1000,all_squash)
[root@NFSserver ~]# exportfs -r
[root@NFSserver ~]# exportfs -v
/data/user      <world>(sync,wdelay,hide,no_subtree_check,anonuid=1000,anongid=1000,sec=sys,rw,secure,root_squash,all_squash)

2.在nfs客户端上实现autofs

[root@localhost ~]# vim /etc/auto.master
/-      /etc/auto.direct
[root@NFSclient ~]# vim /etc/auto.direct
/data/user -fstype=nfs,vers=3 192.168.28.130:/data/user
[root@NFSclient ~]# systemctl restart autofs

3.在nfs客户端上创建用户user

[root@NFSclient ~]# mkdir /data
[root@NFSclient ~]# useradd -d /data/user -u 1000 user

4.测试是否完成目标

[root@NFSserver ~]# su - user
[user@NFSserver ~]$ touch file
// 在NSF服务器上登录user用户,创建文件在家目录中
[root@NFSclient /]# su - user
[user@NFSclient ~]$ ll
总用量 0
-rw-rw-r--. 1 user user 0 4月  30 10:13 file
//在NSF客户机上登录user用户,发现文件已经被共享了