×

Mount CIFS/SMB shares RW in LXD containers

One of the biggest limitations with LXD I’ve found to date is the inability to mount remote shares on unprivileged containers. While it’s still not possible at this point to mount CIFS shares from within a container directly, I’ve figured out a way to get around this by first mounting the shares on the LXD host and then using lxd config device add to mount them in my containers from there.

So continuing the recent LXD theme, in this article we’ll work through mounting CIFs shares read/write on containers.

Before we begin

This guide assumes you already have a CIFS/SMB (referred to only as CIFS in the guide) share set up and ready to mount on your LXD containers. If you don’t, set this up first.

Additionally, a container should be provisioned and ready to use. If this is not the case, create a new LXD Xenial container with the following command before continuing:

lxc launch ubuntu:xenial c1

Both the host and containers are Ubuntu 16.04 LTS.

The container name throughout this guide is c1. Please change this in any commands you copy into your own terminal.

Warning

By following this guide, any mounted CIFS shares will be visible on the LXD host and can be modified by sudo/root user(s). This method is not recommended with private shares on a shared LXD host server. Only continue if you’re happy accepting any risks associated with this configuration.

Find the UID/GID of your LXD user

Before we begin to look at mounting the share(s), the first step is to obtain the UID & GID of the user/group you wish to mount the share under within the target container.

In my testing, mounting shares either anonymously (nouser:nogroup) or under a user on the host (jason:jason) will, when mounted in the container, result in “permission denied” any time file or folder creation is attempted.

jason@c1:/media/lxd-share$ touch example
touch: cannot touch 'example': Permission denied

To obtain the root user uid, run the following command:

sudo ls -la /var/lib/lxd/containers/c1/rootfs/

This will display the ownership of the root folder . and its contents within the container. Note the uid/gid of the folder for later (in bold/red below)

jason@ubuntu-lxd-tut:~$ sudo ls -la /var/lib/lxd/containers/c1/rootfs/root
total 10
drwx------  3 100000 100000    6 May  2 12:19 .
drwxr-xr-x 22 100000 100000   22 May  2 12:10 ..
-rw-------  1 100000 100000  610 May 10 00:50 .bash_history
-rw-r--r--  1 100000 100000 3106 Oct 22  2015 .bashrc
-rw-r--r--  1 100000 100000  148 Aug 17  2015 .profile
drwx------  2 100000 100000    3 May  2 12:11 .ssh

For individual users, if you have any, we can do a simple ls -l on the home directories:

sudo ls -l /var/lib/lxd/containers/c1/rootfs/home/

jason@ubuntu-lxd-tut:~$ sudo ls -l /var/lib/lxd/containers/c1/rootfs/home/
total 1
drwxr-xr-x 2 101001 101001 6 May 10 00:28 jason
drwxr-xr-x 3 101000 101000 6 May  2 12:11 ubuntu

Again, note down the uid/gid of the user for later.

Prepare the host

Having now noted the uid/gid, we can begin setting up the LXD host. In order to mount the CIFS shares within the container, they first need to be mounted on our host.

Install cifs-utils

In order for us to mount a CIFS share, the host needs to understand what that is. We can install the package cifs-utils to achieve this:

sudo apt-get install cifs-utils

It’s a big install, consuming ~50MB on the LXD host, so may take a moment to install depending on connection speed and host resources.

Create the mount points and authentication file

For this guide we’re mounting a CIFS share requiring authentication on a mount point that doesn’t currently exist. This won’t apply to all scenarios and can be skipped/amended as necessary.

Mount points

Unless the mount point already exists, when attempting to mount a CIFS share (or any share) we’ll see an error as follows:

jason@ubuntu-lxd-tut:~$ sudo mount -a
mount: mount point /media/lxd-share does not exist

Use mkdir to create it:

sudo mkdir /media/lxd-share

Authentication file

When mounting a CIFS share that requires authentication, it’s possible to put the username and password directly into the fstab entry. However, as everyone can read this file it’s not particularly secure (so I won’t show an example).

An alternative is to create a hidden authentication file in our home directory. Permissions can then be set on this file to prevent anyone else from accessing it:

vim /home/jason/.cifscreds

Now we’ll add the CIFS credentials as follows (yes, just the two lines in an otherwise empty file):

username=jason
password=lxd-password

Then save the file and set permissions:

chmod 600 /home/jason/.cifscreds

Edit fstab

With the host now aware of how to interpret CIFS shares in fstab, our mount point set up and our credentials file created, we can now add the share to /etc/fstab as follows:

#lxd-share
//192.168.0.44/lxd-share /media/lxd-share cifs credentials=/home/jason/.cifscreds,uid=101001,gid=101001,iocharset=utf8,sec=ntlm 0 0

Where:

//192.168.0.44/lxd-share is the remote CIFS share
/media/lxd-share is the local LXD host mount point
cifs is the mount type
credentials=/home/jason/.cifscreds is our credentials file
uid=101001,gid=101001 is the uid/gid of the lxd container user

With that file saved, we should be able to mount the share using sudo mount -a

jason@ubuntu-lxd-tut:/$ sudo mount -a
jason@ubuntu-lxd-tut:/$

Finally, feel free to check the CIFS share is mounted with the correct uid/gid using ls -l /media/

jason@ubuntu-lxd-tut:/$ ls -l /media/
total 8
drwxr-xr-x  2 root   root   4096 May  1 22:27 cdrom
drwxr-xr-x+ 2 101001 101001    0 May 10 09:12 lxd-share

Mount the share in an LXD container

Now the CIFS share is mounted on the LXD host, we can use lxc config device add to mount the share as a device within our LXD container:

jason@ubuntu-lxd-tut:/$ lxc config device add c1 lxdshare disk source=/media/lxd-share path=/media/lxd-share
Device lxdshare added to c1

Where:

c1 is our LXD container
lxdshare is the unique name we’re providing for this device
disk is the device type
source=/media/lxd-share is the LXD host source file path
path=/media/lxd-share is the LXD container destination file path

Finally, we’ll log into the the LXD container with lxc exec c1 bash and make sure everything is working OK.

First, check the device exists and is assigned to the correct user with ls -l /media/

root@c1:~# ls -l /media/
total 1
drwxr-xr-x+ 2 jason jason 0 May 10 08:12 lxd-share

Now we’ll check we can read from and write to the share:

root@c1:~# ls -l /media/lxd-share/
total 5848
-rwxr--r--+ 1 jason jason 5987895 Feb 18 13:05 getting_started.pdf

root@c1:~# touch /media/lxd-share/example

root@c1:~# ls -l /media/lxd-share/
total 5848
-rw-r--r--+ 1 jason jason       0 May 10 09:35 example
-rwxr--r--+ 1 jason jason 5987895 Feb 18 13:05 getting_started.pdf

root@c1:~# rm /media/MI_SHARE/example
root@c1:~#

You can see from the output above I first checked to see what was already on the share. It’s readable.
I then created the file “example” on the share and promptly deleted it. It’s writeable.

Success!

Conclusion

As with the process of setting up LXD, ZFS and bridged networking on Ubuntu 16.04 LTS this is a little long-winded. Again though, it’s not overly complex.

I’ve been using this method for a number of months on my home lab to share several directories from my storage server to various containers. It’s stable and feels no different to any other native directory within the container.

Are you brand new to LXD? I thoroughly recommend you take a look at LXD developer Stéphane Graber’s incredible LXD blog series to get up to speed.
Ready to try something more challenging? Opt in to enable experimental fuse and ext4 mounts in on 16.04 by following this excellent guide by Seth Forshee.

Comments

There are no comments on Discuss yet, click below to leave one:

Comment
Previous comments & pings (read only)

2 responses to “Mount CIFS/SMB shares RW in LXD containers”

  1. Arne Svendsen says:

    Why do we need Google, when we have bayton.org? Last night I have followed 3 guides by Jason. Now I’m up an running with a Ubuntu VM on FreeNAS with Nextcloud in a LXD container and data from a Cifs share from FreeNAS. I’ll buy you a beer soon ?.