nfs server

NFS服务简介

NFSNetwork File System的缩写,即网络文件系统。一种使用于分散式文件系统的协定,由Sun公司开发,于1984年向外公布。功能是通过网络让不同的机器、不同的操 作系统能够彼此分享个别的数据,让应用程序在客户端通过网络访问位于服务器磁盘中的数据,是在类Unix系统间实现磁盘文件共享的一种方法。
NFS的基本原则是“容许不同的客户端及服务端通过一组RPC分享相同的文件系统”,它是独立于操作系统,容许不同硬件及操作系统的系统共同进行文件的分享。
NFS在文件传送或信息传送过程中依赖于RPC协议。RPC,远程过程调用 (Remote Procedure Call) 是能使客户端执行其他系统中程序的一种机制。NFS本身是没有提供信息传输的协议和功能的,但NFS却能让我们通过网络进行资料的分享,这是因为NFS使 用了一些其它的传输协议。而这些传输协议用到这个RPC功能的。可以说NFS本身就是使用RPC的一个程序。或者说NFS也是一个RPC SERVER。所以只要用到NFS的地方都要启动RPC服务,不论是NFS SERVER或者NFS CLIENT。这样SERVER和CLIENT才能通过RPC来实现PROGRAM PORT的对应。可以这么理解RPC和NFS的关系:NFS是一个文件系统,而RPC是负责负责信息的传输。

nfs_01

portmap和rpcbind实质是一种东西,rpc服务不监听任何端口,rpcbind监听端口111,NFS借助RPC协议实现通信
portmap是在centos5以及之前的版本叫做portmap,之后叫rpcbind

什么是 RPC (Remote Procedure Call)

因为 NFS 支持的功能相当的多,而不同的功能都会使用不同的程序来启动,每启动一个功能就会启用一些端口来传输数据,因此, NFS 的功能所对应的端口才没有固定,而是随机取用一些未被使用的小于1024的端口来作为传输之用。但如此一来又造成客户端想要连上服务器时的困扰, 因为客户端得要知道服务器端的相关埠口才能够联机吧!

此时我们就得需要远程过程调用 (RPC) 的服务啦!RPC 最主要的功能就是在指定每个 NFS 功能所对应的 port number ,并且回报给客户端,让客户端可以连结到正确的埠口上去。 那 RPC 又是如何知道每个 NFS 的埠口呢?这是因为当服务器在启动 NFS 时会随机取用数个端口,并主动的向 RPC 注册,因此 RPC 可以知道每个埠口对应的 NFS 功能,然后 RPC 又是固定使用port 111来监听客户端的需求并回报客户端正确的埠口, 所以当然可以让 NFS 的启动更为轻松愉快了!

所以你要注意,要启动 NFS 之前,RPC 就要先启动了,否则 NFS 会无法向 RPC 注册。 另外,RPC 若重新启动时,原本注册的数据会不见,因此 RPC 重新启动后,它管理的所有服务都需要重新启动来重新向 RPC 注册。

nfs_02

如上图所示,当客户端有 NFS 档案存取需求时,他会如何向服务器端要求数据呢?

  1. 客户端会向服务器端的 RPC (port 111) 发出 NFS 档案存取功能的询问要求;
  2. 服务器端找到对应的已注册的 NFS daemon 埠口后,会回报给客户端;
  3. 客户端了解正确的埠口后,就可以直接与 NFS daemon 来联机。

使用rpcinfo来查看RPC的注册信息

更多的 NFS 相关协议信息你可以参考底下网页:

  • RFC 1094, NFS 协议解释
  • Linux NFS-HOWTO

nfs install

  • server:
    ``sh
    sudo apt-get install nfs-kernel-server
    1
    2
    3
    - client:
    ```sh
    sudo apt-get install nfs-common

start/stop/restart nfs server

1
2
3
4
5
6
7
8
# start service
systemctl start nfs-kernel-server

# stop service
systemctl stop nfs-kernel-server

# restart service
systemctl restart nfs-kernel-server

NFS服务器的配置

NFS服务器的配置相对比较简单,只需要在相应的配置文件中进行设置,然后启动NFS服务器即可。

NFS的常用目录

1
2
3
4
5
/etc/exports        NFS服务的主要配置文件
/usr/sbin/exportfs NFS服务的管理命令
/usr/sbin/showmount 客户端的查看命令
/var/lib/nfs/etab 记录NFS分享出来的目录的完整权限设定值
/var/lib/nfs/xtab 记录曾经登录过的客户端信息

NFS服务的配置文件为/etc/exports,这个文件是NFS的主要配置文件,不过系统并没有默认值,所以这个文件不一定会存在,可能要使用vim手动建立,然后在文件里面写入配置内容。

/etc/exports文件内容格式:

1
[共享的目录] [主机名或IP(参数,参数)]

其中参数是可选的,当不指定参数时,nfs将使用默认选项。默认的共享选项是sync, ro, root_squash, no_delay

当主机名或IP地址为空时,则代表共享给任意客户机提供服务。

当将同一目录共享给多个客户机,但对每个客户机提供的权限不同时,可以这样:

1
[共享的目录] [主机名1或IP1(参数1,参数2)] [主机名2或IP2(参数3,参数4)]

NFS共享的常用参数:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
ro                  只读访问 
rw 读写访问
sync 将数据同步写入内存缓冲区与磁盘中,效率低,但可以保证数据的一致性
async 将数据先保存在内存缓冲区中,必要时才写入磁盘
secure NFS通过1024以下的安全TCP/IP端口发送
insecure NFS通过1024以上的端口发送
wdelay 如果多个用户要写入NFS目录,则归组写入(默认)
no_wdelay 如果多个用户要写入NFS目录,则立即写入,当使用async时,无需此设置。
hide 在NFS共享目录中不共享其子目录
no_hide 共享NFS目录的子目录
subtree_check 如果共享/usr/bin之类的子目录时,强制NFS检查父目录的权限(默认)
no_subtree_check 和上面相对,不检查父目录权限
all_squash 共享文件的UID和GID映射匿名用户anonymous,适合公用目录。
no_all_squash 保留共享文件的UID和GID(默认)
root_squash root用户的所有请求映射成如anonymous用户一样的权限(默认)
no_root_squas root用户具有根目录的完全管理访问权限
anonuid=xxx 指定NFS服务器/etc/passwd文件中匿名用户的UID
anongid=xxx 指定NFS服务器/etc/passwd文件中匿名用户的GID

修改了**/etc/exports配置文件后,可以用exportfs命令重新扫描/etc/exports**文件,来使改动立刻生效,而不是重启整个nfs服务。

1
2
:~$ exportfs -au 卸载所有共享目录
:~$ exportfs -rv 重新共享所有目录并输出详细信息

exportfs命令有软件包nfs-kernel-server提供,详细的exportfs命令说明请查看man exportfs

example

配置文件/etc/exports内容如下:

1
2
$ cat /etc/exports
/home/share 192.168.102.15(rw,sync) *(ro)

配置说明: 对192.168.102.15赋予读写权限,其他机器仅有只读权限。

nfs client

客户端是指网络中可以访问这个NFS输出目录的计算机

客户端常用的指定方式

  • 指定ip地址的主机:192.168.0.200
  • 指定子网中的所有主机:192.168.0.0/24 192.168.0.0/255.255.255.0
  • 指定域名的主机:david.bsmart.cn
  • 指定域中的所有主机:*.bsmart.cn
  • 所有主机:*

查看NFS服务器的资源共享情况

1
2
3
:~$ showmount -e 192.168.102.47
Export list for 192.168.102.47:
/home/share (everyone)

mount nfs shares

在客户机192.168.102.15上加载共享资源

1
mount 192.168.102.47:/home/share /mnt

problem

  1. 检查网络
    1
    2
    3
    4
    5
    # mount -o nolock 192.168.2.211:/ /mnt
    mount: RPC: Unable to receive; eNrno = No route Fo host
    mount: Sfsmount failed::Bad file descriptor
    mount program didn't pass remote address!
    mount: Mounting 192.168.2.211:/ on /mnt failed: Invalid argument
    这个错误代码是典型的网络问题,好好检查一下,实在不行就reboot一下。
  2. 关闭firewall
  3. udp和tcp选项
  4. 配置文件exports中参数是否正确、是否生效

安全

防火墙的设定问题与解决方案

一般来说,NFS的服务仅会对内部网域开放,不会对因特网开放的。然而,如果你有特殊需求的话,那么也可能会跨不同网域就是了。但是,NFS的防火墙特别难搞,为什么呢?因为除了固定的port 111, 2049之外, 还有很多不固定的端口是由 rpc.mountd, rpc.rquotad 等服务所开启的,所以,你的 iptables 就很难设定规则! 那怎办?难道整个防火墙机制都要取消才可以?

启动NFS会开启如下端口:

  1. portmapper 端口:111 udp/tcp;

  2. nfs/nfs_acl 端口:2049 udp/tcp;

  3. mountd 端口:”32768–65535” udp/tcp

  4. nlockmgr 端口:”32768–65535” udp/tcp
    系统 RPC服务在 nfs服务启动时默认会给 mountd 和 nlockmgr 动态选取一个随机端口来进行通讯。

  5. 查看NFS需要开启的服务和对应的端口号

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    root@debian:~# rpcinfo -p                    
    program vers proto port service
    100000 4 tcp 111 portmapper
    100000 3 tcp 111 portmapper
    100000 2 tcp 111 portmapper
    100000 4 udp 111 portmapper
    100000 3 udp 111 portmapper
    100000 2 udp 111 portmapper
    100005 1 udp 57974 mountd
    100005 1 tcp 60537 mountd
    100005 2 udp 36805 mountd
    100005 2 tcp 35311 mountd
    100005 3 udp 60721 mountd
    100005 3 tcp 54945 mountd
    100003 3 tcp 2049 nfs
    100003 4 tcp 2049 nfs
    100227 3 tcp 2049
    100003 3 udp 2049 nfs
    100003 4 udp 2049 nfs
    100227 3 udp 2049
    100021 1 udp 41235 nlockmgr
    100021 3 udp 41235 nlockmgr
    100021 4 udp 41235 nlockmgr
    100021 1 tcp 38331 nlockmgr
    100021 3 tcp 38331 nlockmgr
    100021 4 tcp 38331 nlockmgr
    root@debian:~#

    通过上面的显示可以看到NFS启动了portmapper、mountd、nfs、nlockmgr四个服务和对应的端口号, portmapper和nfs是固定端口,我们可以将剩下的两个服务的端口也固定下来。

  6. 通过配置文件/etc/default/nfs-kernel-server可以设置mountd服务的固定端口,添加如下的内容:

    1
    2
    root@debian:~# vim /etc/default/nfs-kernel-server
    RPCMOUNTDOPTS="-p 50444" #设置规定端口好为50444,重启服务生效
  7. 通过配置文件/etc/modprobe.d/local.conf可以设置nlockmgr服务的固定端口,添加如下的内容

    1
    2
    3
    root@debian:~# vim /etc/modprobe.d/local.conf            #这个local.conf文件没有需要创建,重启电脑生效
    options lockd nlm_udpport=50445 nlm_tcpport=50445
    options nfs callback_tcpport=32764

    有关更多设置可以查看这个网址

  8. 重启电脑从新查看对应的端口

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    root@debian:~# rpcinfo -p     
    program vers proto port service
    100000 4 tcp 111 portmapper
    100000 3 tcp 111 portmapper
    100000 2 tcp 111 portmapper
    100000 4 udp 111 portmapper
    100000 3 udp 111 portmapper
    100000 2 udp 111 portmapper
    100005 1 udp 50444 mountd
    100005 1 tcp 50444 mountd
    100005 2 udp 50444 mountd
    100005 2 tcp 50444 mountd
    100005 3 udp 50444 mountd
    100005 3 tcp 50444 mountd
    100003 3 tcp 2049 nfs
    100003 4 tcp 2049 nfs
    100227 3 tcp 2049
    100003 3 udp 2049 nfs
    100003 4 udp 2049 nfs
    100227 3 udp 2049
    100021 1 udp 50445 nlockmgr
    100021 3 udp 50445 nlockmgr
    100021 4 udp 50445 nlockmgr
    100021 1 tcp 50445 nlockmgr
    100021 3 tcp 50445 nlockmgr
    100021 4 tcp 50445 nlockmgr
    root@debian:~#
  9. 添加防火墙规则


Refence:

  • 51cto
  • ⻦哥的Linux私房菜
  • cnblogs.com