Status: CURRENT — 2026 CLEANUP
Last reviewed: 31 August 2026
Applies to: Debian/Ubuntu Linux mounting an SMB/CIFS share from Windows, TrueNAS, Samba or another NASThe basic
/etc/fstabmethod from my original guide is still perfectly useful. The big changes are tightening the old0777permissions, putting credentials somewhere sensible, and using systemd’s network/automount options so a slow or unavailable NAS doesn’t make boot unnecessarily cactus.
One of the first hurdles I hit when I started playing with Linux VMs was getting them to use storage sitting on my NAS.
Windows/Samba shares use SMB/CIFS, and Linux can mount them just like another filesystem. Once it’s in /etc/fstab, the VM can bring the share in automatically and applications can use a normal Linux path instead of knowing anything about SMB.
Basically:
//NAS/share
↓
mount.cifs
↓
/mnt/nas-share
↓
Linux apps / Docker / whatever other nonsense I'm running :)1. Install cifs-utils
On Debian/Ubuntu:
sudo apt update
sudo apt install cifs-utilscifs-utils provides the mount.cifs helper used by the normal Linux mount command and /etc/fstab.
2. Create a mount point
I now prefer /mnt for a system/NAS mount rather than /media, which is more commonly used for removable/user-mounted media.
sudo mkdir -p /mnt/nas-shareCall it whatever makes sense. If the share contains TV, movies or backups, use a name that future-you won’t have to decode at 2am.
3. Create a credentials file
Do not put the SMB username and password directly into /etc/fstab. It works, but now every local user that can read the file gets a free NAS password. Nice one.
Create a root-owned credentials file:
sudo install -m 600 /dev/null /etc/samba/credentials-nas
sudo nano /etc/samba/credentials-nasPut:
username=NAS_USERNAME
password=NAS_PASSWORDIf the SMB server actually uses a Windows/AD domain, add:
domain=DOMAIN_NAMEIf it doesn’t, leave domain out completely. No need to invent one for emotional support.
Double-check the file is locked down:
sudo chown root:root /etc/samba/credentials-nas
sudo chmod 600 /etc/samba/credentials-nas
sudo ls -l /etc/samba/credentials-nasYou want something equivalent to:
-rw------- 1 root root ... /etc/samba/credentials-nas4. Work out the Linux UID and GID
If you want files on the mounted share to appear owned by a particular Linux user, get that user’s numeric UID/GID:
id yourusernameFor example:
uid=1000(yourusername) gid=1000(yourusername) groups=...Use the numeric values in fstab. Numeric IDs avoid relying on name lookup while the system is mounting filesystems during boot.
5. Test the SMB mount manually first
Before permanently touching /etc/fstab, test the exact share and credentials.
sudo mount -t cifs //NAS_OR_IP/SHARE /mnt/nas-share -o credentials=/etc/samba/credentials-nas,uid=1000,gid=1000,file_mode=0660,dir_mode=0770Then:
findmnt /mnt/nas-share
ls -lah /mnt/nas-shareIf that fails, fix SMB credentials, DNS/networking or share permissions before adding it to boot. Otherwise you’re just making a broken mount more persistent 😅.
Unmount the test:
sudo umount /mnt/nas-share6. Add it to /etc/fstab
Back up fstab first because a typo here can make boot considerably more exciting than intended:
sudo cp /etc/fstab /etc/fstab.before-nas
sudo nano /etc/fstabA sensible current example:
//NAS_OR_IP/SHARE /mnt/nas-share cifs credentials=/etc/samba/credentials-nas,uid=1000,gid=1000,iocharset=utf8,file_mode=0660,dir_mode=0770,nofail,_netdev,x-systemd.automount,x-systemd.idle-timeout=10min 0 0What those options are doing
credentials=...— keeps the username/password out offstab.uid=1000,gid=1000— presents files locally as owned by that Linux UID/GID.file_mode=0660— local presentation: owner/group read + write, no access for everyone else.dir_mode=0770— owner/group can access/write directories, no access for everyone else.iocharset=utf8— sensible filename character handling.nofail— don’t fail the entire boot just because the NAS is unavailable._netdev— explicitly tells the init system this filesystem depends on networking.x-systemd.automount— creates an automount so the share is mounted when first accessed rather than blocking boot waiting for it.x-systemd.idle-timeout=10min— allows systemd to unmount it after ten minutes idle; the next access automatically mounts it again.
Don’t want the mount to idle-unmount? Remove
x-systemd.idle-timeout=10min. I like automounting because NASes and networks occasionally decide to have a little fucking nap during boot, but a permanently busy application mount won’t normally become idle anyway.
Why I removed vers=3.0
My original fstab line explicitly used:
vers=3.0That isn’t necessarily wrong, but I no longer pin a protocol version unless I have a reason to.
Modern CIFS clients can negotiate a suitable modern SMB dialect with the server. Hard-coding a version can become unnecessary baggage later when both ends support something newer.
If a particular old NAS needs a specific version, add it deliberately after checking what the server supports. Do not fall all the way back to SMB1 just to make an ancient box stop complaining — that’s a different flavour of cactus.
Why 0777 was a bit enthusiastic
The original guide used:
file_mode=0777,dir_mode=0777Which basically says “everyone gets everything”. That made permission problems disappear very efficiently because permissions themselves had also disappeared 😂.
For a single-user VM I now prefer something like:
file_mode=0660
dir_mode=0770Adjust them for your actual use case. If multiple Linux services need the mount, using a shared group and a deliberate GID is much cleaner than opening it to everybody.
Important: Linux mode bits are not your NAS ACL
This catches people constantly.
uid, gid, file_mode and dir_mode control how the SMB mount is presented to Linux locally. They do not override whatever permissions the NAS/Windows server applies to the SMB account.
If the NAS user only has read access, giving the mount file_mode=0777 does not magically make the server allow writes.
That’s why sometimes you can stare at chmod for half an hour and nothing changes. You’re arguing with the wrong bloody computer.
7. Validate fstab before rebooting
After saving /etc/fstab, reload systemd’s generated mount units:
sudo systemctl daemon-reloadCheck the file for obvious problems:
sudo findmnt --verify --verboseThen trigger the mount by accessing it:
ls /mnt/nas-share
findmnt /mnt/nas-shareIf it works now, a reboot shouldn’t contain any horrible surprises.
Troubleshooting
If it doesn’t mount, start simple:
ping NAS_OR_IP
sudo mount -v /mnt/nas-share
dmesg | tail -n 50- Permission denied: check the SMB username/password and NAS share ACL.
- Host unreachable: this is networking/DNS, not an
fstabpermission problem. - Protocol negotiation errors: check which SMB versions the NAS actually supports.
- Files appear as the wrong Linux user: check the numeric
uid/gid. - Works manually but not at boot: keep
_netdev/x-systemd.automountand check the system journal for the generated mount unit.
Using this with Docker
I generally prefer mounting the SMB share once on the Linux host and then bind-mounting the resulting local path into Docker containers.
For example:
services:
some-app:
volumes:
- /mnt/nas-share:/dataThat keeps SMB credentials and mount behaviour on the host instead of teaching five different containers how to connect to the same NAS. Fewer moving parts, fewer places for shit to break.
Old article verdict
The original approach was absolutely fine:
//NAS/share /media/mountpoint cifs credentials=/home/user/.sharelogin,... 0 0The things I’d change today are:
- Keep credentials in a root-only system location.
- Use
/mntfor the persistent NAS mount. - Don’t default everything to
0777. - Don’t pin
vers=3.0unless the server actually needs it. - Add
_netdev,nofailand systemd automounting for friendlier boot behaviour. - Test and verify
fstabbefore rebooting instead of crossing your fingers.
Same idea, just less “it works, don’t touch it” and more “it works and I actually know why now” 🙂
