NAS Mount
This role manages CIFS/SMB network share mounting from NAS devices.
NAS Mount Role
Overview
This role manages CIFS/SMB network share mounting from NAS devices. It installs cifs-utils, creates mount point directories, generates secure credential files, mounts network shares with proper ownership (UID/GID), adds entries to /etc/fstab for persistence across reboots, and supports both mounting and unmounting operations for multiple NAS devices.
Purpose
- Automated NAS Mounting: Mount network shares via CIFS/SMB protocol
- Dual NAS Support: Mount multiple NAS devices (Synology DS418, Proxmox OMV)
- Secure Credentials: Store passwords in separate credential files
- Persistent Mounts: Automatic mounting via /etc/fstab
- Ownership Control: Configure UID/GID for file access
- State Management: Mount or unmount shares on demand
- Backup Storage: Provides storage for backup roles
Requirements
- Ansible 2.9 or higher
- Collection:
ansible.posix(for mount module) - NAS devices accessible via network
- CIFS/SMB shares configured on NAS
- NAS user accounts with appropriate permissions
- Ansible Vault for storing NAS passwords
- Proper sudo/root permissions on target host
What is CIFS/SMB?
CIFS (Common Internet File System) and SMB (Server Message Block) are network file sharing protocols that:
- Allow mounting remote file systems over network
- Provide file and print sharing
- Support authentication and permissions
- Compatible with Windows, Linux, NAS devices
Common use cases:
- Mounting Windows shares on Linux
- Accessing NAS storage (Synology, QNAP, etc.)
- Network backup storage
- Shared file access across systems
Role Variables
Required Variables
| Variable | Required | Description |
|---|---|---|
nas_mount_mounts | Yes | List of NAS mount configurations |
vault_nas_mount_*_password | Yes | NAS passwords in Ansible Vault |
Optional Variables
| Variable | Default | Description |
|---|---|---|
nas_mount_uid | 1001 | User ID for mount ownership |
nas_mount_gid | 1001 | Group ID for mount ownership |
nas_mount_state | mounted | Mount state (mounted/unmounted) |
Variable Details
nas_mount_mounts
List of NAS mounts to configure.
Structure:
nas_mount_mounts:
- name: nas_identifier
server: nas_ip_address
share: /share_path
mount_point: /local/mount/point
user: nas_username
password: "{{ vault_password }}"
domain: WORKGROUP
Default configuration:
nas_mount_mounts:
- name: synology-ds418
server: "{{ hostvars['synology-ds418']['ip_vlan12'] }}"
share: "/Backups"
mount_point: "/mnt/synology-ds418"
user: "backupuser"
password: "{{ vault_nas_mount_synology_ds418_backup_password }}"
domain: "WORKGROUP"
- name: prxmx-omv
server: "{{ hostvars['prxmx-omv']['ip_vlan12'] }}"
share: "/Backups"
mount_point: "/mnt/prxmx-omv"
user: "backupuser"
password: "{{ vault_nas_mount_prxmx_omv_backup_password }}"
domain: "WORKGROUP"
Field descriptions:
| Field | Required | Description |
|---|---|---|
name | Yes | Unique identifier for this mount |
server | Yes | NAS IP address or hostname |
share | Yes | Share path on NAS (e.g., /Backups) |
mount_point | Yes | Local directory to mount share |
user | Yes | CIFS/SMB username for authentication |
password | Yes | Password (from vault) |
domain | Yes | Windows domain or workgroup |
Custom example:
nas_mount_mounts:
- name: qnap-storage
server: "192.168.x.x"
share: "/Media"
mount_point: "/mnt/qnap/media"
user: "mediauser"
password: "{{ vault_qnap_media_password }}"
domain: "WORKGROUP"
- name: windows-server
server: "192.168.x.x"
share: "/SharedFiles"
mount_point: "/mnt/winserver"
user: "domain\\username"
password: "{{ vault_winserver_password }}"
domain: "COMPANY"
nas_mount_uid and nas_mount_gid
User and Group IDs for mount ownership. Files on mounted shares appear owned by this UID/GID.
Default:
nas_mount_uid: 1001
nas_mount_gid: 1001
How to find UID/GID:
# For user 'backupuser'
id backupuser
# Output: uid=1001(backupuser) gid=1001(backupuser) groups=1001(backupuser)
Example for different user:
nas_mount_uid: 1000 # Standard user UID
nas_mount_gid: 1000 # Standard user GID
nas_mount_state
Control whether shares should be mounted or unmounted.
Values:
mounted: Mount shares and add to /etc/fstabunmounted: Unmount shares, remove from /etc/fstab, cleanup
Default: mounted
Unmounting example:
nas_mount_state: unmounted
Dependencies
This role requires:
- Collection:
ansible.posix(for mount module) - Package:
cifs-utils(installed by role) - NAS devices accessible on network
- Ansible Vault for storing passwords
Example Playbook
Basic Usage
---
- name: Mount NAS Shares
hosts: backup_server
become: true
roles:
- nas_mount
Mount Custom NAS
---
- name: Mount QNAP Storage
hosts: media_server
become: true
vars:
nas_mount_mounts:
- name: qnap-media
server: "192.168.x.x"
share: "/Media"
mount_point: "/mnt/qnap"
user: "mediauser"
password: "{{ vault_qnap_password }}"
domain: "WORKGROUP"
nas_mount_uid: 1000
nas_mount_gid: 1000
roles:
- nas_mount
Unmount All Shares
---
- name: Unmount NAS Shares
hosts: backup_server
become: true
vars:
nas_mount_state: unmounted
roles:
- nas_mount
With Custom Ownership
---
- name: Mount NAS with Custom UID/GID
hosts: backup_server
become: true
vars:
nas_mount_uid: 1002 # User 'mediauser'
nas_mount_gid: 1002 # Group 'mediauser'
roles:
- nas_mount
What This Role Does
When nas_mount_state = mounted
-
Installs cifs-utils package
- Required for CIFS/SMB mounting
- Provides mount.cifs helper
-
For each NAS in nas_mount_mounts:
- Creates mount point directory (e.g.,
/mnt/synology-ds418) - Creates credentials file (
/etc/nas_creds_{name}) with mode 0600 - Mounts the share using ansible.posix.mount
- Adds to /etc/fstab for persistent mounting
- Creates mount point directory (e.g.,
When nas_mount_state = unmounted
- For each NAS in nas_mount_mounts:
- Unmounts the share
- Removes mount point directory
- Deletes credentials file
- Removes from /etc/fstab
Credential Files
Format
Role creates credential files at /etc/nas_creds_{name}:
username=backupuser
password=secret_password
domain=WORKGROUP
Security
- Location:
/etc/nas_creds_synology-ds418 - Permissions: 0600 (owner read/write only)
- Ownership: root:root
- Purpose: Avoid passwords in /etc/fstab
Why Separate Credentials Files?
Security benefits:
- Passwords not visible in
mountoutput - Passwords not in
/etc/fstab(world-readable by default) - Each mount can have different credentials
- Easy to rotate passwords (update file, remount)
/etc/fstab Entry
Role adds entries to /etc/fstab:
//192.168.x.x/Backups /mnt/synology-ds418 cifs credentials=/etc/nas_creds_synology-ds418,uid=1001,gid=1001 0 0
//192.168.x.x/Backups /mnt/prxmx-omv cifs credentials=/etc/nas_creds_prxmx-omv,uid=1001,gid=1001 0 0
Field explanation:
- Device:
//server/share(UNC path) - Mount point:
/mnt/synology-ds418 - Type:
cifs(CIFS/SMB filesystem) - Options:
credentials=...,uid=...,gid=... - Dump:
0(don’t backup with dump) - Pass:
0(don’t fsck at boot)
Mount Options
The role uses these mount options:
| Option | Value | Description |
|---|---|---|
credentials | /etc/nas_creds_{name} | Path to credentials file |
uid | 1001 (configurable) | User ID for file ownership |
gid | 1001 (configurable) | Group ID for file ownership |
Additional options (not used by role but can be added):
| Option | Description |
|---|---|
vers=3.0 | Force SMB version 3.0 |
ro | Read-only mount |
noserverino | Don’t trust server inode numbers |
noperm | Don’t check permissions |
file_mode=0644 | Set file permissions |
dir_mode=0755 | Set directory permissions |
Custom mount options example:
# In mount.yml, modify opts parameter:
opts: "credentials=/etc/nas_creds_{{ nas.name }},uid={{ nas_mount_uid }},gid={{ nas_mount_gid }},vers=3.0,noperm"
UID/GID Ownership
Why UID/GID Matters
CIFS mounts don’t preserve Linux ownership from NAS. Instead, all files appear owned by specified UID/GID.
Example:
nas_mount_uid: 1001 # User 'backupuser'
nas_mount_gid: 1001 # Group 'backupuser'
Result:
ls -la /mnt/synology-ds418/
# All files show: -rw-r--r-- 1 backupuser backupuser
Finding Correct UID/GID
# Check user's UID/GID
id username
# Example output:
# uid=1001(backupuser) gid=1001(backupuser) groups=1001(backupuser)
# Use these values in role variables
Common UID/GID Values
| User | Typical UID | Typical GID |
|---|---|---|
| root | 0 | 0 |
| First user | 1000 | 1000 |
| Second user | 1001 | 1001 |
| Service account | 999-1000 | 999-1000 |
Verifying Mounts
Check Mounted Shares
# List all mounts
mount | grep cifs
# Should show:
# //192.168.x.x/Backups on /mnt/synology-ds418 type cifs (...)
# //192.168.x.x/Backups on /mnt/prxmx-omv type cifs (...)
# Check specific mount
df -h /mnt/synology-ds418
# List files
ls -la /mnt/synology-ds418/
Check /etc/fstab
# View fstab entries
grep cifs /etc/fstab
# Should show mount configurations
Check Credentials Files
# List credential files
ls -l /etc/nas_creds_*
# Should show:
# -rw------- 1 root root /etc/nas_creds_synology-ds418
# -rw------- 1 root root /etc/nas_creds_prxmx-omv
# View credentials (as root)
cat /etc/nas_creds_synology-ds418
Test Read/Write
# Test read
ls /mnt/synology-ds418/
# Test write (as user with UID matching mount)
touch /mnt/synology-ds418/test_file.txt
# Test as different user
sudo -u backupuser touch /mnt/synology-ds418/test_file.txt
Security Considerations
- Credential Files: Protected with mode 0600 (root only)
- Passwords in Vault: Never in plaintext in playbooks
- No Logging: Tasks marked with
no_log: trueto prevent password exposure - Root Ownership: Credential files owned by root:root
- fstab Security: Passwords not in /etc/fstab (uses credentials files)
- Network Security: CIFS traffic is not encrypted (consider VPN for remote access)
- NAS Permissions: Configure appropriate ACLs on NAS side
Tags
This role does not define any tags. Use playbook-level tags if needed:
- hosts: backup_server
roles:
- nas_mount
tags:
- nas
- mount
- storage
- backup
Notes
- Role uses
/etc/fstabfor persistent mounts (survives reboots) - Credentials stored in separate files (not in fstab)
- Supports multiple NAS devices simultaneously
- Mount options include UID/GID for ownership
- Role is idempotent (safe to run multiple times)
- Unmount state removes all traces (directories, credentials, fstab entries)
- CIFS protocol requires
cifs-utilspackage
Troubleshooting
”mount error(13): Permission denied”
Cause: Invalid credentials or insufficient permissions on NAS
Solution:
# Verify credentials
cat /etc/nas_creds_synology-ds418
# Test credentials manually
smbclient //nas-ip/Backups -U username
# Check NAS permissions for user
# (verify user has access to share on NAS)
# Check credentials file exists and is readable by root
ls -l /etc/nas_creds_synology-ds418
“mount error(112): Host is down”
Cause: NAS not reachable or wrong IP
Solution:
# Test network connectivity
ping nas-ip
# Check if NAS is powered on
# Verify IP address is correct
# Test SMB port
telnet nas-ip 445
# Should connect
# Check DNS resolution
nslookup nas-hostname
“mount error(115): Operation now in progress”
Cause: Network timeout or firewall blocking
Solution:
# Check firewall allows SMB (port 445)
# On NAS and client
# Increase timeout (in mount options):
opts: "credentials=...,uid=...,gid=...,_netdev,timeo=30"
# Check network stability
ping -c 100 nas-ip
“mount.cifs: command not found”
Cause: cifs-utils not installed
Solution:
# Install manually
dnf install cifs-utils # RedHat
apt install cifs-utils # Debian
# Re-run role (should install automatically)
ansible-playbook site.yml --tags nas
Permission denied when writing to mount
Cause: UID/GID mismatch
Solution:
# Check current user UID
id username
# Check mount UID
mount | grep cifs
# Look for uid=XXXX in options
# If mismatch, update role variables:
nas_mount_uid: correct_uid
nas_mount_gid: correct_gid
# Re-run role
ansible-playbook site.yml --tags nas
Mount exists but shows empty
Cause: Mount overlaying existing directory with files
Solution:
# Unmount to see original directory
umount /mnt/synology-ds418
# Check what was hidden
ls /mnt/synology-ds418/
# Remove files if needed, remount
mount /mnt/synology-ds418
Stale mount after NAS reboot
Cause: Connection broken, mount not refreshed
Solution:
# Lazy unmount (force)
umount -l /mnt/synology-ds418
# Remount
mount /mnt/synology-ds418
# Or restart autofs if using it
systemctl restart autofs
Testing After Role Execution
Verify Packages Installed
# Check cifs-utils installed
rpm -q cifs-utils # RedHat
dpkg -l cifs-utils # Debian
Verify Mounts Active
# List CIFS mounts
mount -t cifs
# Check with df
df -h -t cifs
# Should show both NAS mounts
Test File Operations
# As user with matching UID
ls /mnt/synology-ds418/
touch /mnt/synology-ds418/test_file.txt
echo "test content" > /mnt/synology-ds418/test_file.txt
cat /mnt/synology-ds418/test_file.txt
rm /mnt/synology-ds418/test_file.txt
Verify Persistence
# Reboot system
reboot
# After reboot, check mounts
mount | grep cifs
# Should be automatically mounted via /etc/fstab
Performance Considerations
- Network Speed: Limited by network bandwidth (1 Gbps typical)
- Latency: Higher than local storage (network round-trip)
- Concurrent Access: May be slower with many simultaneous users
- NAS Performance: Depends on NAS hardware (CPU, RAM, disk speed)
Tips for better performance:
- Use Gigabit or 10 Gigabit network
- Minimize network hops (direct connection preferred)
- Use SSD storage on NAS
- Consider SMB version 3.0 for multichannel support
Best Practices
- Store passwords in Ansible Vault (never plaintext)
- Use descriptive mount names (matches NAS device name)
- Configure appropriate UID/GID (matches backup user)
- Test mounts after changes (verify read/write access)
- Monitor mount status (check for stale mounts)
- Document share purposes (backup, media, etc.)
- Use network redundancy (dual NAS for critical backups)
- Regular connectivity checks (monitor NAS availability)
- Backup credential files (part of system backup)
- Review NAS permissions (least privilege principle)
Unmounting NAS Shares
To cleanly remove NAS mounts:
---
- name: Unmount NAS Shares
hosts: backup_server
become: true
vars:
nas_mount_state: unmounted
roles:
- nas_mount
What this does:
- Unmounts all shares
- Removes mount point directories
- Deletes credential files
- Removes /etc/fstab entries
Clean system state - no traces of mounts remain.
Related Roles
This role is often used with:
- nas_mount_systemd: Alternative using systemd mount units
- docker_data_backup: Backup Docker data to NAS
- ansible_code_backup: Backup Ansible code to NAS
- centreon_clapi_backup: Backup Centreon config to NAS
Alternative: Manual Mount
If you prefer manual mounting:
# Install cifs-utils
dnf install cifs-utils
# Create mount point
mkdir /mnt/nas
# Create credentials file
cat > /etc/nas_creds << EOF
username=nasuser
password=naspassword
domain=WORKGROUP
EOF
chmod 600 /etc/nas_creds
# Mount manually
mount -t cifs //nas-ip/ShareName /mnt/nas -o credentials=/etc/nas_creds,uid=1001,gid=1001
# Add to /etc/fstab for persistence
echo "//nas-ip/ShareName /mnt/nas cifs credentials=/etc/nas_creds,uid=1001,gid=1001 0 0" >> /etc/fstab
License
MIT
Author
Created for homelab infrastructure management.