内核 RPC 服务器的 rpcsec_gss 支持

本文档提供了用于在内核 RPC 服务器(例如 NFS 服务器和 NFS 客户端的 NFSv4.0 回调服务器)中实现 RPCGSS 身份验证的标准和协议的参考。(但请注意,NFSv4.1 及更高版本不需要客户端充当服务器进行身份验证。)

RPCGSS 在一些 IETF 文档中进行了规定

我们目前没有实现第三个版本

背景

RPCGSS 身份验证方法描述了一种为 NFS 执行 GSSAPI 身份验证的方法。虽然 GSSAPI 本身完全与机制无关,但在许多情况下,只有 KRB5 机制受到 NFS 实现的支持。

Linux 内核目前仅支持 KRB5 机制,并且依赖于 KRB5 特定的 GSSAPI 扩展。

GSSAPI 是一个复杂的库,在内核中完全实现它是没有必要的。 但是,GSSAPI 操作在根本上可以分为两部分

  • 初始上下文建立

  • 完整性/隐私保护(签名和加密单个数据包)

前者更复杂且与策略无关,但对性能不太敏感。 后者更简单,需要非常快。

因此,我们在内核中执行每个数据包的完整性和隐私保护,但将初始上下文建立留给用户空间。我们需要 upcall 来请求用户空间执行上下文建立。

NFS 服务器旧版 Upcall 机制

经典的 upcall 机制使用自定义的基于文本的 upcall 机制与由 nfs-utils 软件包提供的自定义守护程序 rpc.svcgssd 通信。

这种 upcall 机制有两个限制

  1. 它可以处理不超过 2KiB 的令牌

在某些 Kerberos 部署中,由于附加到 Kerberos 票证的各种授权扩展,GSSAPI 令牌可能非常大,高达 64KiB 以上,这些授权扩展需要通过 GSS 层发送才能执行上下文建立。

B) 由于可以发送回内核的缓冲区大小的限制(4KiB),它无法正确处理用户所属组超过数千个(内核中当前的硬性限制是 65K 个组)的凭据。

NFS 服务器新 RPC Upcall 机制

较新的 upcall 机制使用基于 unix 套接字的 RPC 与名为 gss-proxy 的守护程序通信,该守护程序由名为 Gssproxy 的用户空间程序实现。

gss_proxy RPC 协议目前在此处记录:此处.

此 upcall 机制使用内核 rpc 客户端并通过常规 unix 套接字连接到 gssproxy 用户空间程序。 gssproxy 协议不存在旧版协议的大小限制。

协商 Upcall 机制

为了提供向后兼容性,内核默认使用旧版机制。 要切换到新机制,gss-proxy 必须绑定到 /var/run/gssproxy.sock,然后将“1”写入 /proc/net/rpc/use-gss-proxy。 如果 gss-proxy 死亡,它必须重复这两个步骤。

一旦选择了 upcall 机制,就无法更改它。 为了防止锁定到旧版机制,必须在启动 nfsd 之前执行上述步骤。 启动 nfsd 的人可以通过从 /proc/net/rpc/use-gss-proxy 读取并检查它是否包含“1”来保证这一点——读取操作将阻塞,直到 gss-proxy 将其写入文件为止。