public inbox for kernel-tls-handshake@lists.linux.dev
 help / color / mirror / Atom feed
From: Ken Milmore <ken.milmore@gmail.com>
To: kernel-tls-handshake@lists.linux.dev
Subject: ktls-utils client address verification and other patches
Date: Sun, 8 Jun 2025 11:51:03 +0100	[thread overview]
Message-ID: <427f90d7-5bc9-4d40-ab94-a1f024b7742b@gmail.com> (raw)

I've been evaluating the use of mtls to secure NFS mounts and have noticed there's a fairly serious limitation:
Any client which has a valid certificate can impersonate a different client, since the server does not verify client address.

This is unfortunate, as I'd like to give different clients access to different NFS shares by naming the clients in /etc/exports,
and I'd like to use mtls to ensure that each client not only has a trusted certificate, but that it is only able to access the
shares to which it is entitled by /etc/exports. In other words, I want to verify the client host name or address against the
client certificate to avoid address spoofing.

I can understand why this is not the default behaviour: In general, a server will not be able to verify clients in this way.
But for NFS on a personal or corporate LAN, it is highly desirable.

To this end, I've developed some patches which allow the tlshd server to be configured to instruct GnuTLS to perform client
address verification.

Please see patch series here:

https://codeberg.org/kbm0/ktls-utils/commits/branch/verification-patchset

Because the server can only obtain the client hostname by reverse address lookup, and this has security implications, I have
been careful to confirm the hostname first by performing a forward lookup in the manner of FCrDNS: We call getaddrinfo() and
check that one of the resulting addresses matches the one which was obtained from the reverse lookup. Should this check fail,
we reject the certificate.

I've also added an option to use a textualized IP/IPv6 address for verification against the certificate, in cases where no DNS
address can be found. This works if the certificate includes the client IP address as an alternative name. It is also possible
to use the IP address as the first recourse, and this may be useful in some circumstances - it is possible for client and server
to verify each other entirely based on IP addresses with no reliance on DNS, if the certificates are set up correctly.

These behaviours are enabled by setting options in tlshd.conf like so:

[authenticate.server]
verify_peername=true
verify_peeraddr=true

Another issue I came across involves the fact that when a client connects to a server, the server name is passed to GnuTLS for
the purposes of SNI. If the client connects with a bare IP or IPv6 address, this is not strictly allowed, as only DNS names may
be used for SNI. This causes the server to reject the transaction. I've added an option to omit the SNI in cases where the client
is connecting using an IP address:

[authenticate.client]
relax_sni=true

There are some other patches in the series: I wanted to textualize the peer address up front so it can be used for both logging
and also for verification.

I also thought some of the processing in netlink.c looked a bit sloppy: Optimistic assumptions were being made about the
contents of return buffers when functions like getnameinfo() are called. I have tried to correct these.

I am hoping for some informal review or feedback for these patches in the first instance. I didn't want to just spam the mailing
list with them upfront. If there is any interest in them, I will submit them formally.

Thanks,

-Ken. :-)


             reply	other threads:[~2025-06-08 10:51 UTC|newest]

Thread overview: 5+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2025-06-08 10:51 Ken Milmore [this message]
2025-06-08 15:51 ` ktls-utils client address verification and other patches Chuck Lever
2025-06-08 16:57   ` Ken Milmore
2025-06-08 17:58     ` Chuck Lever
2025-06-08 18:28       ` Ken Milmore

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=427f90d7-5bc9-4d40-ab94-a1f024b7742b@gmail.com \
    --to=ken.milmore@gmail.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