[TUTORIAL] Tutorial: Unprivileged LXCs - Mount CIFS shares

TheHellSite

Member
Mar 4, 2020
68
16
13
Since unprivileged LXCs are not allowed to mount CIFS shares and priviliged LXCs are considered unsafe (for a reason) I was scraping my head around how to still have my NAS shares available in my LXCs, f.e. (Jellyfin, Plex, ...).

The solution provided by the Proxmox Wiki would require many changes to the PVE host config, which I was not willing to do.
https://pve.proxmox.com/wiki/Unprivileged_LXC_containers#Using_local_directory_bind_mount_points

Thanks to the following source I was able to assemble a solution that should work for everyone in under 10 minutes.
https://bayton.org/docs/linux/lxd/mount-cifssmb-shares-rw-in-lxd-containers/


How does it work?
By default CIFS shares are mounted as user root(uid=0) and group root(gid=0) on the PVE host which makes them inaccessible to other users,groups and LXCs.
This is because UIDs/GIDs on the PVE host and LXC guests are both starting at 0. But a UID/GID=0 in an unprivileged LXC is acutally a UID/GID=100000 on the PVE host. See the above Proxmox Wiki link for more information to this.
@Jason Bayton's solution was to mount the share on the PVE host with the UID/GID of the LXC-User that is going to access the share. While this is working great for a single user it would not work for different LXCs with different users having different UIDs and GIDs. I mean it would work, but then you would have to create a single mount entry for your CIFS share for each UID/GID.

My solution is doing this slightly different and more effective I think.
You simply mount the CIFS share to the UID that belongs to the unprivileged LXC root user, which by default is always uid=100000.
But instead of also mounting it to the GID of the LXC root user, your are going to create a group in your LXC called lxc_cifs_shares with a gid=10000 which refers to gid=110000 on the PVE host.
PVE host (UID=100000/GID=110000) <--> unprivileged LXC (UID=0/GID=10000)


How to configure it

1. In the LXC (run commands as root user)

  1. Create the group "lxc_shares" with GID=10000 in the LXC which will match the GID=110000 on the PVE host.
    groupadd -g 10000 lxc_shares
  2. Add the user(s) that need access to the CIFS share to the group "lxc_shares".
    f.e.: jellyfin, plex, ... (the username depends on the application)
    usermod -aG lxc_shares USERNAME
  3. Shutdown the LXC.
2. On the PVE host (run commands as root user)
  1. Create the mount point on the PVE host.
    mkdir -p /mnt/lxc_shares/nas_rwx
  2. Add NAS CIFS share to /etc/fstab.
    _netdev Forces systemd to consider the mount unit a network mount.
    x-systemd.automount Automatically remounts the CIFS share in case the NAS went offline for some time.
    noatime Access timestamps are not updated when a file/folder is read.
    uid=100000,gid=110000 See part "How does it work?" paragraph two for explanation.
    dir_mode=0770,file_mode=0770 Only that uid/gid will have rwx access to the share. (PVE root user always has rwx to everything.)
    !!! Adjust //NAS/nas/ in the middle of the command to match your CIFS hostname (or IP) //NAS/ and the share name /nas/. !!!
    !!! Adjust user=smb_username,pass=smb_password at the end of the command. !!!

    Code:
    { echo '' ; echo '# Mount CIFS share on demand with rwx permissions for use in LXCs (manually added)' ; echo '//NAS/nas/ /mnt/lxc_shares/nas_rwx cifs _netdev,x-systemd.automount,noatime,uid=100000,gid=110000,dir_mode=0770,file_mode=0770,user=smb_username,pass=smb_password 0 0' ; } | tee -a /etc/fstab
  3. Mount the share on the PVE host.
    mount /mnt/lxc_shares/nas_rwx
  4. Add a bind mount of the share to the LXC config.
    !!! Adjust the LXC_ID at the end of the command. !!!
    Code:
    You can mount it in the LXC with read+write+execute (rwx) permissions.
    { echo 'mp0: /mnt/lxc_shares/nas_rwx/,mp=/mnt/nas' ; } | tee -a /etc/pve/lxc/LXC_ID.conf
    
    You can also mount it in the LXC with read-only (ro) permissions.
    { echo 'mp0: /mnt/lxc_shares/nas_rwx/,mp=/mnt/nas,ro=1' ; } | tee -a /etc/pve/lxc/LXC_ID.conf
  5. Start the LXC.
 
Last edited:

argylesocks

New Member
Apr 3, 2022
5
2
3
Thanks for this post, extremely helpful!

One minor addition, adding ",shared=1" to the end of the bind mount line in /etc/pve/lxc/LXC_ID.conf will enable that container to be migrated across Proxmox nodes. It basically tells Proxmox to ignore the bind mounts, and without it will refuse to migrate. Of course if you don't have those CIFS mounts on the target node, I expect something would go poorly, but I didn't test that-- with the same CIFS mounts on every node it works perfectly.
 
  • Like
Reactions: TheHellSite

magnethead

New Member
Jul 9, 2021
5
0
1
45
Hi @TheHellSite ,
Thanks for your solution, are you sure this still works in Proxmox 7? I tried to mount the CIFS share for the first time (I've being using NFS up to now, super newbie here).. I heard that CIFS shares are more secure

I CAN mount with this simple command
mount -t cifs //192.168.1.555/Plex /mnt/pve/lxc_shares/nas_rwx/ -o user=plex,pass=plex123

but trying to run your command is giving an error, and I notice, even he "CIFS" is in a different location? maybe the syntax has being updated?
root@pve:/mnt/pve/lxc_shares# mount -t //192.168.1.555/Plex /mnt/pve/lxc_shares/nas_rwx cifs _netdev,noauto,x-systemd.automount,noatime,uid=100000,gid=110000,dir_mode=0770,file_mode=0770,user=plex,pass=plex123
mount: bad usage
Try 'mount --help' for more information.

I get bad usage :( .... I have tried , rearranging with the CIFS at the start like in my simple working example....but the same 'bad usage' comes up.
Just wondering if you could help a Noob out please?
 

TheHellSite

Member
Mar 4, 2020
68
16
13
It is still working fine on PVE 7.x and should always continue to work.

My "command" is intended to be used by the fstab file! It will obviously not work when manually running it because it uses options that are only available in the fstab file.

Also the mount type "cifs" is located correctly, again only if used in the fstab file.

Just do what I wrote in the tutorial and it will work.
If you can manually mount the share using "mount - t cifs..." the remote location, local location and credentials, then those values will also work in the fstab file but only when used with my "command".
 
Last edited:

magnethead

New Member
Jul 9, 2021
5
0
1
45
Thanks for the reply :) I didn't realize fstab had different commands associated with it. I'm a linux noob.


just tested it out, and it's mounting perfectly, Fairplay to you

Is this considered safe, leaving username/password in the fstab file?
 
Last edited:

magnethead

New Member
Jul 9, 2021
5
0
1
45
I was wondering if I can push my luck with you :) as I think this might be an extension of what you are doing here.
I have the PVE host ---> LXC Container(running Docker) -----> Plex docker image

So thanks to you, I can now see the CIFS share on the LXC container, and what you described above works perfectly.
What's more, if I open a console to the 'plex docker image' and connect as root, I can see the CIFS share :D That's using Portainer to open the docker image console. (I also used portainer to bind mount, that LXC sharefolder to a folder inside the plex docker image.)
But unfortunately in the Plex application, when I go to select the share folder to link my movies , the directory doesn't appear. I guess the application is running with different rights (plex user?)

Dockers runs it's containers with PUID and PGID
Docker PUID and PGID

Do you know, if this mapping you have done from the PVE to the LXC container, could be extended to a docker container, running plex (given that it seems to have a different user/group ID system?

Thanks
 
Last edited:

TheHellSite

Member
Mar 4, 2020
68
16
13
I was wondering if I can push my luck with you :) as I think this might be an extension of what you are doing here.


So thanks to you, I can now see the CIFS share on the LXC container, and what you described above works perfectly.
What's more, if I open a console to the 'plex docker image' and connect as root, I can see the CIFS share :D That's using Portainer to open the docker image console. (I also used portainer to bind mount, that LXC sharefolder to a folder inside the plex docker image.)
But unfortunately in the Plex application, when I go to select the share folder to link my movies , the directory doesn't appear. I guess the application is running with different rights (plex user?)

Dockers runs it's containers with PUID and PGID
Docker PUID and PGID

Do you know, if this mapping you have done from the PVE to the LXC container, could be extended to a docker container, running plex (given that it seems to have a different user/group ID system?

Thanks
Sorry, but totally out of scope of this tutorial. I run plex directly in an LXC.


Is this considered safe, leaving username/password in the fstab file?
Well, you can also use a credentials file located in the root users home directory. This would be a little bit safer. There are other tutorials on how to do this.
 
  • Like
Reactions: magnethead

marcosscriven

Member
Mar 6, 2021
96
7
8
@TheHellSite - just wanted to say thanks; this worked for me, with one niggle: The 'noauto' option means `mount -a` is ignored, which confused me.

To get around this do `mount <mnt dir>`
 

lpereira

New Member
Nov 20, 2022
7
0
1
I followed this but in my LXC

Code:
lpereira@lxc:~$ sudo mkdir /mnt/nas/Media
mkdir: cannot create directory '/mnt/nas/Media': Permission denied

Can someone help me understand why I don't have permission to manage the mounted drive, even if I'm on that group share?
Code:
lpereira@lxc:~$ groups
sudo lxc_shares
 

wrotebyreuben

Active Member
Jan 31, 2017
7
0
26
35
I was wondering if I can push my luck with you :) as I think this might be an extension of what you are doing here.


So thanks to you, I can now see the CIFS share on the LXC container, and what you described above works perfectly.
What's more, if I open a console to the 'plex docker image' and connect as root, I can see the CIFS share :D That's using Portainer to open the docker image console. (I also used portainer to bind mount, that LXC sharefolder to a folder inside the plex docker image.)
But unfortunately in the Plex application, when I go to select the share folder to link my movies , the directory doesn't appear. I guess the application is running with different rights (plex user?)

Dockers runs it's containers with PUID and PGID
Docker PUID and PGID

Do you know, if this mapping you have done from the PVE to the LXC container, could be extended to a docker container, running plex (given that it seems to have a different user/group ID system?

Thanks

If anyone else is having this issue, I put the PUID and PGID of the docker images as both 0 (which is output of `id root` from the unprivileged docker host). I doubt this is best practice, better would be to add another user to host with less permissions (also added to the LXC group) and use the PUID/PGID of that.
 

TheHellSite

Member
Mar 4, 2020
68
16
13
I followed this but in my LXC

Code:
lpereira@lxc:~$ sudo mkdir /mnt/nas/Media
mkdir: cannot create directory '/mnt/nas/Media': Permission denied

Can someone help me understand why I don't have permission to manage the mounted drive, even if I'm on that group share?
Code:
lpereira@lxc:~$ groups
sudo lxc_shares
1. sudo shouldn't be necessary to create the folder.

2. Check if you are able to create a folder in the mounted share on the PVE host! If that also doesn't work than your SMB/CIFS share is misconfigured.

3. If it works on the PVE host then check if you used the right command that grants the LXC rwx permissions using the bind mount. Step 2.4 the first command gives rwx permissions and the second command gives ro permission. You will want to use the first command.
 
  • Like
Reactions: lpereira

thex

New Member
Mar 25, 2021
20
3
3
41
I ran into the same problems and was playing a bit with gid/guid mapping but it quickly becomes complex.

I followed the instructions in the first post and am wondering if "noauto" is really the right property for the fstab.
As with "noauto" set the "mount -a" does actually do nothing as "noauto" entries are ignored and have to be specifically mounted.

EDIT:
Guess the big problem with this is mounting on boot when the guest that is hosting the VM also is running on the same proxmox host...
 
Last edited:

TheHellSite

Member
Mar 4, 2020
68
16
13
I followed the instructions in the first post and am wondering if "noauto" is really the right property for the fstab.
As with "noauto" set the "mount -a" does actually do nothing as "noauto" entries are ignored and have to be specifically mounted.
You are right. I did some reading and the "noauto" option does indeed have no effect when x-systemd.automount is set.
Please also note that "noauto" being set in the fstab entry will have no negative effect on the mountpoint as it is simply ignored by systemd.
They also don't have to be specifically be mounted since the systemd automount options will mount them as soon as they are requested by a service or whatever.
https://www.freedesktop.org/software/systemd/man/systemd.mount.html#noauto

@TheHellSite - just wanted to say thanks; this worked for me, with one niggle: The 'noauto' option means `mount -a` is ignored, which confused me.

To get around this do `mount <mnt dir>`
Also as @marcosscriven pointed out mount -a will also not work and thus it is necessary to use mount /path/to/mountpoint.

I will change both points in the guide.


Guess the big problem with this is mounting on boot when the guest that is hosting the VM also is running on the same proxmox host...
However, I strongly disagree with your second point! This is not an issue at all with my guide!
As I already said, the systemd automount will mount the mountpoint as soon as a service or whatever is trying to access it.

If that is not working for you, f.e. because you have a service that is trying to access the mountpoint BEFORE the VM/LXC hosting that CIFS mountpoint is started, than you should probably restructure your PVE boot order.

I am running this just fine on many of my PVE hosts. Almost all of them are running a TrueNAS VM which is configured (boot order) to be started WAY before any other VMs/LXCs that depend on the CIFS mountpoint hosted by that TrueNAS VM.
 
Last edited:
  • Like
Reactions: thex

vargan

New Member
Dec 3, 2022
1
0
1
Thank you so much! It finally worked!
No matter what I tried before that, it just didn't show me the content of the shared folder in Jellyfin.
 

bobmorane06

New Member
Dec 17, 2022
2
0
1
I've followed the op method and I'm able to mount the share, but it only works from the pve web interface. The trick is that my SAMBA share is another LXC on the same proxmox server and at boot the CIFS share isn't ready yet as indicated in journalctl:

Code:
Dec 19 17:20:19 pve systemd[1]: mnt-shared_lxc-music.automount: Got automount request for /mnt/shared_lxc/music, triggered by 1423 (lxc-pve-prestar)
Dec 19 17:20:19 pve kernel: EXT4-fs (dm-6): mounted filesystem with ordered data mode. Opts: (null). Quota mode: none.
Dec 19 17:20:19 pve systemd[1]: Mounting /mnt/shared_lxc/music...
Dec 19 17:20:19 pve kernel: FS-Cache: Loaded
Dec 19 17:20:19 pve kernel: FS-Cache: Netfs 'cifs' registered for caching
Dec 19 17:20:19 pve mount[1430]: mount error(111): could not connect to 192.168.9.3Unable to find suitable address.
Dec 19 17:20:19 pve kernel: Key type cifs.spnego registered
Dec 19 17:20:19 pve kernel: Key type cifs.idmap registered
Dec 19 17:20:19 pve kernel: CIFS: No dialect specified on mount. Default has changed to a more secure dialect, SMB2.1 or later (e.g. SMB3.1.1), from CIFS (SMB1). To use the less secure SMB1 dialect to access old servers which do not support SMB3.1.1 (or even SMB3 or SMB2.1) specify vers=1.0 on mount.
Dec 19 17:20:19 pve kernel: CIFS: Attempting to mount \\192.168.9.3\music
Dec 19 17:20:19 pve kernel: CIFS: VFS: Error connecting to socket. Aborting operation.
Dec 19 17:20:19 pve kernel: CIFS: VFS: cifs_mount failed w/return code = -111
Dec 19 17:20:19 pve systemd[1]: mnt-shared_lxc-music.mount: Mount process exited, code=exited, status=32/n/a
Dec 19 17:20:19 pve systemd[1]: mnt-shared_lxc-music.mount: Failed with result 'exit-code'.
Dec 19 17:20:19 pve systemd[1]: Failed to mount /mnt/shared_lxc/music.
Dec 19 17:20:19 pve pve-guests[1417]: startup for container '101' failed
Dec 19 17:20:19 pve pvesh[1182]: Starting CT 101 failed: startup for container '101' failed

If I start the LXC after boot, it works fine.

I set the 1st LXC with the samba server to boot first (Options / Start/Shutdown order=1) and the LXC that needs to access the share to boot second (Options / Start/Shutdown order=2 and Startupdelay=180)

In the fstab file I also tried adding 'x-systemd.idle-timeout=1min':

Code:
//192.168.9.3/music/ /mnt/shared_lxc/music cifs _netdev,x-systemd.automount,x-systemd.idle-timeout=3min,noatime,uid=100000,gid=110000,dir_mode=0770,file_mode=0770,user=USER,pass=PASSWORD 0 0

Any suggestions?

EDIT: corrected Options / Start/Shutdown order=1 and Startupdelay=180) to Options / Start/Shutdown order=2 and Startupdelay=180)
 
Last edited:

TheHellSite

Member
Mar 4, 2020
68
16
13
Ehm.... Either you have a typo in your post or your 2nd LXC, that is trying to access the share hosted on your first LXC, is in fact NOT being started after your first LXC.

I set the 1st LXC with the samba server to boot first (Options / Start/Shutdown order=1) and the LXC that needs to access the share to boot second (Options / Start/Shutdown order=1 and Startupdelay=180)
LXC_1 is set to boot_order=1, which is what you want it to be.
BUT your LXC_2 is, based on your comment, also set to boot_order=1 which is just wrong.

You should read the PVE docs about boot order and startup delays!
You are totally getting them wrong in terms of how they work.
 

bobmorane06

New Member
Dec 17, 2022
2
0
1
It was a typo, sorry about that, I meant that LXC 2 was order = 2, no need to RTFM me. :) BTW, thanks for your great tutorial.

TLDR: It's solved by adding a delay also to LXC_1.

Here is my config in case someone someday faces the same hurdles.

PVE mounts 2 HDD ext4 partitions via fstab to then be shared with LXC 100 via bind mounts
Code:
# <file system> <mount point> <type> <options> <dump> <pass>
/dev/pve/root / ext4 errors=remount-ro 0 1
UUID=C6A9-3F35 /boot/efi vfat defaults 0 1
/dev/pve/swap none swap sw 0 0
proc /proc proc defaults 0 0

# Mount 4TB drive for use in LXCs (manually added)
UUID=fd412afe-f257-4f54-89bb-0783a41e03fd /mnt/shared_lxc/4tb ext4 defaults 0 0

# Mount 5TB drive for use in LXCs (manually added)
UUID=56ccded1-ae13-4be6-9d66-3a0169e63fb1 /mnt/shared_lxc/5tb ext4 defaults 0 0

# Mount CIFS share on demand with rwx permissions for use in LXCs (manually added)
//192.168.9.3/music/ /mnt/shared_lxc/music cifs _netdev,x-systemd.automount,x-systemd.idle-timeout=3min,noatime,uid=100000,gid=110000,dir_mode=0770,file_mode=0770,user=USER,pass=PASSWORD 0 0

LXC 100 (nas)
This is the LXC that runs the samba server, sharing folders from the 2 HDD (mp0 / mp1 below)
/etc/pve/lxc/100.conf:
Code:
arch: amd64
cores: 2
features: nesting=1
hostname: nas
memory: 2048
mp0: /mnt/shared_lxc/4tb,mp=/mnt/4tb
mp1: /mnt/shared_lxc/5tb,mp=/mnt/5tb
net0: name=eth0,bridge=vmbr0,firewall=1,gw=192.168.9.1,hwaddr=46:2E:6E:63:EA:D2,ip=192.168.9.3/24,type=veth
onboot: 1
ostype: ubuntu
rootfs: local-lvm:vm-100-disk-0,size=8G
startup: order=1,up=60
swap: 512
unprivileged: 1
lxc.idmap: u 0 100000 1000
lxc.idmap: g 0 100000 1000
lxc.idmap: u 1000 1000 1
lxc.idmap: g 1000 1000 1
lxc.idmap: u 1001 101000 64534
lxc.idmap: g 1001 101000 64534

LXC 101 (lms)
This is the LXC that connects to the samba share of LXC 100
/etc/pve/lxc/101.conf:
Code:
arch: amd64
cores: 2
features: nesting=1
hostname: lms
memory: 2048
mp0: /mnt/shared_lxc/music,mp=/mnt/music
net0: name=eth0,bridge=vmbr0,firewall=1,gw=192.168.9.1,hwaddr=DE:D4:ED:68:CE:45,ip=192.168.9.8/24,type=veth
onboot: 1
ostype: ubuntu
rootfs: local-lvm:vm-101-disk-0,size=8G
startup: order=2,up=120
swap: 512
unprivileged: 1

And for completeness, I've added 'root:1000:1' to /etc/subuid and /etc/subgid as per the official wiki (that I had read before posting :cool: ).

BUT your comment made me rethink my config and now it works after I added a delay of 60 to LXC 100, with a delay of 120 for LXC 101 (as shown in updated 100.conf & 101.conf files above).

I'm a bit puzzled by this though. Could it be that before my last change, it took time for the PVE to mount the 4tb and 5tb (the 5tb is an external USB drive) and that the LXC 100 was starting before the mounts were complete, hence its CIFS share was not available for LXC 101? Note that (working) LXC 100 delay 60 + LXC 101 delay 120 is the same total as before with (not working) LXC 100 delay 0 + LXC 101 delay 180.

What do you think?
 

TheHellSite

Member
Mar 4, 2020
68
16
13
What do you think?
What I think is that... (no hate below)
no need to RTFM me.
is the reason you had to ask for help in the first place!

If you would have read the Proxmox docs (https://pve.proxmox.com/pve-docs/pve-admin-guide.html#qm_virtual_machines_settings) about the startup order and delays you could have figured this out on your own.

Keep in mind that the startup delay always delays the start of LXCs/VMs that start after the the LXC/VM on which it has been configured.
So start order=1,delay=60 means that it will start LXCs/VMs with a start order=2(or none) 60 seconds after order=1 LXCs/VMs have been started
The delay=120 on your LXC_101 is pointless unless you have other LXCs/VMs that rely on services hosted by this LXC.

Anyway glad it is working for you now!


Let me give you an example of how I handle this...
I have my FIREWALL_VM(order=1,delay=90) to start first and let it fully boot so that internet, dns, ... etc. is all working.
Then I have my NAS_VM(order=2,delay=60) to start second and let it fully boot so that all shares, services, ... etc. are working.
Lastly I have all other LXCs/VMs set to boot

I measured the delays exactly for each VM/LXC with a +15s buffer so that I am always on the safe side.
In reality my NAS_VM only takes about 40s to be fully ready including all shares etc., but I still configured it to 60s so that there is enough time in case of some small delays during boot time, which can always happen.
 
  • Like
Reactions: bobmorane06

Hardy

New Member
Jan 6, 2023
3
0
1
At first... Thanks for this tutorial. Have been looking for something like this for several days.


Has anyone tried this on proxmox 7.3? I can mount a share on my nas from the host, but I didn't figured out how to mount it in the lxc.

I've added this line to my lxc config file
Code:
mp0: /mnt/lxc_shares/nas_rwx/,mp=/mnt/nas
and created the directory
Code:
/mnt/nas
in my lxc. But it won't get mounted. Any ideas?
 

TheHellSite

Member
Mar 4, 2020
68
16
13
Has anyone tried this on proxmox 7.3? I can mount a share on my nas from the host, but I didn't figured out how to mount it in the lxc.
Working fine here ever since.

Double check that the share is actually working on the pve host.
If yes, then share the lxc.conf file.

Also there is no need to create the "/mnt/nas" folder in the lxc manually as this is handled my the mount points.
 

About

The Proxmox community has been around for many years and offers help and support for Proxmox VE, Proxmox Backup Server, and Proxmox Mail Gateway.
We think our community is one of the best thanks to people like you!

Get your subscription!

The Proxmox team works very hard to make sure you are running the best software and getting stable updates and security enhancements, as well as quick enterprise support. Tens of thousands of happy customers have a Proxmox subscription. Get your own in 60 seconds.

Buy now!