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:
Dharma Bellamkonda 2019-10-14 14:53:48 -06:00 коммит произвёл Krishnakumar R
Родитель 76d3a9bd1d
Коммит d56b44ac44
5 изменённых файлов: 38 добавлений и 6 удалений

Просмотреть файл

@ -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,
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 {