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

Additional Seccomp tests #137

Merged
merged 1 commit into from
Sep 20, 2017
Merged

Conversation

mikebrow
Copy link
Contributor

Adding support for seccomp testing.

Will add pod testing after validating these container tests.

@Random-Liu

@k8s-ci-robot k8s-ci-robot added cncf-cla: yes Indicates the PR's author has signed the CNCF CLA. size/L Denotes a PR that changes 100-499 lines, ignoring generated files. labels Sep 15, 2017
@Random-Liu
Copy link
Contributor

Random-Liu commented Sep 15, 2017

@mikebrow According to #135, seccomp is not supported in the current version of Docker we are using.

I'll review and get that PR merged first, and you could see whether your test overlaps with that one or not. And we could consolidate.

@mikebrow
Copy link
Contributor Author

mikebrow commented Sep 16, 2017

@feiskyer Wish I'd known someone else was also drafting seccomp tests :-)

@mikebrow
Copy link
Contributor Author

mikebrow commented Sep 16, 2017

@Random-Liu @feiskyer all good, I don't see any overlap in our test cases. I'll normalize and combine them on Monday. For example, he's using chmod and grep which should work with docker/default and they do not require caps to be set before generating the default seccomp profile (which from my investigation is different with and without certain caps and on different platforms). I'm using hostname which requires caps to make docker/default allow sethostname, so I'm testing with and without caps on to cover both fail and pass cases. I'm also testing the privileged case to make sure you can't block a command when privileged, and i've got a test for runtime/default as that may also be used instead of docker/default. And I just added a test to make sure the profile name is in the format "localhost/*"

@mikebrow mikebrow force-pushed the seccomp-test branch 2 times, most recently from 2c9f66d to edebeb8 Compare September 16, 2017 02:58
@feiskyer
Copy link
Member

@mikebrow Sorry for didn't let you know this. But cool with more complete test cases.

@feiskyer
Copy link
Member

@mikebrow needs a rebase now

@mikebrow
Copy link
Contributor Author

Rebased.

@feiskyer I see there was a change to the CRI api documentation

kubernetes/kubernetes@c242432#diff-df996ad3ce05a000c2009d6e8cfba507L486

Talked to @Random-Liu about this. Will just remove the runtime/default tests for now.

@mikebrow mikebrow changed the title [WIP] Seccomp test Additional Seccomp tests Sep 18, 2017
@mikebrow
Copy link
Contributor Author

@Random-Liu @feiskyer rebased. Tests passing ready for review.

@@ -402,6 +424,41 @@ var _ = framework.KubeDescribe("Security Context", func() {

checkNetworkManagement(rc, containerID, false)
})
})

Context("runtime should support seccomp security context", func() {
Copy link
Member

Choose a reason for hiding this comment

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

nits: [security context] same with other places.

Copy link
Contributor Author

@mikebrow mikebrow Sep 19, 2017

Choose a reason for hiding this comment

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

the top level bucket is "[k8s.io] security context"
This context is for seccomp tests it is already within [k8s.io] security context bucket.

No need to be repeating the phrase security context 2-3 times one at each level in the buckets.

Let me refactor all of the titles making it easier to use focus and skip regexps and only having brackets on the left for ease of reading.

Copy link
Contributor

Choose a reason for hiding this comment

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

@feiskyer On second thought, I also think it is fine to remove the tag given how cri validation test is organized today. :)

@feiskyer feiskyer mentioned this pull request Sep 19, 2017
3 tasks
Signed-off-by: Mike Brown <[email protected]>

adds support for seccomp testing

Signed-off-by: Mike Brown <[email protected]>
@mikebrow
Copy link
Contributor Author

mikebrow commented Sep 19, 2017

@feiskyer I refactored the context container descriptions to fix regexp options and make it easier to read. I also removed repetitive text from the suite descriptions, again to make it easier to read and easier to identify regexp options. Nit addressed.

@feiskyer
Copy link
Member

@mikebrow thanks 👍

@feiskyer
Copy link
Member

/lgtm

@feiskyer feiskyer merged commit 046c028 into kubernetes-sigs:master Sep 20, 2017
@Random-Liu
Copy link
Contributor

@feiskyer I'm still reviewing. There are issues. :p

@feiskyer
Copy link
Member

hmm, didn't notice issues. we could open another fix pr for the issues.

@mikebrow
Copy link
Contributor Author

mikebrow commented Sep 20, 2017

@feiskyer @Random-Liu There was an offline discussion (15min ago) about adding another context to separate docker/default tests. I'll push a pr for that in the morn...

@@ -225,7 +247,7 @@ var _ = framework.KubeDescribe("Security Context", func() {
})
})

Context("runtime should support container with security context", func() {
Context("bucket", func() {
Copy link
Contributor

Choose a reason for hiding this comment

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

What do you mean by "bucket"?

Copy link
Contributor Author

@mikebrow mikebrow Sep 20, 2017

Choose a reason for hiding this comment

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

a bucket of tests... This is the second "bucket", bucket-2 would be another possible name. This context is already within the "Security Context" .. the other buckets at this level are NamespaceOption and SeccompProfilePath.

This bucket comprises tests for: SupplementalGroups, RunAsUser, RunAsUserName, ReadOnlyRootfs, Privileged, and Capability. I couldn't come up with a better name for these than the "Security Context bucket"

@@ -402,8 +424,43 @@ var _ = framework.KubeDescribe("Security Context", func() {

checkNetworkManagement(rc, containerID, false)
})
})

Context("SeccompProfilePath", func() {
Copy link
Contributor

Choose a reason for hiding this comment

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

Probably just Seccomp?

Copy link
Contributor Author

@mikebrow mikebrow Sep 20, 2017

Choose a reason for hiding this comment

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

I like using the litteral CRI spec name here as it doesn't test all of Seccomp here. It is literally testing the CRI spec defined options for the SeccompProfilePath:

// LinuxSandboxSecurityContext holds linux security configuration that will be
// applied to a sandbox. Note that:
// 1) It does not apply to containers in the pods.
// 2) It may not be applicable to a PodSandbox which does not contain any running
//    process.
type LinuxSandboxSecurityContext struct {
	// Configurations for the sandbox's namespaces.
	// This will be used only if the PodSandbox uses namespace for isolation.
	NamespaceOptions *NamespaceOption `protobuf:"bytes,1,opt,name=namespace_options,json=namespaceOptions" json:"namespace_options,omitempty"`
	// Optional SELinux context to be applied.
	SelinuxOptions *SELinuxOption `protobuf:"bytes,2,opt,name=selinux_options,json=selinuxOptions" json:"selinux_options,omitempty"`
	// UID to run sandbox processes as, when applicable.
	RunAsUser *Int64Value `protobuf:"bytes,3,opt,name=run_as_user,json=runAsUser" json:"run_as_user,omitempty"`
	// If set, the root filesystem of the sandbox is read-only.
	ReadonlyRootfs bool `protobuf:"varint,4,opt,name=readonly_rootfs,json=readonlyRootfs,proto3" json:"readonly_rootfs,omitempty"`
	// List of groups applied to the first process run in the sandbox, in
	// addition to the sandbox's primary GID.
	SupplementalGroups []int64 `protobuf:"varint,5,rep,packed,name=supplemental_groups,json=supplementalGroups" json:"supplemental_groups,omitempty"`
	// Indicates whether the sandbox will be asked to run a privileged
	// container. If a privileged container is to be executed within it, this
	// MUST be true.
	// This allows a sandbox to take additional security precautions if no
	// privileged containers are expected to be run.
	Privileged bool `protobuf:"varint,6,opt,name=privileged,proto3" json:"privileged,omitempty"`
	// Seccomp profile for the sandbox, candidate values are:
	// * docker/default: the default profile for the docker container runtime
	// * unconfined: unconfined profile, ie, no seccomp sandboxing
	// * localhost/<full-path-to-profile>: the profile installed on the node.
	//   <full-path-to-profile> is the full path of the profile.
	// Default: "", which is identical with unconfined.
	SeccompProfilePath string `protobuf:"bytes,7,opt,name=seccomp_profile_path,json=seccompProfilePath,proto3" json:"seccomp_profile_path,omitempty"`
}

@@ -37,6 +38,27 @@ import (

const (
nginxContainerImage string = "nginx"
localhost string = "localhost/"
// profile which denies sethostname syscall
seccompBlockHostNameProfile = `{
Copy link
Contributor

Choose a reason for hiding this comment

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

Why not moving those 2 consts into the Seccomp context. No one else is using it.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

sure I'll move..


BeforeEach(func() {
profileDir, err = createSeccompProfileDir()
if err != nil {
Copy link
Contributor

Choose a reason for hiding this comment

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

Don't think we could just log and return, it will still run test then.
You should do assertion here Expect(err).NotTo(HaveOccurred()).

Copy link
Contributor

Choose a reason for hiding this comment

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

@mikebrow This is the issue we need to fix.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

agreed will update ..

checkSetHostname(rc, containerID, true)
})

It("runtime should block setting hostname with no seccomp profile specified", func() {
Copy link
Contributor

Choose a reason for hiding this comment

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

no seccomp profile means "unconfined", why set hostname will be blocked? By whom?
Default capabilities? If so, I feel like this is more a capability test instead of seccomp test.

Copy link
Contributor

Choose a reason for hiding this comment

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

WE can add a test to create a default container, and check whether seccomp is enabled. That is useful.

Copy link
Contributor Author

@mikebrow mikebrow Sep 20, 2017

Choose a reason for hiding this comment

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

This is a duplicate test, I'll delete it.

checkSetHostname(rc, containerID, false)
})

It("runtime should support setting hostname with docker/default seccomp profile and sysCaps", func() {
Copy link
Contributor

Choose a reason for hiding this comment

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

Move this to a separate docker/default context.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Yes, we both had that idea at the same time :-)

checkSetHostname(rc, containerID, true)
})

It("runtime should block sethostname with docker/default seccomp profile and no sysCaps", func() {
Copy link
Contributor

Choose a reason for hiding this comment

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

ditto.

checkSetHostname(rc, containerID, false)
})

It("runtime should block sethostname with nil seccomp profile and no sysCaps", func() {
Copy link
Contributor

Choose a reason for hiding this comment

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

Same. This is a default capability test, not seccomp test.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

see above response to your comments.. maybe we should do a quick call on this.

checkSetHostname(rc, containerID, false)
})

It("runtime should block sethostname with unconfined seccomp profile and no sysCaps", func() {
Copy link
Contributor

Choose a reason for hiding this comment

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

Same. This is a default capability test, not seccomp test.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

it's both a default caps test and a seccomp test. See unconfined and default rules below:

	// Seccomp profile for the sandbox, candidate values are:
	// * docker/default: the default profile for the docker container runtime
	// * unconfined: unconfined profile, ie, no seccomp sandboxing
	// * localhost/<full-path-to-profile>: the profile installed on the node.
	//   <full-path-to-profile> is the full path of the profile.
	// Default: "", which is identical with unconfined.
	SeccompProfilePath string `protobuf:"bytes,7,opt,name=seccomp_profile_path,json=seccompProfilePath,proto3" json:"seccomp_profile_path,omitempty"`

If you have an idea for a better way to test the unconfined and nil SeccompProfilePath options.. I'm all ears :)

@Random-Liu
Copy link
Contributor

@mikebrow Please address the comments.

mikebrow added a commit to mikebrow/cri-tools that referenced this pull request Sep 20, 2017
feiskyer added a commit that referenced this pull request Sep 21, 2017
@feiskyer feiskyer mentioned this pull request Sep 22, 2017
3 tasks
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. 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.

4 participants