FreeIPA and NFSv4
From Linux NFS
This document describes using NFSv4 with FreeIPA.
Historically, configuring a secure NFSv4 export (or even a client) has been challenging, especially when it requires setting up of a Kerberos realm. FreeIPA provides a packaged service of Kerberos 5, LDAP and helper software (ntp, httpd for admin interface, etc) with both a cli and web-based admin interface.
Notes
- These instructions are for Fedora 15. Other distros will require similar setup - the key differences will be:
- a package installation tool other than yum
- a different config file layout
- This example uses a private network (192.168.56.0/24) with a fake DNS realm (example.fake). Using real IPs with a real DNS server should be very similar.
- For simplicity, this domain only has one server (server.example.fake) and one client (client1.example.fake).
- This example is running on a NAT'd private network, so I just turned off the firewall on the server. You probably shouldn't do that! You'll need to allow traffic on:
- port 53 (TCP and UDP) for named
- port 80, 443 (TCP) for httpd (FreeIPA web interface)
- ports 88 and 464 (TCP and UDP) for Kerberos
- ports 389, 636 (TCP and UDP) for LDAP
- ports 123 (UDP) for NTP (network time protocol)
- port 2049 (TCP and UDP) for NFS
- SELinux is in 'permissive' mode. Running in 'enforced' mode will require additional steps.
- You must be root on both the client and server to run (most of) these commands. In this example, all commands are run as root.
Configure DNS realm
You might not need to do this. If you're just setting up a client of FreeIPA, you can skip this section entirely.
Configure existing DNS realm
Make sure the full DNS names and reverse mappings for server(s) and client(s) are in DNS.
[root@client1 ~]# nslookup server.example.fake Server: 192.168.56.20 Address: 192.168.56.20#53 Name: server.example.fake Address: 192.168.56.20 [root@client1 ~]# nslookup 192.168.56.20 Server: 192.168.56.20 Address: 192.168.56.20#53 20.56.168.192.in-addr.arpa name = server.example.fake. [root@client1 ~]# nslookup client1.example.fake Server: 192.168.56.20 Address: 192.168.56.20#53 Name: client1.example.fake Address: 192.168.56.40 [root@client1 ~]# nslookup 192.168.56.40 Server: 192.168.56.20 Address: 192.168.56.20#53 40.56.168.192.in-addr.arpa name = client1.example.fake.
Add the service entries for FreeIPA auto discovery. They are of the form:
; DNS auto discovery of services _ldap._tcp SRV 10 10 389 server.example.fake. _kerberos._udp SRV 10 10 88 server.example.fake. _kerberos._tcp SRV 10 10 88 server.example.fake.
Test Setup
To use kerberos with NFSv4, you must have DNS configured (and reverse mapping) for the server and every client.
For testing NFS, it's useful to make a fake DNS domain that you have control over. If you wish, follow the instructions here: Create a fake DNS realm for testing. If you are using a real DNS domain, these instructions should point you in the right direction.
Install and configure the FreeIPA server
Install and configure the FreeIPA software on the server (server.example.fake).
Install the FreeIPA server and admintools package
This step fetches and installs FreeIPA and it's dependencies. It will install around 100 packages, depending on what you already have installed.
[root@server ~]# yum install freeipa-server freeipa-admintools
Configure FreeIPA server
Run the ipa-server-install program. This takes a while.
All of the default answers should work if DNS hostnames and services are set up correctly and the full domain name is returned by hostname.
[root@server ~]# ipa-server-install The log file for this installation can be found in /var/log/ipaserver-install.log ============================================================================== This program will set up the FreeIPA Server. This includes: * Configure the Network Time Daemon (ntpd) * Create and configure an instance of Directory Server * Create and configure a Kerberos Key Distribution Center (KDC) * Configure Apache (httpd) To accept the default shown in brackets, press the Enter key. Enter the fully qualified domain name of the computer on which you're setting up server software. Using the form <hostname>.<domainname> Example: master.example.com. Server host name [server.example.fake]: The domain name has been calculated based on the host name. Please confirm the domain name [example.fake]: The IPA Master Server will be configured with Hostname: server.example.fake IP address: 192.168.56.20 Domain name: example.fake The kerberos protocol requires a Realm name to be defined. This is typically the domain name converted to uppercase. Please provide a realm name [EXAMPLE.FAKE]: Certain directory server operations require an administrative user. This user is referred to as the Directory Manager and has full access to the Directory for system management tasks and will be added to the instance of directory server created for IPA. The password must be at least 8 characters long. Directory Manager password: Password (confirm): The IPA server requires an administrative user, named 'admin'. This user is a regular system account used for IPA server administration. IPA admin password: Password (confirm): The following operations may take some minutes to complete. Please wait until the prompt is returned. Configuring ntpd [1/4]: stopping ntpd [2/4]: writing configuration [3/4]: configuring ntpd to start on boot [4/4]: starting ntpd done configuring ntpd. Configuring directory server for the CA: Estimated time 30 seconds [1/3]: creating directory server user [2/3]: creating directory server instance [3/3]: restarting directory server done configuring pkids. Configuring certificate server: Estimated time 6 minutes [1/17]: creating certificate server user [2/17]: creating pki-ca instance [3/17]: restarting certificate server [4/17]: configuring certificate server instance [5/17]: restarting certificate server [6/17]: creating CA agent PKCS#12 file in /root [7/17]: creating RA agent certificate database [8/17]: importing CA chain to RA certificate database [9/17]: restarting certificate server [10/17]: requesting RA certificate from CA [11/17]: issuing RA agent certificate [12/17]: adding RA agent as a trusted user [13/17]: fixing RA database permissions [14/17]: setting up signing cert profile [15/17]: set up CRL publishing [16/17]: configuring certificate server to start on boot [17/17]: restarting certificate server done configuring pki-cad. Configuring directory server: Estimated time 1 minute [1/32]: creating directory server user [2/32]: creating directory server instance [3/32]: adding default schema [4/32]: enabling memberof plugin [5/32]: enabling referential integrity plugin [6/32]: enabling winsync plugin [7/32]: configuring replication version plugin [8/32]: enabling IPA enrollment plugin [9/32]: enabling ldapi [10/32]: configuring uniqueness plugin [11/32]: configuring uuid plugin [12/32]: configuring modrdn plugin [13/32]: enabling entryUSN plugin [14/32]: configuring lockout plugin [15/32]: creating indices [16/32]: configuring ssl for ds instance [17/32]: configuring certmap.conf [18/32]: configure autobind for root [19/32]: restarting directory server [20/32]: adding default layout [21/32]: adding delegation layout [22/32]: adding replication acis [23/32]: configuring user private groups [24/32]: configuring netgroups from hostgroups [25/32]: creating default Sudo bind user [26/32]: creating default HBAC rule allow_all [27/32]: initializing group membership [28/32]: adding master entry [29/32]: configuring Posix uid/gid generation [30/32]: enabling compatibility plugin [31/32]: tuning directory server [32/32]: configuring directory to start on boot done configuring dirsrv. Configuring Kerberos KDC: Estimated time 30 seconds [1/14]: setting KDC account password [2/14]: adding sasl mappings to the directory [3/14]: adding kerberos entries to the DS [4/14]: adding default ACIs [5/14]: configuring KDC [6/14]: adding default keytypes [7/14]: adding default password policy [8/14]: creating a keytab for the directory [9/14]: creating a keytab for the machine [10/14]: exporting the kadmin keytab [11/14]: adding the password extension to the directory [12/14]: adding the kerberos master key to the directory [13/14]: starting the KDC [14/14]: configuring KDC to start on boot done configuring krb5kdc. Configuring ipa_kpasswd [1/2]: starting ipa_kpasswd [2/2]: configuring ipa_kpasswd to start on boot done configuring ipa_kpasswd. Configuring the web interface: Estimated time 1 minute [1/12]: disabling mod_ssl in httpd [2/12]: setting mod_nss port to 443 [3/12]: setting mod_nss password file [4/12]: adding URL rewriting rules [5/12]: configuring httpd [6/12]: setting up ssl [7/12]: setting up browser autoconfig [8/12]: publish CA cert [9/12]: creating a keytab for httpd [10/12]: configuring SELinux for httpd [11/12]: restarting httpd [12/12]: configuring httpd to start on boot done configuring httpd. Setting the certificate subject base restarting certificate server Applying LDAP updates Restarting the directory server Restarting the KDC Restarting the web server Sample zone file for bind has been created in /tmp/sample.zone.I_fDwT.db ============================================================================== Setup complete Next steps: 1. You must make sure these network ports are open: TCP Ports: * 80, 443: HTTP/HTTPS * 389, 636: LDAP/LDAPS * 88, 464: kerberos UDP Ports: * 88, 464: kerberos * 123: ntp 2. You can now obtain a kerberos ticket using the command: 'kinit admin' This ticket will allow you to use the IPA tools (e.g., ipa user-add) and the web user interface. Be sure to back up the CA certificate stored in /root/cacert.p12 This file is required to create replicas. The password for this file is the Directory Manager password
Install and configure FreeIPA client(s)
Install the freeipa-client package on each client of the FreeIPA domain.
Install the FreeIPA client package
Fetch and install the FreeIPA client.
[root@client1 ~]# yum install freeipa-client ...
Configure the FreeIPA client
Again, if DNS is setup correctly and hostname returns the full DNS name, the default answers should work.
You want to use "admin" (the administrator user you created when configuring the FreeIPA server) as the enrollment principal.
[root@client1 ~]# ipa-client-install Discovery was successful! Hostname: client1.example.fake Realm: EXAMPLE.FAKE DNS Domain: example.fake IPA Server: server.example.fake BaseDN: dc=example,dc=fake Continue to configure the system with these values? [no]: yes Enrollment principal: admin Password for admin@EXAMPLE.FAKE: Enrolled in IPA realm EXAMPLE.FAKE Created /etc/ipa/default.conf Configured /etc/sssd/sssd.conf Configured /etc/krb5.conf for IPA realm EXAMPLE.FAKE SSSD enabled Kerberos 5 enabled NTP enabled Client configuration complete.
Common Problems
Joining realm failed because of failing XML-RPC request. This error may be caused by incompatible server/client major versions.
This was seen on older Fedora 15 installs, but has since been fixed (on yum 'update' repositories). The problem and workaround are described here: https://www.redhat.com/archives/freeipa-users/2011-July/msg00029.html
Add FreeIPA NFS service for each host
The next step is to setup kerberos principals for the NFS service on each host.
You can also do this through the FreeIPA web administration interface. See: Using the FreeIPA Web UI.
Add FreeIPA NFS service for server
[root@server ~]# ipa service-add nfs/server.example.fake ---------------------------------------------------- Added service "nfs/server.example.fake@EXAMPLE.FAKE" ---------------------------------------------------- Principal: nfs/server.example.fake@EXAMPLE.FAKE Managed by: server.example.fake
Add FreeIPA NFS service for client(s)
[root@server ~]# ipa service-add nfs/client1.example.fake ----------------------------------------------------- Added service "nfs/client1.example.fake@EXAMPLE.FAKE" ----------------------------------------------------- Principal: nfs/client1.example.fake@EXAMPLE.FAKE Managed by: client1.example.fake
Import FreeIPA NFS service tickets on the server
Older kernel and nfs-utils packages will require the use of the encryption type 'des-cbc-crc' (more):
[root@server ~]# ipa-getkeytab -s server.example.fake -e des-cbc-crc -p nfs/server.example.fake -k /etc/krb5.keytab Keytab successfully retrieved and stored in: /etc/krb5.keytab
Newer kernel and nfs-util packages will not need the -e switch:
[root@server ~]# ipa-getkeytab -s server.example.fake -p nfs/server.example.fake -k /etc/krb5.keytab Keytab successfully retrieved and stored in: /etc/krb5.keytab
You can check to see what's in the keytab like this:
[root@server ~]# klist -ke /etc/krb5.keytab Keytab name: WRFILE:/etc/krb5.keytab KVNO Principal ---- -------------------------------------------------------------------------- 6 nfs/server.example.fake@EXAMPLE.FAKE (des-cbc-crc) 4 host/server.example.fake@EXAMPLE.FAKE (aes256-cts-hmac-sha1-96) 4 host/server.example.fake@EXAMPLE.FAKE (aes128-cts-hmac-sha1-96) 4 host/server.example.fake@EXAMPLE.FAKE (des3-cbc-sha1) 4 host/server.example.fake@EXAMPLE.FAKE (arcfour-hmac) 4 host/server.example.fake@EXAMPLE.FAKE (des-cbc-crc)
The following example's output was for older kernel and nfs-utils packages. There would be 5 entries for nfs/ if you didn't use the -e switch.
Import FreeIPA NFS service tickets on the client(s)
Again, the -e des-cbc-crc switch may be needed for your system.
[root@client1 ~]# ipa-getkeytab -s server.example.fake -p nfs/client1.example.fake -k /etc/krb5.keytab Keytab successfully retrieved and stored in: /etc/krb5.keytab
Check your results:
[root@client1 ~]# klist -ke /etc/krb5.keytab ...
Turn on "Secure NFS" on both client(s) and server
This turns on NFS secure mounts and enables rpc.gssd and rpc.svcgssd services.
Edit these lines in file "/etc/sysconfig/nfs":
# Set to turn on Secure NFS mounts. SECURE_NFS="yes" # Optional arguments passed to rpc.gssd. See rpc.gssd(8) RPCGSSDARGS="-vvv" # Optional arguments passed to rpc.svcgssd. See rpc.svcgssd(8) RPCSVCGSSDARGS="-vvv"
The -vvv flags are for better debugging output in file "/var/log/messages".
To pick up the changes, you must restart nfs services:
[root@client1 ~]# service nfs restart Restarting nfs (via systemctl): [ OK ] [root@client1 ~]# service rpcgssd restart Restarting rpcgssd (via systemctl): [ OK ] [root@client1 ~]# service rpcsvcgssd restart Restarting rpcsvcgssd (via systemctl): [ OK ]
This must be run on both clients and servers.
Hosts' full DNS name in /etc/hosts
nfs-util program 'rpc.gssd' (or is this kerberos?) requires that the full dns name of the host be in /etc/hosts. The full DNS name must be the only entry on that line.
On the server:
[root@server ~]# cat /etc/hosts 127.0.0.1 localhost localhost.localdomain localhost4 localhost4.localdomain4 ::1 localhost localhost.localdomain localhost6 localhost6.localdomain6 192.168.56.20 server.example.fake
This must be done on the client(s) as well:
[root@client1 ~]# cat /etc/hosts 127.0.0.1 localhost localhost.localdomain localhost4 localhost4.localdomain4 ::1 localhost localhost.localdomain localhost6 localhost6.localdomain6 192.168.56.40 client1.example.fake
Set up /etc/exports on the server
Edit file "/etc/exports". This makes one krb5 mountpoint of /export to be mounted as "/" or "/export".
/export *(rw,sec=krb5,no_subtree_check,no_root_squash)
Restart nfs:
[root@server ~]# service nfs restart Restarting nfs (via systemctl): [ OK ]
Now exportfs should show the mount:
[root@server ~]# exportfs -av exportfs: scandir /etc/exports.d: No such file or directory exporting *:/export
For Older Systems: Allow Kerberos to use "weak crypto"
If you didn't force des-cbc-crc, you can skip this section.
If you needed to use -e des-cbc-crc, you'll have to edit the /etc/krb5.conf on the server and client(s).
Edit file '/etc/krb5.conf':
In section "libdefaults", add the line:
allow_weak_crypto = true
The "libdefaults" section should look something like this:
[libdefaults] default_realm = EXAMPLE.FAKE dns_lookup_realm = false dns_lookup_kdc = false rdns = false ticket_lifetime = 24h forwardable = yes allow_weak_crypto = true
Mount the filesystem
The moment of truth! If you run in to problems, see Problems Mounting.
On a client, run mount with -o sec=krb5:
[root@client1 ~]# mount -v -t nfs4 -o sec=krb5 server.example.fake:/ /mnt mount.nfs4: timeout set for Tue Jul 19 22:36:46 2011 mount.nfs4: trying text-based options 'sec=krb5,addr=192.168.56.20,clientaddr=192.168.56.40' server.example.fake:/ on /mnt type nfs4 (rw,sec=krb5)
Now test it:
[root@client1 ~]# echo "test" > /mnt/example.com [root@client1 ~]# cat /mnt/example.com test
Test the NFS mount as another user
This section covers testing the NFS mount with other users.
Add another user
First, we need to add another user to FreeIPA.
This must be run with credentials. On the server, run:
[root@server ~]# ipa user-add someguy First name: guy Last name: someone -------------------- Added user "someguy" -------------------- User login: someguy First name: guy Last name: someone Full name: guy someone Display name: guy someone Initials: gs Home directory: /home/someguy GECOS field: guy someone Login shell: /bin/sh Kerberos principal: someguy@EXAMPLE.FAKE UID: 25400004
Now set a temporary password for the user. The first time the user logs in, they must change it to something new.
[root@server ~]# ipa passwd someguy Password: Enter Password again to verify: ------------------------------------------- Changed password for "someguy@EXAMPLE.FAKE" -------------------------------------------
Test NFS
Now there is a new user on the client(s)!
[root@client1 ~]# su someguy sh-4.2$ id uid=25400004(someguy) gid=25400004(someguy) groups=25400004(someguy),25400001(ipausers) context=unconfined_u:unconfined_r:unconfined_t:s0-s0:c0.c1023
Authenticate as the user:
sh-4.2$ kinit Password for someguy@EXAMPLE.FAKE: Password expired. You must change it now. Enter new password: Enter it again:
Now test NFS:
sh-4.2$ echo bar > /mnt/foo sh-4.2$ cat /mnt/foo bar sh-4.2$ ls -l /mnt total 12 -rw-r--r--. 1 nobody nobody 4 Jul 19 17:22 bar -rw-r--r--. 1 nobody nobody 5 Jul 19 22:35 example.com -rw-r--r--. 1 someguy someguy 4 Jul 19 22:44 foo