我正在查看我们环境中几台 Linux 服务器上的 lsof -i 输出,发现 rpcbind 在 TCP 和 UDP 协议中打开常用端口 111,但也无缘无故地打开端口 873 UDP。这会提高安全标志,因为端口 873 已分配给 rsyncd,并且我们的策略要求 rsync 使用 ssh 传输(rsyncd 不执行加密,并且仅通过信任关系进行身份验证)。
通常,当我怀疑 RPC 进程时,我会在 rpcinfo -p 中查找,看看哪个服务实际上正在打开端口。然而,在这些服务器上,我只看到端口映射器的端口 111 以及状态和 nlockmgr 的高编号端口,而看不到端口 873。
我见过很多错误报告(包括 RHEL:https://bugzilla.redhat.com/show_bug.cgi?id=103401和内核:https://patchwork.kernel.org/patch/10153769/)说罪魁祸首是 glibc 中的 bindresvport() 函数,但如果不造成大规模破坏,就无法更改该函数。我看到了三种不同的解决方案:
- RHEL 提供了一个名为 portreserve 的守护进程,用于在 rpcbind 启动之前预先分配这些端口。这对我没有帮助,因为它保证这些端口是开放的,出于安全原因我们不希望这样做。
- Debian 及其后代在 /etc/bindresvport.blacklist 中实现了一个配置文件,这对于我们的目的来说是理想的选择,除了它似乎没有文档记录并且容易被发行版踩踏这一事实。
- 发行版上游的 nfs-utils 软件包遵循 /etc/services 并且不绑定到注册端口。
不过,我想要确定的是,为什么 rpcbind 首先要打开额外的端口,以及如何防止这种情况发生?到目前为止我所检查的一切似乎都表明该端口是在启动时随机分配的,并且重新启动服务器已显示将其推送到不同的端口,但这不是操作的方法。
答案1
实际上,只有 Debian 9 或 RHEL 7 之前的版本才会出现此问题,Debian 10 或 RHEL 8 则不会。导致随机特权 UDP 端口绑定的功能已在 rpcbind 1.2.5(0.2.3 和 0.2 之后的版本)中禁用。 4.
从 Debian 10.1+ 开始/usr/share/doc/rpcbind/README.Debian
:
自版本 1.2.5 起,出于安全考虑,上游默认关闭了远程调用功能,并在构建时添加了一个配置标志来启用它。
此功能导致 rpcbind 打开随机侦听端口。远程调用关闭后,rpcbind 停止接收任何广播查询,从而导致系统(取决于此功能)损坏,例如 NIS 系统。
在 Debian 系统上,可以使用命令行参数“r”在运行时打开远程调用。有关更多详细信息,请参阅 rpcbind(8)。
我可以在 Debian 9 上验证(强制)升级rpcbind
到Debian 10的版本就足以失去额外的特权绑定端口。使用-r
由Debian 提供的新选项Debian 补丁(主要是重新编译--enable-rmtcalls
并添加运行时选项)“恢复”该功能,除非绑定的 UDP 端口不再具有特权。
使用此远程调用功能是rpcinfo -b
(或科迪)向所有 LAN 的端口映射器发送广播查询。例如发现远程过程调用 程序100005 版本 3(对于 NFSv3挂载):
rpcinfo -b 100005 3
这将向端口 111/UDP 发送广播,并且回复端口映射器将使用额外绑定的 UDP 端口作为源(在典型的防火墙不友好方法中,类似于TFTP)。如果没有此端口,它们将不会应答,但仍然可以像往常一样直接从端口 111/UDP 应答直接单播查询。