内核 RPC 服务器的 rpcsec_gss 支持

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

RPCGSS 在一些 IETF 文档中指定

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

背景

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

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

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

  • 初始上下文建立

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

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

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

NFS 服务器旧版向上调用机制

经典的向上调用机制使用自定义的基于文本的向上调用机制与 nfs-utils 包提供的名为 rpc.svcgssd 的自定义守护进程通信。

此向上调用机制有两个限制:

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

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

B) 由于可以发送回内核的缓冲区大小(4KiB)的限制,它不能正确处理用户是几千个以上组的成员的凭据(内核中当前的硬性限制是 65K 个组)。

NFS 服务器新的 RPC 向上调用机制

较新的向上调用机制使用 Unix 套接字上的 RPC 与名为 gss-proxy 的守护进程通信,该守护进程由名为 Gssproxy 的用户空间程序实现。

gss_proxy RPC 协议当前在此处记录。

此向上调用机制使用内核 rpc 客户端,并通过常规 Unix 套接字连接到 gssproxy 用户空间程序。gssproxy 协议不受旧版协议的大小限制。

协商向上调用机制

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

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