Netdev List
 help / color / mirror / Atom feed
From: "Chuck Lever" <cel@kernel.org>
To: "Hannes Reinecke" <hare@suse.de>,
	"Christian Brauner" <brauner@kernel.org>
Cc: keyrings@vger.kernel.org, kernel-tls-handshake@lists.linux.dev,
	netdev@vger.kernel.org, "Trond Myklebust" <trondmy@kernel.org>,
	"Anna Schumaker" <anna@kernel.org>,
	"Christoph Hellwig" <hch@lst.de>,
	"David Howells" <dhowells@redhat.com>,
	"Jarkko Sakkinen" <jarkko@kernel.org>,
	"Sagi Grimberg" <sagi@grimberg.me>,
	linux-nfs@vger.kernel.org
Subject: Re: [RFC] NFS: named client identities for mTLS mounts and a per-namespace .nfs keyring
Date: Fri, 11 Sep 2026 15:20:13 -0400	[thread overview]
Message-ID: <4ff29ed1-e963-4010-a7a1-73b229cc8bd0@app.fastmail.com> (raw)
In-Reply-To: <bb9a872a-d4aa-467a-b4c9-7bca174a6bbc@suse.de>

Christian, we're interested in the question below about user-ns
versus net-ns for keyring ownership.


On Tue, Jun 2, 2026, at 9:39 PM, Hannes Reinecke wrote:
> On 6/2/26 17:47, Chuck Lever wrote:
>> Today, exactly one x.509 certificate and private key pair can be
>> used at a time for all NFS mounts. The location of that pair is
>> set in /etc/tlshd/config.
>> 
>> We currently have an awkward experimental mechanism for specifying
>> an alternative x.509 certificate and private key for an xprtsec=mtls
>> NFS mount, but it needs to be completed so it can be documented and
>> advertised for use.
>> 
>> I asked Claude to write a rough draft of a design document that
>> outlines what needs to be done to finish the work. I would like
>> input on the kernel-side mechanism in particular for the
>> per-network-namespace keyring and the way userspace reaches it.
>> 
>> 
>> Problem
>> =======
>> 
>> NFS mutual-TLS mounts (xprtsec=mtls) need the client to present an
>> x.509 certificate and prove possession of its private key. The
>> handshake runs in userspace in tlshd; the kernel hands tlshd the
>> credentials by keyring serial number over the handshake genetlink
>> upcall.
>> 
>> The only front end today is two undocumented integer mount options:
>> 
>>      mount -o xprtsec=mtls,cert_serial=723847,privkey_serial=723848 \
>>            server:/export /mnt
>> 
>> The administrator must load the cert and key into the keyring out of
>> band, discover the integer serials, and paste them onto the command
>> line. Serials are opaque, non-reproducible across boots, and easy to
>> transpose. There is also no isolation: nfs_tls_key_verify() does a
>> global key_lookup() on the serial, and the .nfs keyring created in
>> fs/nfs/inode.c is module-global and never referenced again -- any tlshd
>> that learns a serial can read the key.
>> 
>> This RFC proposes a named, per-mount client-identity interface backed
>> by a provisioning CLI, and fixes the keyring to isolate credentials per
>> network namespace. The kernel handshake ABI (integer serials over
>> genetlink) does not change.
>> 
>> 
>> The cross-subsystem ask: a per-netns .nfs keyring
>> =================================================
>> 
>> Network namespace is the correct isolation domain. tlshd is bound to a
>> network namespace, not a user namespace: it services sockets passed up
>> from the kernel over the per-netns handshake genetlink socket, and one
>> tlshd runs per network namespace that needs TLS-protected mounts.
>> 
>>    - Replace the dead module-global .nfs keyring with one keyring per
>>      network namespace, held in struct nfs_net (fs/nfs/netns.h) and
>>      allocated at nfs_net_init(). The keys subsystem otherwise
>>      namespaces on user_namespace, so this is a kernel-held object
>>      referenced from nfs_net (like today's global keyring, but one per
>>      netns). The DNS resolver's per-netns key scoping (net->key_domain,
>>      request_key_net()) is precedent that netns-scoped key handling is
>>      acceptable.
>> 
>>    - tlshd attaches at handshake time, not at launch. This matters: the
>>      keyring may be empty or freshly created when tlshd starts, so
>>      linking it by name at startup is the wrong model. Instead NFS sets
>>      ta_keyring to the netns .nfs keyring serial in
>>      xs_tls_handshake_sync(), the kernel sends it as
>>      HANDSHAKE_A_ACCEPT_KEYRING, and tlshd links that serial into its
>>      session keyring per handshake -- the path tlshd already implements.
>>      Linking grants tlshd possession of the keyring and, through it, of
>>      the possessor-scoped cert and privkey keys.
>> 
>>    - Credential keys are created possessor-readable only (no
>>      KEY_USR_READ). That is what makes isolation enforceable rather
>>      than advisory: a key provisioned in namespace A is absent from B's
>>      keyring and unreadable by B's tlshd even if its serial leaks.
>> 
>> Open question, and where I most want input: userspace -- the
>> provisioning CLI and mount.nfs -- needs to name the kernel-held netns
>> keyring in order to add and search keys. Candidates, modeled on
>> KEYCTL_GET_PERSISTENT (security/keys/persistent.c):
>> 
>>    (a) a new keyctl command that links the caller's netns .nfs keyring
>>        into a destination keyring and returns its serial;
>>    (b) an NFS-specific request_key key type the module instantiates to
>>        point at the netns keyring;
>>    (c) a per-netns serial exported via procfs or netlink.
>> 
>> The per-netns keyring decision itself I consider settled; the retrieval
>> primitive is the open one. There is also a user_namespace accounting
>> nuance: keys added by userspace are quota-charged against a key_user
>> keyed by user_namespace even though the keyring lives in nfs_net. I
>> would like the keyrings folks to confirm the quota and ownership
>> interaction is sane when the user_ns and net_ns boundaries do not
>> coincide.
>>
>
> I am all for making keyrings namespace-aware. Logically I _think_ they
> should be tagged per user-namespace, as this really is about the 
> filesystem (and as such would warrant to be tagged per mount ns).
> Tagging it per net-namespace is not a great fit (well, for me, at 
> least), as also block devices might require keys to present the
> bdev (eg nvme authentication)
>
> I might be okay to have it tagged per net-namespace, though, as all
> current users are in some shape or form being network related.
> But I'm not sure if that stays that way, so I am worried if we're
> not restricting ourselves to much by that choice.
> As really, the question is: what is the driving the namespace selection?
> Is it the _requesting_ layer, ie the layer issuing the mount() call?
> Or is it the _providing_ layer, ie the layer providing the 
> devices/interfaces where the mount() call is operating on?
> If it's the former, then we need to tag is as
> net-namespace. If it's the latter, then we need to tag it as a
> user-namespace / mount-ns.
>
> We should probably ask Christian ...
>
> Cheers,
>
> Hannes
> -- 
> Dr. Hannes Reinecke                  Kernel Storage Architect
> hare@suse.de                                +49 911 74053 688
> SUSE Software Solutions GmbH, Frankenstr. 146, 90461 Nürnberg
> HRB 36809 (AG Nürnberg), GF: I. Totev, A. McDonald, W. Knoblich

-- 
Chuck Lever (Come to NFS bake-a-thon! https://nfsv4bat.org)

  parent reply	other threads:[~2026-09-11 19:20 UTC|newest]

Thread overview: 9+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-06-02 15:47 [RFC] NFS: named client identities for mTLS mounts and a per-namespace .nfs keyring Chuck Lever
2026-06-03  1:39 ` Hannes Reinecke
2026-06-03 14:27   ` Chuck Lever
2026-06-05 21:32     ` Sagi Grimberg
2026-06-05 22:07       ` Chuck Lever
2026-09-11 19:20   ` Chuck Lever [this message]
2026-06-05 21:44 ` Sagi Grimberg
2026-06-06  6:50   ` Hannes Reinecke
2026-09-13 16:05 ` Chuck Lever

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=4ff29ed1-e963-4010-a7a1-73b229cc8bd0@app.fastmail.com \
    --to=cel@kernel.org \
    --cc=anna@kernel.org \
    --cc=brauner@kernel.org \
    --cc=dhowells@redhat.com \
    --cc=hare@suse.de \
    --cc=hch@lst.de \
    --cc=jarkko@kernel.org \
    --cc=kernel-tls-handshake@lists.linux.dev \
    --cc=keyrings@vger.kernel.org \
    --cc=linux-nfs@vger.kernel.org \
    --cc=netdev@vger.kernel.org \
    --cc=sagi@grimberg.me \
    --cc=trondmy@kernel.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox