public inbox for kernel-tls-handshake@lists.linux.dev
 help / color / mirror / Atom feed
From: Ken Milmore <ken.milmore@gmail.com>
To: Chuck Lever <chuck.lever@oracle.com>
Cc: kernel-tls-handshake@lists.linux.dev
Subject: Re: [PATCH 1/7] tlshd_handshake_parms: Dispense with unnecessary dynamic storage for peerids.
Date: Sat, 14 Jun 2025 03:03:48 +0100	[thread overview]
Message-ID: <542ac720-c526-4d08-b7cf-d7169f433462@gmail.com> (raw)
In-Reply-To: <6b62e314-02b1-4914-a6e1-ddf7a24ad644@oracle.com>

On 14/06/2025 01:40, Chuck Lever wrote:
> When mounting an NFS server, the server's DNS label comes from the
> client administrator, so we assume trust in that information. The server
> does not have the same benefit with regard to client DNS labels.

In case it helps, I'd like to provide a bit more detail on my use-case, as a
rationale for why I developed these patches, and to show what I would hope to
see covered in a future release of ktls-utils which supports certificate tags
or suchlike.

Suppose I have an NFS server with exports configured like so:

# /etc/exports:
/srv/foo foo.example.org(xprtsec=mtls,rw,sync,no_subtree_check)
/srv/bar bar.example.org(xprtsec=mtls,rw,sync,no_subtree_check)
/srv/baz baz.example.org(xprtsec=mtls,rw,sync,no_subtree_check)

Now I give each of the clients foo, bar and baz their own individual private
key/certificate pair and add all these certificates to the trust store on the
server.

I find that as expected, the exports are effectively secured against access
from random clients which have not been enrolled on the server.

Note that host foo is only meant to be able to access the /srv/foo share. But
suppose that the administrator of foo changes its IP address to match that of
host baz. The admin finds that they can in fact mount any of the shares simply
by adopting the IP address of the other clients. This is something that has, of
course, always been possible with unsecured NFS. But adding mtls actually has
not improved this aspect of security at all.

When I discovered this, I was quite surprised. There's nothing to warn about it
in the man pages relating to NFS and mtls. I expect I'm not the only person who
missed the fact that mtls simply doesn't protect against authorised clients
impersonating each other *even if they have different key/cert pairs and do not
divulge them*.

For my use case, this rendered mtls pretty much useless. I want each client to
be policed individually wrt the shares it gets access to.

Because the hostname(s), or address(es) of the permitted client(s) is/are
explicitly mentioned in /etc/exports, I realised that tying a client to its
certificate effectively allowed me to enforce these share "permissions".

With my patches and verify_peername=true, if host foo attempts to connect to
the baz share by spoofing its IP address, it will be rejected because it does
not have the baz certificate.

Now for this to be watertight, it does require the server admin to ensure one
of the following holds:

- All authorised clients are assigned static IP addresses and these are listed
in /etc/hosts or similar. Or,

- All authorised clients are assigned static IP addresses and these are used
explicitly in /etc/exports instead of DNS names. Or,

- The admin has control of local name resolution for the example.org domain.

What applies to host names above could also be applied to subnets/subdomains
with care, so all sorts of flexibility is possible.

Now I agree the above requirements will be unworkable in may scenarios. But
they happen to be fine for my use case. I've gained the ability to lock NFS
shares down to individual clients, or groups of clients, at the cost of having
to control client naming/addressing. I've found this fairly easy to achieve
using an IPv6 ULA subnet specifically for NFS mounts.


If certificate tagging gets implemented, then I'd hope that this can be used
to tie client certificates to exports in a similar way. But presumably that
would require another change to the NFS export syntax, and a change in the
kernel netlink interface?

Eventually I might hope to be able to do something like this to achieve the
same effect without any reliance on client addressing:

# /etc/exports:
/srv/foo foo.example.org(xprtsec=mtls,tag=FOOTAG,rw,sync,no_subtree_check)
/srv/bar bar.example.org(xprtsec=mtls,tag=BARTAG,rw,sync,no_subtree_check)
/srv/baz baz.example.org(xprtsec=mtls,tag=BAZTAG,rw,sync,no_subtree_check)

Where presumably FOOTAG is mentioned somewhere in foo's client certificate.

In the meantime, it might be helpful if the NFS documentation were to
explicitly mention that mtls does not discriminate between clients for the
purpose of granting access to mounts, and therefore does not protect against
cross-impersonation attacks between "trusted" clients.




  reply	other threads:[~2025-06-14  2:03 UTC|newest]

Thread overview: 11+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2025-06-08 17:42 [PATCH 1/7] tlshd_handshake_parms: Dispense with unnecessary dynamic storage for peerids Ken Milmore
2025-06-08 18:03 ` Chuck Lever
2025-06-08 19:08   ` Ken Milmore
2025-06-09 16:08     ` Chuck Lever
2025-06-13 21:42 ` Chuck Lever
2025-06-13 23:09   ` Ken Milmore
2025-06-14  0:40     ` Chuck Lever
2025-06-14  2:03       ` Ken Milmore [this message]
2025-06-18 13:42   ` Chuck Lever
2025-06-18 15:03     ` Ken Milmore
2025-06-18 16:00       ` 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=542ac720-c526-4d08-b7cf-d7169f433462@gmail.com \
    --to=ken.milmore@gmail.com \
    --cc=chuck.lever@oracle.com \
    --cc=kernel-tls-handshake@lists.linux.dev \
    /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