Writing to Bind Mounts from Unprivileged LXC Containers – closingtags </>
Categories
Automation Linux Security Server

Writing to Bind Mounts from Unprivileged LXC Containers

Update: As evident by the comments on this post, it seems this method may not work for all installs. The issue seems to be with SMB shares. This post outlines the process with NFS shares. Thanks to Alex in the comments for these findings. If you find other issues or learn why this is the case, leave a comment below or fill out the contact form.


When ever I run into an issue during GNU/Linux server administration, 9 times out of 10, it’s due to permissions. By this point, it’s only frustrating when I realize that I didn’t check the permissions first. Since starting my homelab years ago, one issue that has plagued me has been giving write access to my unprivileged LXC containers in a shared storage.

I could possibly sidestep this problem by starting a VM but I like containers. Why? Containers are great because they reduce resources consumed, segment logic, and are quickly reproduced. This is all accomplished by using existing features of the Linux kernel and its user space. The host machine already has a kernel (unlike a VM which is given its own kernel), so when running a container, the host machine kernel is shared with the container and is managed by the host as another user on the system. By design, unprivileged LXC containers (henceforth known as unpriv LXC) have no permissions on the host machine. They are relegated to the nobody user and nogroup group. This ensures that if an attacker were to compromise the container, they would have no permissions on the host machine. That’s all well and good, but what if you want to share storage across your unprivileged containers? There are presumably ways that you can punch holes in AppArmor but Proxmox does in fact, make it simple.

In my example, I have an unpriv LXC running Plex. I don’t want this container to be able to do anything on the host but I would like it to be able to read and write from a shared media folder on my network.

Mounting NFS

The first step, is making sure the Proxmox host has access to the Network File Share (NFS). This is incredibly simple via the GUI. Under Storage View, click the Datacenter, then click Storage. Click the “Add” button and select the appropriate storage option. In your case, it may be SMB/CIFS or Directory but in my case, it’s NFS.

** Update: As noted by commenters, this process does not work for SMB shares. **

The ID will be the name of the storage, the server is your NFS IP address, export is the NFS path, and the content is what Proxmox will use this storage for.

Bind Mount

Once our host has access to the NFS, we need to give the container access to that data via a bind mount. A bind mount is a folder on the host that is mapped inside the container. To create the bind mount, open the Proxmox CLI, and run

pct set 100 -mp0 /host/shared_dir_location,mp=/path/in/container
  • pct is the Proxmox Container Toolkit
  • set tells pct we’re going to set an option
  • 100 is the container ID we’ll be working on
  • -mp0 is the name of the mount point
  • the first path listed is the directory on your host you’re attempting to share with the container
  • ,mp=/path is the path where we want that directory mounted within the container

Permissions

From here, open the Proxmox GUI (web interface) and within the Server View, click Datacenter > Permissions > Groups.

Permissions management for a Proxmox Datacenter

After that, click the “Create” button to make a new group permission. Give it a name like “shared_file_access” and a description so you know what it does. We’ll also go on to select “Roles” below “Groups” and create a new role. Give the new role a name like “DataAccessRole” and assign it the storage related privileges, which are the ones that start with “Datastore.” as well as “Pool.Allocate” and “Pool.Audit.”

Once that’s complete, we can select our container from the server list on the left, navigate to it’s permissions, and click “Add” to give it our group permission and the role. We’ll want to do the same thing for the storage point we mounted earlier on the host. That can be found under Data center > Storage. Select your storage point, and navigate to the permissions of it. From there, give it the same permissions you gave to our container.

If your storage location is properly mounted inside of Proxmox, your unpriv LXC should now be able to read and write to the location we mounted earlier! You can test this by opening a terminal in your unpriv LXC, navigating to the bind mount point, and attempting to create a file there eg. touch test.txt.

Comment below with how well this worked for you, and if you liked this post, share it around.

By Dylan Hildenbrand

Author and full stack web developer experienced with #PHP, #SvelteKit, #JS, #NodeJS, #Linux, #WordPress, and #Ansible. Check out my book at sveltekitbook.dev!

Do you like these posts? Consider sponsoring me on GitHub!

39 replies on “Writing to Bind Mounts from Unprivileged LXC Containers”

Thanks for this write up. It seemed like a perfect option and I was surprised I didn’t think of this as I’ve been using the permission features of proxmox for some time when doing distributed backups.

The problem for me is that this didn’t work despite follwing the steps you’ve laid out.

1. Add share and attach to LXC (I’m using SMB/CIFS)
2. Create a group “shared_file_access”
3. Create a new role with the above DataAccess privileges (why not use the other DataAcccess roles like DataAccessAdmin?)
4. Add the group and role to the datastore
5. Add the group and role to the LXC container

This didn’t work and I couldn’t write within the mount point inside the LXC.

Interesting. I wonder where our steps differed. To recap, you’ve mounted your share within the Proxmox host, created the appropriate permissions, created the bind mount inside the LXC (to bind the host directory to the container directory), and given the container all of the correct permissions?

Did you also give the storage (SM/CIFS) on the host the same permissions group? I may have actually missed outlining that step in the post so forgive me. I’ll update accordingly.

Hi Dylan, i have the same problem. I can’t write in the mounted folder in the LXC.
I do all the steps, but i have only read rights.

My steps:

Datacenter/Permissions/Groups
– create new group “shared_file_access”

Datacenter/Permissions/
– create role “DataAccessRole” with the following rights:
– Datastore.Audit,
– Datastore.Allocate,
– Datastore.AllocateTemplate,
– Datastore.AllocateSpace

Datacenter/pve/xxx-mycontainer/Permissions
– Add Group permission “shared_file_access” and role “DataAccessRole”

Datacenter/pve/mystorage/permissions
– Add Group Permission “shared_file_access” and role “DataAccessRole”

Can you help me? Thank you!!!

It’s expected for one person to have problems, but two? Something is definitely up with my guide. I’m beginning to wonder if I missed documenting a step!

I have a few ideas on things we can test. After each one, reboot the container and check if it has write access. If not, revert the change and move on to the next suggestion. Here they are:

1. Under your DataAccessRole, add Pool.Audit and Pool.Allocate privileges.
2. In storage permissions, try changing the role from the one you created to “PVEAdmin.” while keeping the group the same.
3. Try setting the group/role permissions on the disk where your containers exist instead of the attached storage.

Hi Dylan, thx for your straight tutorial on that. I am just working on using a bind mount with write access into a proxmox lxc container, and I am not getting this done, still having issues with permissions.

What I have done so far:

External NAS
– created a SMB Share on my NAS with guest access, no user/password required

Proxmox Host
– add this NAS-SMB-share to the Proxmox Host as a storage via GUI (datacenter -> storage -> add…)

LXC Container (using CT105 as an example)
– bind mount this share into the lxc with pct set 105 -mp0 /mnt/pve/share,mp=/mnt/share-lcx where “share” is the id and “/mnt/share-lxc” ist the folder in the lxc to mount to that “id”.
Doing ls -la on /mnt/share-lxc afterwards shows owner and group as nobody:nogroup and with ls -n 65534:65534 (before it was root:root resp. 0:0)

Proxmox Host
– Add new group: datacenter -> groups -> add… name: shared_file_access
– Add new role: datacenter -> roles -> add… name: ShareDataAccess and given privileges:
– Datastore:Allocate
– Datastore:AllocateSpace
– Datastore:AllocateTemplate
– Datastore:Audit
– Pool:Allocate
– Pool:Audit

Adding Group and Roles in various combinations
First
a) CT105 -> rights: add (group/role) shared_file_access/ShareDataAccess
b) datacenter -> storage share: add (group/role) shared_file_access/ShareDataAccess
-> reboot CT105: touch test.txt -> Permission denied

Second
a) CT105 -> rights: add (group/role) shared_file_access/ShareDataAccess
c) datacenter -> storage share: add (group/role) shared_file_access/PVEadmin
-> reboot CT105: touch test.txt -> Permission denied

Third
a) CT105 -> rights: add (group/role) shared_file_access/ShareDataAccess
b) datacenter -> storage share: add (group/role) shared_file_access/ShareDataAccess
d) datacenter -> storage of lxc’s local-lvm: add (group/role) shared_file_access/ShareDataAccess
-> reboot CT105: touch test.txt -> Permission denied

btw, I did also a full Proxmox reboot -> no change, still no permission to write into lxc bind-mount.
What I can do is write into the Proxmox share mount and the file shows up on the remote NAS and also in the lxc bind mount, there with owner/group nobody:nogroup
I’m also be able to delete this file from WIN10, which is connected to that NAS SMB Share, and it is being removed from all connected folders, even the lxc bind mount. So, the mounts are setup correctly, its just an issue with permissions between proxmox host and it’s lxc containers.

I also tried the approach with mapping uids and gids, als mentioned in the official proxmox wiki but it didnt get it run til now. Maybe I have to check this again and see, if I did some errors there…

Do you probably have somewhere else different Proxmox configuration which I dont have and which causes your solution being not working on my system? I use PVE as it is with absolutely no specials.

Using PVE 7.1-12

Hi Tobias, thanks for the comment! And I’m sorry this didn’t work out for you. Like you mentioned, I’m wondering if I have some other configuration that I didn’t document here. I’ve been running this setup for years now and attempting to sort this issue for just as long so it’s entirely likely something was changed along the way.

The one commonality I’ve noticed from other uses has been Samba shares. Since I’m using NFS, I’m unsure of what might be different. But even as you said, other devices can access your share and it doesn’t have user/password so that’s really stumped me.

I had the same problem as the other comments. In my case i fixed it by creatingprivileged lxc containers. Seems like binding doesnt work in unprivileged containers

Privileged LXC containers should be able to mount a folder on the host as they are given a unique user:group on the host. Unprivileged LXC containers are relegated to nobody:nogroup to prevent accessing resources on the host so that is one way to get around it. They are not “secure by default” though this method or reading/writing opens up an unpriv LXC anyways.

Hi Dylan, i can only say, thank you very much for this blog.

I lost 2 days with different setup and i wasn’t be able to connect from lxc to my NAS via NFS. But with your setup it works. :-)

i followed just your stepts, and is working well. I am able to write/read from an unprivileged lxc directly to my NAS.

How do you add permissions on the Data store? I don’t see any permissions attributes on the NFS mount in proxmox

I didn’t figure out that you need to go to the data store inside the host to set the permissions, not at the storage level at the data center, but that didn’t resolve the rights issue

Hey! I stumbled upon this while troubleshooting some pesky bind mounts after playing around with my NFS server.

I had previously used the uid:gid map approach as presented on the Proxmox wiki, but after re-creating the NFS storage entry the bind mounts referred to, my containers were no longer able to access anything inside the bind mount (I literally couldn’t even cd into the shared folder). I was hoping that this tutorial would give me a simpler way to manage access this NFS store, but like other commenters, I didn’t have any luck.

What DID work, however, was ensuring that I had properly set the filesystem permission bits on the share. Somehow when recreating the share, the ‘execute’ bit had become unset everywhere, meaning that the only user able to access the NFS share at all was root on the Proxmox host. Restoring ‘execute’ permissions allowed other users (including my containers) to operate normally on the NFS share.

After playing around with this & Proxmox permissions a little bit more, I don’t think there’s any setup using Proxmox Groups/Roles/Permissions/etc that will allow a CT access to a given storage – I’m pretty certain that all of the Proxmox permissions are for users interacting with the Proxmox GUI/CLI/API, and not for resources interacting with each other.

That would mean that the _easiest_ way of allowing containers to use an NFS share through a bind mount is to set the permission bits for “other” users of the NFS share on the Proxmox host to 7 – i.e. full read/write/execute for anyone and everyone. (i.e. for my share, which is mounted on `/mnt/pve/mfnas`, run `chmod o+rwx /mnt/pve/mfnas`)

This isn’t particularly secure, but it’s easy. For use of proper user/group permissions, you’ll have to follow the uid:gid mapping guidelines here & set permission bits on the host accordingly: https://pve.proxmox.com/wiki/Unprivileged_LXC_containers

Works great with NFS share, even without the “Pool.Allocate” and “Pool.Audit” permission.
However does not work with SMB share, no matter how I tweaked it.

Btw, did you get hw-transcoding working with unprivileged container?
It seems that using UID mapping is the only way.

Just wanted to add a comment saying thanks for this. I originally tried with SMB and it didn’t work just as others have commented. I switched to NFS and it works just fine.

Hi, very nice idea. Can you elaborate if this has any security disadvantages? Can a compromised guest be used to harm the host this way? I’m new to the Proxmox topic and do not know very much about roles ans permission handling.

Fantastic questions! To learn how this method could become a security issue, we have to understand that Unprivileged LXC containers are considered “secure by default” because they have “no” permissions on the host machine. This is achieved by assigning the Unpriv LXC container to nobody:nogroup on the host. What this method outlined in this post does essentially bypasses that and gives the container permissions to something on the host. So use with caution as it could very will introduce a security hole. Should the container become compromised, and attacker would have access to the resources on the host that the container was given permission to. As always, give as little permission as you possible. Locking things down to only read permissions would ensure that an attacker wouldn’t be able to damage any data but could still leak potentially sensitive information.

This. Post. Saved. My. Build. I looked everywhere for a whole day and I couldn’t make my bind mount from my new TrueNAS Scale NFS share to my Proxmox Jellyfin container. I wasn’t wild about running as unpriveledged. I was about to cave and just run jellyfin as a docker instance on TrueNAS (prefer not to because of flexibility of Proxmox), and then I found this. AMAZING. Thank you for taking the time to write this up.

I tried but still doesn’t work for my NFS Share. I set the permissions in the Container and in the Storage but I get no write permissions. Do I need to unmount and mount again the NFS share? My NFS Share is in TrueNAS Scale.

Thank you for this blog post, worked perfectly for me using an NFS share from openmediavault – was previously using idmap in the config but this seems a bit ‘nicer’

Hi Dylan,
I followed your steps on Proxmox 8.2.2 and NFS and it does not work on Unpriviliged container. I tried to play with Group and role without success

Hi, I tried suggestion in comments, giving PVE Admin Role, I also tried with Administrator Role. Only way to make it work, is use priviliged, but I don’t want do like this. Any suggestion Would be appreciated

Hi! following your guide I’ve been able to access the NFS share from the console with rw permissions, but I stumbled in a problem i can’t find a solution for:
I installed PBS in this unprivileged lxc and i want to use the NFS share to store my backups, but when I try to create a datastore to the new mount point i get “EPERM: Operation not permitted”
Do you have any suggestion?

Leave a Reply

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

This site uses Akismet to reduce spam. Learn how your comment data is processed.