Ubuntu NFS Home Directory Server Setup for Horizon Linux Desktops

As part of setting up Omnissa Horizon Linux VDI desktops in my lab environment, I needed a dedicated file server to host NFS home directories for the Ubuntu VDI pool. Rather than sharing this responsibility with the existing DEM file server, I set up a separate domain-joined Ubuntu 24.04 LTS server using SSSD for AD authentication and NFS for home directory exports. SSSD is the right choice here over Samba/winbind because it produces consistent UIDs across all Linux machines in the domain, which is essential for NFS home directory ownership to work correctly. This page documents the full setup from scratch.

Environment

Servernfsserver.domain.local
IP Addressx.x.x.x/24
OSUbuntu 24.04 LTS (Noble)
Domaindomain.local
NFS VersionNFSv4
StorageOS disk used directly – no separate data disk required for lab

Why a Separate NFS Server?

The DEM file server (see Omnissa DEM – Ubuntu File Server Setup) uses Samba with winbind for AD authentication. Winbind and SSSD use different algorithms to map AD users to Linux UIDs. If you run both on the same server, you end up with UID mismatches between the file server and the VDI desktops, which causes NFS home directory ownership to break. The cleanest solution is a dedicated NFS server running SSSD only, so all machines in the environment produce identical UIDs for the same AD user.

NFS Export

Export path/srv/home/hzubtp1
PurposeHome directories for Ubuntu VDI pool
Allowed clientsVDI desktop subnet (x.x.x.0/24)

Prerequisites

  • Static IP assigned to the server
  • DNS A record and PTR record created before starting
  • Domain Administrator credentials available
  • VDI desktop subnet known (needed for NFS export restrictions)

Step 1 – OS Installation

Install Ubuntu 24.04 LTS Server with the default guided storage layout (LVM, ext4) and set the hostname during the install wizard. After installation, fix /etc/hosts — the Ubuntu installer places a loopback entry using 127.0.1.1 which needs to be replaced with the actual static IP and FQDN:

Shell
# 127.0.1.1 nfsserver
x.x.x.x nfsserver.domain.local nfsserver

Verify with:

Shell
hostname -f

Step 2 – Install Packages

Shell
sudo apt update && sudo apt upgrade -y
sudo apt install -y sssd sssd-ad sssd-tools realmd adcli krb5-user nfs-kernel-server

Step 3 – Configure Kerberos

Shell
sudo tee /etc/krb5.conf << 'EOF'
[libdefaults]
default_realm = DOMAIN.LOCAL
dns_lookup_realm = false
dns_lookup_kdc = true
[realms]
DOMAIN.LOCAL = {
kdc = dc01.domain.local
admin_server = dc01.domain.local
}
[domain_realm]
.domain.local = DOMAIN.LOCAL
domain.local = DOMAIN.LOCAL
EOF
kinit Administrator@DOMAIN.LOCAL
klist

Step 4 – Domain Join

Use realmd to join the domain. This automatically installs and configures SSSD, creates the keytab, and starts the sssd service — much cleaner than a manual domain join.

Shell
sudo realm join -U Administrator domain.local -v

Verify the join and SSSD:

Shell
realm list
sudo systemctl status sssd --no-pager
id username@domain.local

Step 5 – Configure SSSD

Edit /etc/sssd/sssd.conf to use short usernames, set the correct home directory path, and disable dynamic DNS updates which are not needed on a file server:

Shell
sudo tee /etc/sssd/sssd.conf << 'EOF'
[sssd]
domains = domain.local
config_file_version = 2
services = nss, pam
[domain/domain.local]
default_shell = /bin/bash
krb5_store_password_if_offline = True
cache_credentials = True
krb5_realm = DOMAIN.LOCAL
realmd_tags = manages-system joined-with-adcli
id_provider = ad
fallback_homedir = /home/%u
ad_domain = domain.local
use_fully_qualified_names = False
ldap_id_mapping = True
access_provider = ad
dyndns_update = False
EOF
sudo chmod 600 /etc/sssd/sssd.conf
sudo sss_cache -E
sudo systemctl restart sssd

Verify user resolution uses short names and note the UID returned — it must match the UID produced by SSSD on the VDI golden image for the same user:

id username

Step 6 – Create Home Directory Structure

Create a subfolder per VDI pool under /srv/home. Using per-pool subfolders from the start makes it easy to add more pools later without reorganising the NFS exports. The sticky bit (1770) prevents users from deleting each other’s home directories while still allowing them to create their own subfolder on first login.

Shell
sudo mkdir -p /srv/home/hzubtp1
sudo chown root:"domain users" /srv/home/hzubtp1
sudo chmod 1770 /srv/home/hzubtp1

Step 7 – Configure NFS Export

no_root_squash is required here. When a user logs in for the first time, pam_mkhomedir creates their home directory as root. Without no_root_squash, root on the client is mapped to nobody on the server and the home directory gets created with wrong ownership. With no_root_squash, the directory is created with the correct user ownership automatically.

Shell
sudo tee /etc/exports << 'EOF'
# NFS Home Directory Exports
/srv/home/hzubtp1 x.x.x.0/24(rw,sync,no_subtree_check,no_root_squash,anonuid=65534,anongid=65534)
EOF
sudo exportfs -arv
sudo exportfs -v
sudo systemctl restart nfs-server

Adding a New Pool

To add a new Ubuntu VDI pool later, create the pool subfolder on the NFS server and add the export:

Shell
sudo mkdir -p /srv/home/newpool
sudo chown root:"domain users" /srv/home/newpool
sudo chmod 1770 /srv/home/newpool
echo "/srv/home/newpool x.x.x.0/24(rw,sync,no_subtree_check,no_root_squash)" | sudo tee -a /etc/exports
sudo exportfs -arv

Then update the NFS client configuration on the new pool’s golden image to point at the new subfolder path. See the Ubuntu Desktop 24.04 Horizon Instant Clone page for details on the golden image setup.

Disclaimer: Every tips/tricks/posting I have published here, is tried and tested in different IT-solutions. It is not guaranteed to work everywhere, but is meant as a tip for other users out there. Remember, Google is your friend and don’t be afraid to steal with pride! Feel free to comment below as needed.