-
Notifications
You must be signed in to change notification settings - Fork 452
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
feat: mount /sys/kernel/security into kubelet #8641
Conversation
30aece3
to
6f39b85
Compare
@@ -120,6 +120,7 @@ func (k *Kubelet) Runner(r runtime.Runtime) (runner.Runner, error) { | |||
mounts := []specs.Mount{ | |||
{Type: "bind", Destination: "/dev", Source: "/dev", Options: []string{"rbind", "rshared", "rw"}}, | |||
{Type: "sysfs", Destination: "/sys", Source: "/sys", Options: []string{"bind", "ro"}}, | |||
{Type: "securityfs", Destination: "/sys/kernel/security", Source: "/sys/kernel/security", Options: []string{"bind", "ro"}}, |
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.
should it need to be just "ro"? so kubelet only looks into it, but never configures anything?
do we want it to be backported or part of some future work?
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.
bind
should be needed because that will propagate changes from the host down into the container (if anything does change over time I am unsure of).
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 don't think it needs to be backported but if it wouldn't hurt then it could be useful in 1.7. I can check with the user.
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.
Only ro
is technically needed for AppArmor since kubelet
is checking if AppArmor is enabled via opencontainer apparmor lib: https://github.com/opencontainers/runc/blob/main/libcontainer/apparmor/apparmor_linux.go#L18
Which check if directory /sys/kernel/security/apparmor
exists and a read on /sys/module/apparmor/parameters/enabled
returns Y
.
Both which should have their final value set by the time kubelet
starts.
The part I'm not sure how bind
handles is that /sys/kernel/security/
is one of these virtual filesystems where this securityfs
is a sort of interface to LSM modules in the kernel.
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 bind
should be fine, it just exposes the filesystem at another mountpoint, but without bind we do a completely fresh mount.
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.
So do we want 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.
yep, I think bind
is better, but we also need to handle the case when the filesystem is not mounted on the host (if running in container mode). I believe in container mode we don't mount it explicitly (???) and rely on the container runtime to provide it or not... just to make sure we don't break Talos in containers if securityfs is not mounted on the container runtime host. I don't know if it's even possible though, just as a precaution :)
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.
yep, we don't mount securityfs in container mode:
default: | |
phases = phases.Append( | |
"systemRequirements", | |
EnforceKSPPRequirements, | |
SetupSystemDirectory, | |
MountBPFFS, | |
MountCgroups, | |
MountPseudoFilesystems, | |
SetRLimit, | |
).Append( |
But as we do bind mount, I believe our code will just mount an empty directory into the kubelet if the host doesn't provide securityfs, so bind >> re-mount :)
6f39b85
to
875ffe4
Compare
Since AppArmor landed with 1.7 kernel it probably makes sense to backport |
I think getting this in to v1.7 fits nicely with the bump to Kubernetes 1.30 that includes the move of AppArmor config to Pod SecurityContext fields. kubernetes/kubernetes#123435 |
I tried to validate if this fixes the problem with AppArmor configured on Pod causing it to get stuck in I mounted the
Starting a Pod with AppArmor profile specified (that I have loaded into the node Kernel beforehand):
I no longer get the message Feels like there is something else that also needs to be fixed around the |
@konrader it might be easier if you could provide us with a full set of steps to launch a pod with AppArmor profile, which we could include into Talos as an integration test. This way we can develop a fix and a test. |
I will write down the steps needed. It does include loading a AppArmor profile (with Where are the integration tests located today? |
in the |
Here is a complete script for doing the test of both loading AppArmor profile into kernel and running a Pod with profile enabled.
This depends on AppArmor profile being in a separate file named
|
875ffe4
to
d9d91ee
Compare
I've located the error which at the core relies on This check does more than On Talos (or other Linux platforms) where AppArmor profile loading is done either from other user-land tool or from inside container this check is not necessary since containerd requires the profile to be loaded into kernel before you reference it for a container anyway. This PR is still a step in the right direction since it gets rid of the problem with |
@konrader we can put an empty |
I was actually thinking about adding empty /sbin/apparmor_parser to Talos rootfs to try but didn't have my build-instance up. |
I tried to add empty
Got this message during boot: What is the easiest way to add the file in rootfs to try out if this would work? |
The only way is to rebuild Talos with changes to the I can get to it with the steps you provided to build a test for AppArmor. |
I'm looking into why Moby/Docker want Moby removed their own AppArmor enabled check and started relying on containerd's check: moby/moby#42276 I do see that the default profile loading stuff is put under /contrib in containerd and it could possible be a problem with missing
Docs: https://kubernetes.io/docs/tutorials/security/apparmor/#securing-a-pod I will try to verify this. |
I could reproduce the scenario with Kubernetes 1.30 running on a Ubuntu 22.04 when I uninstalled AppArmor userland tools ( With no I created an empty So it seem like the CRI implementation in containerd do try to apply some default AppArmor profile for all containers (that does not have specific AppArmor profile specified in security option). If we do want AppArmor support in Talos then I see the following options:
|
It does not seem possible to disable automatic applying of a default AppArmor profile (called If we would include |
@konrader thanks for your research here. I think having AppArmor (better security) is in the best spirit of Talos. We can think whether we want apparmor-parser as an extension for example, but I guess this becomes a bigger change, so would likely be in the timeframe of 1.8 |
This allows the kubelet to detect AppArmor. Signed-off-by: Andrew Rynhard <andrew@rynhard.io> Signed-off-by: Andrey Smirnov <andrey.smirnov@siderolabs.com>
I created issue #8715 to track the actual AppArmor work, while this PR makes sense on its own, so should be good to merge |
/m |
This allows the kubelet to enforce AppArmor.