Fix container terminal security risk

Signed-off-by: hongming <talonwan@yunify.com>
This commit is contained in:
hongming
2021-06-10 15:16:12 +08:00
parent b77beedbf7
commit 2c60762cfc
4 changed files with 36 additions and 5 deletions

View File

@@ -229,7 +229,7 @@ func (s *APIServer) installKubeSphereAPIs() {
s.KubernetesClient.Master()))
urlruntime.Must(tenantv1alpha2.AddToContainer(s.container, s.InformerFactory, s.KubernetesClient.Kubernetes(),
s.KubernetesClient.KubeSphere(), s.EventsClient, s.LoggingClient, s.AuditingClient, amOperator, rbacAuthorizer, s.MonitoringClient, s.RuntimeCache, s.Config.MeteringOptions))
urlruntime.Must(terminalv1alpha2.AddToContainer(s.container, s.KubernetesClient.Kubernetes(), s.KubernetesClient.Config()))
urlruntime.Must(terminalv1alpha2.AddToContainer(s.container, s.KubernetesClient.Kubernetes(), rbacAuthorizer, s.KubernetesClient.Config()))
urlruntime.Must(clusterkapisv1alpha1.AddToContainer(s.container,
s.InformerFactory.KubernetesSharedInformerFactory(),
s.InformerFactory.KubeSphereSharedInformerFactory(),

View File

@@ -17,8 +17,13 @@ limitations under the License.
package v1alpha2
import (
"errors"
"net/http"
"kubesphere.io/kubesphere/pkg/api"
"kubesphere.io/kubesphere/pkg/apiserver/authorization/authorizer"
requestctx "kubesphere.io/kubesphere/pkg/apiserver/request"
"github.com/emicklei/go-restful"
"github.com/gorilla/websocket"
"k8s.io/client-go/kubernetes"
@@ -37,9 +42,10 @@ var upgrader = websocket.Upgrader{
type terminalHandler struct {
terminaler terminal.Interface
authorizer authorizer.Authorizer
}
func newTerminalHandler(client kubernetes.Interface, config *rest.Config) *terminalHandler {
func newTerminalHandler(client kubernetes.Interface, authorizer authorizer.Authorizer, config *rest.Config) *terminalHandler {
return &terminalHandler{
terminaler: terminal.NewTerminaler(client, config),
}
@@ -51,6 +57,29 @@ func (t *terminalHandler) handleTerminalSession(request *restful.Request, respon
containerName := request.QueryParameter("container")
shell := request.QueryParameter("shell")
user, _ := requestctx.UserFrom(request.Request.Context())
createPodsExec := authorizer.AttributesRecord{
User: user,
Verb: "create",
Resource: "pods",
Subresource: "exec",
Namespace: namespace,
ResourceRequest: true,
ResourceScope: requestctx.NamespaceScope,
}
decision, reason, err := t.authorizer.Authorize(createPodsExec)
if err != nil {
api.HandleInternalError(response, request, err)
return
}
if decision != authorizer.DecisionAllow {
api.HandleForbidden(response, request, errors.New(reason))
return
}
conn, err := upgrader.Upgrade(response.ResponseWriter, request.Request, nil)
if err != nil {
klog.Warning(err)

View File

@@ -23,6 +23,8 @@ import (
"k8s.io/client-go/kubernetes"
"k8s.io/client-go/rest"
"kubesphere.io/kubesphere/pkg/apiserver/authorization/authorizer"
"kubesphere.io/kubesphere/pkg/apiserver/runtime"
"kubesphere.io/kubesphere/pkg/constants"
"kubesphere.io/kubesphere/pkg/models"
@@ -34,11 +36,11 @@ const (
var GroupVersion = schema.GroupVersion{Group: GroupName, Version: "v1alpha2"}
func AddToContainer(c *restful.Container, client kubernetes.Interface, config *rest.Config) error {
func AddToContainer(c *restful.Container, client kubernetes.Interface, authorizer authorizer.Authorizer, config *rest.Config) error {
webservice := runtime.NewWebService(GroupVersion)
handler := newTerminalHandler(client, config)
handler := newTerminalHandler(client, authorizer, config)
webservice.Route(webservice.GET("/namespaces/{namespace}/pods/{pod}/exec").
To(handler.handleTerminalSession).

View File

@@ -132,7 +132,7 @@ func generateSwaggerJson() []byte {
urlruntime.Must(resourcesv1alpha2.AddToContainer(container, clientsets.Kubernetes(), informerFactory, ""))
urlruntime.Must(resourcesv1alpha3.AddToContainer(container, informerFactory, nil))
urlruntime.Must(tenantv1alpha2.AddToContainer(container, informerFactory, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil))
urlruntime.Must(terminalv1alpha2.AddToContainer(container, clientsets.Kubernetes(), nil))
urlruntime.Must(terminalv1alpha2.AddToContainer(container, clientsets.Kubernetes(), nil, nil))
urlruntime.Must(metricsv1alpha2.AddToContainer(container))
urlruntime.Must(networkv1alpha2.AddToContainer(container, ""))
alertingOptions := &alerting.Options{}