diff --git a/README.md b/README.md index 6abdc4b1..5a7566e7 100644 --- a/README.md +++ b/README.md @@ -556,6 +556,8 @@ Usage of kube2iam: --iam-role-session-ttl Length of session when assuming the roles (default 15m) --debug Enable debug features --default-role string Fallback role to use when annotation is not set + --disable-sensitive-metadata Make some sensitive metadata paths return empty strings + --disable-user-data Make the user-data endpoint return an empty string instead of the host's user-data --host-interface string Host interface for proxying AWS metadata (default "docker0") --host-ip string IP address of host --iam-role-key string Pod annotation key used to retrieve the IAM role (default "iam.amazonaws.com/role") diff --git a/cmd/main.go b/cmd/main.go index d43bb5a1..86b2b437 100644 --- a/cmd/main.go +++ b/cmd/main.go @@ -41,6 +41,8 @@ func addFlags(s *server.Server, fs *pflag.FlagSet) { fs.BoolVar(&s.UseRegionalStsEndpoint, "use-regional-sts-endpoint", false, "use the regional sts endpoint if AWS_REGION is set") fs.BoolVar(&s.Verbose, "verbose", false, "Verbose") fs.BoolVar(&s.Version, "version", false, "Print the version and exits") + fs.BoolVar(&s.DisableSensitiveMetadata, "disable-sensitive-metadata", false, "Make some sensitive metadata paths return empty strings") + fs.BoolVar(&s.DisableUserData, "disable-user-data", false, "Make the user-data endpoint return an empty string instead of the host's user-data") } func main() { diff --git a/server/server.go b/server/server.go index 4d13ace6..7de1f4f9 100644 --- a/server/server.go +++ b/server/server.go @@ -70,6 +70,8 @@ type Server struct { NamespaceRestriction bool Verbose bool Version bool + DisableSensitiveMetadata bool + DisableUserData bool iam *iam.Client k8s *k8s.Client roleMapper *mappings.RoleMapper @@ -268,6 +270,10 @@ func (s *Server) debugStoreHandler(logger *log.Entry, w http.ResponseWriter, r * write(logger, w, string(o)) } +func (s *Server) emptyResponseHandler(logger *log.Entry, w http.ResponseWriter, r *http.Request) { + w.Header().Set("Server", "EC2ws") +} + func (s *Server) securityCredentialsHandler(logger *log.Entry, w http.ResponseWriter, r *http.Request) { w.Header().Set("Server", "EC2ws") remoteIP := parseRemoteAddr(r.RemoteAddr) @@ -371,6 +377,25 @@ func (s *Server) Run(host, token, nodeName string, insecure bool) error { // This is a potential security risk if enabled in some clusters, hence the flag r.Handle("/debug/store", newAppHandler("debugStoreHandler", s.debugStoreHandler)) } + + emptyResponseHandler := newAppHandler("emptyResponseHandler", s.emptyResponseHandler) + if s.DisableUserData { + r.Handle("/{version}/user-data", emptyResponseHandler) + r.Handle("/{version}/user-data/{path:.*}", emptyResponseHandler) + } + if s.DisableSensitiveMetadata { + // permit instance identity document, but not its signatures + r.Handle("/{version}/dynamic/instance-identity/document", newAppHandler("reserveProxyHandler", s.reverseProxyHandler)) + r.Handle("/{version}/dynamic/instance-identity/{path:.+}", emptyResponseHandler) + // hide public keys, disk configuration, security group & iam information + r.Handle("/{version}/meta-data/public-keys/{path:.*}", emptyResponseHandler) + r.Handle("/{version}/meta-data/block-device-mapping/{path:.*}", emptyResponseHandler) + r.Handle("/{version}/meta-data/network/{path:.*}", emptyResponseHandler) + r.Handle("/{version}/meta-data/security-groups", emptyResponseHandler) + r.Handle("/{version}/meta-data/security-groups/{path:.*}", emptyResponseHandler) + r.Handle("/{version}/meta-data/iam/info", emptyResponseHandler) + r.Handle("/{version}/meta-data/iam/info/{path:.*}", emptyResponseHandler) + } r.Handle("/{version}/meta-data/iam/security-credentials", securityHandler) r.Handle("/{version}/meta-data/iam/security-credentials/", securityHandler) r.Handle(