Skip to content
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

WIP: PoC for Recording seccomp profiles #140

Closed
wants to merge 3 commits into from

Conversation

rhafer
Copy link
Contributor

@rhafer rhafer commented Oct 7, 2020

What type of PR is this?

/kind feature

What this PR does / why we need it:

This PoC adds a controller to the controller that will collect seccomp profiles generated by the seccomp-bpf oci-hook. It works by watching for pods carrying the "io.containers.trace-syscall" annotation which is used by the above oci hook to enable tracing of syscalls issued by a pod and generating a seccomp profiles from that.
After pod completion the controller will collect the generated profile and create a "SeccompProfile" resource in the namespace that the traced pod was running in.

This is still in it's early stages and there are still quite a few things to work on:

  • Better error handling
  • Documentation
  • Tests

And a ton of open questions to be detailed out:

  • What to do with the generated profiles? Currently the collected profiles will be just created as a "SeccompProfile" resource and will unconditionally be installed on every node. For that point the profile is generally usable by everybody who can access it. Should we maybe add some flag (label?, annotation?) to the SeccompProfile CRD that will mark a profile as being disabled until e.g. a manual review?
  • In the non-namespaced deployment the operatore now needs pretty wide (read) access to resources (namely pods and nodes). It also needs to be able to create "SeccompProfiles" in any namespace. Can this be further restricted?
  • Deeper integration with the oci-hook? Currently the integration with the tracing mechanism is pretty rough and based on specifying the right filename/directory in the .trace-syscall annotation. This is not only a bad UX but also raises question about how to cleanup the directory and what to when e.g. to pods specify the same output file.
    • Instead of watching for the hook annotation and giving the user control over the output file I guess we could create a mutating webhook that triggers on a different annotation (something specific to the seccomp operator) and injects the oci-hook annotation into the pod, which would give us better control over the output.
    • The oci-hook could be modified to "submit" the profile directly to the operator (e.g. via grpc) instead of writing a file to disk
  • Trying out different approach for the syscall tracing. (See also Record seccomp profiles #46 (comment)) and https://kubernetes.slack.com/archives/C013FQNB0A2/p1600971007007100)

Which issue(s) this PR fixes:

Fixes #46

@k8s-ci-robot k8s-ci-robot added do-not-merge/work-in-progress Indicates that a PR should not merge because it is a work in progress. kind/feature Categorizes issue or PR as related to a new feature. cncf-cla: yes Indicates the PR's author has signed the CNCF CLA. labels Oct 7, 2020
@k8s-ci-robot
Copy link
Contributor

[APPROVALNOTIFIER] This PR is NOT APPROVED

This pull-request has been approved by: rhafer
To complete the pull request process, please assign saschagrunert after the PR has been reviewed.
You can assign the PR to them by writing /assign @saschagrunert in a comment when ready.

The full list of commands accepted by this bot can be found here.

Needs approval from an approver in each of these files:

Approvers can indicate their approval by writing /approve in a comment
Approvers can cancel approval by writing /approve cancel in a comment

@k8s-ci-robot k8s-ci-robot added the size/L Denotes a PR that changes 100-499 lines, ignoring generated files. label Oct 7, 2020
@pjbgf
Copy link
Member

pjbgf commented Oct 9, 2020

@rhafer really good job so far! Here's my 2 pence on the open questions:

What to do with the generated profiles? Currently the collected profiles will be just created as a "SeccompProfile" resource and will unconditionally be installed on every node. For that point the profile is generally usable by everybody who can access it. Should we maybe add some flag (label?, annotation?) to the SeccompProfile CRD that will mark a profile as being disabled until e.g. a manual review?

Very good question. Maybe it would be worth keeping it simple for now and just create the CRD profile, which will lead to sync/saving into all nodes. At this point, the user would always need to actively map a profile to a workload, which they should be allowed to. We can refine this further once we have the auto apply in place.

On that point, it would be nice to auto populate the new field that defines what image is this profile for. This is still WIP, just linking here for future reference: #138 (comment)

In the non-namespaced deployment the operatore now needs pretty wide (read) access to resources (namely pods and nodes). It also needs to be able to create "SeccompProfiles" in any namespace. Can this be further restricted?

My understanding is that now that we are deprecating the ConfigMap support, we won't have cluster level profiles anymore. So we probably want to have a default target namespace for the profiles to be generated into so we can have a tight RBAC by default. @cmurphy please correct me if my namespace comment is gibberish. 😄

@rhafer
Copy link
Contributor Author

rhafer commented Oct 9, 2020

On that point, it would be nice to auto populate the new field that defines what image is this profile for. This is still WIP, just linking here for future reference: #138 (comment)

👍

My understanding is that now that we are deprecating the ConfigMap support, we won't have cluster level profiles anymore. So we probably want to have a default target namespace for the profiles to be generated into so we can have a tight RBAC by default.

Hm, not sure I completely understand that. But I think the recorded profile should endup in the same namespace as the pod that it was recorded from. Otherwise it would just be too easy to have two pods from different namespaces overwrite each other's recorded profiles.

@cmurphy
Copy link
Contributor

cmurphy commented Oct 9, 2020

In the non-namespaced deployment the operatore now needs pretty wide (read) access to resources (namely pods and nodes). It also needs to be able to create "SeccompProfiles" in any namespace. Can this be further restricted?

My understanding is that now that we are deprecating the ConfigMap support, we won't have cluster level profiles anymore.

I didn't fully understand this before, but I guess the "cluster level profiles" are, e.g. the seccomp-operator-profile configmap which gets mounted and copied by the initcontainer to /var/lib/kubelet/seccomp/seccomp-operator.json? Right now SeccompProfile doesn't do that, but maybe it should?

So we probably want to have a default target namespace for the profiles to be generated into so we can have a tight RBAC by default.

I agree with @rhafer that the profile should go in the namespace it was recorded from, and as such I'm not sure how the operator could be further restricted: it needs broad permissions to write SeccompProfiles to any namespace.

// traceAnnotation is the annotation on a Pod that triggers the
// oci-seccomp-bpf-hook to trace the syscalls of a Pod and created a
// seccomp profile.
traceAnnotation = "io.containers.trace-syscall"
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Did you use the CRI-O annotation patch to make this work? I'm thinking if we can choose another way to pass the data than the annotation…

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah. For now this depends on the annotation patch. (For reference cri-o/cri-o#4138)

@k8s-ci-robot k8s-ci-robot added the needs-rebase Indicates a PR cannot be merged because it has merge conflicts with HEAD. label Oct 15, 2020
@pjbgf
Copy link
Member

pjbgf commented Oct 20, 2020

Hm, not sure I completely understand that. But I think the recorded profile should endup in the same namespace as the pod that it was recorded from. Otherwise it would just be too easy to have two pods from different namespaces overwrite each other's recorded profiles.

@rhafer I am not opposed to get the recorded profile into the namespace the recorded pod was running from, I just thought this probably would happen as two separate steps to start with:

  1. A pod is selected for profile recording, a temporary seccomp profile may be created and will be amended through this process.
  2. A user promotes the generated profile by pushing it to a given namespace and applying it to a workload.

Given how difficult it is to get a complete profile, I was thinking on restricting the first part to a given namespace, which we could then enforce simply by RBAC. Then second step would be the user's responsibility until this feature matured.

However, I think it is more important to have an end-to-end process we can play around with then get bog down on this details, so feel free to go ahead and we will then tackle such concerns as they appear.

This controller is watching pods carrying the "io.containers.trace-syscall"
annotation which is used by the oci-seccomp-bpf hook to trigger the
tracing of syscalls issued by a pod to generate a seccomp profile.

After pod completion the controller will collect the generated profile
and create a "SeccompProfile" resource in the namespace that the traced
pod was running in.

Signed-off-by: Ralf Haferkamp <rhafer@suse.com>
The profile recorder controller needs some adjustments in the deployment
of the operator:
- New volume "host-seccomp-host-output-volume" this the location that
  the controller is trying to collect seccomp profiles from.
- New RBAC requirements:
  - read access in "node" resources are required in order to figure
    out the nodes' internal IP addresses
  - read access on "pod" resources is required as the controller needs
    access to the "annoation" of the pods in order to scan for the
    trace annotation
  - As the controller is created SeccompProfile resources now it needs
    to have elevated access on the SeccompProfiles resources.

Signed-off-by: Ralf Haferkamp <rhafer@suse.com>
@k8s-ci-robot k8s-ci-robot removed the needs-rebase Indicates a PR cannot be merged because it has merge conflicts with HEAD. label Nov 23, 2020
@rhafer
Copy link
Contributor Author

rhafer commented Nov 23, 2020

rebased

@saschagrunert
Copy link
Member

/ok-to-test

@k8s-ci-robot k8s-ci-robot added the ok-to-test Indicates a non-member PR verified by an org member that is safe to test. label Nov 23, 2020
@k8s-ci-robot
Copy link
Contributor

@rhafer: The following test failed, say /retest to rerun all failed tests:

Test name Commit Details Rerun command
pull-security-profiles-operator-verify 308ffdc link /test pull-security-profiles-operator-verify

Full PR test history. Your PR dashboard. Please help us cut down on flakes by linking to an open issue when you hit one in your PR.

Instructions for interacting with me using PR comments are available here. If you have questions or suggestions related to my behavior, please file an issue against the kubernetes/test-infra repository. I understand the commands that are listed here.

@saschagrunert
Copy link
Member

rebased

Do you think that we can demo this at the community meeting this Thursday?

@rhafer
Copy link
Contributor Author

rhafer commented Nov 23, 2020

Do you think that we can demo this at the community meeting this Thursday?

Yeah, that should work. Even if just for discussing some of the road blocks I've hit recently with the current approach :-)

Signed-off-by: Ralf Haferkamp <rhafer@suse.com>
@saschagrunert
Copy link
Member

@rhafer I reused most of your work in #247, thank you again for the contribution. I assume that you will not continue this PR now. Feel free to reopen if that is not the case. 🙏

/close

@k8s-ci-robot k8s-ci-robot added the needs-rebase Indicates a PR cannot be merged because it has merge conflicts with HEAD. label Feb 1, 2021
@k8s-ci-robot
Copy link
Contributor

@saschagrunert: Closed this PR.

In response to this:

@rhafer I reused most of your work in #247, thank you again for the contribution. I assume that you will not continue this PR now. Feel free to reopen if that is not the case. 🙏

/close

Instructions for interacting with me using PR comments are available here. If you have questions or suggestions related to my behavior, please file an issue against the kubernetes/test-infra repository.

@k8s-ci-robot
Copy link
Contributor

@rhafer: PR needs rebase.

Instructions for interacting with me using PR comments are available here. If you have questions or suggestions related to my behavior, please file an issue against the kubernetes/test-infra repository.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
cncf-cla: yes Indicates the PR's author has signed the CNCF CLA. do-not-merge/work-in-progress Indicates that a PR should not merge because it is a work in progress. kind/feature Categorizes issue or PR as related to a new feature. needs-rebase Indicates a PR cannot be merged because it has merge conflicts with HEAD. ok-to-test Indicates a non-member PR verified by an org member that is safe to test. size/L Denotes a PR that changes 100-499 lines, ignoring generated files.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Record seccomp profiles
5 participants