[TUTORIAL] Tutorial: Unprivileged LXCs - Mount CIFS shares

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 actually a UID/GID=100000 on the PVE host. See the above Proxmox Wiki link for more information on 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.

I ran into this same issue. It's a permissions issue and I fixed it with (change dir_mode and file_mode) :
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=0777,file_mode=0774,user=smb_username,pass=smb_password 0 0' ; } | tee -a /etc/fstab


Note that I didn't say the way I fixed it is the best/most secure way. Just that plex can see the subfolders now.
I was able to share my library on Windows PC by combining these 2 for my PLEX LXC.
Now I plan to run Jellyfin and Emby as well to test them using the same shared folder. How can I share the same library with 2 additional LXCs?

Also, I have created a new library on my Truenas. Can I share this additional library the same way or I can only share one library at a time?
 
Apologies in advance as a very new Proxmox user with ridiculously basic questions:

In the LXC - So does this need to be run in each LXC I spin up for an Arr?
1. I literally type in 'groupadd -g 10000 lxc_shares' in the 102 (radarr) Console section?
2. Now I enter 'usermod -aG lxc_shares radarr' and do this with a different name for each LXC that needs CIFS access?
3. Shutdown - I can figure this one out ;-)

On the PVE host - so these get put in under host1 - Shell (correct?). My shell prompt shows root@host1:~#
1. Create mount point - so just copy/paste 'mkdir -p /mnt/lxc_shares/nas_rwx'
2. Do I now use 'nano /etc/fstab' to edit the fstab?
And my code would be (all TV, movies are in /volume1/data); I have a user Sonarr that I made per MariusHosting and it has uid=1028(sonarr), gid=100(users), groups=100(users)

{ echo '' ; echo '# Mount CIFS share on demand with rwx permissions for use in LXCs (manually added)' ; echo '//MySynology/data/ /mnt/lxc_shares/nas_rwx cifs _netdev,x-systemd.automount,noatime,uid=100000,gid=110000,dir_mode=0770,file_mode=0770,user=sonarr,pass=smb_password 0 0' ; } | tee -a /etc/fstab

3. Mount share - so Ctrl-X and Y for saving the fstab above then back in the shell type in 'mount /mnt/lxc_shares/nas_rwx'
4. Add bind mount (type into shell again?):
{ echo 'mp0: /mnt/lxc_shares/nas_rwx/,mp=/mnt/nas' ; } | tee -a /etc/pve/lxc/102.conf

And doe this bind mount have to be done for each of the other apps? ie Sonarr would be 103, etc?

5. Start the LXC - got it ;-)

Thank you and sorry!