Access network shares in unpriveleged ProxMox VE LXC containers

Estimated reading time: 4 minutes


What is it:

Sharing your network attached storages to your LXCs in a safer manner

Why it matters:

Security. Compartmentalising all of your containers, by running them without privilege, is an extra step of security in case one of your running systems gets compromised. This allows us to share certain external data with apps in an LXC.

Let’s Begin:

Due to permissions systems in LXC, the user and group IDs are mismatched from the host, so giving rights to shares doesn’t work in the standard way, Thanks to this post (seriously, I’m just paraphrasing it), we have a way to leave the container unpriveleged as it should be. This is especially useful if you intend to store your media on an external device – such as my setup where i have ProxMox VE on a miniPC running plex and unraid on a typical PC setup.

Function

This process mounts the SMB/CIFS share to the User ID that belongs to the unprivileged LXC root user, which by default is always uid=100000.
Instead of assigning the Group ID of the LXC root user, a group in your LXC with gid=10000 is created, which refers to gid=110000 on the PVE host, bitwise.

[HOST] UID=100000 GID=110000 <--> [(unpriv)LXC] UID=0 GID=10000

Process:

In the LXC (as root user)

1. Create a group and give it the gid 10000, to match the gid 110000 on host. in this example, we are using “lxc_shares”:

groupadd -g 10000 lxc_shares

2. Add the user(s) that need access to the network share to the group you’ve just created. This will be your non-root application users. the example uses the user “plex” and adds it to our lxc_shares group. Adjust it as necessary.

usermod -aG lxc_shares plex
HINT: How do i find my users?

If you created your LXCs via PVE helper scripts, they are often auto-made for you. users are stored in /etc/passwd and my favourite way of determining which users exist is to run this lil’ number:

awk -F: '{ print $1 }' /etc/passwd

3. Shutdown the LXC.

On the PVE host (as root user)

1. Create the folder mount point. I believe it’s always best to name the folders something obvious. For example, I use the group name “lxc_shares” and the unraid share name “data”.

mkdir -p /mnt/lxc_shares/data

2. Add the share to /etc/fstab with the following code. Replace the address, username and password with the details of your network share. For ease, I’ve bolded the sections that are relevant.

{ echo '' ; echo '# Mount network share on demand with rwx permissions for use in LXCs' ; echo '//unraid/data/ /mnt/lxc_shares/data cifs _netdev,x-systemd.automount,noatime,uid=100000,gid=110000,dir_mode=0770,file_mode=0770,user=USERNAME,pass=PASSWORD 0 0' ; } | tee -a /etc/fstab
Whats all that then?
  • _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.
  • dir_mode=0770,file_mode=0770 sets our created uid/gid to have rwx access to the share. (PVE root user always has rwx to everything.)

3. Mount the share on the PVE host. This is how it would be on mine:

mount /mnt/lxc_shares/data

4. Add a bind mount of the share and it’s LXC localation to the LXC configuration. replace LXC_ID with the LXC number. for example if your LXC is 105, yours would be “105.conf”

{ echo 'mp0: /mnt/lxc_shares/data/,mp=/nas/data' ; } | tee -a /etc/pve/lxc/LXC_ID.conf
You can also set it to read only!

adding read only ro=1 into the command will set the files as read only, handy for plex servers that don’t manage the media.

{ echo 'mp0: /mnt/lxc_shares/data/,mp=/nas/data,ro=1' ; } | tee -a /etc/pve/lxc/LXC_ID.conf

5. Start the LXC.

Now your networked storage will be accessible in the LXC at /nas/data

Comments

Leave a Reply

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