Skip to content

OL 10.2: selinux-policy confines tlshd (ktlshd_t) with no rules for nfsd_t sockets, server-side NFS over TLS (xprtsec=mtls) broken in enforcing mode #229

Description

@bfilin

NFS v4.2 server upgraded OL 10.1 --> 10.2; NFS-over-TLS mounts stopped working immediately after.

TL;DR: OL 10.2's new ktlshd_t confinement ships zero allow rules for nfsd_t:tcp_socket, so tlshd cannot service TLS handshakes for kernel nfsd --> server-side NFS-over-TLS mounts fail in enforcing mode. The read/write denials are masked by the policy-wide dontaudit domain domain:tcp_socket rule, making diagnosis difficult. Worked in 10.1 (tlshd was unconfined). Verified 5-line policy fix below.

Versions

  • Oracle Linux 10.2 (server), SELinux enforcing, targeted policy
  • selinux-policy-targeted-42.1.18-4.0.1.el10_2.noarch
  • ktls-utils-1.2.1-3.el10.x86_64, gnutls-3.8.10-3.el10_1.x86_64
  • kernel-uek 6.12.0-204.92.4.3.el10uek
  • Reproduction client: OL 9.8 (autofs-triggered mounts; client tlshd unconfined on 9.8, not at fault)

Reproduce
OL 10.2 NFS server, SELinux enforcing, valid x.509 setup in /etc/tlshd.conf, export with xprtsec=mtls. From a client, trigger a mount (reproduced with autofs-managed home directories, map option xprtsec=mtls) --> mount fails, server journal shows tlshd handshake errors. The failure occurs server-side in the handshake upcall, only autofs-triggered mounts were tested.

Root cause

Stock policy has no ktlshd_t <--> nfsd_t rules at all:

# sesearch -A -s ktlshd_t -t nfsd_t -c tcp_socket
(returns empty)

The policy only covers sockets created by unconfined_t and init_t (the client mount paths). Server-side handshake sockets belong to kernel nfsd (nfsd_t) and have no rules. The denials surface in two stages:

  • denied { getattr } getpeername() fails; journal: getpeername: Permission denied
  • denied { read } handshake recv fails; journal: gnutls: Error in the pull function. (-54). This denial is hidden from ausearch by the generic rule below, and only appears after semodule -DB:
# sesearch --dontaudit -s ktlshd_t -c tcp_socket
dontaudit domain domain:tcp_socket { read write };

ausearch details (obfuscated):

type=AVC ... denied { getattr } for comm="tlshd" laddr=192.0.2.10 lport=2049
     scontext=system_u:system_r:ktlshd_t:s0 tcontext=system_u:system_r:nfsd_t:s0 tclass=tcp_socket permissive=0
type=AVC ... denied { read } for comm="tlshd" laddr=192.0.2.10 lport=2049
     scontext=system_u:system_r:ktlshd_t:s0 tcontext=system_u:system_r:nfsd_t:s0 tclass=tcp_socket permissive=0

Verified fix / workaround
With this module loaded, a full TLS 1.3 mutual-auth handshake completes and kTLS is established; autofs mounts work in enforcing mode:

module local-ktlshd 1.1;

require {
        type nfsd_t;
        type ktlshd_t;
        class tcp_socket { getattr getopt setopt read write };
}

allow ktlshd_t nfsd_t:tcp_socket { getattr getopt setopt read write };

Expected behavior
Shipped policy should allow ktlshd_t these permissions on nfsd_t:tcp_socket so NFS over TLS works server-side out of the box, as in 10.1.

Notes

  • Likely inherited from upstream RHEL 10.2 selinux-policy; may warrant forwarding. But posting here since OL devs do a lot of work on the kTLS/nfsd front.
  • Consider exempting ktlshd_t (as source) from dontaudit domain domain:tcp_socket { read write } (tlshd services other domains' sockets by design) so these denials are missing-rule signals, not fd-leak noise.
  • Client side:
    • On OL 9.8, autofs-triggered mTLS mounts work against our fixed OL 10.2 server.
    • Future concern (needs testing): on OL 10.2 clients, tlshd is confined and the shipped rules cover only unconfined_t/init_t (autofs initiated mounts are therefore suspect and not yet verified)

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions