Set up enterprise-grade encrypted network storage by combining LUKS disk encryption with NFS file sharing. This advanced configuration provides secure, centralized file access across multiple systems while maintaining data protection at rest.
Prerequisites
- Root access to server
- Additional storage device for encryption
- Network connectivity between server and clients
- Basic understanding of Linux file systems and networking
What this solves
This tutorial configures encrypted network storage using LUKS (Linux Unified Key Setup) and NFS (Network File System) to create secure, centralized file sharing. You'll combine disk-level encryption with network file sharing to protect sensitive data both at rest and in transit across multiple systems.
Step-by-step configuration
Update system packages and install required tools
Start by updating your package manager and installing the cryptsetup utilities for LUKS and NFS server components.
sudo apt update && sudo apt upgrade -y
sudo apt install -y cryptsetup nfs-kernel-server nfs-common
Prepare the storage device for encryption
Identify your target storage device and initialize it with LUKS encryption. Replace /dev/sdb with your actual device path.
sudo lsblk
sudo cryptsetup luksFormat /dev/sdb
Enter a strong passphrase when prompted. This passphrase encrypts your entire storage device.
Open the encrypted device and create filesystem
Unlock the LUKS container and create an ext4 filesystem on the encrypted volume.
sudo cryptsetup luksOpen /dev/sdb encrypted_storage
sudo mkfs.ext4 /dev/mapper/encrypted_storage
Create mount point and configure persistent mounting
Create the directory where your encrypted storage will be mounted and configure automatic mounting on boot.
sudo mkdir -p /mnt/encrypted_nfs
sudo mount /dev/mapper/encrypted_storage /mnt/encrypted_nfs
Create key file for automatic unlocking
Generate a key file to automatically unlock the encrypted volume on boot without manual password entry.
sudo dd if=/dev/urandom of=/etc/luks-keys/storage.key bs=1024 count=4
sudo chmod 400 /etc/luks-keys/storage.key
sudo cryptsetup luksAddKey /dev/sdb /etc/luks-keys/storage.key
Configure crypttab for automatic decryption
Add the encrypted device to crypttab so it automatically unlocks during boot using the key file.
encrypted_storage /dev/sdb /etc/luks-keys/storage.key luks
Configure fstab for automatic mounting
Add the decrypted volume to fstab for automatic mounting after decryption.
echo '/dev/mapper/encrypted_storage /mnt/encrypted_nfs ext4 defaults 0 2' | sudo tee -a /etc/fstab
Create NFS export directories and set permissions
Create subdirectories within the encrypted storage for different NFS exports and configure appropriate permissions.
sudo mkdir -p /mnt/encrypted_nfs/shared
sudo mkdir -p /mnt/encrypted_nfs/private
sudo chown nobody:nogroup /mnt/encrypted_nfs/shared
sudo chown nobody:nogroup /mnt/encrypted_nfs/private
sudo chmod 755 /mnt/encrypted_nfs/shared
sudo chmod 750 /mnt/encrypted_nfs/private
Configure NFS exports
Define which directories are exported via NFS and specify client access controls in the exports configuration.
/mnt/encrypted_nfs/shared 192.168.1.0/24(rw,sync,no_subtree_check,no_root_squash)
/mnt/encrypted_nfs/private 192.168.1.100(rw,sync,no_subtree_check,no_root_squash)
Replace the IP addresses and subnets with your actual network configuration. The shared directory allows access from the entire subnet, while private restricts access to a single host.
Enable and start NFS services
Enable the NFS server daemon and export the configured directories to make them available to network clients.
sudo systemctl enable --now nfs-kernel-server
sudo exportfs -ra
sudo systemctl status nfs-kernel-server
Configure firewall rules for NFS
Open the necessary ports for NFS communication. NFS requires multiple ports for different services.
sudo ufw allow from 192.168.1.0/24 to any port nfs
sudo ufw allow from 192.168.1.0/24 to any port 111
sudo ufw allow from 192.168.1.0/24 to any port 2049
sudo ufw reload
Configure NFS client systems
On client systems that need to access the encrypted NFS storage, install NFS client packages and create mount points.
sudo apt install -y nfs-common
sudo mkdir -p /mnt/nfs_shared
sudo mkdir -p /mnt/nfs_private
Mount NFS shares on client systems
Mount the encrypted NFS shares on client systems and configure persistent mounting.
sudo mount -t nfs 192.168.1.10:/mnt/encrypted_nfs/shared /mnt/nfs_shared
sudo mount -t nfs 192.168.1.10:/mnt/encrypted_nfs/private /mnt/nfs_private
Add these mounts to /etc/fstab on client systems for persistence:
192.168.1.10:/mnt/encrypted_nfs/shared /mnt/nfs_shared nfs defaults 0 0
192.168.1.10:/mnt/encrypted_nfs/private /mnt/nfs_private nfs defaults 0 0
Configure performance optimization
Optimize NFS performance by tuning mount options and server parameters for better throughput and reduced latency.
sudo mount -o remount,rsize=1048576,wsize=1048576,hard,intr /mnt/nfs_shared
Update the fstab entries with optimized mount options:
192.168.1.10:/mnt/encrypted_nfs/shared /mnt/nfs_shared nfs rsize=1048576,wsize=1048576,hard,intr 0 0
Set up automated backup procedures
Create backup scripts to regularly backup the encrypted storage and NFS configuration files.
#!/bin/bash
Backup encrypted NFS data and configuration
BACKUP_DIR="/backup/nfs-$(date +%Y%m%d)"
mkdir -p "$BACKUP_DIR"
Backup NFS data
rsync -av /mnt/encrypted_nfs/ "$BACKUP_DIR/data/"
Backup configuration files
cp /etc/exports "$BACKUP_DIR/exports"
cp /etc/fstab "$BACKUP_DIR/fstab"
cp /etc/crypttab "$BACKUP_DIR/crypttab"
Create LUKS header backup
cryptsetup luksHeaderBackup /dev/sdb --header-backup-file "$BACKUP_DIR/luks-header-backup"
Compress backup
tar -czf "/backup/encrypted-nfs-$(date +%Y%m%d).tar.gz" -C /backup "nfs-$(date +%Y%m%d)"
rm -rf "$BACKUP_DIR"
sudo chmod +x /etc/cron.daily/backup-encrypted-nfs
Verify your setup
Test that your encrypted NFS storage is working correctly by checking the encryption status, NFS exports, and client connectivity.
# Check LUKS encryption status
sudo cryptsetup status encrypted_storage
Verify NFS exports
sudo exportfs -v
Test NFS connectivity from client
showmount -e 192.168.1.10
Check mounted filesystems
df -h | grep encrypted
df -h | grep nfs
Test file operations
echo "test file" | sudo tee /mnt/encrypted_nfs/shared/test.txt
cat /mnt/nfs_shared/test.txt
Security hardening
Enable NFS over TLS (NFSv4.2)
Configure transport layer security for NFS connections to encrypt data in transit.
[nfsd]
vers4.2=y
xprtsec=tls
[gssd]
use-gss-proxy=1
Configure Kerberos authentication
Set up Kerberos authentication for stronger access controls on NFS shares.
/mnt/encrypted_nfs/shared 192.168.1.0/24(rw,sync,sec=krb5p,no_subtree_check)
/mnt/encrypted_nfs/private 192.168.1.100(rw,sync,sec=krb5p,no_subtree_check)
Implement access logging
Enable comprehensive logging for NFS access monitoring and security auditing.
# NFS logging configuration
kern.* /var/log/nfs.log
daemon.* /var/log/nfs.log
sudo systemctl restart rsyslog
Performance optimization
Tune NFS server threads
Optimize the number of NFS server threads based on expected concurrent client connections.
RPCNFSDCOUNT=16
RPCMOUNTDOPTS="--manage-gids -p 2000"
Configure kernel parameters for NFS performance
Tune kernel parameters to optimize NFS performance for your workload.
# Increase NFS performance
net.core.rmem_default = 262144
net.core.rmem_max = 16777216
net.core.wmem_default = 262144
net.core.wmem_max = 16777216
net.ipv4.tcp_rmem = 4096 65536 16777216
net.ipv4.tcp_wmem = 4096 65536 16777216
sudo sysctl --system
Disaster recovery procedures
Create disaster recovery documentation
Document the recovery process for your encrypted NFS setup including key locations and restore procedures.
# Encrypted NFS Disaster Recovery
Recovery Steps
- Restore LUKS header: cryptsetup luksHeaderRestore /dev/sdb --header-backup-file luks-header-backup
- Unlock device: cryptsetup luksOpen /dev/sdb encrypted_storage
- Mount filesystem: mount /dev/mapper/encrypted_storage /mnt/encrypted_nfs
- Restore configuration files: /etc/exports, /etc/fstab, /etc/crypttab
- Restart NFS services
Key Files
- LUKS key: /etc/luks-keys/storage.key
- NFS exports: /etc/exports
- Mount config: /etc/fstab
- Crypt config: /etc/crypttab
Test recovery procedures
Regularly test your disaster recovery procedures to ensure they work when needed.
# Test LUKS header backup
sudo cryptsetup luksHeaderBackup /dev/sdb --header-backup-file /tmp/test-header
Verify backup integrity
sudo cryptsetup luksHeaderRestore /dev/sdb --header-backup-file /tmp/test-header --test-passphrase
Clean up test files
rm /tmp/test-header
Common issues
| Symptom | Cause | Fix |
|---|---|---|
| NFS mount fails with "access denied" | Incorrect export configuration or firewall blocking | Check /etc/exports syntax and verify firewall rules with sudo exportfs -ra |
| LUKS device won't unlock on boot | Missing or incorrect key file permissions | Verify key file exists at /etc/luks-keys/storage.key with chmod 400 |
| Poor NFS performance | Suboptimal mount options or network configuration | Use rsize=1048576,wsize=1048576 mount options and check network MTU |
| "Device or resource busy" during umount | Active processes using the mounted filesystem | Use sudo lsof /mnt/encrypted_nfs to find processes, then sudo fuser -km /mnt/encrypted_nfs |
| NFS exports not visible to clients | NFS services not running or ports blocked | Check sudo systemctl status nfs-kernel-server and verify ports 111, 2049 are open |
Next steps
- Implement Linux file system encryption with LUKS and cryptsetup for more advanced LUKS configurations
- Configure network-attached storage backup with NFS and encryption for automated backup strategies
- Configure advanced iptables firewall rules to secure NFS traffic with granular controls
- Set up NFS high availability cluster with failover for production-ready redundancy
- Implement Kerberos authentication for NFS shares for enterprise security requirements
Running this in production?
Automated install script
Run this to automate the entire setup
#!/usr/bin/env bash
set -euo pipefail
# Colors for output
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
BLUE='\033[0;34m'
NC='\033[0m'
# Script configuration
SCRIPT_NAME="$(basename "$0")"
TOTAL_STEPS=12
# Default configuration
DEFAULT_DEVICE=""
DEFAULT_MOUNT_POINT="/mnt/encrypted_nfs"
DEFAULT_NETWORK="192.168.1.0/24"
DEFAULT_PRIVATE_HOST="192.168.1.100"
# Variables
DEVICE=""
MOUNT_POINT="$DEFAULT_MOUNT_POINT"
NETWORK="$DEFAULT_NETWORK"
PRIVATE_HOST="$DEFAULT_PRIVATE_HOST"
usage() {
cat << EOF
Usage: $SCRIPT_NAME -d DEVICE [OPTIONS]
Configure encrypted network storage with LUKS and NFS
Required:
-d DEVICE Block device to encrypt (e.g., /dev/sdb)
Optional:
-m MOUNT_POINT Mount point (default: $DEFAULT_MOUNT_POINT)
-n NETWORK NFS client network (default: $DEFAULT_NETWORK)
-p PRIVATE_HOST Private host IP (default: $DEFAULT_PRIVATE_HOST)
-h Show this help
Example:
$SCRIPT_NAME -d /dev/sdb -n 10.0.0.0/24 -p 10.0.0.50
EOF
}
log() {
echo -e "${GREEN}[INFO]${NC} $1"
}
warn() {
echo -e "${YELLOW}[WARN]${NC} $1"
}
error() {
echo -e "${RED}[ERROR]${NC} $1" >&2
}
step() {
echo -e "\n${BLUE}[$1/$TOTAL_STEPS]${NC} $2"
}
cleanup() {
error "Script failed. Cleaning up..."
# Unmount if mounted
if mountpoint -q "$MOUNT_POINT" 2>/dev/null; then
umount "$MOUNT_POINT" || true
fi
# Close LUKS container if open
if [ -e /dev/mapper/encrypted_storage ]; then
cryptsetup luksClose encrypted_storage || true
fi
}
trap cleanup ERR
# Parse arguments
while getopts "d:m:n:p:h" opt; do
case $opt in
d) DEVICE="$OPTARG" ;;
m) MOUNT_POINT="$OPTARG" ;;
n) NETWORK="$OPTARG" ;;
p) PRIVATE_HOST="$OPTARG" ;;
h) usage; exit 0 ;;
*) usage; exit 1 ;;
esac
done
# Validate required arguments
if [ -z "$DEVICE" ]; then
error "Device is required"
usage
exit 1
fi
# Check prerequisites
step 1 "Checking prerequisites"
if [ "$EUID" -ne 0 ]; then
error "This script must be run as root"
exit 1
fi
if [ ! -b "$DEVICE" ]; then
error "Device $DEVICE does not exist or is not a block device"
exit 1
fi
if mountpoint -q "$DEVICE" 2>/dev/null; then
error "Device $DEVICE is currently mounted"
exit 1
fi
# Detect distribution
if [ -f /etc/os-release ]; then
. /etc/os-release
case "$ID" in
ubuntu|debian)
PKG_MGR="apt"
PKG_INSTALL="apt install -y"
PKG_UPDATE="apt update && apt upgrade -y"
NFS_SERVER_PKG="nfs-kernel-server"
NFS_SERVICE="nfs-kernel-server"
FIREWALL_CMD="ufw"
;;
almalinux|rocky|centos|rhel|ol|fedora)
PKG_MGR="dnf"
PKG_INSTALL="dnf install -y"
PKG_UPDATE="dnf update -y"
NFS_SERVER_PKG="nfs-utils"
NFS_SERVICE="nfs-server"
FIREWALL_CMD="firewall-cmd"
;;
amzn)
PKG_MGR="yum"
PKG_INSTALL="yum install -y"
PKG_UPDATE="yum update -y"
NFS_SERVER_PKG="nfs-utils"
NFS_SERVICE="nfs-server"
FIREWALL_CMD="firewall-cmd"
;;
*)
error "Unsupported distribution: $ID"
exit 1
;;
esac
else
error "Cannot detect distribution"
exit 1
fi
log "Detected distribution: $ID"
log "Using device: $DEVICE"
log "Mount point: $MOUNT_POINT"
# Update system and install packages
step 2 "Updating system and installing packages"
$PKG_UPDATE
$PKG_INSTALL cryptsetup $NFS_SERVER_PKG
# Create key directory
step 3 "Creating LUKS key directory"
mkdir -p /etc/luks-keys
chmod 700 /etc/luks-keys
# Format device with LUKS
step 4 "Formatting device with LUKS encryption"
warn "This will destroy all data on $DEVICE"
read -p "Continue? (y/N): " -r
if [[ ! $REPLY =~ ^[Yy]$ ]]; then
error "Aborted by user"
exit 1
fi
cryptsetup luksFormat "$DEVICE"
# Open encrypted device
step 5 "Opening encrypted device"
cryptsetup luksOpen "$DEVICE" encrypted_storage
# Create filesystem
step 6 "Creating ext4 filesystem"
mkfs.ext4 /dev/mapper/encrypted_storage
# Create mount point and mount
step 7 "Creating mount point and mounting"
mkdir -p "$MOUNT_POINT"
mount /dev/mapper/encrypted_storage "$MOUNT_POINT"
# Create key file for automatic unlocking
step 8 "Creating key file for automatic unlocking"
dd if=/dev/urandom of=/etc/luks-keys/storage.key bs=1024 count=4
chmod 400 /etc/luks-keys/storage.key
cryptsetup luksAddKey "$DEVICE" /etc/luks-keys/storage.key
# Configure crypttab
step 9 "Configuring crypttab for automatic decryption"
echo "encrypted_storage $DEVICE /etc/luks-keys/storage.key luks" >> /etc/crypttab
# Configure fstab
step 10 "Configuring fstab for automatic mounting"
echo "/dev/mapper/encrypted_storage $MOUNT_POINT ext4 defaults 0 2" >> /etc/fstab
# Create NFS directories
step 11 "Creating and configuring NFS directories"
mkdir -p "$MOUNT_POINT"/{shared,private}
chown nobody:nogroup "$MOUNT_POINT"/{shared,private}
chmod 755 "$MOUNT_POINT/shared"
chmod 750 "$MOUNT_POINT/private"
# Configure NFS exports
cat > /etc/exports << EOF
$MOUNT_POINT/shared $NETWORK(rw,sync,no_subtree_check,no_root_squash)
$MOUNT_POINT/private $PRIVATE_HOST(rw,sync,no_subtree_check,no_root_squash)
EOF
# Start and enable NFS service
systemctl enable --now "$NFS_SERVICE"
exportfs -ra
# Configure firewall
step 12 "Configuring firewall for NFS"
if [ "$FIREWALL_CMD" = "ufw" ]; then
ufw allow from "$NETWORK" to any port nfs
ufw allow from "$NETWORK" to any port 111
ufw allow from "$NETWORK" to any port 2049
elif [ "$FIREWALL_CMD" = "firewall-cmd" ]; then
firewall-cmd --permanent --add-service=nfs
firewall-cmd --permanent --add-service=rpc-bind
firewall-cmd --permanent --add-service=mountd
firewall-cmd --reload
fi
# Verification
echo -e "\n${GREEN}=== Verification ===${NC}"
log "Checking encrypted device status:"
cryptsetup status encrypted_storage
log "Checking mount status:"
df -h "$MOUNT_POINT"
log "Checking NFS service status:"
systemctl status "$NFS_SERVICE" --no-pager -l
log "Checking NFS exports:"
exportfs -v
log "Testing NFS directories:"
ls -la "$MOUNT_POINT"
echo -e "\n${GREEN}=== Installation Complete ===${NC}"
log "Encrypted NFS storage is now configured and running"
log "Shared directory: $MOUNT_POINT/shared (accessible from $NETWORK)"
log "Private directory: $MOUNT_POINT/private (accessible from $PRIVATE_HOST)"
log "Mount clients with: sudo mount -t nfs SERVER_IP:$MOUNT_POINT/shared /local/mount/point"
Review the script before running. Execute with: bash install.sh