Skip to content

Commit 97cb563

Browse files
committed
Require auth for all new Kubelet endpoints
1 parent f0077a3 commit 97cb563

File tree

2 files changed

+82
-9
lines changed

2 files changed

+82
-9
lines changed

pkg/kubelet/server/server.go

Lines changed: 15 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -306,9 +306,10 @@ func NewServer(
306306
if auth != nil {
307307
server.InstallAuthFilter()
308308
}
309-
server.InstallDefaultHandlers()
309+
server.InstallAuthNotRequiredHandlers()
310310
if kubeCfg != nil && kubeCfg.EnableDebuggingHandlers {
311-
server.InstallDebuggingHandlers()
311+
klog.InfoS("Adding debug handlers to kubelet server")
312+
server.InstallAuthRequiredHandlers()
312313
// To maintain backward compatibility serve logs and pprof only when enableDebuggingHandlers is also enabled
313314
// see https://github.com/kubernetes/kubernetes/pull/87273
314315
server.InstallSystemLogHandler(kubeCfg.EnableSystemLogHandler, kubeCfg.EnableSystemLogQuery)
@@ -402,9 +403,11 @@ func (s *Server) getMetricMethodBucket(method string) string {
402403
return "other"
403404
}
404405

405-
// InstallDefaultHandlers registers the default set of supported HTTP request
406-
// patterns with the restful Container.
407-
func (s *Server) InstallDefaultHandlers() {
406+
// InstallAuthNotRequiredHandlers registers request handlers that do not require authorization, which are
407+
// installed on both the unsecured and secured (TLS) servers.
408+
// NOTE: This method is maintained for backwards compatibility, but no new endpoints should be added
409+
// to this set. New handlers should be added under InstallAuthorizedHandlers.
410+
func (s *Server) InstallAuthNotRequiredHandlers() {
408411
s.addMetricsBucketMatcher("healthz")
409412
checkers := []healthz.HealthChecker{
410413
healthz.PingHealthz,
@@ -480,12 +483,15 @@ func (s *Server) InstallDefaultHandlers() {
480483
s.restfulCont.Handle(proberMetricsPath,
481484
compbasemetrics.HandlerFor(p, compbasemetrics.HandlerOpts{ErrorHandling: compbasemetrics.ContinueOnError}),
482485
)
483-
}
484486

485-
// InstallDebuggingHandlers registers the HTTP request patterns that serve logs or run commands/containers
486-
func (s *Server) InstallDebuggingHandlers() {
487-
klog.InfoS("Adding debug handlers to kubelet server")
487+
// DO NOT ADD NEW HANDLERS HERE!
488+
// See note in method comment.
489+
}
488490

491+
// InstallAuthRequiredHandlers registers the HTTP handlers that should only be installed on servers
492+
// with authorization enabled.
493+
// NOTE: New endpoints must require authorization.
494+
func (s *Server) InstallAuthRequiredHandlers() {
489495
s.addMetricsBucketMatcher("run")
490496
ws := new(restful.WebService)
491497
ws.

pkg/kubelet/server/server_test.go

Lines changed: 67 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,7 @@ import (
4444
"k8s.io/apimachinery/pkg/types"
4545
"k8s.io/apimachinery/pkg/util/httpstream"
4646
"k8s.io/apimachinery/pkg/util/httpstream/spdy"
47+
"k8s.io/apimachinery/pkg/util/sets"
4748
"k8s.io/apiserver/pkg/authentication/authenticator"
4849
"k8s.io/apiserver/pkg/authentication/user"
4950
"k8s.io/apiserver/pkg/authorization/authorizer"
@@ -575,6 +576,72 @@ func TestAuthzCoverage(t *testing.T) {
575576
}
576577
}
577578

579+
func TestInstallAuthNotRequiredHandlers(t *testing.T) {
580+
fw := newServerTestWithDebug(false, nil)
581+
defer fw.testHTTPServer.Close()
582+
583+
// No new handlers should be added to this list.
584+
allowedAuthNotRequiredHandlers := sets.NewString(
585+
"/healthz",
586+
"/healthz/log",
587+
"/healthz/ping",
588+
"/healthz/syncloop",
589+
"/metrics",
590+
"/metrics/slis",
591+
"/metrics/cadvisor",
592+
"/metrics/probes",
593+
"/metrics/resource",
594+
"/pods/",
595+
"/stats/",
596+
"/stats/summary",
597+
)
598+
599+
// These handlers are explicitly disabled.
600+
debuggingDisabledHandlers := sets.NewString(
601+
"/run/",
602+
"/exec/",
603+
"/attach/",
604+
"/portForward/",
605+
"/containerLogs/",
606+
"/runningpods/",
607+
"/debug/pprof/",
608+
"/logs/",
609+
)
610+
allowedAuthNotRequiredHandlers.Insert(debuggingDisabledHandlers.UnsortedList()...)
611+
612+
// Test all the non-web-service handlers
613+
for _, path := range fw.serverUnderTest.restfulCont.RegisteredHandlePaths() {
614+
if !allowedAuthNotRequiredHandlers.Has(path) {
615+
t.Errorf("New handler %q must require auth", path)
616+
}
617+
}
618+
619+
// Test all the generated web-service paths
620+
for _, ws := range fw.serverUnderTest.restfulCont.RegisteredWebServices() {
621+
for _, r := range ws.Routes() {
622+
if !allowedAuthNotRequiredHandlers.Has(r.Path) {
623+
t.Errorf("New handler %q must require auth", r.Path)
624+
}
625+
}
626+
}
627+
628+
// Ensure the disabled handlers are in fact disabled.
629+
for path := range debuggingDisabledHandlers {
630+
for _, method := range []string{"GET", "POST", "PUT", "PATCH", "DELETE"} {
631+
t.Run(method+":"+path, func(t *testing.T) {
632+
req, err := http.NewRequest(method, fw.testHTTPServer.URL+path, nil)
633+
require.NoError(t, err)
634+
635+
resp, err := http.DefaultClient.Do(req)
636+
require.NoError(t, err)
637+
defer resp.Body.Close() //nolint:errcheck
638+
639+
assert.Equal(t, http.StatusMethodNotAllowed, resp.StatusCode)
640+
})
641+
}
642+
}
643+
}
644+
578645
func TestAuthFilters(t *testing.T) {
579646
// Enable features.ContainerCheckpoint during test
580647
featuregatetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, features.ContainerCheckpoint, true)

0 commit comments

Comments
 (0)