Configure network-attached storage backup with NFS and encryption

Intermediate 45 min May 10, 2026 81 views
Ubuntu 24.04 Debian 12 AlmaLinux 9 Rocky Linux 9

Set up an encrypted NFS backup server with automated backup scripts and performance monitoring. Configure LUKS encryption, NFS exports, and centralized backup management for secure enterprise storage.

Prerequisites

  • Root access to server
  • Secondary storage device or partition
  • Network connectivity between server and clients
  • At least 4GB free space for backup operations

What this solves

Network-attached storage (NAS) backup systems provide centralized, scalable backup solutions for multiple servers and workstations. This tutorial configures an NFS server with LUKS encryption to secure backup data at rest, automated backup scripts for scheduled operations, and monitoring tools to track backup performance and security events.

Step-by-step configuration

Update system and install required packages

Start by updating your system and installing NFS server components, encryption tools, and monitoring utilities.

sudo apt update && sudo apt upgrade -y
sudo apt install -y nfs-kernel-server nfs-common cryptsetup rsync cron-apt smartmontools
sudo dnf update -y
sudo dnf install -y nfs-utils cryptsetup rsync smartmontools

Create and encrypt backup storage partition

Set up LUKS encryption on your backup storage device. Replace /dev/sdb1 with your actual backup partition.

Warning: This will destroy all data on the specified partition. Ensure you have backups of any important data.
sudo cryptsetup luksFormat /dev/sdb1
sudo cryptsetup luksOpen /dev/sdb1 backup_encrypted
sudo mkfs.ext4 /dev/mapper/backup_encrypted

Configure automatic decryption on boot

Create a keyfile and configure automatic mounting to avoid manual password entry on system restart.

sudo mkdir -p /etc/luks-keys
sudo dd if=/dev/urandom of=/etc/luks-keys/backup.key bs=1024 count=4
sudo chmod 400 /etc/luks-keys/backup.key
sudo cryptsetup luksAddKey /dev/sdb1 /etc/luks-keys/backup.key

Configure crypttab for automatic decryption:

backup_encrypted /dev/sdb1 /etc/luks-keys/backup.key luks

Create mount point and configure fstab

Set up the mount point and configure automatic mounting on boot.

sudo mkdir -p /srv/nfs/backup
sudo mount /dev/mapper/backup_encrypted /srv/nfs/backup

Add the mount to fstab for persistence:

/dev/mapper/backup_encrypted /srv/nfs/backup ext4 defaults,noatime 0 2

Configure NFS server exports

Set up NFS exports with proper security options and access controls.

sudo mkdir -p /srv/nfs/backup/clients
sudo chown -R nobody:nogroup /srv/nfs/backup
sudo chmod -R 755 /srv/nfs/backup

Configure NFS exports with security restrictions:

/srv/nfs/backup 192.168.1.0/24(rw,sync,no_subtree_check,no_root_squash,secure)
/srv/nfs/backup/clients 192.168.1.0/24(rw,sync,no_subtree_check,root_squash,secure)
Note: Replace 192.168.1.0/24 with your actual network range. The secure option requires connections from ports below 1024.

Start and enable NFS services

Enable and start the NFS server services for persistent operation.

sudo systemctl enable --now nfs-kernel-server
sudo systemctl enable --now nfs-common
sudo exportfs -arv
sudo systemctl enable --now nfs-server
sudo systemctl enable --now rpcbind
sudo exportfs -arv

Configure firewall rules

Open required ports for NFS communication while maintaining security.

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 2049
sudo ufw allow from 192.168.1.0/24 to any port 111
sudo firewall-cmd --permanent --add-rich-rule="rule family=ipv4 source address=192.168.1.0/24 service name=nfs accept"
sudo firewall-cmd --permanent --add-rich-rule="rule family=ipv4 source address=192.168.1.0/24 port port=2049 protocol=tcp accept"
sudo firewall-cmd --permanent --add-rich-rule="rule family=ipv4 source address=192.168.1.0/24 port port=111 protocol=tcp accept"
sudo firewall-cmd --reload

Create automated backup script

Develop a comprehensive backup script with encryption, compression, and logging capabilities.

#!/bin/bash

NFS Backup Script with Encryption

Configuration

BACKUP_SOURCE="/home /etc /var/www" BACKUP_DEST="/srv/nfs/backup/daily" LOG_FILE="/var/log/nfs-backup.log" RETENTION_DAYS=30 ENCRYPTION_KEY="/etc/backup-encryption.key" DATE=$(date +%Y-%m-%d_%H-%M-%S)

Create encryption key if it doesn't exist

if [ ! -f "$ENCRYPTION_KEY" ]; then openssl rand -base64 32 > "$ENCRYPTION_KEY" chmod 600 "$ENCRYPTION_KEY" fi

Logging function

log_message() { echo "$(date '+%Y-%m-%d %H:%M:%S') - $1" >> "$LOG_FILE" }

Start backup

log_message "Starting backup process" mkdir -p "$BACKUP_DEST"

Perform rsync backup with compression

for source in $BACKUP_SOURCE; do if [ -d "$source" ]; then log_message "Backing up $source" rsync -avz --delete "$source" "$BACKUP_DEST/" 2>&1 | tee -a "$LOG_FILE" fi done

Create encrypted archive

log_message "Creating encrypted archive" tar -czf - "$BACKUP_DEST" | openssl enc -aes-256-cbc -salt -pass file:"$ENCRYPTION_KEY" > "$BACKUP_DEST/../backup_$DATE.tar.gz.enc"

Cleanup old backups

log_message "Cleaning up old backups" find "$BACKUP_DEST/../" -name "backup_*.tar.gz.enc" -mtime +$RETENTION_DAYS -delete

Verify backup integrity

if [ -f "$BACKUP_DEST/../backup_$DATE.tar.gz.enc" ]; then log_message "Backup completed successfully: backup_$DATE.tar.gz.enc" else log_message "ERROR: Backup failed - encrypted archive not created" exit 1 fi log_message "Backup process completed"

Make the script executable:

sudo chmod 755 /usr/local/bin/nfs-backup.sh
sudo chown root:root /usr/local/bin/nfs-backup.sh

Configure scheduled backups with cron

Set up automated backup scheduling with proper logging and error handling.

sudo crontab -e

Add the following cron entries:

# Daily backup at 2 AM
0 2   * /usr/local/bin/nfs-backup.sh

Weekly backup verification at 3 AM on Sundays

0 3 0 /usr/local/bin/verify-backups.sh

Monthly cleanup at 4 AM on the 1st

0 4 1 find /srv/nfs/backup -type f -mtime +90 -delete

Create backup verification script

Implement automated backup integrity checking and monitoring.

#!/bin/bash

Backup Verification Script

BACKUP_DIR="/srv/nfs/backup" LOG_FILE="/var/log/backup-verification.log" ENCRYPTION_KEY="/etc/backup-encryption.key" ALERT_EMAIL="admin@example.com" log_message() { echo "$(date '+%Y-%m-%d %H:%M:%S') - $1" >> "$LOG_FILE" }

Check disk space

DISK_USAGE=$(df "$BACKUP_DIR" | awk 'NR==2 {print $5}' | sed 's/%//') if [ "$DISK_USAGE" -gt 85 ]; then log_message "WARNING: Backup disk usage is ${DISK_USAGE}%" echo "Backup disk usage critical: ${DISK_USAGE}%" | mail -s "NFS Backup Alert" "$ALERT_EMAIL" fi

Verify latest encrypted backup

LATEST_BACKUP=$(find "$BACKUP_DIR" -name "backup_*.tar.gz.enc" -type f -printf '%T@ %p\n' | sort -n | tail -1 | cut -d' ' -f2-) if [ -f "$LATEST_BACKUP" ]; then log_message "Verifying backup: $LATEST_BACKUP" if openssl enc -aes-256-cbc -d -salt -pass file:"$ENCRYPTION_KEY" -in "$LATEST_BACKUP" | tar -tzf - > /dev/null 2>&1; then log_message "Backup verification successful" else log_message "ERROR: Backup verification failed" echo "Backup verification failed for $LATEST_BACKUP" | mail -s "NFS Backup Error" "$ALERT_EMAIL" fi else log_message "ERROR: No backup files found" fi

Check NFS service status

if ! systemctl is-active --quiet nfs-kernel-server 2>/dev/null && ! systemctl is-active --quiet nfs-server 2>/dev/null; then log_message "ERROR: NFS server is not running" echo "NFS server is down" | mail -s "NFS Server Alert" "$ALERT_EMAIL" fi

Make the verification script executable:

sudo chmod 755 /usr/local/bin/verify-backups.sh

Configure NFS performance monitoring

Set up monitoring for NFS performance metrics and security events.

[Unit]
Description=NFS Performance Monitor
After=nfs-kernel-server.service

[Service]
Type=forking
ExecStart=/usr/local/bin/nfs-monitor.sh
Restart=always
RestartSec=60
User=root

[Install]
WantedBy=multi-user.target

Create the monitoring script:

#!/bin/bash

NFS Performance Monitoring Script

LOG_FILE="/var/log/nfs-performance.log" MONITOR_INTERVAL=300 # 5 minutes log_metric() { echo "$(date '+%Y-%m-%d %H:%M:%S') - $1" >> "$LOG_FILE" } while true; do # Monitor NFS connections ACTIVE_CONNECTIONS=$(netstat -an | grep :2049 | grep ESTABLISHED | wc -l) log_metric "Active NFS connections: $ACTIVE_CONNECTIONS" # Monitor disk I/O DISK_IO=$(iostat -x 1 1 | awk '/sdb/ {print "Read: " $4 " Write: " $5}') log_metric "Backup disk I/O - $DISK_IO" # Monitor backup mount status if mountpoint -q /srv/nfs/backup; then log_metric "Backup mount: OK" else log_metric "ERROR: Backup mount failed" fi # Check encryption status if cryptsetup status backup_encrypted > /dev/null 2>&1; then log_metric "Encryption: Active" else log_metric "ERROR: Encryption not active" fi sleep $MONITOR_INTERVAL done

Enable the monitoring service:

sudo chmod 755 /usr/local/bin/nfs-monitor.sh
sudo systemctl enable --now nfs-monitor.service

Configure client connections

Install NFS client packages

On client machines, install NFS client tools to connect to your backup server.

sudo apt install -y nfs-common
sudo dnf install -y nfs-utils

Mount NFS backup share

Configure client machines to mount the NFS backup share.

sudo mkdir -p /mnt/backup
sudo mount -t nfs 192.168.1.100:/srv/nfs/backup/clients /mnt/backup

For persistent mounting, add to fstab:

192.168.1.100:/srv/nfs/backup/clients /mnt/backup nfs defaults,_netdev 0 0

Verify your setup

Test your NFS backup configuration and verify all components are working correctly.

# Check NFS server status
sudo systemctl status nfs-kernel-server  # Ubuntu/Debian
sudo systemctl status nfs-server         # AlmaLinux/Rocky

Verify NFS exports

sudo exportfs -v

Test NFS connectivity from server

showmount -e localhost

Check encryption status

sudo cryptsetup status backup_encrypted

Verify backup mount

df -h /srv/nfs/backup

Test backup script

sudo /usr/local/bin/nfs-backup.sh

Check backup logs

sudo tail -f /var/log/nfs-backup.log

Verify client connection (from client machine)

mount | grep nfs touch /mnt/backup/test-file.txt

Performance optimization

Optimize NFS server settings

Configure NFS server parameters for better performance with backup workloads.

RPCNFSDCOUNT=16
RPCNFSDPRIORITY=0
RPCMOUNTDOPTS="--manage-gids"
NEED_SVCGSSD=no
RPCSVCGSSDOPTS=""

For systems that need monitoring integration, you might want to configure advanced htop monitoring with custom scripts and alerting to track NFS performance metrics.

Configure network buffer optimization

Optimize network settings for large file transfers typical in backup operations.

net.core.rmem_max = 67108864
net.core.wmem_max = 67108864
net.ipv4.tcp_rmem = 4096 87380 67108864
net.ipv4.tcp_wmem = 4096 65536 67108864
net.core.netdev_max_backlog = 5000

Apply the settings:

sudo sysctl -p /etc/sysctl.d/99-nfs-performance.conf

Security hardening

Configure backup rotation and retention

Implement secure backup rotation with proper cleanup and archival policies.

#!/bin/bash

Backup Rotation Script

BACKUP_DIR="/srv/nfs/backup" ARCHIVE_DIR="/srv/nfs/backup/archive" DAILY_RETENTION=7 WEEKLY_RETENTION=4 MONTHLY_RETENTION=12

Create archive directory

mkdir -p "$ARCHIVE_DIR"/{daily,weekly,monthly}

Rotate daily backups

find "$BACKUP_DIR" -name "backup_*.tar.gz.enc" -mtime +$DAILY_RETENTION -exec mv {} "$ARCHIVE_DIR/daily/" \;

Create weekly archive (every Sunday)

if [ $(date +%u) -eq 7 ]; then LATEST_DAILY=$(find "$ARCHIVE_DIR/daily" -name "backup_*.tar.gz.enc" -type f -printf '%T@ %p\n' | sort -n | tail -1 | cut -d' ' -f2-) if [ -f "$LATEST_DAILY" ]; then cp "$LATEST_DAILY" "$ARCHIVE_DIR/weekly/weekly_$(date +%Y-%m-%d).tar.gz.enc" fi fi

Create monthly archive (1st of month)

if [ $(date +%d) -eq 01 ]; then LATEST_WEEKLY=$(find "$ARCHIVE_DIR/weekly" -name "weekly_*.tar.gz.enc" -type f -printf '%T@ %p\n' | sort -n | tail -1 | cut -d' ' -f2-) if [ -f "$LATEST_WEEKLY" ]; then cp "$LATEST_WEEKLY" "$ARCHIVE_DIR/monthly/monthly_$(date +%Y-%m).tar.gz.enc" fi fi

Cleanup old archives

find "$ARCHIVE_DIR/daily" -name "backup_*.tar.gz.enc" -mtime +30 -delete find "$ARCHIVE_DIR/weekly" -name "weekly_*.tar.gz.enc" -mtime +120 -delete find "$ARCHIVE_DIR/monthly" -name "monthly_*.tar.gz.enc" -mtime +365 -delete

Implement access logging

Enable comprehensive logging for security auditing and troubleshooting.

# NFS logging configuration
kern.* /var/log/nfs-kernel.log
daemon.* /var/log/nfs-daemon.log

Separate NFS client access logs

:msg, contains, "nfs" /var/log/nfs-access.log & stop

Restart rsyslog to apply changes:

sudo systemctl restart rsyslog

Common issues

Symptom Cause Fix
Mount fails with "Permission denied" Firewall blocking NFS ports Check firewall rules: sudo ufw status or firewall-cmd --list-all
"Stale file handle" errors NFS server restart or network issues Unmount and remount: sudo umount /mnt/backup && sudo mount /mnt/backup
Backup script fails with encryption error Missing or corrupted encryption key Recreate encryption key: sudo openssl rand -base64 32 > /etc/backup-encryption.key
Poor backup performance Network buffer sizes too small Apply network optimization settings and restart NFS services
LUKS device won't auto-mount Incorrect /etc/crypttab configuration Verify crypttab syntax and key file permissions: chmod 400 /etc/luks-keys/backup.key
NFS exports not visible Export table not refreshed Refresh exports: sudo exportfs -arv

Next steps

Running this in production?

Want this handled for you? Setting up encrypted NFS backup once is straightforward. Keeping it monitored, securing encryption keys, managing retention policies and ensuring backups are restorable across environments is the harder part. See how we run infrastructure like this for European SaaS and e-commerce teams.

Automated install script

Run this to automate the entire setup

Need help?

Don't want to manage this yourself?

We handle managed cloud infrastructure for businesses that depend on uptime. From initial setup to ongoing operations.