NFS如何限制可以获取NFS输出列表的IP和用户

一、概要

在这里插入图片描述
NFS(Network File System)即网络文件系统,是FreeBSD支持的文件系统中的一种,它允许网络中的计算机之间通过TCP/IP网络共享资源。NFS是一个使用RPC构造的客户端/服务器应用程序,其客户端通过向一台NFS服务器发送RPC请求来访问其中的文件。尽管这一工作可以使用一般的用户进程来实现,即NFS客户端可以是一个用户进程,对服务器进行显式调用在NFS的应用中,本地NFS的客户端应用可以透明地读写位于远端NFS服务器上的文件,就像访问本地文件一样。NFS本身没有提供信息传输的协议和功能,但NFS却能让我们通过网络进行资料的分享,就是因为NFS使用了RPC提供的传输协议,可以说NFS就是使用PRC的一个程序。NFS依赖于RPC协议。所谓RPC远程过程调用(Remote Procedure Call),是使客户端能够执行其他系统中程序的一种机制。NFS服务器在端口UDP2049接收作为UDP数据包的客户端请求,NFS服务本身不提供文件传输功能,我们要远程使用NFS文件系统就需要RPC服务的支持;而portmap服务用来为RPC服务进行动态端口分配和映射,所以portmap服务也是NFS服务所必须的。可以把NFS服务看作RPC服务的一种,开启NFS服务其实就是在开启RPC服务,portmap 服务是用于 RPC 服务(如 NIS (network information service)和 NFS)的动态端口分配守护进程。安装NFS服务时所需要的两个软件包nfs-utils和portmap:Nfs-utils软件包提供了rpc.nfsd和rpc.mountd两个RPC的daemon(守护进程)程序,而portmap软件包提供了portmap程序。

目前NFS已具备了防止被利用导出文件夹的功能,但遗留系统中的NFS服务配置不当,则仍可遭到恶意攻击者的利用。

二、安装

rpm -qa |grep nfs			//检查系统是否已经安装
nfs4-acl-tools-0.3.3-13.el7.x86_64
nfs-utils-1.3.0-0.48.el7_4.x86_64		//必要安装
libnfsidmap-0.25-9.el7.x86_64

rpm -qa |grep rpc   //
xmlrpc-c-1.32.5-1905.svn2451.el7.x86_64
xmlrpc-c-client-1.32.5-1905.svn2451.el7.x86_64
libtirpc-0.2.4-0.10.el7.x86_64
rpcbind-0.2.0-42.el7.x86_64		//必要安装
yum install rpcbind  nfs-utils.x86_64  nfs4-acl-tools  //如果没有安装
systemctl enable rpcbind.service  //即之前的portmap
systemctl enable nfs-server.service
systemctl start rpcbind.service  //需要首先要启动RPC服务(即portmap 服务),否则NFS SERVER就无法向RPC服务区注册,当然如果RPC服务重新启动,原来已经注册好的NFS端口数据就会全部丢失。
systemctl start nfs-server.service
chkconfig --list nfs
chkconfig --list rpcbind
exportfs -rv  //重新读取NFS配置文件; 当修改NFS配置文档后,不需要重启NFS,exportfs –rv即可使修改的/etc/exports生效,或执行systemctl reload nfs

#客户端
yum install nfs-utils rpcbind

NFS 原理回顾:

在这里插入图片描述

NFS本身的服务并没有提供数据传递的协议,而是通过使用RPC(远程过程调用 Remote Procedure Call)来实现。当NFS启动后,会随机的使用一些端口,NFS就会向RPC去注册这些端口。RPC就会记录下这些端口,RPC会开启111端口。通过client端和sever端端口的连接来进行数据的传输。在启动nfs之前,首先要确保rpc服务启动。其中,RPC,基于C/S模型。程序可以使用这个协议请求网络中另一台计算机上某程序的服务而不需知道网络细节,甚至可以请求对方的系统调用。

在这里插入图片描述

在这里插入图片描述

涉及关联服务组件:

  • rpc:远程过程调用协议,是实现本地调用远程主机实现系统调用的协议。当NFS启动后,就会随机使用一些端口;然后NFS就会向RPC去注册这些端口,RPC就会记录下这些端口,并且RPC会开启111端口,等待客户端RPC的请求,如果客户端有请求,那么服务器端的RPC就会将之前记录的NFS端口信息告知客户端;如此客户端就会获取NFS服务器端的端口信息,就会以实际端口进行数据的传输了;总之,RPC 就是用来统一管理NFS端口的服务,并且统一对外的端口是111;PRC最主要的功能就是指定每个NFS功能所对应的 port number,并且通知客户端,可以连接到正常端口上去。
  • portmapper:负责分配rpc server的端口,并在client端请求时,负责响应目的rpc server端口返回给client端,工作在tcp与udp的111端口上。
  • mountd:是nfs服务的认证服务的守护进程,client在收到返回的真正端口时,就会去连接mountd,认证取得令牌。
  • nfsd:nfs的守护进程,负责接收到用户的调用请求后与内核发出请求并得到调用结果响应给用户,工作在tcp和udp的2049端口。
  • idmapd:是NFS的一个程序,用来负责远程client端创建文件后的权限问题。
  • quotad:用用于实现磁盘配额,当client端挂载nfs后可以限制磁盘空间的大小

三、服务确认及配置

服务器端:/etc/exports就是nfs服务的主配置文件,这个文件不一定会存在,要使用vim手动建立;

/usr/sbin/exportfs:NFS服务的管理命令
/usr/sbin/showmount:客户端的查看命令
/var/lib/nfs/etab:记录NFS分享出来的目录的完整权限设定值
/var/lib/nfs/xtab:记录曾经登录过的客户端信息
systemctl status rpcbind.service //查看RPC的服务状态
netstat -antlp |grep rpc //查看rpcbind服务的端口
rpcinfo -p localhost //查看本地主机是否有端口注册
systemctl status nfs.service //查看nfs服务的状态

/etc/exports文件内容格式:

<输出目录> [客户端1 选项(访问权限,用户映射,其他)] [客户端2 选项(访问权限,用户映射,其他)] 

说明:

  • 输出目录:指NFS系统中需要共享给客户机使用的目录;
  • 客户端是指网络中可以访问这个NFS输出目录的计算机,可以这么写:
    指定ip地址的主机:192.168.0.200
    指定子网中的所有主机:192.168.0.0/24 192.168.0.0/255.255.255.0
    指定域名的主机:david.bsmart.cn
    指定域中的所有主机:*.bsmart.cn
    所有主机:*
  • 选项用来设置输出目录的访问权限、用户映射:
    设置输出目录只读:ro
    设置输出目录读写:rw
    all_squash:将远程访问的所有普通用户及所属组都 映射为匿名用户或用户组(nfsnobody),即共 享文件的UID和GID映射匿名用户anonymous,适合公用目录
    no_all_squash:与all_squash取反(默认设置),保留共享文件的UID和GID(默认);
    root_squash:将root用户及所属组都
    映射为匿名用户或用户组(默认设置),相当于在服务器使用nobody用户访问目录;配置后,在登入 NFS 主机使用分享之目录的使用者如果是 root 时,那么这个使用者的权限将被压缩成为匿名使用者,通常他的 UID 与 GID 都会变成 nobody 那个系统账号的身份;
    no_root_squash:与rootsquash取反,即root用户及及所属组都不映射(no_root_squash),即相当于在服务器上用root身份访问该目录;如果启用该选项,当客户端用root身份登录时,挂载nfs的共享目录时,客户端的root将对共享目录具备root权限(风险高)。设置no_root_squash后,登入 NFS 主机使用分享目录的使用者,如果是 root 的话,那么对于这个分享的目录来说,他就具有 root 的权限!这个项目『极不安全』,不建议使用!
    subtree_check 是NFS服务中的一个选项,它用于控制服务器在进行导出目录的权限检查时是否应该考虑目录的inode所属用户和组。当NFS客户端尝试访问一个被export的目录时,NFS服务器会检查访问权限,检查它的挂载点变化,且到挂载点之间的目录是否均有访问权限,尤其服务侧expor下的A目录迁移到B目录时,客户端依然访问已经变化后的A目录,这时如果配置了 no_subtree_check,则不检查a目录的expor点变化,可以成功继续访问A目录并创建文件,否则会报错:
    Stale file handle
    ,发现挂载点变化,创建文件失败。如果subtree_check选项被启用,服务器会检查访问路径上的每个目录的所属用户和组,确保客户端的用户和组有权限访问这些目录。这可以防止客户端越权访问文件系统的子目录。
    anonuid=xxx:将远程访问的所有用户都映射为匿名用户,并指定该用户为本地用户(UID=xxx);
    anongid=xxx:将远程访问的所有用户组都映射为匿名用户组账户,并指定该匿名用户组账户为本 地用户组账户(GID=xxx);
    secure:限制客户端只能从小于1024的tcp/ip端口连接nfs服务器(默认设置);
    insecure:允许客户端从大于1024的tcp/ip端口连接服务器;
    sync:将数据同步写入内存缓冲区与磁盘中,效率低,但可以保证数据的一致性;
    async:将数据先保存在内存缓冲区中,必要时才写入磁盘;
    wdelay:检查是否有相关的写操作,如果有则将这些写操作一起执行,这样可以提高效率(默认设置);
    no_wdelay:若有写操作则立即执行,应与sync配合使用;
    subtree:若输出目录是一个子目录,则nfs服务器将检查其父目录的权限(默认设置);
    no_subtree:即使输出目录是一个子目录,nfs服务器也不检查其父目录的权限,这样可以提高效率;
    hide 在NFS共享目录中不共享其子目录
    no_hide 共享NFS目录的子目录

【mount挂载参数】

-t ntfs:告诉挂载命令将要挂载的文件系统类型。这个选项并不是必须的,因为mount会自动识别大多数的文件系统。
-r:以只读形式挂载卷。挂载操作默认以可读写形式挂载卷。除非指明,否则驱动将会以只读形式自动挂载文件系统,同-o ro。
-o umask={VALUE}:
-o uid={USERID}
-o gid={GROUPID}:
-o iocharset={NAME}
-o fmask={VALUE}
-o dmask={VALUE}

注:参数umask同时改变文件和路径两者的权限,fmask以同样的方式作用于文件而dmask作用于路径,这些选项也可以被组合使用

eg:mount /dev/hda1 /mnt/windows -t ntfs -r -o umask=0222

mount /dev/hda1 /mnt/windows -t ntfs -r -o uid=flatcap
mount /dev/hda1 /mnt/windows -t ntfs -r -o uid=500
mount /dev/hda1 /mnt/windows -t ntfs -r -o gid=winusers
mount /dev/hda1 /mnt/windows -t ntfs -r -o gid=520
mount /dev/hda1 /mnt/windows -t ntfs -r -o iocharset=utf8
mount /dev/hda1 /mnt/windows -t ntfs -r -o iocharset=iso8859-2(中欧)
mount /dev/hda1 /mnt/windows -t ntfs -r -o iocharset=gb2312(简体中文)
mount /dev/hda1 /mnt/windows -t ntfs -r -o utf8=tru
mount /dev/hda1 /mnt/windows -t ntfs -r -o fmask=0222
mount /dev/hda1 /mnt/windows -t ntfs -r -o dmask=0222
mount /dev/hda1 /mnt/windows -t ntfs -r -o fmask=0077,dmask=0222

3.1【权限配置】:

1)如果同一目要针对不同用户/不同区域开放不同权限:比如nfs共享目录/home/public

setfacl -m g:blue:rwx /home/public
vim /etc/exports  //如下所示
/opt          *(rw,sync,root_squash)
/tmp          *(rw,no_root_squash)   //因配置no_root_squash参数,client上root访问访问/tmp,文件所有者为/root
/home/public  192.168.100.0/24(rw)    *(ro)   //网段不能写成192.168.100.* 这样的格式

上面通过配置文件里权限配置内容+acl配置,共同实现/home/public 只有192.168.100.0/24且加入blue组的用户才能读写,其他主机或用户只能读;当用户从客户端挂载NFS共享目录/home/public后,192.168.100.0/24内的主机可以对改目录可以读写,其他的只能只读;

2)如果限制NFS的目录为指定主机是的某一个用户才可以访问:

setfacl -m u:admin:rwx /home/public

vim /etc/exports  //
/tmp          *(rw,no_root_squash)     //当客户端uid=600用户访问该目录,创建文件是文件uid会变成600,即使NFS服务器上没有uid=600的用户
/home/public  192.168.100.2(rw)       //只有100.2上的admin用户才能有完整的访问权限

3)开通匿名访问,假如客户端过来的用户在nfs共享目录存储文件时,希望文件的 UID 與 GID 都变成 45 這個身份的使用者,且改用户的属主为nfsanon,相当于只有uid=45的用户才能访问/home/public 。

groupadd -g 45 nfsanon
useradd -u 45 -g nfsanon nfsanon
setfacl -m u:nfsanon:rwx /home/public

vim /etc/exports
/tmp          *(rw,no_root_squash)
/home/public  192.168.100.0/24(rw,all_squash,anonuid=45,anongid=45)  //如果要开放匿名,那麼重点是 all_squash,且要配合 anonuid 使用!这样当客户端访问 NFS 主机,且在 /home/public 写入文件时,该文件的所有者或所有組,就會变成 /etc/passwd 裡面对应的 UID45 的那个用户!
/opt   172.16.19.0/16(ro,async) 192.16.18.0/24(rw,sync) *(ro)   //多个客户之间使用空白字符分隔,每个客户端后面必须跟一个小括号,里面定义了此客户访问特性

3.2 Linux漏洞:showmount -e信息泄露(CEE-1999-0554)

修改该漏洞,实现允许指定主机通过mount到nfs服务器上,阻止其他主机通过showmount -e方式,泄露NFS共享目录结构信息。

在这里插入图片描述
1)在目标主机上编辑:vi /etc/hosts.allow

在这里插入图片描述
注:对一个网段限制:172.18.1.,172.18.2.:allow,172.18.1.12x:allow

2)vi /etc/hosts.deny

在这里插入图片描述
注:上述所有操作无需重启rpc.bind和nfs

3)验证:
本机验证:# showmount -a
clnt_create: RPC: Unknown host
远程验证:showmount -e 172.13.14.15 //远程主机ip
clnt_create: RPC: Port mapper failure - Authentication error

4)联系安全部分扫描确认,正常应该漏洞已经无法扫描到。

四、客户端命令:

#showmount -e 192.168.0.10 //将得到一个在 192.168.0.10 上可用的 NFS 共享的列表,命令执行会检索给定主机的导出文件夹列表,这些信息将被用于访问这些文件夹。
显示指定NFS服务器连接NFS客户端的信息
# showmount 192.168.1.1 #此ip为nfs服务器的

# showmount -e #显示输出目录列表

# showmount -d #显示被挂载的共享目录

# showmount -a #显示客户端信息和共享目录

# showmount -a 192.168.1.1 #显示指定NFS服务器的客户端信息和共享目录

如报错:clnt_create: RPC: Program not registered
可重启服务侧的nfs-server和rpcbind

客户端维护工具:NFS Shell;它可以连接到NFS共享并可以帮助我们手动识别一些常见的安全问题;安装执行如下:
a

pt-get install libreadline-dev libncurses5-dev
make
gcc -g -o nfsshell mount_clnt.o mount_xdr.o nfs_prot_clnt.o nfs_prot_xdr.o nfsshell.o -L/usr/local/lib -lreadline -lhistory -lncurses
./nfsshell
nfs> host IP // 连接NFS服务
nfs> export // 导出NFS列表
mount -t nfs 192.168.1.172:/ /temp -o nolock  //将共享文件夹或导出的NFS列表挂载到客户端一个空目录来访问
挂载后,如果对于共享上的文件我们没有读取权限,可改写文件所有者的UID来欺骗NFS服务器,ls-al列出访问文件的UID,可在客户端本地创建一个新用户,并将该用户的UID和名称修改为与文件所有者相同。当然UID可以在passwd文件中更改,vi /etc/passwd将第2、3个冒号后id改为同文件的UID和GID;执行su到新用户后,由于该文件的UID与新用户的UID相同,因此系统会误认为这是文件权限的所有者,这样我们就可以以一个合法的用户身份来读取文件的内容了。

造成这种问题,原因在于导出文件夹并未设置root_squash选项。root_squash登入NFS主机,使用该共享目录时相当于该目录的拥有者。但是如果是以root身份使用这个共享目录的时候,那么这个使用者(root)的权限将被压缩成为匿名使用者,即通常他的UID与GID都会变成nobody那个身份,以防止越权访问。如果passwd文件还具有写入权限,那么我们可以通过将一些非特权用户的UID更改为0,使其具有根级别的访问权限,因此要跟passwd加权限限制chattr +i禁止修改。

//禁用root_squash选项:
vi /etc/exports   #编辑:
/home 192.168.1.47(root_squash) // Enables Root Squash
/home 192.168.1.47(no_root_squash) // Disables Root Squash

注:NFS共享目录可能含:authorized_keys和rhosts2个文件,而.rhosts文件用来配置哪些远程主机或用户可以访问系统上的本地帐户。如果.rhosts文件的内容为++符号,则说明它允许来自网络上的任何主机和用户的连接。这样的话,

cd /root/.ssh/
ssh-keygen -t rsa -b 4096
cp /root/.ssh/id_rsa.pub /temp/root/.ssh/
cat id_rsa.pub >> /temp/root/.ssh/authorized_keys
ssh -i /root/.ssh/id_rsa root@192.168.1.189  //

//以下命令将允许系统的root用户直接连接目标系统,系统将不会提示密码输入,因为来自系统的所有用户都将被信任。
rsh -l root IP
rlogin -l root IP

应定期检查文件将有助于确定哪些主机和用户是可信的,因此可以在无需密码的情况下进行身份验证。

  • 8
    点赞
  • 39
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 3
    评论
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

羌俊恩

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值