Merge pull request #96616 from perithompson/windows-check-permissions

Check Kubelet is running with correct Windows Permissions
This commit is contained in:
Kubernetes Prow Robot 2021-03-11 19:08:17 -08:00 committed by GitHub
commit a8ac0c98b9
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 122 additions and 15 deletions

View File

@ -1,5 +1,5 @@
/*
Copyright 2015 The Kubernetes Authors.
Copyright 2021 The Kubernetes Authors.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
@ -25,7 +25,6 @@ import (
"math"
"net"
"net/http"
"os"
"path"
"path/filepath"
"strconv"
@ -260,6 +259,9 @@ HTTP server: The kubelet can also listen for HTTP and respond to a simple API
// add the kubelet config controller to kubeletDeps
kubeletDeps.KubeletConfigController = kubeletConfigController
if err := checkPermissions(); err != nil {
klog.ErrorS(err, "kubelet running with insufficient permissions")
}
// set up signal context here in order to be reused by kubelet and docker shim
ctx := genericapiserver.SetupSignalContext()
@ -430,15 +432,6 @@ func Run(ctx context.Context, s *options.KubeletServer, kubeDeps *kubelet.Depend
return nil
}
func checkPermissions() error {
if uid := os.Getuid(); uid != 0 {
return fmt.Errorf("kubelet needs to run as uid `0`. It is being run as %d", uid)
}
// TODO: Check if kubelet is running in the `initial` user namespace.
// http://man7.org/linux/man-pages/man7/user_namespaces.7.html
return nil
}
func setConfigz(cz *configz.Config, kc *kubeletconfiginternal.KubeletConfiguration) error {
scheme, _, err := kubeletscheme.NewSchemeAndCodecs()
if err != nil {
@ -760,10 +753,6 @@ func run(ctx context.Context, s *options.KubeletServer, kubeDeps *kubelet.Depend
}
}
if err := checkPermissions(); err != nil {
klog.Error(err)
}
utilruntime.ReallyCrash = s.ReallyCrashForTesting
// TODO(vmarmol): Do this through container config.

View File

@ -0,0 +1,33 @@
// +build !windows
/*
Copyright 2021 The Kubernetes Authors.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package app
import (
"fmt"
"os"
)
func checkPermissions() error {
if uid := os.Getuid(); uid != 0 {
return fmt.Errorf("kubelet needs to run as uid `0`. It is being run as %d", uid)
}
// TODO: Check if kubelet is running in the `initial` user namespace.
// http://man7.org/linux/man-pages/man7/user_namespaces.7.html
return nil
}

View File

@ -0,0 +1,85 @@
// +build windows
/*
Copyright 2021 The Kubernetes Authors.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package app
import (
"fmt"
"os/user"
"golang.org/x/sys/windows"
)
func isAdmin() (bool, error) {
// Get current user
u, err := user.Current()
if err != nil {
return false, fmt.Errorf("Error retrieving current user: %s", err)
}
// Get IDs of group user is a member of
ids, err := u.GroupIds()
if err != nil {
return false, fmt.Errorf("Error retrieving group ids: %s", err)
}
// Check for existence of BUILTIN\ADMINISTRATORS group id
for i := range ids {
// BUILTIN\ADMINISTRATORS
if "S-1-5-32-544" == ids[i] {
return true, nil
}
}
return false, nil
}
func checkPermissions() error {
//https://github.com/golang/go/issues/28804#issuecomment-505326268
var sid *windows.SID
var userIsAdmin bool
// https://docs.microsoft.com/en-us/windows/desktop/api/securitybaseapi/nf-securitybaseapi-checktokenmembership
err := windows.AllocateAndInitializeSid(
&windows.SECURITY_NT_AUTHORITY,
2,
windows.SECURITY_BUILTIN_DOMAIN_RID,
windows.DOMAIN_ALIAS_RID_ADMINS,
0, 0, 0, 0, 0, 0,
&sid)
if err != nil {
return fmt.Errorf("Error while checking for elevated permissions: %s", err)
}
//We must free the sid to prevent security token leaks
defer windows.FreeSid(sid)
token := windows.Token(0)
userIsAdmin, err = isAdmin()
if err != nil {
return fmt.Errorf("Error while checking admin group membership: %s", err)
}
member, err := token.IsMember(sid)
if err != nil {
return fmt.Errorf("Error while checking for elevated permissions: %s", err)
}
if !member {
return fmt.Errorf("kubelet needs to run with administrator permissions. Run as admin is: %t, User in admin group: %t", member, userIsAdmin)
}
return nil
}