From 6d9035762d4bb5da8d39c9cad0210ede237c7515 Mon Sep 17 00:00:00 2001 From: Davanum Srinivas Date: Mon, 6 Aug 2018 16:54:04 -0400 Subject: [PATCH] Multi-arch images for metadata-concealment check container Originally from: https://github.com/GoogleCloudPlatform/k8s-metadata-proxy/tree/master/test Moving the code here to prevent bit-rot and to be sure we can recreate or update the images on demand. Moving it here also ensures we can use the common harness to build the multi-arch manifests needed for running the metadata concealment e2e test can run on multiple architectures. Change-Id: I15009268da4e7809a1c03d9af3181b585afa8139 --- test/images/BUILD | 1 + test/images/metadata-concealment/BUILD | 28 ++++ test/images/metadata-concealment/Dockerfile | 19 +++ test/images/metadata-concealment/Makefile | 25 +++ test/images/metadata-concealment/VERSION | 1 + .../check_metadata_concealment.go | 150 ++++++++++++++++++ test/utils/image/manifest.go | 2 +- 7 files changed, 225 insertions(+), 1 deletion(-) create mode 100644 test/images/metadata-concealment/BUILD create mode 100644 test/images/metadata-concealment/Dockerfile create mode 100644 test/images/metadata-concealment/Makefile create mode 100644 test/images/metadata-concealment/VERSION create mode 100644 test/images/metadata-concealment/check_metadata_concealment.go diff --git a/test/images/BUILD b/test/images/BUILD index e8a70a09309..4f169c9bc9f 100644 --- a/test/images/BUILD +++ b/test/images/BUILD @@ -16,6 +16,7 @@ filegroup( "//test/images/fakegitserver:all-srcs", "//test/images/liveness:all-srcs", "//test/images/logs-generator:all-srcs", + "//test/images/metadata-concealment:all-srcs", "//test/images/mounttest:all-srcs", "//test/images/net:all-srcs", "//test/images/netexec:all-srcs", diff --git a/test/images/metadata-concealment/BUILD b/test/images/metadata-concealment/BUILD new file mode 100644 index 00000000000..b6b55eb4034 --- /dev/null +++ b/test/images/metadata-concealment/BUILD @@ -0,0 +1,28 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_binary", "go_library") + +go_library( + name = "go_default_library", + srcs = ["check_metadata_concealment.go"], + importpath = "k8s.io/kubernetes/test/images/metadata-concealment", + visibility = ["//visibility:private"], +) + +filegroup( + name = "package-srcs", + srcs = glob(["**"]), + tags = ["automanaged"], + visibility = ["//visibility:private"], +) + +filegroup( + name = "all-srcs", + srcs = [":package-srcs"], + tags = ["automanaged"], + visibility = ["//visibility:public"], +) + +go_binary( + name = "metadata-concealment", + embed = [":go_default_library"], + visibility = ["//visibility:public"], +) diff --git a/test/images/metadata-concealment/Dockerfile b/test/images/metadata-concealment/Dockerfile new file mode 100644 index 00000000000..e3e3053240c --- /dev/null +++ b/test/images/metadata-concealment/Dockerfile @@ -0,0 +1,19 @@ +# Copyright 2016 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. + +FROM scratch + +COPY check_metadata_concealment / + +ENTRYPOINT ["/check_metadata_concealment"] diff --git a/test/images/metadata-concealment/Makefile b/test/images/metadata-concealment/Makefile new file mode 100644 index 00000000000..970ccd3babe --- /dev/null +++ b/test/images/metadata-concealment/Makefile @@ -0,0 +1,25 @@ +# Copyright 2016 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. + +SRCS=check_metadata_concealment +ARCH ?= amd64 +TARGET ?= $(CURDIR) +GOLANG_VERSION ?= latest +SRC_DIR = $(notdir $(shell pwd)) +export + +bin: + ../image-util.sh bin $(SRCS) + +.PHONY: bin diff --git a/test/images/metadata-concealment/VERSION b/test/images/metadata-concealment/VERSION new file mode 100644 index 00000000000..d3827e75a5c --- /dev/null +++ b/test/images/metadata-concealment/VERSION @@ -0,0 +1 @@ +1.0 diff --git a/test/images/metadata-concealment/check_metadata_concealment.go b/test/images/metadata-concealment/check_metadata_concealment.go new file mode 100644 index 00000000000..9269bd82087 --- /dev/null +++ b/test/images/metadata-concealment/check_metadata_concealment.go @@ -0,0 +1,150 @@ +/* +Copyright 2017 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 main + +import ( + "fmt" + "io/ioutil" + "log" + "net/http" + "os" + "regexp" +) + +var ( + successEndpoints = []string{ + // Discovery + "http://169.254.169.254", + "http://metadata.google.internal", + "http://169.254.169.254/", + "http://metadata.google.internal/", + "http://metadata.google.internal/0.1", + "http://metadata.google.internal/0.1/", + "http://metadata.google.internal/0.1/meta-data", + "http://metadata.google.internal/computeMetadata", + "http://metadata.google.internal/computeMetadata/v1beta1", + "http://metadata.google.internal/computeMetadata/v1", + // Allowed API versions. + "http://metadata.google.internal/0.1/meta-data/", + "http://metadata.google.internal/computeMetadata/v1beta1/", + "http://metadata.google.internal/computeMetadata/v1/", + // Service account token endpoints. + "http://metadata.google.internal/0.1/meta-data/service-accounts/default/acquire", + "http://metadata.google.internal/computeMetadata/v1beta1/instance/service-accounts/default/token", + "http://metadata.google.internal/computeMetadata/v1/instance/service-accounts/default/token", + // Params that contain 'recursive' as substring. + "http://metadata.google.internal/computeMetadata/v1/instance/?nonrecursive=true", + "http://metadata.google.internal/computeMetadata/v1/instance/?something=other&nonrecursive=true", + } + noKubeEnvEndpoints = []string{ + // Check that these don't get a recursive result. + "http://metadata.google.internal/computeMetadata/v1/instance/?recursive%3Dtrue", // urlencoded + "http://metadata.google.internal/computeMetadata/v1/instance/?re%08ecursive=true", // backspaced + } + failureEndpoints = []string{ + // Other API versions. + "http://metadata.google.internal/0.2/", + "http://metadata.google.internal/computeMetadata/v2/", + // kube-env. + "http://metadata.google.internal/0.1/meta-data/attributes/kube-env", + "http://metadata.google.internal/computeMetadata/v1beta1/instance/attributes/kube-env", + "http://metadata.google.internal/computeMetadata/v1/instance/attributes/kube-env", + // VM identity. + "http://metadata.google.internal/0.1/meta-data/service-accounts/default/identity", + "http://metadata.google.internal/computeMetadata/v1beta1/instance/service-accounts/default/identity", + "http://metadata.google.internal/computeMetadata/v1/instance/service-accounts/default/identity", + // Recursive. + "http://metadata.google.internal/computeMetadata/v1/instance/?recursive=true", + "http://metadata.google.internal/computeMetadata/v1/instance/?something=other&recursive=true", + "http://metadata.google.internal/computeMetadata/v1/instance/?recursive=true&something=other", + // Other. + "http://metadata.google.internal/computeMetadata/v1/instance/attributes//kube-env", + "http://metadata.google.internal/computeMetadata/v1/instance/attributes/../attributes/kube-env", + "http://metadata.google.internal/computeMetadata/v1/instance/service-accounts//default/identity", + "http://metadata.google.internal/computeMetadata/v1/instance/service-accounts/../service-accounts/default/identity", + } +) + +func main() { + success := 0 + h := map[string][]string{ + "Metadata-Flavor": {"Google"}, + } + for _, e := range successEndpoints { + if err := checkURL(e, h, 200, ""); err != nil { + log.Printf("Wrong response for %v: %v", e, err) + success = 1 + } + } + for _, e := range noKubeEnvEndpoints { + if err := checkURL(e, h, 200, "kube-env"); err != nil { + log.Printf("Wrong response for %v: %v", e, err) + success = 1 + } + } + for _, e := range failureEndpoints { + if err := checkURL(e, h, 403, ""); err != nil { + log.Printf("Wrong response for %v: %v", e, err) + success = 1 + } + } + + xForwardedForHeader := map[string][]string{ + "X-Forwarded-For": {"Somebody-somewhere"}, + } + // Check that success endpoints fail if X-Forwarded-For is present. + for _, e := range successEndpoints { + if err := checkURL(e, xForwardedForHeader, 403, ""); err != nil { + log.Printf("Wrong response for %v with X-Forwarded-For: %v", e, err) + success = 1 + } + } + os.Exit(success) +} + +// Checks that a URL with the given headers returns the right code, and if s is +// non-empty, checks that the body doesn't contain s. +func checkURL(url string, header http.Header, expectedStatus int, s string) error { + client := &http.Client{} + req, err := http.NewRequest("GET", url, nil) + if err != nil { + return err + } + req.Header = header + resp, err := client.Do(req) + if err != nil { + return err + } + defer resp.Body.Close() + if resp.StatusCode != expectedStatus { + return fmt.Errorf("unexpected response: got %d, want %d", resp.StatusCode, expectedStatus) + } + body, err := ioutil.ReadAll(resp.Body) + if err != nil { + return err + } + if s != "" { + matched, err := regexp.Match(s, body) + if err != nil { + return err + } + if matched { + return fmt.Errorf("body incorrectly contained %q: got %v", s, string(body)) + } + } + return nil +} diff --git a/test/utils/image/manifest.go b/test/utils/image/manifest.go index 78828b8d9f4..52349cf3878 100644 --- a/test/utils/image/manifest.go +++ b/test/utils/image/manifest.go @@ -53,7 +53,7 @@ var ( APIServer = ImageConfig{e2eRegistry, "sample-apiserver", "1.0", false} AppArmorLoader = ImageConfig{e2eRegistry, "apparmor-loader", "1.0", false} BusyBox = ImageConfig{dockerLibraryRegistry, "busybox", "1.29", false} - CheckMetadataConcealment = ImageConfig{gcRegistry, "check-metadata-concealment", "v0.0.3", false} + CheckMetadataConcealment = ImageConfig{e2eRegistry, "metadata-concealment", "1.0", false} CudaVectorAdd = ImageConfig{e2eRegistry, "cuda-vector-add", "1.0", false} Dnsutils = ImageConfig{e2eRegistry, "dnsutils", "1.1", false} EchoServer = ImageConfig{gcRegistry, "echoserver", "1.10", false}