From b2268574c5ebd94e4fc9ad402f81f00464bf571a Mon Sep 17 00:00:00 2001 From: Jordan Liggitt Date: Tue, 8 Sep 2015 23:58:36 -0400 Subject: [PATCH] Add pods/attach to long running requests, protect in admission for privileged pods --- cmd/kube-apiserver/app/server.go | 2 +- cmd/kube-apiserver/app/server_test.go | 4 +++ .../exec/denyprivileged/admission.go | 6 ++-- .../exec/denyprivileged/admission_test.go | 29 ++++++++++++++----- 4 files changed, 30 insertions(+), 11 deletions(-) diff --git a/cmd/kube-apiserver/app/server.go b/cmd/kube-apiserver/app/server.go index 085fb376929..80d8269e6a7 100644 --- a/cmd/kube-apiserver/app/server.go +++ b/cmd/kube-apiserver/app/server.go @@ -57,7 +57,7 @@ const ( // Set to a value larger than the timeouts in each watch server. ReadWriteTimeout = time.Minute * 60 //TODO: This can be tightened up. It still matches objects named watch or proxy. - defaultLongRunningRequestRE = "(/|^)((watch|proxy)(/|$)|(logs|portforward|exec)/?$)" + defaultLongRunningRequestRE = "(/|^)((watch|proxy)(/|$)|(logs?|portforward|exec|attach)/?$)" ) // APIServer runs a kubernetes api server. diff --git a/cmd/kube-apiserver/app/server_test.go b/cmd/kube-apiserver/app/server_test.go index 04ab483c5a6..c6bca513293 100644 --- a/cmd/kube-apiserver/app/server_test.go +++ b/cmd/kube-apiserver/app/server_test.go @@ -38,12 +38,16 @@ func TestLongRunningRequestRegexp(t *testing.T) { "/api/v1/watch/stuff", "/api/v1/default/service/proxy", "/api/v1/pods/proxy/path/to/thing", + "/api/v1/namespaces/myns/pods/mypod/log", "/api/v1/namespaces/myns/pods/mypod/logs", "/api/v1/namespaces/myns/pods/mypod/portforward", "/api/v1/namespaces/myns/pods/mypod/exec", + "/api/v1/namespaces/myns/pods/mypod/attach", + "/api/v1/namespaces/myns/pods/mypod/log/", "/api/v1/namespaces/myns/pods/mypod/logs/", "/api/v1/namespaces/myns/pods/mypod/portforward/", "/api/v1/namespaces/myns/pods/mypod/exec/", + "/api/v1/namespaces/myns/pods/mypod/attach/", "/api/v1/watch/namespaces/myns/pods", } for _, path := range dontMatch { diff --git a/plugin/pkg/admission/exec/denyprivileged/admission.go b/plugin/pkg/admission/exec/denyprivileged/admission.go index 481eb557baa..9fa8ffb202a 100644 --- a/plugin/pkg/admission/exec/denyprivileged/admission.go +++ b/plugin/pkg/admission/exec/denyprivileged/admission.go @@ -45,8 +45,8 @@ func (d *denyExecOnPrivileged) Admit(a admission.Attributes) (err error) { if !ok { return errors.NewBadRequest("a connect request was received, but could not convert the request object.") } - // Only handle exec requests on pods - if connectRequest.ResourcePath != "pods/exec" { + // Only handle exec or attach requests on pods + if connectRequest.ResourcePath != "pods/exec" && connectRequest.ResourcePath != "pods/attach" { return nil } pod, err := d.client.Pods(a.GetNamespace()).Get(connectRequest.Name) @@ -54,7 +54,7 @@ func (d *denyExecOnPrivileged) Admit(a admission.Attributes) (err error) { return admission.NewForbidden(a, err) } if isPrivileged(pod) { - return admission.NewForbidden(a, fmt.Errorf("Cannot exec into a privileged container")) + return admission.NewForbidden(a, fmt.Errorf("Cannot exec into or attach to a privileged container")) } return nil } diff --git a/plugin/pkg/admission/exec/denyprivileged/admission_test.go b/plugin/pkg/admission/exec/denyprivileged/admission_test.go index 22d5b97613d..4c0bc7115ec 100644 --- a/plugin/pkg/admission/exec/denyprivileged/admission_test.go +++ b/plugin/pkg/admission/exec/denyprivileged/admission_test.go @@ -47,15 +47,30 @@ func testAdmission(t *testing.T, pod *api.Pod, shouldAccept bool) { handler := &denyExecOnPrivileged{ client: mockClient, } - req := &rest.ConnectRequest{Name: pod.Name, ResourcePath: "pods/exec"} - err := handler.Admit(admission.NewAttributesRecord(req, "Pod", "test", "name", "pods", "exec", admission.Connect, nil)) - if shouldAccept && err != nil { - t.Errorf("Unexpected error returned from admission handler: %v", err) - } - if !shouldAccept && err == nil { - t.Errorf("An error was expected from the admission handler. Received nil") + + // pods/exec + { + req := &rest.ConnectRequest{Name: pod.Name, ResourcePath: "pods/exec"} + err := handler.Admit(admission.NewAttributesRecord(req, "Pod", "test", "name", "pods", "exec", admission.Connect, nil)) + if shouldAccept && err != nil { + t.Errorf("Unexpected error returned from admission handler: %v", err) + } + if !shouldAccept && err == nil { + t.Errorf("An error was expected from the admission handler. Received nil") + } } + // pods/attach + { + req := &rest.ConnectRequest{Name: pod.Name, ResourcePath: "pods/attach"} + err := handler.Admit(admission.NewAttributesRecord(req, "Pod", "test", "name", "pods", "attach", admission.Connect, nil)) + if shouldAccept && err != nil { + t.Errorf("Unexpected error returned from admission handler: %v", err) + } + if !shouldAccept && err == nil { + t.Errorf("An error was expected from the admission handler. Received nil") + } + } } func acceptPod(name string) *api.Pod {