NFS over TLS
Overview
While NFS has been a great solution to expose a single filesystem across a number of hosts over a network, it’s security has been significantly “outdated” for some time.
Those who’ve had the task of securing NFS in the past had to rely on local file ownership and permissions, restricting client access manually, etc. Another solution was around the authentication was kerberos which is another dinosaur platform with plenty of features and potentially a bloated solution for the simple task of securing a remote file system.
If the beforementioned was yesterday’s problem, then today’s solution is TLS over NFS. Available as of linux 6.5 the xprtsec=tls option can be used when mounting the export on the client side.
NFS over TLS offers:
- encryption in transit
- certificate based server authentication (optional)
- certificate based client authentication (optional)
NOTE - In addition to TLS, squash related options are also important to consider. Ideally when possible ownership dependencies should be avoided, however certain workloads (for example elasticsearch or postgresql) require strict ownership to work as expected and squashing may or may not be desirable - DYOR!
Prerequisites
In order to tag along you will need a:
- NFS server and a linux client machine running a kernel 6.5 or newer
- An SSL certificate(s) - this can be a Lets Encrypt certificate or signed and issued by your CA
- The ktls-utils package installed on both the server and client
Server side
Ensure the ktls-utils package is installed, the tlshd.service started and enabled as well as nfs-server.service.
In your /etc/tlshd.conf file at the very least you need:
[authenticate.server]
x509.certificate=/path/to/nfs-server.crt
x509.private_key= /path/to/nfs-server.key
Optionally a [client] and [server] sub-sections can be added that specify a SSL certificate/key to be used when establishing a handshare. See man tlshd.conf.
Client side
On the client side you still need the tlshd.service running, however you don’t need to create an /etc/tlshd.conf file neccessarily.
If using certificates signed by a custom CA, make sure the CA in question is added to the client’s certificate truststore.
To mount the nfs partition over NFS:
# mount -o xprtsec=tls nfs.server.example.com:/export /mnt/remote-nfs
Verification
To verify the encryption is working use the tcpdump command to capture nfs traffic:
tcpdump -i <interface> port 2049 -w nfs_capture.pcap
You can read the data with tcpdump: tcpdump -r nfs_capture.pcap , however loading it into wireshard is probably a more convenient option.
You should see still messages being sent and handshakes done, however the contents of these should now be encrypted.
The End
Hopefully this has been useful and something new you can benefit from in your work or homelab.
If you’ve enjoyed this, make sure to go ahead and look at the Articles section.
My personal projects you can find on my git server.
If you have a question or want to get in touch, feel free to email me.
Thank you for reading and have a good night!