Traditional NFS contains essentially no security features. NFS assumes that the physical network is secure, and all machines on it are uncompromised. If an attacker has root access to any machine on the network, he can read or write to any location on the NFS file system. To allow NFS to be used on insecure networks, version 4 of that protocol added optional security extensions using Kerberos. This document will describe how to configure %%FreeBSD%% to use secure NFS as either a client or a server. There are three steps: [[#authentication|authentication]], [[#authorization|authorization]], and [[#nfs|NFS]].
===== Authentication =====
With NFSv4, the problem of authenticating a user is solved by Kerberos. Kerberos is a trusted third party authentication service. An NFS server and an NFS user separately prove their identities to a KDC server, which issues them cryptographically signed tickets asserting their successful authentication. Then the server and user can trust each other. Any secure NFS network must contain a Kerberos KDC server. Configuring Kerberos on %%FreeBSD%% is described at https://www.freebsd.org/doc/handbook/kerberos5.html. From Kerberos's perspective, both NFS servers and NFS clients are Kerberos clients. After configuring your NFS machines as Kerberos clients, you must create a static NFS service ticket on any NFS servers. If your KDC server is Heimdal, start ''%%kadmin%%'' and use these commands:
kadmin> add --random-key --keytab=/tmp/my_nfs_server.keytab nfs/my_nfs_server.mydomain.com
kadmin> ext_keytab nfs/my_nfs_server.mydomain.com
then copy the keytab file to your ''%%my_nfs_server%%'' and either move it to ''%%/etc/krb5.keytab%%'' or merge it to an existing ''%%/etc/krb5.keytab%%'' with one of the following commands:
# Move the temporary keytab file to /etc/krb5.keytab
mv /tmp/my_nfs_server.keytab /etc/krb5.keytab
chown root:wheel /etc/krb5.keytab
chmod 600 /etc/krb5.keytb
# OR, merge the temporary keytab file with an existing /etc/krb5.keytab
ktutil copy /tmp/my_nfs_server.keytab /etc/krb5.keytab
rm /tmp/my_nfs_server.keytab
===== Authorization =====
Authentication is the process of determining whether a user is whom says he says he is. Authorization, on the other hand, is the process of determining which operations are allowed for which users. Kerberos does not provide authorization, and NFSv4 does not specify how authorization is to be performed. On %%FreeBSD%%, it is performed by the kernel using the traditional UNIX file attributes, but there is a catch: unlike NFSv3, NFSv4 does not transmit UIDs across the wire. Instead, it transmits user identifiers as strings in the format "username@domain". %%FreeBSD%% must translate these strings into UIDs, and that is handled by PAM. There are many ways to configure PAM to manage users; here are the most common. As a rule of thumb, if you can do ''%%id %%'' for any user, then you've successfully configured PAM and NFSv4 will work for that user.
==== Local users only ====
The simplest setup is to manage users separately on all machines, using the regular ''%%pw%%'', ''%%adduser%%'', etc utilities. This method requires no special configuration, but is tedious as changes must be synchronized on multiple machines. In particular, each account must have the same UID on all machines. This method is only practical for the smallest networks.
==== NIS ====
NIS is a mature directory service that is well integrated into %%FreeBSD%%. If you follow the directions at https://www.freebsd.org/doc/handbook/network-nis.html , then NFSv4 user mapping will work with no further modifications.
==== ActiveDirectory ====
%%ActiveDirectory%% is a proprietary product from Microsoft that combines Kerberos, LDAP, and other protocols into a single package. It can be used to manage users on networks with mixed Windows and Unix machines. From %%FreeBSD%%'s perspective, %%ActiveDirectory%% is both the KDC and LDAP server. To use %%ActiveDirectory%% with Kerberos, add these lines to the ''%%[libdefaults]%%'' section of ''%%/etc/krb5.conf%%'' on every machine. Your Windows Domain is identical to your Kerberos Realm.
default_realm =
dns_lookup_realm = true
dns_lookup_kdc = true
forwardable = yes
As described above, you will need to generate a static NFS service ticket. This is significantly different than with Heimdal. Follow these instructions:
- Using %%ActiveDirectory%%'s GUI, create a Computer account named ''%%nfs%%''. For example, if your NFS server is named ''%%frank.example.com%%'', create a Computer account named ''%%nfsFrank%%''.
- From the Windows CLI, run ''%%ktpass -princ nfs/@ mapuser \$ +rndPass -out .keytab%%''. For example, if your NFS server is named ''%%frank.example.com%%'' and your Windows Domain is "EXAMPLE.COM", you would run ''%%ktpass -princ nfs/frank.example.com@EXAMPLE.COM mapuser EXAMPLE\nfsFrank$ +rndPass -out nfsFrank.keytab%%''
- Transfer the temporary keytab file to the NFS server
- As described above, move or merge the temporary keytab file to ''%%/etc/krb5.keytab%%''.
TODO: describe how to connect PAM to %%ActiveDirectory%% for user id mapping
===== NFS =====
Strictly speaking, we haven't been dealing with NFS at all up until this point. Once Kerberos and PAM are configured, NFS can be configured like normal according to nfsv4(4), exports(5), and mount_nfs(8). Unlike NFSv3, with Kerberized NFSv4 each user (not system) must have a Kerberos ticket in order to access the NFS file system. On a %%FreeBSD%% client, type "kinit" to check out a Kerberos ticket. The user who performs the mount must also have a Kerberos ticket. Optionally, you can use the static service ticket for mounting. This way, you can mount at boot time and the mount will stay available for as long as the static service ticket is valid (usually forever). To do this, use the ''%%gssname%%'' option in your client's ''%%/etc/fstab%%'' file.
==== Security Flavors ====
NFSv4 supports four flavors of security. Increasing levels provide more security but impose a performance penalty. You must choose the flavor appropriate for your installation. Security flavors are specified in ''%%/etc/exports%%'' on a per-export basis. That means they may vary per export, and also per client IP or network. The four flavors are:
* **sys**: System-provided security. This is identical to NFSv3's security model. If you're reading this guide, then you probably don't want ''%%sec=sys%%''.
* **krb5**: Kerberos authentication. With this flavor, all RPC headers are cryptographically signed with the requestor's Kerberos ticket. This ensures that an unauthenticated attacker cannot access the NFS server. However, krb5 is vulnerable to man-in-the-middle attacks. krb5 is a good choice for networks that are secure and reliable, but with untrusted endpoints.
* **krb5i**: Kerberos authentication and integrity. With this flavor, not only are RPC headers cryptographically signed, but the header also contains a secure hash of the contents of the RPC's payload. This ensures that corrupted or altered requests will not be accepted by the server, and corrupted and altered responses will not be accepted by the client. krb5i is robust against man-in-the-middle attacks, but provides no privacy from passive eavesdroppers; all RPC payloads are transmitted in the clear. krb5i is a good choice for networks that are secure but want robustness against accidental corruption. It can also be used by underpriveleged clients on insecure networks. For example, the NFS server may export sensitive files with krb5p, but use krb5i for insensitive files to improve performance.
* **krb5p**: Kerberos authentication, integrity, and privacy. This is the most secure flavor of NFS. Not only does it provide authentication and integrity, but the entire RPC payload is encrypted. Thus a passive eavesdropper can see nothing but RPC headers. krb5p is a good choice for insecure networks, including wireless networks.
===== Tips =====
* Ensure that every machine's hostname is set to the FQDN, and reverse DNS is working.
* Windows Server 2008 is the oldest that supports reasonably secure encryption. Older versions should not be used as a KDC.
* NFSv4 includes powerful ACLs. %%FreeBSD%% fully supports them on both client and server. You can manipulate them using getfacl(1) and setfacl(1).
* If your NFS exported directories will not be accessed locally (and Samba counts as local access), then you can enable NFSv4 delegations to improve performance. On a %%FreeBSD%% NFS server, they may be enabled globally for all exports by adding the following line to ''%%/etc/sysctl.conf%%'':
vfs.nfsd.issue_delegations=1
* If you want your %%FreeBSD%% client to mount an NFS share at boot, you can use the static service ticket for mounting
===== Troubleshooting =====
**The client can mount a share, but ''%%ls%%'' shows it to be empty, and ''%%dmesg%%'' shows ''%%nfsv4 client/server protocol prob err=10020%%''**
The server has mounted or unmounted its exports after starting mountd. The solution is to restart mountd.
**A linux client says ''%%Remote I/O error%%'' during mount, and a packet trace shows that the server returned ''%%NFS4ERR_SERVERFAULT%%''**
Some linux clients seem to request ''%%krb5i%%'' even if you try to use plain ''%%krb5%%''. Try setting ''%%sec=krb5,krb5i%%'' in the server's exports file.
----
{{tag>HowTo Stale}}