Received: by 2002:a05:6358:3188:b0:123:57c1:9b43 with SMTP id q8csp4429616rwd; Tue, 23 May 2023 07:38:28 -0700 (PDT) X-Google-Smtp-Source: ACHHUZ76VXOIEVMXXTZ4xeNIJnmhxQeQURFNE367l4r7bsSvn+e0KmbcfD5XNyZKBg7zb79TbN9V X-Received: by 2002:a17:90b:2305:b0:253:750f:3187 with SMTP id mt5-20020a17090b230500b00253750f3187mr14542580pjb.8.1684852707701; Tue, 23 May 2023 07:38:27 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1684852707; cv=none; d=google.com; s=arc-20160816; b=KHBw2luwc3kHpLDc1gKRP7s+sjQqxKzFfCJGfLjpAiUef370jqva4jY9392eOgvxP0 ftlWB1as2/MV8/n8mEAU7QlXmJwg0u/ggzanfTx8zYi3QeWNKy7PFGxUV9eZDUQ+4k5T UywfKcaiC/5gf/dcyfKRix772uWbfBL6PB0mqKTmnnVQfJwXkE9GFFuFDI5xKD/0kdtb VIGfMlt6j2FWOlLBUWSC4aBNjedOrHowtDXrbESM5LDVzSBaf2EvUegnsIC3vrEiO8wc LCCR/Xb1KSNIN9Siym68g+hf7zFzlQubdWgLLoK5pa8SffqEIsyMmHxrlnqwDhlS5X1l W3zA== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:content-transfer-encoding:mime-version :user-agent:references:in-reply-to:message-id:date:cc:to:from :subject:dkim-signature; bh=SZSHGMuA77fOa//MduwPasWD1xyeGSR5YvM2PpJzqyM=; b=PoTjTTmm7Yd8qJi10juthGYoVtrupK9ZQrajYZ9nQfDjB+DyWkhGBO0TJzulXy2Hlj QBdI1nEuR73Ipw/aGCjmhpnpdeGFeJGTMpN9q7niYi+Z7lNkxR1RIS/tVbfk0VXnUlIN nse4Osa0T6rdC2OfAkUor2F7DXS/4uWkfWVJRZ3h6LKvCxtYolJyDMDpRiUerYJ6tPNB H31kSi/H0jSuGI8ppCZLpu3mVbIp4FH7kpXunqgipuCrniIuDCGw6cDrIOpVdP6bbpeI p3O9KDl9X3r4VLpNtnFc+Mv0xwOx7TFBg3mLb0NzErDKaTGLWXDuKr9DjOW2VW9fGIP2 FHIw== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@kernel.org header.s=k20201202 header.b=Qeg29ZQC; spf=pass (google.com: domain of linux-nfs-owner@vger.kernel.org designates 2620:137:e000::1:20 as permitted sender) smtp.mailfrom=linux-nfs-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=kernel.org Return-Path: Received: from out1.vger.email (out1.vger.email. [2620:137:e000::1:20]) by mx.google.com with ESMTP id g14-20020a17090a3c8e00b0024e1172c1d5si6439034pjc.155.2023.05.23.07.38.12; Tue, 23 May 2023 07:38:27 -0700 (PDT) Received-SPF: pass (google.com: domain of linux-nfs-owner@vger.kernel.org designates 2620:137:e000::1:20 as permitted sender) client-ip=2620:137:e000::1:20; Authentication-Results: mx.google.com; dkim=pass header.i=@kernel.org header.s=k20201202 header.b=Qeg29ZQC; spf=pass (google.com: domain of linux-nfs-owner@vger.kernel.org designates 2620:137:e000::1:20 as permitted sender) smtp.mailfrom=linux-nfs-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=kernel.org Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S235873AbjEWOe3 (ORCPT + 99 others); Tue, 23 May 2023 10:34:29 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:33680 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S233444AbjEWOe3 (ORCPT ); Tue, 23 May 2023 10:34:29 -0400 Received: from dfw.source.kernel.org (dfw.source.kernel.org [139.178.84.217]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id BFF01E9 for ; Tue, 23 May 2023 07:34:27 -0700 (PDT) Received: from smtp.kernel.org (relay.kernel.org [52.25.139.140]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by dfw.source.kernel.org (Postfix) with ESMTPS id 500E5616E6 for ; Tue, 23 May 2023 14:34:27 +0000 (UTC) Received: by smtp.kernel.org (Postfix) with ESMTPSA id 39D18C433EF; Tue, 23 May 2023 14:34:26 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1684852466; bh=3nhiEVR6knicIQw7nQwJ68OIrHbmkkUmFCogRz5Mkvs=; h=Subject:From:To:Cc:Date:In-Reply-To:References:From; b=Qeg29ZQC9vz1R7E1AoHn1ER6W0sBPvhHa60O9GIFKMcauUhJcMwwiBpuIz83VwLO2 okRtKJDmKyC9zblAg1gORe/ahcDMTkAIyES1tRyjQHPLrwv4tA0F9j8iejwTNmQuPi /o6s27HRv4UEXkH2L7TuErUX8O3yZDrHPsPy9xA+p/m94nCo0HaKnUNfQPxE65oQ8Y rBzZrlLn3AiKeX2rxNFeLuN+M5cVmrZcGUBauzQYom+mdfGjLK9TzPlzj4mudnP90l Ds8+X8J3x4SIcu6ZzU1YfYdQ6PuEgCiHjA4L1ILg/ek37R6N84ZXB1V30JtzCchG0a sLGt0xBUhH2kQ== Subject: [PATCH v2 11/11] NFS: Add an "xprtsec=" NFS mount option From: Chuck Lever To: anna.schumaker@netapp.com, trondmy@hammerspace.com Cc: Chuck Lever , Jeff Layton , jlayton@redhat.com, linux-nfs@vger.kernel.org, kernel-tls-handshake@lists.linux.dev Date: Tue, 23 May 2023 10:34:15 -0400 Message-ID: <168485244517.6613.10337354362650432426.stgit@oracle-102.nfsv4bat.org> In-Reply-To: <168485183242.6613.7025123558596119858.stgit@oracle-102.nfsv4bat.org> References: <168485183242.6613.7025123558596119858.stgit@oracle-102.nfsv4bat.org> User-Agent: StGit/1.5 MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: 7bit X-Spam-Status: No, score=-7.1 required=5.0 tests=BAYES_00,DKIMWL_WL_HIGH, DKIM_SIGNED,DKIM_VALID,DKIM_VALID_AU,DKIM_VALID_EF,RCVD_IN_DNSWL_HI, SPF_HELO_NONE,SPF_PASS,T_SCC_BODY_TEXT_LINE autolearn=ham autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on lindbergh.monkeyblade.net Precedence: bulk List-ID: X-Mailing-List: linux-nfs@vger.kernel.org From: Chuck Lever After some discussion, we decided that controlling transport layer security policy should be separate from the setting for the user authentication flavor. To accomplish this, add a new NFS mount option to select a transport layer security policy for RPC operations associated with the mount point. xprtsec=none - Transport layer security is forced off. xprtsec=tls - Establish an encryption-only TLS session. If the initial handshake fails, the mount fails. If TLS is not available on a reconnect, drop the connection and try again. xprtsec=mtls - Both sides authenticate and an encrypted session is created. If the initial handshake fails, the mount fails. If TLS is not available on a reconnect, drop the connection and try again. To support client peer authentication (mtls), the handshake daemon will have configurable default authentication material (certificate or pre-shared key). In the future, mount options can be added that can provide this material on a per-mount basis. Updates to mount.nfs (to support xprtsec=auto) and nfs(5) will be sent under separate cover. Signed-off-by: Chuck Lever Reviewed-by: Jeff Layton --- fs/nfs/client.c | 5 ++--- fs/nfs/fs_context.c | 50 ++++++++++++++++++++++++++++++++++++++++++++++++++ fs/nfs/internal.h | 1 + fs/nfs/nfs4client.c | 6 ++---- fs/nfs/super.c | 12 ++++++++++++ 5 files changed, 67 insertions(+), 7 deletions(-) diff --git a/fs/nfs/client.c b/fs/nfs/client.c index 9bfdade0f6e6..c3a984b1879d 100644 --- a/fs/nfs/client.c +++ b/fs/nfs/client.c @@ -515,6 +515,7 @@ int nfs_create_rpc_client(struct nfs_client *clp, .version = clp->rpc_ops->version, .authflavor = flavor, .cred = cl_init->cred, + .xprtsec = cl_init->xprtsec, }; if (test_bit(NFS_CS_DISCRTRY, &clp->cl_flags)) @@ -680,9 +681,7 @@ static int nfs_init_server(struct nfs_server *server, .cred = server->cred, .nconnect = ctx->nfs_server.nconnect, .init_flags = (1UL << NFS_CS_REUSEPORT), - .xprtsec = { - .policy = RPC_XPRTSEC_NONE, - }, + .xprtsec = ctx->xprtsec, }; struct nfs_client *clp; int error; diff --git a/fs/nfs/fs_context.c b/fs/nfs/fs_context.c index 5626d358ee2e..e49e3d18ef88 100644 --- a/fs/nfs/fs_context.c +++ b/fs/nfs/fs_context.c @@ -18,6 +18,9 @@ #include #include #include + +#include + #include "nfs.h" #include "internal.h" @@ -88,6 +91,7 @@ enum nfs_param { Opt_vers, Opt_wsize, Opt_write, + Opt_xprtsec, }; enum { @@ -194,6 +198,7 @@ static const struct fs_parameter_spec nfs_fs_parameters[] = { fsparam_string("vers", Opt_vers), fsparam_enum ("write", Opt_write, nfs_param_enums_write), fsparam_u32 ("wsize", Opt_wsize), + fsparam_string("xprtsec", Opt_xprtsec), {} }; @@ -267,6 +272,20 @@ static const struct constant_table nfs_secflavor_tokens[] = { {} }; +enum { + Opt_xprtsec_none, + Opt_xprtsec_tls, + Opt_xprtsec_mtls, + nr__Opt_xprtsec +}; + +static const struct constant_table nfs_xprtsec_policies[] = { + { "none", Opt_xprtsec_none }, + { "tls", Opt_xprtsec_tls }, + { "mtls", Opt_xprtsec_mtls }, + {} +}; + /* * Sanity-check a server address provided by the mount command. * @@ -430,6 +449,29 @@ static int nfs_parse_security_flavors(struct fs_context *fc, return 0; } +static int nfs_parse_xprtsec_policy(struct fs_context *fc, + struct fs_parameter *param) +{ + struct nfs_fs_context *ctx = nfs_fc2context(fc); + + trace_nfs_mount_assign(param->key, param->string); + + switch (lookup_constant(nfs_xprtsec_policies, param->string, -1)) { + case Opt_xprtsec_none: + ctx->xprtsec.policy = RPC_XPRTSEC_NONE; + break; + case Opt_xprtsec_tls: + ctx->xprtsec.policy = RPC_XPRTSEC_TLS_ANON; + break; + case Opt_xprtsec_mtls: + ctx->xprtsec.policy = RPC_XPRTSEC_TLS_X509; + break; + default: + return nfs_invalf(fc, "NFS: Unrecognized transport security policy"); + } + return 0; +} + static int nfs_parse_version_string(struct fs_context *fc, const char *string) { @@ -696,6 +738,11 @@ static int nfs_fs_context_parse_param(struct fs_context *fc, if (ret < 0) return ret; break; + case Opt_xprtsec: + ret = nfs_parse_xprtsec_policy(fc, param); + if (ret < 0) + return ret; + break; case Opt_proto: if (!param->string) @@ -1574,6 +1621,9 @@ static int nfs_init_fs_context(struct fs_context *fc) ctx->selected_flavor = RPC_AUTH_MAXFLAVOR; ctx->minorversion = 0; ctx->need_mount = true; + ctx->xprtsec.policy = RPC_XPRTSEC_NONE; + ctx->xprtsec.cert_serial = TLS_NO_CERT; + ctx->xprtsec.privkey_serial = TLS_NO_PRIVKEY; fc->s_iflags |= SB_I_STABLE_WRITES; } diff --git a/fs/nfs/internal.h b/fs/nfs/internal.h index 5c986c0d3cce..0019c7578f9d 100644 --- a/fs/nfs/internal.h +++ b/fs/nfs/internal.h @@ -102,6 +102,7 @@ struct nfs_fs_context { unsigned int bsize; struct nfs_auth_info auth_info; rpc_authflavor_t selected_flavor; + struct xprtsec_parms xprtsec; char *client_address; unsigned int version; unsigned int minorversion; diff --git a/fs/nfs/nfs4client.c b/fs/nfs/nfs4client.c index 75ed8354576b..bfc68d4e8d32 100644 --- a/fs/nfs/nfs4client.c +++ b/fs/nfs/nfs4client.c @@ -1130,9 +1130,6 @@ static int nfs4_server_common_setup(struct nfs_server *server, static int nfs4_init_server(struct nfs_server *server, struct fs_context *fc) { struct nfs_fs_context *ctx = nfs_fc2context(fc); - struct xprtsec_parms xprtsec = { - .policy = RPC_XPRTSEC_NONE, - }; struct rpc_timeout timeparms; int error; @@ -1164,7 +1161,7 @@ static int nfs4_init_server(struct nfs_server *server, struct fs_context *fc) ctx->nfs_server.nconnect, ctx->nfs_server.max_connect, fc->net_ns, - &xprtsec); + &ctx->xprtsec); if (error < 0) return error; @@ -1323,6 +1320,7 @@ int nfs4_update_server(struct nfs_server *server, const char *hostname, .dstaddr = (struct sockaddr *)sap, .addrlen = salen, .servername = hostname, + /* cel: bleh. We might need to pass TLS parameters here */ }; char buf[INET6_ADDRSTRLEN + 1]; struct sockaddr_storage address; diff --git a/fs/nfs/super.c b/fs/nfs/super.c index 30e53e93049e..059b0beabc1b 100644 --- a/fs/nfs/super.c +++ b/fs/nfs/super.c @@ -59,6 +59,8 @@ #include #include +#include + #include "nfs4_fs.h" #include "callback.h" #include "delegation.h" @@ -491,6 +493,16 @@ static void nfs_show_mount_options(struct seq_file *m, struct nfs_server *nfss, seq_printf(m, ",timeo=%lu", 10U * nfss->client->cl_timeout->to_initval / HZ); seq_printf(m, ",retrans=%u", nfss->client->cl_timeout->to_retries); seq_printf(m, ",sec=%s", nfs_pseudoflavour_to_name(nfss->client->cl_auth->au_flavor)); + switch (clp->cl_xprtsec.policy) { + case RPC_XPRTSEC_TLS_ANON: + seq_puts(m, ",xprtsec=tls"); + break; + case RPC_XPRTSEC_TLS_X509: + seq_puts(m, ",xprtsec=mtls"); + break; + default: + break; + } if (version != 4) nfs_show_mountd_options(m, nfss, showdefaults);