0001 =========================================
0002 rpcsec_gss support for kernel RPC servers
0003 =========================================
0004
0005 This document gives references to the standards and protocols used to
0006 implement RPCGSS authentication in kernel RPC servers such as the NFS
0007 server and the NFS client's NFSv4.0 callback server. (But note that
0008 NFSv4.1 and higher don't require the client to act as a server for the
0009 purposes of authentication.)
0010
0011 RPCGSS is specified in a few IETF documents:
0012
0013 - RFC2203 v1: https://tools.ietf.org/rfc/rfc2203.txt
0014 - RFC5403 v2: https://tools.ietf.org/rfc/rfc5403.txt
0015
0016 There is a third version that we don't currently implement:
0017
0018 - RFC7861 v3: https://tools.ietf.org/rfc/rfc7861.txt
0019
0020 Background
0021 ==========
0022
0023 The RPCGSS Authentication method describes a way to perform GSSAPI
0024 Authentication for NFS. Although GSSAPI is itself completely mechanism
0025 agnostic, in many cases only the KRB5 mechanism is supported by NFS
0026 implementations.
0027
0028 The Linux kernel, at the moment, supports only the KRB5 mechanism, and
0029 depends on GSSAPI extensions that are KRB5 specific.
0030
0031 GSSAPI is a complex library, and implementing it completely in kernel is
0032 unwarranted. However GSSAPI operations are fundementally separable in 2
0033 parts:
0034
0035 - initial context establishment
0036 - integrity/privacy protection (signing and encrypting of individual
0037 packets)
0038
0039 The former is more complex and policy-independent, but less
0040 performance-sensitive. The latter is simpler and needs to be very fast.
0041
0042 Therefore, we perform per-packet integrity and privacy protection in the
0043 kernel, but leave the initial context establishment to userspace. We
0044 need upcalls to request userspace to perform context establishment.
0045
0046 NFS Server Legacy Upcall Mechanism
0047 ==================================
0048
0049 The classic upcall mechanism uses a custom text based upcall mechanism
0050 to talk to a custom daemon called rpc.svcgssd that is provide by the
0051 nfs-utils package.
0052
0053 This upcall mechanism has 2 limitations:
0054
0055 A) It can handle tokens that are no bigger than 2KiB
0056
0057 In some Kerberos deployment GSSAPI tokens can be quite big, up and
0058 beyond 64KiB in size due to various authorization extensions attacked to
0059 the Kerberos tickets, that needs to be sent through the GSS layer in
0060 order to perform context establishment.
0061
0062 B) It does not properly handle creds where the user is member of more
0063 than a few thousand groups (the current hard limit in the kernel is 65K
0064 groups) due to limitation on the size of the buffer that can be send
0065 back to the kernel (4KiB).
0066
0067 NFS Server New RPC Upcall Mechanism
0068 ===================================
0069
0070 The newer upcall mechanism uses RPC over a unix socket to a daemon
0071 called gss-proxy, implemented by a userspace program called Gssproxy.
0072
0073 The gss_proxy RPC protocol is currently documented `here
0074 <https://fedorahosted.org/gss-proxy/wiki/ProtocolDocumentation>`_.
0075
0076 This upcall mechanism uses the kernel rpc client and connects to the gssproxy
0077 userspace program over a regular unix socket. The gssproxy protocol does not
0078 suffer from the size limitations of the legacy protocol.
0079
0080 Negotiating Upcall Mechanisms
0081 =============================
0082
0083 To provide backward compatibility, the kernel defaults to using the
0084 legacy mechanism. To switch to the new mechanism, gss-proxy must bind
0085 to /var/run/gssproxy.sock and then write "1" to
0086 /proc/net/rpc/use-gss-proxy. If gss-proxy dies, it must repeat both
0087 steps.
0088
0089 Once the upcall mechanism is chosen, it cannot be changed. To prevent
0090 locking into the legacy mechanisms, the above steps must be performed
0091 before starting nfsd. Whoever starts nfsd can guarantee this by reading
0092 from /proc/net/rpc/use-gss-proxy and checking that it contains a
0093 "1"--the read will block until gss-proxy has done its write to the file.