Provide a way to override the new HTTP loopback-only validation
Add new deprecated_insecure_accept_external_unencrypted_http_requests value in values.yaml. Allow it to be a boolean or a string to make it easier to use (both --data-value and --data-value-yaml will work). Also: - Consider "ip6-localhost" and "ip6-loopback" to be loopback addresses for the validation - Remove unused env.SupervisorHTTPAddress var - Deprecate the `service_http_*` values in values.yaml by renaming them and causing a ytt render error when the old names are used
This commit is contained in:
parent
8d12c1b674
commit
488f08dd6e
@ -1,4 +1,4 @@
|
|||||||
#! Copyright 2020-2021 the Pinniped contributors. All Rights Reserved.
|
#! Copyright 2020-2022 the Pinniped contributors. All Rights Reserved.
|
||||||
#! SPDX-License-Identifier: Apache-2.0
|
#! SPDX-License-Identifier: Apache-2.0
|
||||||
|
|
||||||
#@ load("@ytt:data", "data")
|
#@ load("@ytt:data", "data")
|
||||||
@ -52,6 +52,7 @@ _: #@ template.replace(data.values.custom_labels)
|
|||||||
#@ "defaultTLSCertificateSecret": defaultResourceNameWithSuffix("default-tls-certificate"),
|
#@ "defaultTLSCertificateSecret": defaultResourceNameWithSuffix("default-tls-certificate"),
|
||||||
#@ },
|
#@ },
|
||||||
#@ "labels": labels(),
|
#@ "labels": labels(),
|
||||||
|
#@ "insecure_accept_external_unencrypted_http_requests": data.values.deprecated_insecure_accept_external_unencrypted_http_requests
|
||||||
#@ }
|
#@ }
|
||||||
#@ if data.values.log_level:
|
#@ if data.values.log_level:
|
||||||
#@ config["logLevel"] = getAndValidateLogLevel()
|
#@ config["logLevel"] = getAndValidateLogLevel()
|
||||||
|
@ -1,10 +1,23 @@
|
|||||||
#! Copyright 2020-2021 the Pinniped contributors. All Rights Reserved.
|
#! Copyright 2020-2022 the Pinniped contributors. All Rights Reserved.
|
||||||
#! SPDX-License-Identifier: Apache-2.0
|
#! SPDX-License-Identifier: Apache-2.0
|
||||||
|
|
||||||
#@ load("@ytt:data", "data")
|
#@ load("@ytt:data", "data")
|
||||||
#@ load("helpers.lib.yaml", "labels", "deploymentPodLabel", "namespace", "defaultResourceName", "defaultResourceNameWithSuffix")
|
#@ load("helpers.lib.yaml", "labels", "deploymentPodLabel", "namespace", "defaultResourceName", "defaultResourceNameWithSuffix")
|
||||||
|
|
||||||
#@ if data.values.service_http_nodeport_port or data.values.service_https_nodeport_port:
|
#@ if data.values.service_http_nodeport_port != "removed":
|
||||||
|
#@ fail("value service_http_nodeport_port has been renamed to deprecated_service_http_nodeport_port and will be removed in a future release")
|
||||||
|
#@ end
|
||||||
|
#@ if data.values.service_http_nodeport_nodeport != "removed":
|
||||||
|
#@ fail("value service_http_nodeport_nodeport has been renamed to deprecated_service_http_nodeport_nodeport and will be removed in a future release")
|
||||||
|
#@ end
|
||||||
|
#@ if data.values.service_http_loadbalancer_port != "removed":
|
||||||
|
#@ fail("value service_http_loadbalancer_port has been renamed to deprecated_service_http_loadbalancer_port and will be removed in a future release")
|
||||||
|
#@ end
|
||||||
|
#@ if data.values.service_http_clusterip_port != "removed":
|
||||||
|
#@ fail("value service_http_clusterip_port has been renamed to deprecated_service_http_clusterip_port and will be removed in a future release")
|
||||||
|
#@ end
|
||||||
|
|
||||||
|
#@ if data.values.deprecated_service_http_nodeport_port or data.values.service_https_nodeport_port:
|
||||||
---
|
---
|
||||||
apiVersion: v1
|
apiVersion: v1
|
||||||
kind: Service
|
kind: Service
|
||||||
@ -19,13 +32,13 @@ spec:
|
|||||||
type: NodePort
|
type: NodePort
|
||||||
selector: #@ deploymentPodLabel()
|
selector: #@ deploymentPodLabel()
|
||||||
ports:
|
ports:
|
||||||
#@ if data.values.service_http_nodeport_port:
|
#@ if data.values.deprecated_service_http_nodeport_port:
|
||||||
- name: http
|
- name: http
|
||||||
protocol: TCP
|
protocol: TCP
|
||||||
port: #@ data.values.service_http_nodeport_port
|
port: #@ data.values.deprecated_service_http_nodeport_port
|
||||||
targetPort: 8080
|
targetPort: 8080
|
||||||
#@ if data.values.service_http_nodeport_nodeport:
|
#@ if data.values.deprecated_service_http_nodeport_nodeport:
|
||||||
nodePort: #@ data.values.service_http_nodeport_nodeport
|
nodePort: #@ data.values.deprecated_service_http_nodeport_nodeport
|
||||||
#@ end
|
#@ end
|
||||||
#@ end
|
#@ end
|
||||||
#@ if data.values.service_https_nodeport_port:
|
#@ if data.values.service_https_nodeport_port:
|
||||||
@ -39,7 +52,7 @@ spec:
|
|||||||
#@ end
|
#@ end
|
||||||
#@ end
|
#@ end
|
||||||
|
|
||||||
#@ if data.values.service_http_clusterip_port or data.values.service_https_clusterip_port:
|
#@ if data.values.deprecated_service_http_clusterip_port or data.values.service_https_clusterip_port:
|
||||||
---
|
---
|
||||||
apiVersion: v1
|
apiVersion: v1
|
||||||
kind: Service
|
kind: Service
|
||||||
@ -54,10 +67,10 @@ spec:
|
|||||||
type: ClusterIP
|
type: ClusterIP
|
||||||
selector: #@ deploymentPodLabel()
|
selector: #@ deploymentPodLabel()
|
||||||
ports:
|
ports:
|
||||||
#@ if data.values.service_http_clusterip_port:
|
#@ if data.values.deprecated_service_http_clusterip_port:
|
||||||
- name: http
|
- name: http
|
||||||
protocol: TCP
|
protocol: TCP
|
||||||
port: #@ data.values.service_http_clusterip_port
|
port: #@ data.values.deprecated_service_http_clusterip_port
|
||||||
targetPort: 8080
|
targetPort: 8080
|
||||||
#@ end
|
#@ end
|
||||||
#@ if data.values.service_https_clusterip_port:
|
#@ if data.values.service_https_clusterip_port:
|
||||||
@ -68,7 +81,7 @@ spec:
|
|||||||
#@ end
|
#@ end
|
||||||
#@ end
|
#@ end
|
||||||
|
|
||||||
#@ if data.values.service_http_loadbalancer_port or data.values.service_https_loadbalancer_port:
|
#@ if data.values.deprecated_service_http_loadbalancer_port or data.values.service_https_loadbalancer_port:
|
||||||
---
|
---
|
||||||
apiVersion: v1
|
apiVersion: v1
|
||||||
kind: Service
|
kind: Service
|
||||||
@ -86,10 +99,10 @@ spec:
|
|||||||
loadBalancerIP: #@ data.values.service_loadbalancer_ip
|
loadBalancerIP: #@ data.values.service_loadbalancer_ip
|
||||||
#@ end
|
#@ end
|
||||||
ports:
|
ports:
|
||||||
#@ if data.values.service_http_loadbalancer_port:
|
#@ if data.values.deprecated_service_http_loadbalancer_port:
|
||||||
- name: http
|
- name: http
|
||||||
protocol: TCP
|
protocol: TCP
|
||||||
port: #@ data.values.service_http_loadbalancer_port
|
port: #@ data.values.deprecated_service_http_loadbalancer_port
|
||||||
targetPort: 8080
|
targetPort: 8080
|
||||||
#@ end
|
#@ end
|
||||||
#@ if data.values.service_https_loadbalancer_port:
|
#@ if data.values.service_https_loadbalancer_port:
|
||||||
|
@ -35,26 +35,31 @@ image_tag: latest
|
|||||||
#! Optional.
|
#! Optional.
|
||||||
image_pull_dockerconfigjson: #! e.g. {"auths":{"https://registry.example.com":{"username":"USERNAME","password":"PASSWORD","auth":"BASE64_ENCODED_USERNAME_COLON_PASSWORD"}}}
|
image_pull_dockerconfigjson: #! e.g. {"auths":{"https://registry.example.com":{"username":"USERNAME","password":"PASSWORD","auth":"BASE64_ENCODED_USERNAME_COLON_PASSWORD"}}}
|
||||||
|
|
||||||
#! Specify how to expose the Supervisor app's HTTP and/or HTTPS ports as a Service.
|
#! Specify how to expose the Supervisor app's HTTPS port as a Service.
|
||||||
#! Typically you would set a value for only one of the following service types, for either HTTP or HTTPS depending on your needs.
|
#! Typically, you would set a value for only one of the following service types.
|
||||||
#! An HTTP service should not be exposed outside the cluster. It would not be secure to serve OIDC endpoints to end users via HTTP.
|
#! Setting any of these values means that a Service of that type will be created. They are all optional.
|
||||||
#! Setting any of these values means that a Service of that type will be created.
|
|
||||||
#! Note that all port numbers should be numbers (not strings), i.e. use ytt's `--data-value-yaml` instead of `--data-value`.
|
#! Note that all port numbers should be numbers (not strings), i.e. use ytt's `--data-value-yaml` instead of `--data-value`.
|
||||||
service_http_nodeport_port: #! when specified, creates a NodePort Service with this `port` value, with port 8080 as its `targetPort`; e.g. 31234
|
#! Several of these values have been deprecated and will be removed in a future release. Their names have been changed to
|
||||||
service_http_nodeport_nodeport: #! the `nodePort` value of the NodePort Service, optional when `service_http_nodeport_port` is specified; e.g. 31234
|
#! mark them as deprecated and to make it obvious upon upgrade to anyone who was using them that they have been deprecated.
|
||||||
service_http_loadbalancer_port: #! when specified, creates a LoadBalancer Service with this `port` value, with port 8080 as its `targetPort`; e.g. 8443
|
service_http_nodeport_port: removed #! this value has been deprecated and renamed to deprecated_service_http_nodeport_port; will be removed in a future release
|
||||||
service_http_clusterip_port: #! when specified, creates a ClusterIP Service with this `port` value, with port 8080 as its `targetPort`; e.g. 8443
|
service_http_nodeport_nodeport: removed #! this value has been deprecated and renamed to deprecated_service_http_nodeport_nodeport; will be removed in a future release
|
||||||
|
service_http_loadbalancer_port: removed #! this value has been deprecated and renamed to deprecated_service_http_loadbalancer_port; will be removed in a future release
|
||||||
|
service_http_clusterip_port: removed #! this value has been deprecated and renamed to deprecated_service_http_clusterip_port; will be removed in a future release
|
||||||
|
deprecated_service_http_nodeport_port: #! will be removed in a future release; when specified, creates a NodePort Service with this `port` value, with port 8080 as its `targetPort`; e.g. 31234
|
||||||
|
deprecated_service_http_nodeport_nodeport: #! will be removed in a future release; the `nodePort` value of the NodePort Service, optional when `deprecated_service_http_nodeport_port` is specified; e.g. 31234
|
||||||
|
deprecated_service_http_loadbalancer_port: #! will be removed in a future release; when specified, creates a LoadBalancer Service with this `port` value, with port 8080 as its `targetPort`; e.g. 8443
|
||||||
|
deprecated_service_http_clusterip_port: #! will be removed in a future release; when specified, creates a ClusterIP Service with this `port` value, with port 8080 as its `targetPort`; e.g. 8443
|
||||||
service_https_nodeport_port: #! when specified, creates a NodePort Service with this `port` value, with port 8443 as its `targetPort`; e.g. 31243
|
service_https_nodeport_port: #! when specified, creates a NodePort Service with this `port` value, with port 8443 as its `targetPort`; e.g. 31243
|
||||||
service_https_nodeport_nodeport: #! the `nodePort` value of the NodePort Service, optional when `service_http_nodeport_port` is specified; e.g. 31243
|
service_https_nodeport_nodeport: #! the `nodePort` value of the NodePort Service, optional when `service_https_nodeport_port` is specified; e.g. 31243
|
||||||
service_https_loadbalancer_port: #! when specified, creates a LoadBalancer Service with this `port` value, with port 8443 as its `targetPort`; e.g. 8443
|
service_https_loadbalancer_port: #! when specified, creates a LoadBalancer Service with this `port` value, with port 8443 as its `targetPort`; e.g. 8443
|
||||||
service_https_clusterip_port: #! when specified, creates a ClusterIP Service with this `port` value, with port 8443 as its `targetPort`; e.g. 8443
|
service_https_clusterip_port: #! when specified, creates a ClusterIP Service with this `port` value, with port 8443 as its `targetPort`; e.g. 8443
|
||||||
#! The `loadBalancerIP` value of the LoadBalancer Service.
|
#! The `loadBalancerIP` value of the LoadBalancer Service.
|
||||||
#! Ignored unless service_http_loadbalancer_port and/or service_https_loadbalancer_port are provided.
|
#! Ignored unless service_https_loadbalancer_port is provided.
|
||||||
#! Optional.
|
#! Optional.
|
||||||
service_loadbalancer_ip: #! e.g. 1.2.3.4
|
service_loadbalancer_ip: #! e.g. 1.2.3.4
|
||||||
|
|
||||||
#! Specify the verbosity of logging: info ("nice to know" information), debug (developer
|
#! Specify the verbosity of logging: info ("nice to know" information), debug (developer information), trace (timing information),
|
||||||
#! information), trace (timing information), all (kitchen sink).
|
#! or all (kitchen sink). Do not use trace or all on production systems, as credentials may get logged.
|
||||||
log_level: #! By default, when this value is left unset, only warnings and errors are printed. There is no way to suppress warning and error logs.
|
log_level: #! By default, when this value is left unset, only warnings and errors are printed. There is no way to suppress warning and error logs.
|
||||||
|
|
||||||
run_as_user: 65532 #! run_as_user specifies the user ID that will own the process, see the Dockerfile for the reasoning behind this choice
|
run_as_user: 65532 #! run_as_user specifies the user ID that will own the process, see the Dockerfile for the reasoning behind this choice
|
||||||
@ -115,3 +120,14 @@ no_proxy: "$(KUBERNETES_SERVICE_HOST),169.254.169.254,127.0.0.1,localhost,.svc,.
|
|||||||
#!
|
#!
|
||||||
#! Optional.
|
#! Optional.
|
||||||
endpoints:
|
endpoints:
|
||||||
|
|
||||||
|
#! Optionally override the validation on the endpoints.http value which checks that only loopback interfaces are used.
|
||||||
|
#! When deprecated_insecure_accept_external_unencrypted_http_requests is true, the HTTP listener is allowed to bind to any
|
||||||
|
#! interface, including interfaces that are listening for traffic from outside the pod. This value is being introduced
|
||||||
|
#! to ease the transition to the new loopback interface validation for the HTTP port for any users who need more time
|
||||||
|
#! to change their ingress strategy to avoid using plain HTTP into the Supervisor pods.
|
||||||
|
#! This value is being introduced and immediately deprecated. It will be removed in some future release, at which time
|
||||||
|
#! traffic from outside the pod will need to be sent to the HTTPS listener instead, with no simple workaround available.
|
||||||
|
#! Allowed values are true (boolean), "true" (string), false (boolean), and "false" (string). The default is false.
|
||||||
|
#! Optional.
|
||||||
|
deprecated_insecure_accept_external_unencrypted_http_requests: false
|
||||||
|
@ -10,13 +10,6 @@ nodes:
|
|||||||
containerPort: 31243
|
containerPort: 31243
|
||||||
hostPort: 12344
|
hostPort: 12344
|
||||||
listenAddress: 127.0.0.1
|
listenAddress: 127.0.0.1
|
||||||
- protocol: TCP
|
|
||||||
# This same port number is hardcoded in the integration test setup
|
|
||||||
# when creating a Service on a kind cluster. It is used to talk to
|
|
||||||
# the supervisor app via HTTP.
|
|
||||||
containerPort: 31234
|
|
||||||
hostPort: 12345
|
|
||||||
listenAddress: 127.0.0.1
|
|
||||||
- protocol: TCP
|
- protocol: TCP
|
||||||
# This same port number is hardcoded in the integration test setup
|
# This same port number is hardcoded in the integration test setup
|
||||||
# when creating a Service on a kind cluster. It is used to talk to
|
# when creating a Service on a kind cluster. It is used to talk to
|
||||||
|
@ -187,7 +187,7 @@ fi
|
|||||||
log_note "Checking for running kind cluster..."
|
log_note "Checking for running kind cluster..."
|
||||||
if ! kind get clusters | grep -q -e '^pinniped$'; then
|
if ! kind get clusters | grep -q -e '^pinniped$'; then
|
||||||
log_note "Creating a kind cluster..."
|
log_note "Creating a kind cluster..."
|
||||||
# Our kind config exposes node port 31234 as 127.0.0.1:12345, 31243 as 127.0.0.1:12344, and 31235 as 127.0.0.1:12346
|
# Our kind config exposes node port 31243 as 127.0.0.1:12344 and 31235 as 127.0.0.1:12346
|
||||||
./hack/kind-up.sh
|
./hack/kind-up.sh
|
||||||
else
|
else
|
||||||
if ! kubectl cluster-info | grep -E '(master|control plane)' | grep -q 127.0.0.1; then
|
if ! kubectl cluster-info | grep -E '(master|control plane)' | grep -q 127.0.0.1; then
|
||||||
@ -290,8 +290,6 @@ supervisor_app_name="pinniped-supervisor"
|
|||||||
supervisor_namespace="supervisor"
|
supervisor_namespace="supervisor"
|
||||||
supervisor_custom_labels="{mySupervisorCustomLabelName: mySupervisorCustomLabelValue}"
|
supervisor_custom_labels="{mySupervisorCustomLabelName: mySupervisorCustomLabelValue}"
|
||||||
log_level="debug"
|
log_level="debug"
|
||||||
service_http_nodeport_port="80"
|
|
||||||
service_http_nodeport_nodeport="31234"
|
|
||||||
service_https_nodeport_port="443"
|
service_https_nodeport_port="443"
|
||||||
service_https_nodeport_nodeport="31243"
|
service_https_nodeport_nodeport="31243"
|
||||||
service_https_clusterip_port="443"
|
service_https_clusterip_port="443"
|
||||||
@ -311,15 +309,10 @@ else
|
|||||||
--data-value "image_tag=$tag" \
|
--data-value "image_tag=$tag" \
|
||||||
--data-value "log_level=$log_level" \
|
--data-value "log_level=$log_level" \
|
||||||
--data-value-yaml "custom_labels=$supervisor_custom_labels" \
|
--data-value-yaml "custom_labels=$supervisor_custom_labels" \
|
||||||
--data-value-yaml "service_http_nodeport_port=$service_http_nodeport_port" \
|
|
||||||
--data-value-yaml "service_http_nodeport_nodeport=$service_http_nodeport_nodeport" \
|
|
||||||
--data-value-yaml "service_https_nodeport_port=$service_https_nodeport_port" \
|
--data-value-yaml "service_https_nodeport_port=$service_https_nodeport_port" \
|
||||||
--data-value-yaml "service_https_nodeport_nodeport=$service_https_nodeport_nodeport" \
|
--data-value-yaml "service_https_nodeport_nodeport=$service_https_nodeport_nodeport" \
|
||||||
--data-value-yaml "service_https_clusterip_port=$service_https_clusterip_port" \
|
--data-value-yaml "service_https_clusterip_port=$service_https_clusterip_port" \
|
||||||
>"$manifest"
|
>"$manifest"
|
||||||
# example of how to disable the http endpoint
|
|
||||||
# this is left enabled for now because our integration tests still rely on it
|
|
||||||
# --data-value-yaml 'endpoints={"http": {"network": "disabled"}}' \
|
|
||||||
|
|
||||||
kapp deploy --yes --app "$supervisor_app_name" --diff-changes --file "$manifest"
|
kapp deploy --yes --app "$supervisor_app_name" --diff-changes --file "$manifest"
|
||||||
kubectl apply --dry-run=client -f "$manifest" # Validate manifest schema.
|
kubectl apply --dry-run=client -f "$manifest" # Validate manifest schema.
|
||||||
@ -392,7 +385,6 @@ export PINNIPED_TEST_WEBHOOK_CA_BUNDLE=${webhook_ca_bundle}
|
|||||||
export PINNIPED_TEST_SUPERVISOR_NAMESPACE=${supervisor_namespace}
|
export PINNIPED_TEST_SUPERVISOR_NAMESPACE=${supervisor_namespace}
|
||||||
export PINNIPED_TEST_SUPERVISOR_APP_NAME=${supervisor_app_name}
|
export PINNIPED_TEST_SUPERVISOR_APP_NAME=${supervisor_app_name}
|
||||||
export PINNIPED_TEST_SUPERVISOR_CUSTOM_LABELS='${supervisor_custom_labels}'
|
export PINNIPED_TEST_SUPERVISOR_CUSTOM_LABELS='${supervisor_custom_labels}'
|
||||||
export PINNIPED_TEST_SUPERVISOR_HTTP_ADDRESS="127.0.0.1:12345"
|
|
||||||
export PINNIPED_TEST_SUPERVISOR_HTTPS_ADDRESS="localhost:12344"
|
export PINNIPED_TEST_SUPERVISOR_HTTPS_ADDRESS="localhost:12344"
|
||||||
export PINNIPED_TEST_PROXY=http://127.0.0.1:12346
|
export PINNIPED_TEST_PROXY=http://127.0.0.1:12346
|
||||||
export PINNIPED_TEST_LDAP_HOST=ldap.tools.svc.cluster.local
|
export PINNIPED_TEST_LDAP_HOST=ldap.tools.svc.cluster.local
|
||||||
|
@ -76,7 +76,7 @@ func FromPath(path string) (*Config, error) {
|
|||||||
if err := validateEndpoint(*config.Endpoints.HTTP); err != nil {
|
if err := validateEndpoint(*config.Endpoints.HTTP); err != nil {
|
||||||
return nil, fmt.Errorf("validate http endpoint: %w", err)
|
return nil, fmt.Errorf("validate http endpoint: %w", err)
|
||||||
}
|
}
|
||||||
if err := validateAdditionalHTTPEndpointRequirements(*config.Endpoints.HTTP); err != nil {
|
if err := validateAdditionalHTTPEndpointRequirements(*config.Endpoints.HTTP, config.AllowExternalHTTP); err != nil {
|
||||||
return nil, fmt.Errorf("validate http endpoint: %w", err)
|
return nil, fmt.Errorf("validate http endpoint: %w", err)
|
||||||
}
|
}
|
||||||
if err := validateAtLeastOneEnabledEndpoint(*config.Endpoints.HTTPS, *config.Endpoints.HTTP); err != nil {
|
if err := validateAtLeastOneEnabledEndpoint(*config.Endpoints.HTTPS, *config.Endpoints.HTTP); err != nil {
|
||||||
@ -131,8 +131,16 @@ func validateEndpoint(endpoint Endpoint) error {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func validateAdditionalHTTPEndpointRequirements(endpoint Endpoint) error {
|
func validateAdditionalHTTPEndpointRequirements(endpoint Endpoint, allowExternalHTTP string) error {
|
||||||
if endpoint.Network == NetworkTCP && !addrIsOnlyOnLoopback(endpoint.Address) {
|
if endpoint.Network == NetworkTCP && !addrIsOnlyOnLoopback(endpoint.Address) {
|
||||||
|
if allowExternalHTTP == "true" {
|
||||||
|
// Log that the validation should have been triggered.
|
||||||
|
plog.Warning("Listening on non-loopback interfaces for the HTTP port is deprecated and will be removed " +
|
||||||
|
"in a future release. Your current configuration would not be allowed in that future release. " +
|
||||||
|
"Please see comments in deploy/supervisor/values.yaml and review your settings.")
|
||||||
|
// Skip enforcement of the validation.
|
||||||
|
return nil
|
||||||
|
}
|
||||||
return fmt.Errorf(
|
return fmt.Errorf(
|
||||||
"http listener address %q for %q network may only bind to loopback interfaces",
|
"http listener address %q for %q network may only bind to loopback interfaces",
|
||||||
endpoint.Address,
|
endpoint.Address,
|
||||||
@ -170,8 +178,9 @@ func addrIsOnlyOnLoopback(addr string) bool {
|
|||||||
// Input was :port. This would bind to all interfaces, so it is not only on loopback.
|
// Input was :port. This would bind to all interfaces, so it is not only on loopback.
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
if host == "localhost" {
|
if host == "localhost" || host == "ip6-localhost" || host == "ip6-loopback" {
|
||||||
// This is only on loopback.
|
// These hostnames are documented as the loopback hostnames seen inside the pod's containers in
|
||||||
|
// https://kubernetes.io/docs/tasks/network/customize-hosts-file-for-pods/#default-hosts-file-content
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
// The host could be a hostname, an IPv4 address, or an IPv6 address.
|
// The host could be a hostname, an IPv4 address, or an IPv6 address.
|
||||||
|
@ -39,6 +39,7 @@ func TestFromPath(t *testing.T) {
|
|||||||
http:
|
http:
|
||||||
network: tcp
|
network: tcp
|
||||||
address: 127.0.0.1:1234
|
address: 127.0.0.1:1234
|
||||||
|
insecure_accept_external_unencrypted_http_requests: false
|
||||||
`),
|
`),
|
||||||
wantConfig: &Config{
|
wantConfig: &Config{
|
||||||
APIGroupSuffix: pointer.StringPtr("some.suffix.com"),
|
APIGroupSuffix: pointer.StringPtr("some.suffix.com"),
|
||||||
@ -59,6 +60,7 @@ func TestFromPath(t *testing.T) {
|
|||||||
Address: "127.0.0.1:1234",
|
Address: "127.0.0.1:1234",
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
AllowExternalHTTP: "false",
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@ -83,6 +85,7 @@ func TestFromPath(t *testing.T) {
|
|||||||
Network: "disabled",
|
Network: "disabled",
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
AllowExternalHTTP: "",
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@ -128,7 +131,7 @@ func TestFromPath(t *testing.T) {
|
|||||||
wantError: `validate http endpoint: unknown network "bar"`,
|
wantError: `validate http endpoint: unknown network "bar"`,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "http endpoint uses tcp but binds to more than only loopback interfaces",
|
name: "http endpoint uses tcp but binds to more than only loopback interfaces with insecure_accept_external_unencrypted_http_requests missing",
|
||||||
yaml: here.Doc(`
|
yaml: here.Doc(`
|
||||||
---
|
---
|
||||||
names:
|
names:
|
||||||
@ -142,6 +145,100 @@ func TestFromPath(t *testing.T) {
|
|||||||
`),
|
`),
|
||||||
wantError: `validate http endpoint: http listener address ":8080" for "tcp" network may only bind to loopback interfaces`,
|
wantError: `validate http endpoint: http listener address ":8080" for "tcp" network may only bind to loopback interfaces`,
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
name: "http endpoint uses tcp but binds to more than only loopback interfaces with insecure_accept_external_unencrypted_http_requests set to boolean false",
|
||||||
|
yaml: here.Doc(`
|
||||||
|
---
|
||||||
|
names:
|
||||||
|
defaultTLSCertificateSecret: my-secret-name
|
||||||
|
endpoints:
|
||||||
|
https:
|
||||||
|
network: disabled
|
||||||
|
http:
|
||||||
|
network: tcp
|
||||||
|
address: :8080
|
||||||
|
insecure_accept_external_unencrypted_http_requests: false
|
||||||
|
`),
|
||||||
|
wantError: `validate http endpoint: http listener address ":8080" for "tcp" network may only bind to loopback interfaces`,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "http endpoint uses tcp but binds to more than only loopback interfaces with insecure_accept_external_unencrypted_http_requests set to string false",
|
||||||
|
yaml: here.Doc(`
|
||||||
|
---
|
||||||
|
names:
|
||||||
|
defaultTLSCertificateSecret: my-secret-name
|
||||||
|
endpoints:
|
||||||
|
https:
|
||||||
|
network: disabled
|
||||||
|
http:
|
||||||
|
network: tcp
|
||||||
|
address: :8080
|
||||||
|
insecure_accept_external_unencrypted_http_requests: "false"
|
||||||
|
`),
|
||||||
|
wantError: `validate http endpoint: http listener address ":8080" for "tcp" network may only bind to loopback interfaces`,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "http endpoint uses tcp but binds to more than only loopback interfaces with insecure_accept_external_unencrypted_http_requests set to boolean true",
|
||||||
|
yaml: here.Doc(`
|
||||||
|
---
|
||||||
|
names:
|
||||||
|
defaultTLSCertificateSecret: my-secret-name
|
||||||
|
endpoints:
|
||||||
|
http:
|
||||||
|
network: tcp
|
||||||
|
address: :1234
|
||||||
|
insecure_accept_external_unencrypted_http_requests: true
|
||||||
|
`),
|
||||||
|
wantConfig: &Config{
|
||||||
|
APIGroupSuffix: pointer.StringPtr("pinniped.dev"),
|
||||||
|
Labels: map[string]string{},
|
||||||
|
NamesConfig: NamesConfigSpec{
|
||||||
|
DefaultTLSCertificateSecret: "my-secret-name",
|
||||||
|
},
|
||||||
|
Endpoints: &Endpoints{
|
||||||
|
HTTPS: &Endpoint{
|
||||||
|
Network: "tcp",
|
||||||
|
Address: ":8443",
|
||||||
|
},
|
||||||
|
HTTP: &Endpoint{
|
||||||
|
Network: "tcp",
|
||||||
|
Address: ":1234",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
AllowExternalHTTP: "true",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "http endpoint uses tcp but binds to more than only loopback interfaces with insecure_accept_external_unencrypted_http_requests set to string true",
|
||||||
|
yaml: here.Doc(`
|
||||||
|
---
|
||||||
|
names:
|
||||||
|
defaultTLSCertificateSecret: my-secret-name
|
||||||
|
endpoints:
|
||||||
|
http:
|
||||||
|
network: tcp
|
||||||
|
address: :1234
|
||||||
|
insecure_accept_external_unencrypted_http_requests: "true"
|
||||||
|
`),
|
||||||
|
wantConfig: &Config{
|
||||||
|
APIGroupSuffix: pointer.StringPtr("pinniped.dev"),
|
||||||
|
Labels: map[string]string{},
|
||||||
|
NamesConfig: NamesConfigSpec{
|
||||||
|
DefaultTLSCertificateSecret: "my-secret-name",
|
||||||
|
},
|
||||||
|
Endpoints: &Endpoints{
|
||||||
|
HTTPS: &Endpoint{
|
||||||
|
Network: "tcp",
|
||||||
|
Address: ":8443",
|
||||||
|
},
|
||||||
|
HTTP: &Endpoint{
|
||||||
|
Network: "tcp",
|
||||||
|
Address: ":1234",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
AllowExternalHTTP: "true",
|
||||||
|
},
|
||||||
|
},
|
||||||
{
|
{
|
||||||
name: "endpoint disabled with non-empty address",
|
name: "endpoint disabled with non-empty address",
|
||||||
yaml: here.Doc(`
|
yaml: here.Doc(`
|
||||||
@ -234,6 +331,14 @@ func TestAddrIsOnlyOnLoopback(t *testing.T) {
|
|||||||
{addr: "localhost:0", want: true},
|
{addr: "localhost:0", want: true},
|
||||||
{addr: "localhost:80", want: true},
|
{addr: "localhost:80", want: true},
|
||||||
{addr: "localhost:http", want: true},
|
{addr: "localhost:http", want: true},
|
||||||
|
{addr: "ip6-localhost:", want: true},
|
||||||
|
{addr: "ip6-localhost:0", want: true},
|
||||||
|
{addr: "ip6-localhost:80", want: true},
|
||||||
|
{addr: "ip6-localhost:http", want: true},
|
||||||
|
{addr: "ip6-loopback:", want: true},
|
||||||
|
{addr: "ip6-loopback:0", want: true},
|
||||||
|
{addr: "ip6-loopback:80", want: true},
|
||||||
|
{addr: "ip6-loopback:http", want: true},
|
||||||
{addr: "127.0.0.1:", want: true},
|
{addr: "127.0.0.1:", want: true},
|
||||||
{addr: "127.0.0.1:0", want: true},
|
{addr: "127.0.0.1:0", want: true},
|
||||||
{addr: "127.0.0.1:80", want: true},
|
{addr: "127.0.0.1:80", want: true},
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
// Copyright 2020-2021 the Pinniped contributors. All Rights Reserved.
|
// Copyright 2020-2022 the Pinniped contributors. All Rights Reserved.
|
||||||
// SPDX-License-Identifier: Apache-2.0
|
// SPDX-License-Identifier: Apache-2.0
|
||||||
|
|
||||||
package supervisor
|
package supervisor
|
||||||
@ -7,11 +7,12 @@ import "go.pinniped.dev/internal/plog"
|
|||||||
|
|
||||||
// Config contains knobs to setup an instance of the Pinniped Supervisor.
|
// Config contains knobs to setup an instance of the Pinniped Supervisor.
|
||||||
type Config struct {
|
type Config struct {
|
||||||
APIGroupSuffix *string `json:"apiGroupSuffix,omitempty"`
|
APIGroupSuffix *string `json:"apiGroupSuffix,omitempty"`
|
||||||
Labels map[string]string `json:"labels"`
|
Labels map[string]string `json:"labels"`
|
||||||
NamesConfig NamesConfigSpec `json:"names"`
|
NamesConfig NamesConfigSpec `json:"names"`
|
||||||
LogLevel plog.LogLevel `json:"logLevel"`
|
LogLevel plog.LogLevel `json:"logLevel"`
|
||||||
Endpoints *Endpoints `json:"endpoints"`
|
Endpoints *Endpoints `json:"endpoints"`
|
||||||
|
AllowExternalHTTP string `json:"insecure_accept_external_unencrypted_http_requests"`
|
||||||
}
|
}
|
||||||
|
|
||||||
// NamesConfigSpec configures the names of some Kubernetes resources for the Supervisor.
|
// NamesConfigSpec configures the names of some Kubernetes resources for the Supervisor.
|
||||||
|
@ -55,7 +55,11 @@ The most common ways are:
|
|||||||
to use HTTP, because the user's secret OIDC tokens would be transmitted across the network without encryption.
|
to use HTTP, because the user's secret OIDC tokens would be transmitted across the network without encryption.
|
||||||
If your Ingress controller does not support this feature, then consider using one of the other configurations
|
If your Ingress controller does not support this feature, then consider using one of the other configurations
|
||||||
described here instead of using an Ingress. The backend of the Ingress would typically point to a NodePort or
|
described here instead of using an Ingress. The backend of the Ingress would typically point to a NodePort or
|
||||||
LoadBalancer Service which exposes the HTTPS port 8443 of the Supervisor pods.
|
LoadBalancer Service which exposes the HTTPS port 8443 of the Supervisor pods. (Using plain HTTP from the Ingress
|
||||||
|
to the Supervisor pods is deprecated and will be removed in a future release. To aid in transition, it may be enabled
|
||||||
|
using the `insecure_accept_external_unencrypted_http_requests` value in
|
||||||
|
[values.yaml](https://github.com/vmware-tanzu/pinniped/blob/main/deploy/supervisor/values.yaml),
|
||||||
|
until that setting is removed in a future release.)
|
||||||
|
|
||||||
The required configuration of the Ingress is specific to your cluster's Ingress Controller, so please refer to the
|
The required configuration of the Ingress is specific to your cluster's Ingress Controller, so please refer to the
|
||||||
documentation from your Kubernetes provider. If you are using a cluster from a cloud provider, then you'll probably
|
documentation from your Kubernetes provider. If you are using a cluster from a cloud provider, then you'll probably
|
||||||
@ -65,7 +69,9 @@ The most common ways are:
|
|||||||
Otherwise, the Kubernetes documentation provides a list of popular
|
Otherwise, the Kubernetes documentation provides a list of popular
|
||||||
[Ingress Controllers](https://kubernetes.io/docs/concepts/services-networking/ingress-controllers/), including
|
[Ingress Controllers](https://kubernetes.io/docs/concepts/services-networking/ingress-controllers/), including
|
||||||
[Contour](https://projectcontour.io/) and many others. Contour is an example of an ingress implementation which
|
[Contour](https://projectcontour.io/) and many others. Contour is an example of an ingress implementation which
|
||||||
[supports TLS on the backend](https://projectcontour.io/docs/main/config/upstream-tls/).
|
[supports TLS on the backend](https://projectcontour.io/docs/main/config/upstream-tls/),
|
||||||
|
along with [TLS session proxying and TLS session pass-through](https://projectcontour.io/docs/main/config/tls-termination/)
|
||||||
|
as alternative ways to maintain TLS all the way to the backend service.
|
||||||
|
|
||||||
- Or, expose the Supervisor app using a Kubernetes service mesh technology (e.g. [Istio](https://istio.io/)).
|
- Or, expose the Supervisor app using a Kubernetes service mesh technology (e.g. [Istio](https://istio.io/)).
|
||||||
|
|
||||||
|
@ -48,7 +48,6 @@ type TestEnv struct {
|
|||||||
KubernetesDistribution KubeDistro `json:"kubernetesDistribution"`
|
KubernetesDistribution KubeDistro `json:"kubernetesDistribution"`
|
||||||
Capabilities map[Capability]bool `json:"capabilities"`
|
Capabilities map[Capability]bool `json:"capabilities"`
|
||||||
TestWebhook auth1alpha1.WebhookAuthenticatorSpec `json:"testWebhook"`
|
TestWebhook auth1alpha1.WebhookAuthenticatorSpec `json:"testWebhook"`
|
||||||
SupervisorHTTPAddress string `json:"supervisorHttpAddress"`
|
|
||||||
SupervisorHTTPSAddress string `json:"supervisorHttpsAddress"`
|
SupervisorHTTPSAddress string `json:"supervisorHttpsAddress"`
|
||||||
SupervisorHTTPSIngressAddress string `json:"supervisorHttpsIngressAddress"`
|
SupervisorHTTPSIngressAddress string `json:"supervisorHttpsIngressAddress"`
|
||||||
SupervisorHTTPSIngressCABundle string `json:"supervisorHttpsIngressCABundle"`
|
SupervisorHTTPSIngressCABundle string `json:"supervisorHttpsIngressCABundle"`
|
||||||
@ -207,12 +206,7 @@ func loadEnvVars(t *testing.T, result *TestEnv) {
|
|||||||
result.SupervisorAppName = needEnv(t, "PINNIPED_TEST_SUPERVISOR_APP_NAME")
|
result.SupervisorAppName = needEnv(t, "PINNIPED_TEST_SUPERVISOR_APP_NAME")
|
||||||
result.TestWebhook.TLS = &auth1alpha1.TLSSpec{CertificateAuthorityData: needEnv(t, "PINNIPED_TEST_WEBHOOK_CA_BUNDLE")}
|
result.TestWebhook.TLS = &auth1alpha1.TLSSpec{CertificateAuthorityData: needEnv(t, "PINNIPED_TEST_WEBHOOK_CA_BUNDLE")}
|
||||||
|
|
||||||
result.SupervisorHTTPAddress = os.Getenv("PINNIPED_TEST_SUPERVISOR_HTTP_ADDRESS")
|
result.SupervisorHTTPSIngressAddress = needEnv(t, "PINNIPED_TEST_SUPERVISOR_HTTPS_INGRESS_ADDRESS")
|
||||||
result.SupervisorHTTPSIngressAddress = os.Getenv("PINNIPED_TEST_SUPERVISOR_HTTPS_INGRESS_ADDRESS")
|
|
||||||
require.NotEmptyf(t,
|
|
||||||
result.SupervisorHTTPAddress+result.SupervisorHTTPSIngressAddress,
|
|
||||||
"must specify either PINNIPED_TEST_SUPERVISOR_HTTP_ADDRESS or PINNIPED_TEST_SUPERVISOR_HTTPS_INGRESS_ADDRESS env var (or both) for integration tests",
|
|
||||||
)
|
|
||||||
result.SupervisorHTTPSAddress = needEnv(t, "PINNIPED_TEST_SUPERVISOR_HTTPS_ADDRESS")
|
result.SupervisorHTTPSAddress = needEnv(t, "PINNIPED_TEST_SUPERVISOR_HTTPS_ADDRESS")
|
||||||
require.NotRegexp(t, "^[0-9]", result.SupervisorHTTPSAddress,
|
require.NotRegexp(t, "^[0-9]", result.SupervisorHTTPSAddress,
|
||||||
"PINNIPED_TEST_SUPERVISOR_HTTPS_ADDRESS must be a hostname with an optional port and cannot be an IP address",
|
"PINNIPED_TEST_SUPERVISOR_HTTPS_ADDRESS must be a hostname with an optional port and cannot be an IP address",
|
||||||
|
Loading…
Reference in New Issue
Block a user