-
Notifications
You must be signed in to change notification settings - Fork 237
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[Question] bwrap in LXC #362
Comments
LXC probably doesn't leave it with enough privileges to run successfully. In general, "nesting" containers is harder to do successfully or securely than creating a single level of container on a "bare metal" machine or VM. |
@smcv yes, I was just thinking if bwrap could be used universally for jailed shell :) Even if it’s not so “secure” as jailing in KVM/Xen or bare-metal. |
Related issue: https://gitlab.steamos.cloud/steamrt/steam-runtime-tools/-/issues/35 |
LXC explicitly supports nested containers. Here is the relevant LXC container config option:
The bubblewrap errors that I am encountering are due to the above apparmor profile being permissive enough for nested LXC containers, but not permissive enough for whatever system calls bubblewrap is attempting on Proton's behalf. That apparmor profile isn't static, though; we can configure whatever rules we want. Given that LXC can already nest containers if the appropriate apparmor profile is used, it seems to me that there should be a way to make bubblewrap and LXC cooperate. (And if that can be done, it also seems there should be a solution for Steam & Proton.) |
As a step towards this, please try to get it to work with the LXC container being completely I think there are probably two sides to this. One is that the LXC container can apply AppArmor (and maybe seccomp?) restrictions that prevent bubblewrap from doing its job; you can avoid this factor by making the LXC container unconfined. After you have a proof-of-concept with it unconfined, we can either allow more operations in the AppArmor profile, or potentially do things slightly differently in bubblewrap so that it is only doing things that LXC's AppArmor profile would allow. The other is that running |
@smcv I'd like to investigate further, but running Steam with an unconfined apparmor profile defeats the purpose of my running it in LXC at all. For the sake of testing without having to poke giant holes in my sandbox, can you tell me a bubblewrap command line I could use to test this chroot issue? Also, what is creating the chroot you're referring to? Steam? If the chroot syscall turns out to be a real blocker for bwrap, couldn't it be replaced with a different approach, like a mount namespace? |
Any bubblewrap command line would do. The simplest is
No, it's the equivalent of your use of LXC. Most Steam users run it on "the real system" (for which bubblewrap is fine), but some people run Steam in a LXC container, or in a Docker container, or in schroot (which uses chroot(2) internally), or some similar environment, and that doesn't currently work in all cases. Similarly, most people who run bubblewrap for other purposes (Flatpak, WebKitGTK, libgnome-desktop, etc.) are running it on "the real system", but some people try to run it inside a LXC container, inside a Docker container, or in schroot, and that doesn't currently work. bubblewrap does create a new mount namespace, but it needs to use either pivot_root(2) or chroot(2) to get its root directory to be the new root that it has created. It currently uses pivot_root(2) for that. When Steam games run under the Steam container runtime or recent Proton versions, that is exactly a mount namespace, using bubblewrap. Steam doesn't use chroot or pivot_root itself. |
Okay, I made another (unprivileged) lxc container and configured it with
I think that means there should be a solution here, if we can find the minimal set of apparmor permissions (or bwrap changes) to get it working without the container running unconfined. Right? What would you suggest next? |
Progress! The following steps got bwrap to work in an (unprivileged) lxc container:
I have only tested this on Ubuntu 20.04 LTS so far. Different LXC versions and configurations might require something different. This command is handy for watching AppArmor complaints on a distro that uses systemd: I haven't thought deeply about the security implications of these rules, but just seeing it work was an exciting step forward. It might be worth a review from the LXC maintainers, and maybe asking them to include a bubblewrap/steam AppArmor profile alongside the ones they already provide for nested containers and other common cases. This would relieve users from duplicating upstream policy files, and avoid falling out of sync with upstream changes. Both bwrap and pressure-vessel do more {bind,re,}mount jugging than I would have expected. I tried to minimize the number of AppArmor rules required to accommodate it all, by leaning on globbing and the in conditional operator, but the result is still a bit more verbose than I would like and might not be as restrictive as it should be. I wonder if the bubblewrap and pressure-vessel maintainers could do anything differently to help with this. |
I think if you were using bubblewrap non-trivially (actually changing processes' view of the filesystem), you would find that the rules you found that you needed for pressure-vessel are also necessary for most (all?) non-trivial uses of bubblewrap. I'm somewhat surprised you didn't also need to add options to mount a tmpfs below
Everything pressure-vessel does, it does because there is some reason why it has to. I wish it could be simpler, but I don't think it can. If you look into the code and commit history for either bubblewrap, pressure-vessel, or another user of bubblewrap such as Flatpak, I think you'll see that it's all there for a reason. Simpler would be better, but we do have to make things "as simple as possible, but no simpler". |
I'm afraid Generally protecting something that allows you to arbitrary manipulate fs paths like bubblewrap is undoable with something that rely on those paths to protect like apparmor. |
Thanks for pointing that out. Given that the current recommendation for running bubblewrap in LXC containers is to use Also, as noted in comment #8 of that report, the AppArmor maintainers intend to fix the pivot_root problem. In the meantime, I wonder if an AppArmor policy could be crafted that would allow pivot_root only for the container's /usr/bin/bwrap, meaning an attacker would first have to become uid 0 within the LXC container in order to exploit it. |
It depends on the AppArmor rules and how they are being used. If you're using AppArmor in a way that runs all programs in the same mount namespace and completely relies on path-based policies, like the traditional use of If you're using AppArmor as part of lxc, as a way to prevent container breakout by blocking things like mount operations and other VFS manipulation, similar to the way Docker and Flatpak use seccomp, then the path-based parts of AppArmor are hopefully a lot less important, because anything the container shouldn't be able to access shouldn't be visible in the container's filesystem namespace at all. You can't read a file if there is no name you can give that will result in it being opened! That's how Docker and Flatpak manage to do access-control for files despite not using a path-based LSM like AppArmor: they build a filesystem namespace where only the allowed files exist. |
Ah, I see this is because |
The thing is lxc apparmor profiles rely on apparmor blocking access to various sensitive files which are visible in container namesapce. With bublewrap you may mount those files in different path in container which make apparmor protection useless. |
If that's the case, then it is not possible to do this securely, and you'll need to either:
Flatpak protects a few sensitive files in If you are using lxc to confine Steam, I'd recommend the unofficial Flatpak app as an alternative to that. It has some limitations that make Valve hesitant to recommend it in general or treat it as official, but running Steam inside lxc will already have most of those limitations anyway. Using fast user switching to run Steam as an unprivileged user, either on its own or combined with Flatpak, is another way Steam can be given fewer privileges. |
Feels like a bunch of the issues here may have been related to the direct use of LXC rather than something like LXD which knows to configure a variety of LXC features to make nesting work nicely. Here is an example on LXD which seems to behave just fine:
Everything that LXD does can of course be done by hand with LXC, but that may require quite a lot of care, especially when dealing with something as tricky as nesting. The exact config may also be quite dependent on the exact set of kernel features and host OS configuration. In this case, the main things to get right are:
|
I can't speak for @smtalk, who opened this issue, but I can respond to these suggestions with respect to my own use case... @smcv suggested:
AFAICT, Flatpak allows images to define their own security policy, which is a curious choice that effectively makes externally-built ones not confined at all; I think I would have to either build my own Steam flatpaks (a hassle) or diligently review and override the permissions of every community-built release (more hassle). Also, Flatpak doesn't seem to make modifying a runtime environment or running multiple applications in the same container particularly easy, so operations like that would mean still more hassles compared to lxc. On the other hand, perhaps those ongoing hassles would be tolerable (at least until AppArmor fixes the pivot_root issue) if accepting them meant my Steam games would work again. The possible blocker that comes to mind is ALSA. Last time I considered Flatpak for Steam, it didn't support ALSA-only systems without resorting to I suppose I could give it another try, and at least get an updated view of what problems remain. Does the Steam flatpak requie a particular version of Flatpak, or a particular version of bubblewrap on the host system? |
@stgraber suggested:
As far as I know, LXD didn't exist when I started using Steam in an LXC container. (Inspired by your blog, by the way.) At least, I wasn't aware of its existence back then. I have considered moving to LXD, but as I recall, I was told it had no way for an unprivileged container to run on (a subtree of) the hosts's filesystem. I use that functionality in LXC. It makes a number of things convenient and efficient, such as using GUI tools to manage the container's files without having to install GUI tools in the container, and allowing a contained program to communicate with a program on the host via a unix domain socket. It was probably a couple years ago when I last asked, though; has this filesystem limitation been lifted since then? If not, are the steps that LXD takes to make LXC nesting work nicely available in a format that that could be (relatively easily) copied to an LXC-only system? |
@foresto suggested:
Sorry to barge in on an unrelated matter: would you mind naming the GUI tools you use to manage the container's files? |
When the guest's filesystem is a subtree of the host's, (which LXC allows), all the software running on the host system can directly access guest files. That includes shells, scripts, desktop file managers, save game editors... everything. |
A quick info that bubblewrap works perfectly in a "nested LXC" in Proxmox 6.4. |
@gitfan2 For the sake of others who find their way here, what steps were involved in that guidance? |
@foresto Essentially, Proxmox is creating the structure in LXC that enables the nesting and is generating an apparmor profile to support it. Here are the relevant lines from the profile.
Conclusion: In a nested LXC in Proxmox 6.4, bubblewrap 0.5+ works flawlessly and creates the required sandbox for users. In the same apparmor profile, there's an additional section for nesting LXDs.
|
I don't think there's an actionable request for a change to be made in bwrap here, so I'm closing this issue. |
I'd like to know if someone has a solution for this -- running flatpak/bwrap inside an LXC sandbox is something I would like to be able to do (I was able to do it in LXD using its nesting feature, but not in LXC, even with the apparmor changes in this discussion). |
Hello,
Is bwrap suitable for sandboxing apps/users in LXC environment? If yes - any special flag for it?
The text was updated successfully, but these errors were encountered: