Mount Windows (CIFS) shares on Linux with credentials in a secure way

In almost all cases, when mounting a CIFS-share on a Linux host, you will need to supply some credentials. Either you could enter the credentials by hand every time you need the share or add the credentials to /etc/fstab to automatically mount the share. Entering the password manually is secure but not comfortable, leaving the password in /etc/fstab is comfortable but not secure since the file /etc/fstab is world readable.

Generally, it’s a good idea to password protect shares since you don’t want everyone to freely have access to a share. The “problem” you have with that, if you want to automatically mount the share on your Linux-system, is that the password needs to be saved somewhere or entered manually. For obvious reasons, entering the password every time you need the share isn’t very convenient. Especially not when you want the share to be automatically mounted on boot. This article is about how to avoid manually mounting a Windows share and still keep the credentials secure.

Installing CIFS support

A share created on a Windows-machine can be used on a Linux box by using the CIFS file system. CIFS (Common Internet File System) is a dialect of SMB (Server Message Block).

First thing to do before we are able to use a CIFS-share on our Linux machine is to make sure that it understands how to talk CIFS and thus has support for the CIFS file system.

To check which file systems are supported on your machine:

[jensd@cen ~]$ cat /proc/filesystems
nodev sysfs
nodev rootfs
nodev bdev
nodev proc
nodev cgroup
nodev cpuset
nodev tmpfs
nodev devtmpfs
nodev debugfs
nodev securityfs
nodev sockfs
nodev pipefs
nodev anon_inodefs
nodev configfs
nodev devpts
nodev ramfs
nodev hugetlbfs
nodev autofs
nodev pstore
nodev mqueue
nodev selinuxfs
 xfs
nodev rpc_pipefs
nodev nfsd
nodev binfmt_misc

As you can see in the above list, CIFS is not there. This means that we’ll have to install the necessary packages to support CIFS. In case you were wondering (as I did), the nodev option means that such filesystem doesn’t require a block device but can be used as a virtual fs.

To install CIFS-support on RHEL/CentOS/SL and variants:

[jensd@cen ~]$ sudo yum install cifs-utils
 ...
 Complete!

For Debian/Ubuntu/Mint and variants:

jensd@deb:~$ sudo apt-get install cifs-utils

When checking the entries in /proc/filesystems after installation, you should see CIFS:

[jensd@cen ~]$ cat /proc/filesystems |grep cifs
nodev cifs

On some Linux distro’s, filesystems do not appear in /proc/filesystems before the first use, even if it’s installed. In that case you can check which kernel modules are available for filesystems:

To look at the full list:

[jensd@cen ~]$ ls /lib/modules/$(uname -r)/kernel/fs/*/*ko
/lib/modules/3.10.0-123.el7.x86_64/kernel/fs/btrfs/btrfs.ko
/lib/modules/3.10.0-123.el7.x86_64/kernel/fs/cachefiles/cachefiles.ko
/lib/modules/3.10.0-123.el7.x86_64/kernel/fs/cifs/cifs.ko
/lib/modules/3.10.0-123.el7.x86_64/kernel/fs/cramfs/cramfs.ko
/lib/modules/3.10.0-123.el7.x86_64/kernel/fs/dlm/dlm.ko
/lib/modules/3.10.0-123.el7.x86_64/kernel/fs/exofs/libore.ko
/lib/modules/3.10.0-123.el7.x86_64/kernel/fs/ext4/ext4.ko
/lib/modules/3.10.0-123.el7.x86_64/kernel/fs/fat/fat.ko
/lib/modules/3.10.0-123.el7.x86_64/kernel/fs/fat/msdos.ko
/lib/modules/3.10.0-123.el7.x86_64/kernel/fs/fat/vfat.ko
...

To look for CIFS-support:

[jensd@cen ~]$ ls /lib/modules/$(uname -r)/kernel/fs/*/*ko|grep cifs
/lib/modules/3.10.0-123.el7.x86_64/kernel/fs/cifs/cifs.ko

Mount the CIFS share manually

After installing the packages and checking the filesystem support, our system should be able to mount a Windows/CIFS-share. The best way to be sure is simply to mount a CIFS-share:

 [jensd@cen ~]$ sudo mount -t cifs //192.168.202.2/drive_e /mnt -o user=jensd
Password for jensd@//192.168.202.2/drive_e: **********
[jensd@cen ~]$ mount
...
//192.168.202.2/drive_e on /mnt type cifs (rw,relatime,vers=1.0,cache=strict,username=jensd,domain=TEST,uid=0,noforceuid,gid=0,noforcegid,addr=192.168.202.2,file_mode=0755,dir_mode=0755,nounix,rsize=61440,wsize=65536,actimeo=1)

As you can see in the above output, we had to enter the password manually when mounting. To avoid entering the password, it is possible, next to the username, to supply the password directly on the command but this means it’s readable by everyone looking at your screen or previously entered commands.

Automatically mount the CIFS share

What we really want is to automatically mount the share on boot. For that, we basically have two options:

  • The first option is to create a small script with the above mount-command, including the password, and let it run on boot. The positive thing with this option would be that the script can be protected from being read by other users by changing the permissions. The negative part is that a simple mount or re-mount won’t work anymore since our mountpoint isn’t in /etc/fstab and that this isn’t really considered as a best practice solution.
  • The second, and best, option, is to add the mountpoint to /etc/fstab. The only problem we have there is that we will have to find a way to supply the credentials. The file /etc/fstab is readable by everyone, so to put the password directly in /etc/fstab isn’t really a good idea.

To continue with the second option, we’ll provide the credentials required in an external file. The file only contains the required username and password and we can restrict the file to be only readable by root. The fstab-entry contains only the path to the file.

The file providing the credentials which is made only readable by root:

[jensd@cen ~]$ sudo vi /root/.smbcred
[jensd@cen ~]$ sudo cat /root/.smbcred
username=jensd
password=secret
[jensd@cen ~]$ sudo chmod 400 /root/.smbcred
[jensd@cen ~]$ sudo ls -al /root/.smbcred
-r--------. 1 root root 36 Sep 9 15:43 /root/.smbcred

The line to automatically mount the share on boot in /etc/fstab:

[jensd@cen ~]$ cat /etc/fstab|grep /mnt
//192.168.202.2/drive_e  /mnt  cifs  credentials=/root/.smbcred  0 0

The line in /etc/fstab consists out of 6 parts:

  • the remote location (//192.168.202.2/drive_e)
  • the local mountpoint (/mnt)
  • the type of filesystem (cifs)
  • the options (credentials=/root/.smbcred)
  • dump-option (0)
  • check/pass-option (0)

After adding the above line, we can simply mount our share without providing credentials. On top of that, the share should be mounted at boot time automatically

[jensd@cen ~]$ sudo mount /mnt/

The above seems to be a simple solution, and it is, but I still see too often that password are simply entered in /etc/fstab or that a “work-around-boot-script” is used in order to prevent other from knowing precious Windows-share passwords.

17 thoughts on “Mount Windows (CIFS) shares on Linux with credentials in a secure way

    • /etc/fstab has to be world readable so all users on the system can see the password. A separate file containing the password can be secured and unreadable for other users.

      • “Hello World” has a point. Best security practice is to never put plaintext passwords in a file. Even if a plaintext password is stored in a file that other users cannot read, it is still vulnerable to being stolen if someone gains access to the user’s account. Using the credentials file is better than /etc/fstab, but not ideal.

  1. The credentials only readable by root can be read by anyone with sudo. How do I prevent reading by anyone with sudo?

    • Most default sudo configs are set up to become root. If you don’t want someone to use sudo to become root you should edit the sudoers file
      Use visudo, so you don’t kick yourself out, like this:

      sudo visudo

      or

      sudo EDITOR=nano visudo

      if you don’t like your current editor ;)

  2. I use the credentials file, and mount manually after boot. Just comment out and clear the password parameter in credentials (# password=) and mount will prompt you for only the password, but not the username and domain. On occasions where I need to automount, say for other users, I can put the password back and change the parameter to auto in fstab. I have a sudo script that asks for the password and changes the two files back and forth. It ain’t pretty but it’s a wee little bit more secure, can survive a reboot when I’m not around, and doesn’t take too long to set up. But this really is a security hole in the OS if you have the password in the file unencrypted. OK for me because my antique NAS can’t handle encrypted passwords anyway. Seems like fstab/mount could use a special named account for this type of thing and pass the password to the NAS in whatever flavor (encrypted or not) it needed it. Hopefully new NASes are more graceful than mine.

  3. Since /etc/fstab is only required when the share is first mounted and not required until the share needs to be remounted eg after a restart or dismount. Then do not try to have the share mounted on start up. Always mount it manually. If it is not there then someone with a password to the share needs to create a credentials file and delete it once the share is mounted.

  4. Hi, thanks for this post. Question, there is typically Windows security involved when mounting a Windows shared volume to a Unix/Linux machine. can you go over the various security options? e.g.

    mount -vvv -t cifs -o credentials=/root/cred/.PreProdCredentials “//10.122.10.111/FTP Root” /PreProd

  5. What am I missing? mount command returns,
    mount: //192.168.0.5/MYWIN/Users/ShareFolder: can’t find in /etc/fstab.

  6. When I put the creds file on root, I get an error accessing it because only the root or sudo user can access it. How do I keep a creds file secure on the root and still be able to access it on boot?

  7. Thanks a lot for this VERY important info:
    I could not use mount -t cifs for the reason you gave :
    ls /lib/modules/$(uname -r)/kernel/fs/*/*ko
    my proble is that the /lib/modules/* have a grater version than the one reported by uname -r

    uname -r ==> 5.4.79+
    /lib/modules* ==> 5.4.83+ (from my memory)

    Any idea to solve the problem?

  8. Pingback: cifs login in linux .com Sign In Online Support Customer Service - gologinme.com

  9. I still don’t have an ‘ideal’ solution, however some observations. Windows shares should really only be mounted when the user logs in. There are three ways users log in. In any case, if the user haa a file in their home directory perhaps named .cifs or something equally useful, then a chron job for root could be run every minute to check to see what user’s are logged in, and execute the contents of that file.

    To secure this, the file should be marked 600 so that the user can update their credentials, but no one else can see or execute it, however root can access it in any case. Additionally, if user home folders are encrypted, not even root can see the contents of this file unless the user is logged in, so if user Abe is not logged in, Bea can’t access the file contents even with sudo privileges.

    I would also advise that another script be set up as a chron job, perhaps to be run every 10 min, that checks to see if there are any users who were logged in last time, who are no longer logged in, and unmount any shares that are attached to folders not in their home directory. Say /mnt/abe/WindowsHome or /media/bea/smbmusic.

    It is at least theoretically possible that a root script can be written that follows /var/log/auth.log and kicks off the share mounts and umount tasks based on user’s logging in and logging out there. Keep in mind though that a user may still be logged in even though the auth.log file shows that they logged out, so a part of the scripts should check to see if the mounts are already mounted at a user login, another part of the script should check to see if the user is still logged in under a separate session when they close a session.

    In any case, securing this does require adding user encrypted home directories, or folders that are locally mounted when the user loggs in that are encrypted till they log in. And as far as I can tell, none of these options are secure against Charly logging in with his own credentials via an ssh session while Abe is logged in, and scarfing the credentials via Sudo. It would be better if the credentials were stored in a user keyring. I can’t see this as being a particularily difficult process to do, but still not sure of the steps needed. One I imagine would work would be to have the decryption process validate that the mounts are not already mounted, when the script goes to decrypt the credentials with the root (or sudo) privleges, and fail. The user themselves may have access (especially if they need to update their credentials on some regular schedule) but again, I don’t have the experience with doing that.

Leave a Reply to Andrew Cancel reply

Your email address will not be published. Required fields are marked *