Categories
automation linux Security Server

Writing to Bind Mounts from Unprivileged LXC Containers

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 possible 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.

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

10+ years experience in web development, homelab enthusiast, tinkerer

profile for Dylan Hildenbrand on Stack Exchange, a network of free, community-driven Q&A sites  

Do you like these posts? Consider sponsoring me or making a donation!

13 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

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.

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.

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

Leave a Reply

Your email address will not be published.

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