-
-
Notifications
You must be signed in to change notification settings - Fork 12.7k
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
Allow access to /dev/net/tun inside containers #18822
Conversation
@wlhlm, thanks for your PR! By analyzing the annotation information on this pull request, we identified @kampfschlaefer, @edolstra and @wavewave to be potential reviewers |
@@ -518,6 +518,7 @@ in | |||
KillSignal = "WINCH"; | |||
|
|||
DevicePolicy = "closed"; | |||
DeviceAllow = "/dev/net/tun rw"; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I am not sure, what a good policy would be here.
One device people could also request in future is /dev/fuse.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think preventing containers from accessing device files by default using a strict DevicePolicy
(closed or strict) and explicitly whitelisting devices that are "safe" to use is a good choice here. Additional devices can be allowed in subsequent PRs, of course.
Personally, I'm not sure how safe it is to use FUSE in containers (but I don't see an obvious problem with it).
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Maybe adding a list of allowed devices (with a default value?), would be helpful, so people can decide them self, what to allow.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
That sounds like a good idea. I see what I can do.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hmm, problem is that I can't have multiple DeviceAllow
lines, since nix doesn't allow multiple attributes with the same name.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
argh, this is really an issue in nix's generating of systemd units, which I encountered multiple times already.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I opened an issue regarding this, but I currently lack of a good idea, how this could be solved properly in future.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It is possible to pass a list to DeviceAllow instead.
Hi, could you please also make the list of allowed devices a configuration thing? I actually don't want all my containers to work with tun/tap devices. Only the single instance that is running openvpn (in the future). And you might want to write a test for that. There are quite a number of container-networking tests already. You could add one that has one host with two containers, one with tun/tap enable, one without and then check whether access to tun device works or not. Also Maybe the openvpn module could make use of a test that uses two containers instead of two VMs? (Okay, openvpn could actually use a test.) |
If |
In the first iteration this would mean that admins creating the container with openvpn inside would have to add the option. But it would prevent all other (existing) admins from opening their containers via undesired tun/tap. So this is firstly a security issue for me. The openvpn module/service in nixos could then detect whether its inside a container (I think boot.isContainer == true) and maybe add the relevant option. I could also help you with writing the test. Somehow I started liking system tests in NixOS so much I started writing them a lot on my spare time 😉 |
I'm not sure if OpenVPN should implicitly give itself the necessary privileges (capability+device access) when it detects that it's inside a container. Basically, what I was thinking was to merge this PR with the other one (#18823 - capabilities) to make things easier. Than I'd add options I would then add a third option What do you think? |
This adds the containers.<name>.enableTun option allowing containers to access /dev/net/tun. This is required by openvpn, tinc, etc. in order to work properly inside containers. The new option builds on top of two generic options containers.<name>.additionalCapabilities and containers.<name>.allowedDevices which also can be used for example when adding support for FUSE later down the road.
I have updated the branch according to the plan I described in the previous comment. Please have a look! This is currently missing tests, which I'll be looking into. |
Sadly no new container test. How do we know it actually works. And how do we ensure that it still works in 17.03? |
As I said, I'm still working on tests. I've tested against the master snapshot of nixpkgs with |
Ah, I am sorry. The new review-feature of github irritated me and let me believe this is already merged. Sorry. Keep on testing 😉 |
information. | ||
''; | ||
}; | ||
enableTun = mkOption { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I am unsure whether "enableTun" should be an explicit option or just a good example for "allowedDevices". It will probably be the primary use-case, but is it worth the special handling?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It hides implementation details, people might don't know what is needed in order to use tun devices inside a container. Therefor it improves usability. As it only describe the semantics, in future more options might be required to enable tun devices container. In this respect it is comparable to systemd's hardening flags: PrivateDevices=true creates a private /dev
with /dev/null
, /dev/zero
and /dev/random
. However in future this list can be extended without breaking the semantic.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@kampfschlaefer The plan is to add more similar options later on. For example, I can imagine an enableFuse
option, because FUSE requires access to /dev/fuse
. Having multiple options like containers.<name>.enable{Tun,Fuse}
that abstract over capabilities and device access make things easier for admins.
EDIT: Basically, what @Mic92 already said. 😉
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
For /dev/fuse
you may find this info helpful: systemd/systemd#2178 (comment)
Thanks! |
This allows containers to access
/dev/net/tun
by adding an optioncontainers.<name>.enableTun
that enables the correct capabilities and permissions for the container.Also adds two generic options
containers.<name>.additionalCapabilitites
andcontainers.<name>.allowedDevices
that help adding things like FUSE access (/dev/fuse
) later down the road.Motivation for this change
This change is useful for programs running in containers trying to set up tunnel interfaces. The current
DevicePolicy
prevents containers from accessing most device files thus explicitly allow/dev/net/tun
.Fixes #18708.
/cc @Mic92
Things done
nixos-rebuild test
nix-shell -p nox --run "nox-review wip"
./result/bin/
)