Last active
December 6, 2023 13:13
-
-
Save libesz/ddf16b9d074d6af3b9cda2946047cf93 to your computer and use it in GitHub Desktop.
Egress routing solution with Istio, using two Envoy listeners, but the second is internal. Ref: https://github.com/istio/istio.io/issues/14126
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# Use-case: have a set of (possibly wildcard) external target hostnames | |
# that are approached with TLS (HTTPS) by mesh applications. Traffic towards | |
# these targets are routed through an egress gateway with the mesh mTLS. | |
# Egress gateway checks the hostname and if allowed, dynamically forwards the | |
# traffic to the exact destination that is in the SNI property. | |
# | |
# This version uses an internal listener to dispatch the final destination | |
# from the application traffic. | |
# Istio release independent. | |
apiVersion: v1 | |
kind: Service | |
metadata: | |
name: egressgateway | |
namespace: istio-egress | |
spec: | |
type: ClusterIP | |
selector: | |
istio: egressgateway | |
ports: | |
- port: 443 | |
name: tls-egress | |
targetPort: 8443 | |
--- | |
apiVersion: apps/v1 | |
kind: Deployment | |
metadata: | |
name: istio-egressgateway | |
namespace: istio-egress | |
spec: | |
selector: | |
matchLabels: | |
istio: egressgateway | |
template: | |
metadata: | |
annotations: | |
inject.istio.io/templates: gateway | |
labels: | |
istio: egressgateway | |
sidecar.istio.io/inject: "true" | |
spec: | |
containers: | |
- name: istio-proxy | |
image: auto # The image will automatically update each time the pod starts. | |
securityContext: | |
capabilities: | |
drop: | |
- ALL | |
runAsUser: 1337 | |
runAsGroup: 1337 | |
--- | |
# Set up roles to allow reading credentials for TLS | |
apiVersion: rbac.authorization.k8s.io/v1 | |
kind: Role | |
metadata: | |
name: istio-egressgateway-sds | |
namespace: istio-egress | |
rules: | |
- apiGroups: [""] | |
resources: ["secrets"] | |
verbs: ["get", "watch", "list"] | |
- apiGroups: | |
- security.openshift.io | |
resourceNames: | |
- anyuid | |
resources: | |
- securitycontextconstraints | |
verbs: | |
- use | |
--- | |
apiVersion: rbac.authorization.k8s.io/v1 | |
kind: RoleBinding | |
metadata: | |
name: istio-egressgateway-sds | |
namespace: istio-egress | |
roleRef: | |
apiGroup: rbac.authorization.k8s.io | |
kind: Role | |
name: istio-egressgateway-sds | |
subjects: | |
- kind: ServiceAccount | |
name: default | |
--- | |
apiVersion: v1 | |
kind: List | |
items: | |
- apiVersion: networking.istio.io/v1alpha3 | |
kind: Gateway | |
metadata: | |
name: egressgateway | |
namespace: istio-system | |
spec: | |
selector: | |
istio: egressgateway | |
servers: | |
- port: | |
number: 8443 | |
name: tls-egress | |
protocol: TLS | |
hosts: | |
- "*" | |
tls: | |
mode: ISTIO_MUTUAL | |
- apiVersion: networking.istio.io/v1alpha3 | |
kind: VirtualService | |
metadata: | |
name: direct-wildcard-through-egress-gateway | |
namespace: istio-system | |
spec: | |
hosts: | |
- "*.foo.com" | |
gateways: | |
- mesh | |
tls: | |
- match: | |
- gateways: | |
- mesh | |
port: 443 | |
sniHosts: | |
- "*.foo.com" | |
route: | |
- destination: | |
host: egressgateway.istio-egress.svc.cluster.local | |
subset: wildcard | |
- apiVersion: networking.istio.io/v1alpha3 | |
kind: VirtualService | |
metadata: | |
name: direct-wildcard-through-egress-gateway2 | |
namespace: istio-system | |
spec: | |
hosts: | |
- "*" # not effective, but necessary | |
gateways: | |
- egressgateway | |
tcp: | |
- match: | |
- gateways: | |
- egressgateway | |
port: 8443 | |
route: | |
- destination: | |
host: "dummy.local" | |
weight: 100 | |
- apiVersion: networking.istio.io/v1alpha3 | |
kind: DestinationRule | |
metadata: | |
name: egressgateway | |
namespace: istio-system | |
spec: | |
host: egressgateway.istio-egress.svc.cluster.local | |
subsets: | |
- name: wildcard | |
trafficPolicy: | |
tls: | |
mode: ISTIO_MUTUAL | |
- apiVersion: networking.istio.io/v1alpha3 | |
kind: ServiceEntry | |
metadata: | |
name: wildcard | |
namespace: istio-system | |
spec: | |
hosts: | |
- "*.foo.com" | |
ports: | |
- number: 443 | |
name: tls | |
protocol: TLS | |
- apiVersion: telemetry.istio.io/v1alpha1 | |
kind: Telemetry | |
metadata: | |
name: mesh-default | |
namespace: istio-system | |
spec: | |
accessLogging: | |
- providers: | |
- name: envoy | |
- apiVersion: networking.istio.io/v1alpha3 | |
kind: EnvoyFilter | |
metadata: | |
name: sni-magic | |
namespace: istio-system | |
spec: | |
configPatches: | |
- applyTo: CLUSTER | |
match: | |
context: GATEWAY | |
patch: | |
operation: ADD | |
value: | |
name: sni_cluster | |
load_assignment: | |
cluster_name: sni_cluster | |
endpoints: | |
- lb_endpoints: | |
- endpoint: | |
address: | |
envoy_internal_address: | |
server_listener_name: sni_listener | |
- applyTo: CLUSTER | |
match: | |
context: GATEWAY | |
patch: | |
operation: ADD | |
value: | |
name: dynamic_forward_proxy_cluster | |
lb_policy: CLUSTER_PROVIDED | |
cluster_type: | |
name: envoy.clusters.dynamic_forward_proxy | |
typed_config: | |
"@type": type.googleapis.com/envoy.extensions.clusters.dynamic_forward_proxy.v3.ClusterConfig | |
dns_cache_config: | |
name: dynamic_forward_proxy_cache_config | |
dns_lookup_family: V4_ONLY | |
- applyTo: LISTENER | |
match: | |
context: GATEWAY | |
patch: | |
operation: ADD | |
value: | |
name: sni_listener | |
internal_listener: {} | |
listener_filters: | |
- name: envoy.filters.listener.tls_inspector | |
typed_config: | |
"@type": type.googleapis.com/envoy.extensions.filters.listener.tls_inspector.v3.TlsInspector | |
filter_chains: | |
- filter_chain_match: | |
server_names: | |
- "*.foo.com" | |
filters: | |
- name: envoy.filters.network.sni_dynamic_forward_proxy | |
typed_config: | |
"@type": type.googleapis.com/envoy.extensions.filters.network.sni_dynamic_forward_proxy.v3.FilterConfig | |
port_value: 443 | |
dns_cache_config: | |
name: dynamic_forward_proxy_cache_config | |
dns_lookup_family: V4_ONLY | |
- name: envoy.tcp_proxy | |
typed_config: | |
"@type": type.googleapis.com/envoy.extensions.filters.network.tcp_proxy.v3.TcpProxy | |
stat_prefix: tcp | |
cluster: dynamic_forward_proxy_cluster | |
access_log: | |
- name: envoy.access_loggers.file | |
typed_config: | |
"@type": type.googleapis.com/envoy.extensions.access_loggers.file.v3.FileAccessLog | |
path: "/dev/stdout" | |
log_format: | |
text_format_source: | |
inline_string: '[%START_TIME%] "%REQ(:METHOD)% %REQ(X-ENVOY-ORIGINAL-PATH?:PATH)% | |
%PROTOCOL%" %RESPONSE_CODE% %RESPONSE_FLAGS% %RESPONSE_CODE_DETAILS% %CONNECTION_TERMINATION_DETAILS% | |
"%UPSTREAM_TRANSPORT_FAILURE_REASON%" %BYTES_RECEIVED% %BYTES_SENT% %DURATION% | |
%RESP(X-ENVOY-UPSTREAM-SERVICE-TIME)% "%REQ(X-FORWARDED-FOR)%" "%REQ(USER-AGENT)%" | |
"%REQ(X-REQUEST-ID)%" "%REQ(:AUTHORITY)%" "%UPSTREAM_HOST%" %UPSTREAM_CLUSTER% | |
%UPSTREAM_LOCAL_ADDRESS% %DOWNSTREAM_LOCAL_ADDRESS% %DOWNSTREAM_REMOTE_ADDRESS% | |
%REQUESTED_SERVER_NAME% %ROUTE_NAME% | |
' | |
- applyTo: NETWORK_FILTER | |
match: | |
context: GATEWAY | |
listener: | |
filterChain: | |
filter: | |
name: "envoy.filters.network.tcp_proxy" | |
patch: | |
operation: MERGE | |
value: | |
name: envoy.tcp_proxy | |
typed_config: | |
"@type": type.googleapis.com/envoy.extensions.filters.network.tcp_proxy.v3.TcpProxy | |
stat_prefix: tcp | |
cluster: sni_cluster |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment