Last active
November 9, 2023 10:09
-
-
Save libesz/961ac221f210f8a2a3ff3b8e69ad9cc2 to your computer and use it in GitHub Desktop.
Egress routing solution with Istio, using two Envoy listeners. 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. | |
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: | |
securityContext: | |
sysctls: | |
- name: net.ipv4.ip_unprivileged_port_start | |
value: "0" | |
containers: | |
- name: istio-proxy | |
image: auto # The image will automatically update each time the pod starts. | |
securityContext: | |
capabilities: | |
drop: | |
- ALL | |
runAsUser: 1337 | |
runAsGroup: 1337 | |
--- | |
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 to avoid warnings | |
gateways: | |
- egressgateway | |
tcp: | |
- match: | |
- gateways: | |
- egressgateway | |
port: 8443 | |
route: | |
- destination: | |
host: "sni-proxy.local" | |
port: | |
number: 443 | |
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: DestinationRule | |
metadata: | |
name: disable-mtls-for-sni-proxy | |
namespace: istio-egress | |
spec: | |
host: sni-proxy.local | |
trafficPolicy: | |
tls: | |
mode: DISABLE | |
- 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: networking.istio.io/v1alpha3 | |
kind: ServiceEntry | |
metadata: | |
name: sni-proxy | |
namespace: istio-egress | |
spec: | |
hosts: | |
- sni-proxy.local | |
addresses: | |
- "127.0.0.1" | |
location: MESH_EXTERNAL | |
ports: | |
- number: 443 | |
name: tcp | |
protocol: TCP | |
endpoints: | |
- address: "127.0.0.1" | |
resolution: STATIC | |
- 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: 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 | |
address: | |
socket_address: | |
protocol: TCP | |
address: "127.0.0.1" | |
port_value: 443 | |
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% | |
' |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment