From 006e48e5eb1a62bc9613a5157faf20853e7f448a Mon Sep 17 00:00:00 2001 From: Steve Dickson Date: Tue, 30 Apr 2024 14:52:35 -0400 Subject: [PATCH] gssd: add support for an "allowed-enctypes" option in nfs.conf (RHEL-31858) --- .nfs-utils.metadata | 1 + nfs-utils-2.3.3-nfsconf-usegssproxy.patch | 12 +- nfs-utils-2.5.4-gssd-allowed-enctypes.patch | 251 ++++++++++++++++++++ nfs-utils.spec | 10 +- 4 files changed, 267 insertions(+), 7 deletions(-) create mode 100644 .nfs-utils.metadata create mode 100644 nfs-utils-2.5.4-gssd-allowed-enctypes.patch diff --git a/.nfs-utils.metadata b/.nfs-utils.metadata new file mode 100644 index 0000000..fd1e03c --- /dev/null +++ b/.nfs-utils.metadata @@ -0,0 +1 @@ +1b097d511c85f95671619f51b37abd75d56ea777 nfs-utils-2.5.4.tar.xz diff --git a/nfs-utils-2.3.3-nfsconf-usegssproxy.patch b/nfs-utils-2.3.3-nfsconf-usegssproxy.patch index d87ae7d..023fc1f 100644 --- a/nfs-utils-2.3.3-nfsconf-usegssproxy.patch +++ b/nfs-utils-2.3.3-nfsconf-usegssproxy.patch @@ -1,7 +1,7 @@ -diff -up nfs-utils-2.3.4/nfs.conf.orig nfs-utils-2.3.4/nfs.conf ---- nfs-utils-2.3.4/nfs.conf.orig 2019-05-10 14:49:49.000000000 -0400 -+++ nfs-utils-2.3.4/nfs.conf 2019-05-10 14:58:20.198714920 -0400 -@@ -13,7 +13,7 @@ +diff -up nfs-utils-2.5.4/nfs.conf.orig nfs-utils-2.5.4/nfs.conf +--- nfs-utils-2.5.4/nfs.conf.orig 2024-04-30 14:42:44.551812808 -0400 ++++ nfs-utils-2.5.4/nfs.conf 2024-04-30 14:43:29.985032677 -0400 +@@ -20,7 +20,7 @@ # rpc-verbosity=0 # use-memcache=0 # use-machine-creds=1 @@ -9,8 +9,8 @@ diff -up nfs-utils-2.3.4/nfs.conf.orig nfs-utils-2.3.4/nfs.conf +use-gss-proxy=1 # avoid-dns=1 # limit-to-legacy-enctypes=0 - # context-timeout=0 -@@ -77,6 +77,5 @@ + # allowed-enctypes=aes256-cts-hmac-sha384-192,aes128-cts-hmac-sha256-128,camellia256-cts-cmac,camellia128-cts-cmac,aes256-cts-hmac-sha1-96,aes128-cts-hmac-sha1-96 +@@ -97,6 +97,5 @@ rdma-port=20049 # outgoing-port= # outgoing-addr= # lift-grace=y diff --git a/nfs-utils-2.5.4-gssd-allowed-enctypes.patch b/nfs-utils-2.5.4-gssd-allowed-enctypes.patch new file mode 100644 index 0000000..298d4cf --- /dev/null +++ b/nfs-utils-2.5.4-gssd-allowed-enctypes.patch @@ -0,0 +1,251 @@ +commit 9b1f860a3457328a08395651d029a454e0303454 +Author: Scott Mayhew +Date: Fri Mar 15 06:34:52 2024 -0400 + + gssd: add support for an "allowed-enctypes" option in nfs.conf + + Newer kernels have support for newer krb5 encryption types, AES with + SHA2 and Camellia. An NFS client with an "old" kernel can talk to + and NFS server with a "new" kernel and it just works. An NFS client + with a "new" kernel can talk to an NFS server with an "old" kernel, but + that requires some additional configuration (particularly if the NFS + server does have support for the newer encryption types in its userspace + krb5 libraries) that may be unclear and/or burdensome to the admin. + + 1) If the NFS server has support for the newer encryption types in the + userspace krb5 libraries, but not in the kernel's RPCSEC_GSS code, + then its possible that it also already has "nfs" keys using those + newer encryption types in its keytab. In that case, it's necessary + to regenerate the "nfs" keys without the newer encryption types. + The reason this is necessary is because if the NFS client requests + an "nfs" service ticket from the KDC, and the list of enctypes in + in that TGS-REQ contains a newer encryption type, and the KDC had + previously generated a key for the NFS server using the newer + encryption type, then the resulting service ticket in the TGS-REP + will be using the newer encryption type and the NFS server will not + be able to decrypt it. + + 2) It is necessary to either modify the permitted_enctypes field of the + krb5.conf or create a custom crypto-policy module (if the + crypto-policies package is being used) on the NFS *client* so that it + does not include the newer encryption types. The reason this is + necessary is because it affects the list of encryption types that + will be present in the RPCSEC_GSS_INIT request that the NFS client + sends to the NFS server. The kernel on the NFS server cannot not + process the request on its own; it has to upcall to gssproxy to do + that... and again if the userspace krb5 libraries on the NFS server + have support for the newer encryption types, then it will select one + of those and the kernel will not be able to import the context when + it gets the downcall. Also note that modifying the permitted_enctypes + field and/or crypto policy has the side effect of impacting everything + krb5 related, not just just NFS. + + So add support for an "allowed-enctypes" field in nfs.conf. This allows + the admin to restrict gssd to using a subset of the encryption types + that are supported by the kernel and krb5 libraries. This will remove + the need for steps 1 & 2 above, and will only affect NFS rather than + krb5 as a whole. + + For example, for a "new" NFS client talking to an "old" NFS server, the + admin will probably want this in the client's nfs.conf: + + allowed-enctypes=aes256-cts-hmac-sha1-96,aes128-cts-hmac-sha1-96 + + Signed-off-by: Scott Mayhew + Signed-off-by: Steve Dickson + +diff --git a/nfs.conf b/nfs.conf +index 323f072..23b5f7d 100644 +--- a/nfs.conf ++++ b/nfs.conf +@@ -23,6 +23,7 @@ + # use-gss-proxy=0 + # avoid-dns=1 + # limit-to-legacy-enctypes=0 ++# allowed-enctypes=aes256-cts-hmac-sha384-192,aes128-cts-hmac-sha256-128,camellia256-cts-cmac,camellia128-cts-cmac,aes256-cts-hmac-sha1-96,aes128-cts-hmac-sha1-96 + # context-timeout=0 + # rpc-timeout=5 + # keytab-file=/etc/krb5.keytab +diff --git a/utils/gssd/gssd.c b/utils/gssd/gssd.c +index ca9b326..10c731a 100644 +--- a/utils/gssd/gssd.c ++++ b/utils/gssd/gssd.c +@@ -1232,6 +1232,12 @@ main(int argc, char *argv[]) + + daemon_init(fg); + ++#ifdef HAVE_SET_ALLOWABLE_ENCTYPES ++ rc = get_allowed_enctypes(); ++ if (rc) ++ exit(EXIT_FAILURE); ++#endif ++ + if (gssd_check_mechs() != 0) + errx(1, "Problem with gssapi library"); + +diff --git a/utils/gssd/gssd.man b/utils/gssd/gssd.man +index 2a5384d..c735eff 100644 +--- a/utils/gssd/gssd.man ++++ b/utils/gssd/gssd.man +@@ -346,6 +346,15 @@ flag. + Equivalent to + .BR -l . + .TP ++.B allowed-enctypes ++Allows you to restrict ++.B rpc.gssd ++to using a subset of the encryption types permitted by the kernel and the krb5 ++libraries. This is useful if you need to interoperate with an NFS server that ++does not have support for the newer SHA2 and Camellia encryption types, for ++example. This configuration file option does not have an equivalent ++command-line option. ++.TP + .B context-timeout + Equivalent to + .BR -t . +diff --git a/utils/gssd/krb5_util.c b/utils/gssd/krb5_util.c +index 6f66ef4..57b3cf8 100644 +--- a/utils/gssd/krb5_util.c ++++ b/utils/gssd/krb5_util.c +@@ -129,6 +129,7 @@ + #include "err_util.h" + #include "gss_util.h" + #include "krb5_util.h" ++#include "conffile.h" + + /* + * List of principals from our keytab that we +@@ -155,6 +156,8 @@ static pthread_mutex_t ple_lock = PTHREAD_MUTEX_INITIALIZER; + + #ifdef HAVE_SET_ALLOWABLE_ENCTYPES + int limit_to_legacy_enctypes = 0; ++krb5_enctype *allowed_enctypes = NULL; ++int num_allowed_enctypes = 0; + #endif + + /*==========================*/ +@@ -1596,6 +1599,68 @@ out_cred: + } + + #ifdef HAVE_SET_ALLOWABLE_ENCTYPES ++int ++get_allowed_enctypes(void) ++{ ++ struct conf_list *allowed_etypes = NULL; ++ struct conf_list_node *node; ++ char *buf = NULL, *old = NULL; ++ int len, ret = 0; ++ ++ allowed_etypes = conf_get_list("gssd", "allowed-enctypes"); ++ if (allowed_etypes) { ++ TAILQ_FOREACH(node, &(allowed_etypes->fields), link) { ++ allowed_enctypes = realloc(allowed_enctypes, ++ (num_allowed_enctypes + 1) * ++ sizeof(*allowed_enctypes)); ++ if (allowed_enctypes == NULL) { ++ ret = ENOMEM; ++ goto out_err; ++ } ++ ret = krb5_string_to_enctype(node->field, ++ &allowed_enctypes[num_allowed_enctypes]); ++ if (ret) { ++ printerr(0, "%s: invalid enctype %s", ++ __func__, node->field); ++ goto out_err; ++ } ++ if (get_verbosity() > 1) { ++ if (buf == NULL) { ++ len = asprintf(&buf, "%s(%d)", node->field, ++ allowed_enctypes[num_allowed_enctypes]); ++ if (len < 0) { ++ ret = ENOMEM; ++ goto out_err; ++ } ++ } else { ++ old = buf; ++ len = asprintf(&buf, "%s,%s(%d)", old, node->field, ++ allowed_enctypes[num_allowed_enctypes]); ++ if (len < 0) { ++ ret = ENOMEM; ++ goto out_err; ++ } ++ free(old); ++ old = NULL; ++ } ++ } ++ num_allowed_enctypes++; ++ } ++ printerr(2, "%s: allowed_enctypes = %s", __func__, buf); ++ } ++ goto out; ++out_err: ++ num_allowed_enctypes = 0; ++ free(allowed_enctypes); ++out: ++ free(buf); ++ if (old != buf) ++ free(old); ++ if (allowed_etypes) ++ conf_free_list(allowed_etypes); ++ return ret; ++} ++ + /* + * this routine obtains a credentials handle via gss_acquire_cred() + * then calls gss_krb5_set_allowable_enctypes() to limit the encryption +@@ -1619,6 +1684,10 @@ limit_krb5_enctypes(struct rpc_gss_sec *sec) + int num_enctypes = sizeof(enctypes) / sizeof(enctypes[0]); + extern int num_krb5_enctypes; + extern krb5_enctype *krb5_enctypes; ++ extern int num_allowed_enctypes; ++ extern krb5_enctype *allowed_enctypes; ++ int num_set_enctypes; ++ krb5_enctype *set_enctypes; + int err = -1; + + if (sec->cred == GSS_C_NO_CREDENTIAL) { +@@ -1631,12 +1700,26 @@ limit_krb5_enctypes(struct rpc_gss_sec *sec) + * If we failed for any reason to produce global + * list of supported enctypes, use local default here. + */ +- if (krb5_enctypes == NULL || limit_to_legacy_enctypes) +- maj_stat = gss_set_allowable_enctypes(&min_stat, sec->cred, +- &krb5oid, num_enctypes, enctypes); +- else +- maj_stat = gss_set_allowable_enctypes(&min_stat, sec->cred, +- &krb5oid, num_krb5_enctypes, krb5_enctypes); ++ if (krb5_enctypes == NULL || limit_to_legacy_enctypes || ++ allowed_enctypes) { ++ if (allowed_enctypes) { ++ printerr(2, "%s: using allowed enctypes from config\n", ++ __func__); ++ num_set_enctypes = num_allowed_enctypes; ++ set_enctypes = allowed_enctypes; ++ } else { ++ printerr(2, "%s: using legacy enctypes\n", __func__); ++ num_set_enctypes = num_enctypes; ++ set_enctypes = enctypes; ++ } ++ } else { ++ printerr(2, "%s: using enctypes from the kernel\n", __func__); ++ num_set_enctypes = num_krb5_enctypes; ++ set_enctypes = krb5_enctypes; ++ } ++ ++ maj_stat = gss_set_allowable_enctypes(&min_stat, sec->cred, ++ &krb5oid, num_set_enctypes, set_enctypes); + + if (maj_stat != GSS_S_COMPLETE) { + pgsserr("gss_set_allowable_enctypes", +diff --git a/utils/gssd/krb5_util.h b/utils/gssd/krb5_util.h +index 7ef8701..40ad323 100644 +--- a/utils/gssd/krb5_util.h ++++ b/utils/gssd/krb5_util.h +@@ -27,6 +27,7 @@ int gssd_k5_remove_bad_service_cred(char *srvname); + #ifdef HAVE_SET_ALLOWABLE_ENCTYPES + extern int limit_to_legacy_enctypes; + int limit_krb5_enctypes(struct rpc_gss_sec *sec); ++int get_allowed_enctypes(void); + #endif + + /* diff --git a/nfs-utils.spec b/nfs-utils.spec index a9cefb2..9317ec7 100644 --- a/nfs-utils.spec +++ b/nfs-utils.spec @@ -2,7 +2,7 @@ Summary: NFS utilities and supporting clients and daemons for the kernel NFS ser Name: nfs-utils URL: http://linux-nfs.org/ Version: 2.5.4 -Release: 25%{?dist} +Release: 26%{?dist} Epoch: 1 # group all 32bit related archs @@ -59,6 +59,11 @@ Patch023: nfs-utils-2.5.4-fix-typos-in-messages.patch Patch024: nfs-utils-2.5.4-blkmapd-double-free.patch Patch025: nfs-utils-2.5.4-rpcdebug-check-read-return.patch +# +# RHEL9.5 +# +Patch026: nfs-utils-2.5.4-gssd-allowed-enctypes.patch + Patch100: nfs-utils-1.2.1-statdpath-man.patch Patch101: nfs-utils-1.2.1-exp-subtree-warn-off.patch Patch102: nfs-utils-1.2.5-idmap-errmsg.patch @@ -499,6 +504,9 @@ fi %{_mandir}/*/nfsiostat.8.gz %changelog +* Tue Apr 30 2024 Steve Dickson 2.5.4-26 +- gssd: add support for an "allowed-enctypes" option in nfs.conf (RHEL-31858) + * Sun Feb 18 2024 Steve Dickson 2.5.4-25 - Update: Typos and documentation fixes (RHEL-22654)