Add --block-instance-metadata flag (#396)
* Add --block-instance-metadata flag * Switch from 404 to 403 for blocked requests * Only block /metadata/instance * Add message body to 403 response * Add docs on --block-instance-metadata
This commit is contained in:
Родитель
76d3a9bd1d
Коммит
d56b44ac44
|
@ -41,6 +41,7 @@ var (
|
|||
findIdentityRetryIntervalInSeconds = pflag.Int("find-identity-retry-interval", defaultlistPodIDsRetryIntervalInSeconds, "Retry interval to find assigned identities in seconds")
|
||||
enableProfile = pflag.Bool("enableProfile", false, "Enable/Disable pprof profiling")
|
||||
enableScaleFeatures = pflag.Bool("enableScaleFeatures", false, "Enable/Disable features for scale clusters")
|
||||
blockInstanceMetadata = pflag.Bool("block-instance-metadata", false, "Block instance metadata endpoints")
|
||||
)
|
||||
|
||||
func main() {
|
||||
|
@ -75,7 +76,7 @@ func main() {
|
|||
exit := make(<-chan struct{})
|
||||
client.Start(exit)
|
||||
*forceNamespaced = *forceNamespaced || "true" == os.Getenv("FORCENAMESPACED")
|
||||
s := server.NewServer(*forceNamespaced, *micNamespace)
|
||||
s := server.NewServer(*forceNamespaced, *micNamespace, *blockInstanceMetadata)
|
||||
s.KubeClient = client
|
||||
s.MetadataIP = *metadataIP
|
||||
s.MetadataPort = *metadataPort
|
||||
|
|
|
@ -21,3 +21,24 @@ node/VMSS.
|
|||
|
||||
Aad-pod-identity has a new flag clientQps which can be used to control the total number of client operations performed per second
|
||||
to the API server by MIC.
|
||||
|
||||
## Block Instance Metadata flag
|
||||
|
||||
The Azure Metadata API includes endpoints under `/instance/metadata` which
|
||||
provide information about the virtual machine. You can see examples of this
|
||||
endpoint in [the Azure documentation](https://docs.microsoft.com/en-us/azure/virtual-machines/linux/instance-metadata-service#retrieving-all-metadata-for-an-instance).
|
||||
|
||||
Some of the information returned by this endpoint may be considered sensitive
|
||||
or secret. The response includes information on the operating system and image,
|
||||
tags, resource IDs, network, and VM custom data.
|
||||
|
||||
This information is legitimately useful for many use cases, but also presents a
|
||||
risk. If an attacker can exploit a vulnerability that allows them to read from
|
||||
this endpoint, they may be able to access sensitive information even if the
|
||||
vulnerable Pod does not use Managed Identity.
|
||||
|
||||
The `blockInstanceMetadata` flag for NMI will intercept any requests to this
|
||||
endpoint from Pods which are not using host networking and return an HTTP 403
|
||||
Forbidden response. This flag is disabled by default to maximize compatibility.
|
||||
Users are encouraged to determine if this option is relevant and beneficial for
|
||||
their use cases.
|
||||
|
|
|
@ -45,6 +45,7 @@ type Server struct {
|
|||
IsNamespaced bool
|
||||
MICNamespace string
|
||||
Initialized bool
|
||||
BlockInstanceMetadata bool
|
||||
|
||||
ListPodIDsRetryAttemptsForCreated int
|
||||
ListPodIDsRetryAttemptsForAssigned int
|
||||
|
@ -58,10 +59,11 @@ type NMIResponse struct {
|
|||
}
|
||||
|
||||
// NewServer will create a new Server with default values.
|
||||
func NewServer(isNamespaced bool, micNamespace string) *Server {
|
||||
func NewServer(isNamespaced bool, micNamespace string, blockInstanceMetadata bool) *Server {
|
||||
return &Server{
|
||||
IsNamespaced: isNamespaced,
|
||||
MICNamespace: micNamespace,
|
||||
BlockInstanceMetadata: blockInstanceMetadata,
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -74,6 +76,9 @@ func (s *Server) Run() error {
|
|||
mux.Handle("/metadata/identity/oauth2/token/", appHandler(s.msiHandler))
|
||||
mux.Handle("/host/token", appHandler(s.hostHandler))
|
||||
mux.Handle("/host/token/", appHandler(s.hostHandler))
|
||||
if s.BlockInstanceMetadata {
|
||||
mux.Handle("/metadata/instance", http.HandlerFunc(forbiddenHandler))
|
||||
}
|
||||
mux.Handle("/", appHandler(s.defaultPathHandler))
|
||||
|
||||
log.Infof("Listening on port %s", s.NMIPort)
|
||||
|
@ -458,6 +463,11 @@ func (s *Server) defaultPathHandler(logger *log.Entry, w http.ResponseWriter, r
|
|||
w.Write(body)
|
||||
}
|
||||
|
||||
// forbiddenHandler responds to any request with HTTP 403 Forbidden
|
||||
func forbiddenHandler(w http.ResponseWriter, r *http.Request) {
|
||||
http.Error(w, "Request blocked by AAD Pod Identity NMI", http.StatusForbidden)
|
||||
}
|
||||
|
||||
func copyHeader(dst, src http.Header) {
|
||||
for k, vv := range src {
|
||||
for _, v := range vv {
|
||||
|
|
Загрузка…
Ссылка в новой задаче