Using istio as an reverse proxy for external TLS services - kubernetes

Istio allows you to route a http request in a VirtualService to an external host provided a ServiceEntry exists. For example:
apiVersion: networking.istio.io/v1alpha3
kind: ServiceEntry
metadata:
name: httpbin-ext
spec:
hosts:
- httpbin.org
ports:
- number: 80
name: http
protocol: HTTP
resolution: DNS
location: MESH_EXTERNAL
---
apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
name: httpbin
spec:
hosts:
- httpbin.domain.co
gateways:
- public-gateway.istio-system.svc.cluster.local
- mesh
http:
- match:
- gateways:
- public-gateway.istio-system.svc.cluster.local
port: 443
host: httpbin.domain.co
route:
- destination:
host: httpbin.org
port:
number: 80
However this only allows for a HTTP endpoint - how do I configure the external endpoint to be TLS/HTTPS?

This took me hours to work out - so worth sharing I feel.
In order to terminate this service as a TLS, a Destination Rule is required. My final config:
apiVersion: networking.istio.io/v1alpha3
kind: ServiceEntry
metadata:
name: httpbin-ext
spec:
hosts:
- httpbin.org
ports:
- number: 443
name: https
protocol: HTTPS
resolution: DNS
location: MESH_EXTERNAL
---
apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
name: httpbin
spec:
hosts:
- httpbin.domain.co
gateways:
- public-gateway.istio-system.svc.cluster.local
- mesh
http:
- match:
- gateways:
- public-gateway.istio-system.svc.cluster.local
port: 443
host: httpbin.domain.co
- gateways:
- public-gateway.istio-system.svc.cluster.local
port: 80
host: httpbin.domain.co
route:
- destination:
host: httpbin.org
port:
number: 443
---
apiVersion: networking.istio.io/v1alpha3
kind: DestinationRule
metadata:
name: httpbin-org
spec:
host: httpbin.org
trafficPolicy:
loadBalancer:
simple: ROUND_ROBIN
portLevelSettings:
- port:
number: 443
tls:
mode: SIMPLE

Related

Istio externalName + egress gateway tls origination host is not replaced

I am trying to configure egress gateway with tls origination using service type ExternalName.
I followed this example: https://istio.io/latest/docs/tasks/traffic-management/egress/egress-tls-origination/
But I am having Host problems with the request because of the SNI, I have to change the host because of the SSL from example-test to example.com, I tried to set header host and rewrite authority on virtual service but didn't work, and now I am trying to use envoy filter but I got nothing so far:
curl example-test
cause a 502 and 400 on the istio-proxy:
GET / HTTP/1.1" 502 UPE upstream_reset_before_response_started{protocol_error} - "-" 0 87 6 - "-" "curl/7.75.0" "example.com" outbound|80|example-test|egressgateway-internal.istio-system.svc.cluster.local service_entry_match
Gateway:
HTTP/1.1" 400 DPE http1.codec_error - "-" 0 11 0 - "-" "-" "-" "-" "-" - - example.com -
Destination rule configuration:
apiVersion: networking.istio.io/v1alpha3
kind: DestinationRule
metadata:
name: egressgateway-for-example
spec:
host: egressgateway-internal.istio-system.svc.cluster.local
subsets:
- name: example-test
trafficPolicy:
loadBalancer:
simple: ROUND_ROBIN
portLevelSettings:
- port:
number: 80
tls:
mode: ISTIO_MUTUAL
sni: 'example.com'
---
apiVersion: networking.istio.io/v1alpha3
kind: DestinationRule
metadata:
name: originate-tls-for-example
spec:
host: 'example.com'
trafficPolicy:
loadBalancer:
simple: ROUND_ROBIN
portLevelSettings:
- port:
number: 443
tls:
mode:
sni: 'example.com'
Service Entry and service type externalName configuration:
apiVersion: networking.istio.io/v1alpha3
kind: ServiceEntry
metadata:
name: example-test
spec:
hosts:
- 'example.com'
ports:
- number: 80
name: http-port
protocol: HTTP
- number: 443
name: https-port
protocol: HTTPS
resolution: DNS
location: MESH_EXTERNAL
---
kind: Service
apiVersion: v1
metadata:
name: example-test
namespace: default
spec:
type: ExternalName
externalName: example.com
ports:
- protocol: TCP
port: 443
targetPort: 443
name: tcp
Virtual service ( I tried the rewrite on destination to authority and set Host to example.com and did not work)
apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
name: direct-example-through-egress-gateway
spec:
hosts:
- 'example.com'
gateways:
- egressgateway-internal
- mesh
http:
- name: "service_entry_match"
match:
- gateways:
- mesh
route:
- destination:
host: egressgateway-internal.istio-system.svc.cluster.local
subset: example-test
port:
number: 80
weight: 100
- name: "tls_destination"
match:
- gateways:
- egressgateway-internal
port: 80
route:
- destination:
host: 'example.com'
port:
number: 443
weight: 100
And the gateway:
apiVersion: networking.istio.io/v1alpha3
kind: Gateway
metadata:
name: egressgateway-internal
namespace: istio-system
spec:
selector:
istio: egressgateway-internal
servers:
- port:
number: 80
name: https-port-for-tls-origination
protocol: HTTPS
hosts:
- 'example.com'
tls:
mode: ISTIO_MUTUAL
Envoy filter:
apiVersion: networking.istio.io/v1alpha3
kind: EnvoyFilter
metadata:
name: test-add-example-host
namespace: default
spec:
configPatches:
- applyTo: HTTP_FILTER
match:
context: SIDECAR_OUTBOUND
listener:
portNumber: 80
filterChain:
filter:
name: "envoy.filters.network.http_connection_manager"
subFilter:
name: "envoy.filters.http.router"
patch:
operation: INSERT_BEFORE
value:
name: envoy.lua
typed_config:
"#type": "type.googleapis.com/envoy.extensions.filters.http.lua.v3.Lua"
inlineCode: |
function envoy_on_request(request_handle)
if (request_handle:headers():get("Host") == "example-test")
then
request_handle:logInfo("[INFO] Add Host to request...")
request_handle:headers():replace(":authority",'example.com')
else
request_handle:logInfo("[INFO]debug..")
end
end

How to use Istio Ingress to forward STOMP protocol of RabbitMQ in Kubernetes?

I tried with this Gateway, and VirtualService, didn't work.
apiVersion: networking.istio.io/v1alpha3
kind: Gateway
metadata:
name: stomp
spec:
selector:
istio: ingressgateway
servers:
- port:
number: 80
name: stomp
protocol: TCP
hosts:
- rmq-stomp.mycompany.com
apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
name: rmq-stomp
spec:
hosts:
- rmq-stomp.mycompany.com
gateways:
- stomp
http:
- match:
- uri:
prefix: /
route:
- destination:
port:
number: 61613
host: rabbitmq.default.svc.cluster.local
There's no problem with the service, because when I tried to connect from other pod, it's connected.
Use tcp.match, not http.match. Here is the example I have found in istio gateway docs and in istio virtualservice dosc
apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
name: bookinfo-mongo
namespace: bookinfo-namespace
spec:
hosts:
- mongosvr.prod.svc.cluster.local # name of internal Mongo service
gateways:
- some-config-namespace/my-gateway # can omit the namespace if gateway is in same namespace as virtual service.
tcp:
- match:
- port: 27017
route:
- destination:
host: mongo.prod.svc.cluster.local
port:
number: 5555
So your would look sth like:
apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
name: rmq-stomp
spec:
hosts:
- rmq-stomp.mycompany.com
gateways:
- stomp
tcp:
- match:
- port: 80
route:
- destination:
host: rabbitmq.default.svc.cluster.local
port:
number: 61613
Here is a similar question answered: how-to-configure-istios-virtualservice-for-a-service-which-exposes-multiple-por

Istio ingress gateway subdomainrouting based

I have three service that I need to expose via istio ingress gateway, i have setup those services dns records to point to the ingress gateway load balancer but i have not succeded to make it work.
The gateway and virtual service config file :
apiVersion: networking.istio.io/v1alpha3
kind: Gateway
metadata:
name: test-gateway
spec:
selector:
istio: ingressgateway # use istio default controller
servers:
- port:
number: 80
name: http
protocol: HTTP
hosts:
- "*.mywebsite.io"
---
apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
name: virtualservice
spec:
hosts:
- "*.mywebsite.io"
gateways:
- test-gateway
http:
- name: "api-gateway"
match:
- uri:
exact: "gateway.mywebsite.io"
route:
- destination:
host: gateway.default.svc.cluster.local
port:
number: 8080
- name: "visitor-service"
match:
- uri:
exact: "visitor-service.mywebsite.io"
route:
- destination:
host: visitor-service.default.svc.cluster.local
port:
number: 8000
- name: "auth-service"
match:
- uri:
exact: "auth-service.mywebsite.io"
route:
- destination:
host: auth-service.default.svc.cluster.local
port:
number: 3004
I guess the URI part of the HttpMatchRequest does not work that way. Try to add VirtualServices for each subdomain, i.e. something like.
apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
name: gateway-virtualservice
spec:
hosts:
- "gateway.mywebsite.io"
gateways:
- test-gateway
http:
- name: "api-gateway"
match:
- uri:
exact: "/" #or prefix
route:
- destination:
host: gateway.default.svc.cluster.local
port:
number: 8080
---
apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
name: visitor-virtualservice
spec:
hosts:
- "visitor-service.mywebsite.io"
gateways:
- test-gateway
http:
- name: "visitor-service"
match:
- uri:
exact: "/"
route:
- destination:
host: visitor-service.default.svc.cluster.local
port:
number: 8000

DestinationRule is not applied on ServiceEntry

When I specify host in ServiceEntry and DestinationRule as httpbin, DestinationRule doesn't work. But it works, if I added suffix, i.e. httpbin.se.
Example:
apiVersion: networking.istio.io/v1alpha3
kind: ServiceEntry
metadata:
name: httpbin
namespace: default
spec:
hosts:
- httpbin # don't work
# - httpbin.se # work
ports:
- number: 443
name: http-443
protocol: HTTP
- number: 80
name: http-80
protocol: HTTP
location: MESH_EXTERNAL
resolution: STATIC
addresses:
- "34.235.36.14"
endpoints:
- address: "34.235.36.14"
ports:
http-443: 443
http-80: 80
---
apiVersion: networking.istio.io/v1alpha3
kind: DestinationRule
metadata:
name: httpbin
namespace: default
spec:
host: httpbin # don't work.
# host: httpbin.se # work
trafficPolicy:
portLevelSettings:
- port:
number: 443
tls:
mode: SIMPLE
Maybe I missed some documentation, can't be sure.

Egress gateway does't work correctly when adding multiple external services

I was trying to define multiple external services(redis: AWS ElastiCache) to route through egress gateway. Two gateways were configured with reference to https://github.com/istio/istio/issues/16806#issuecomment-538718737. I applied the following config, but it didn't work correctly and I could find error logs. It seemed that connecting to both of the destinations was forward to only one of them(random?)
Is this a bug or is there any solution?
apiVersion: networking.istio.io/v1alpha3
kind: Gateway
metadata:
name: istio-egressgateway-redis-1
namespace: test
spec:
selector:
istio: egressgateway
servers:
- port:
name: redis
number: 6379
protocol: TCP
hosts:
- "aaa.aaa.ng.0001.apne1.cache.amazonaws.com"
---
apiVersion: networking.istio.io/v1alpha3
kind: ServiceEntry
metadata:
name: egress-redis-1
namespace: test
spec:
hosts:
- aaa.aaa.ng.0001.apne1.cache.amazonaws.com
ports:
- name: egress-redis-1
number: 6379
protocol: TCP
location: MESH_EXTERNAL
resolution: DNS
---
apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
name: egress-redis-1
namespace: test
spec:
hosts:
- aaa.aaa.ng.0001.apne1.cache.amazonaws.com
gateways:
- istio-egressgateway-redis-1
- mesh
tcp:
- match:
- gateways:
- mesh
port: 6379
route:
- destination:
host: istio-egressgateway.istio-system.svc.cluster.local
subset: egress-redis-1
port:
number: 6379
- match:
- gateways:
- istio-egressgateway-redis-1
port: 6379
route:
- destination:
host: aaa.aaa.ng.0001.apne1.cache.amazonaws.com
port:
number: 6379
weight: 100
---
apiVersion: networking.istio.io/v1alpha3
kind: DestinationRule
metadata:
name: egress-redis-1
namespace: test
spec:
host: istio-egressgateway.istio-system.svc.cluster.local
subsets:
- name: egress-redis-1
---
apiVersion: networking.istio.io/v1alpha3
kind: Gateway
metadata:
name: istio-egressgateway-redis-2
namespace: test
spec:
selector:
istio: egressgateway
servers:
- port:
name: redis
number: 6379
protocol: TCP
hosts:
- "bbb.bbb.clustercfg.apne1.cache.amazonaws.com"
---
apiVersion: networking.istio.io/v1alpha3
kind: ServiceEntry
metadata:
name: egress-redis-2
namespace: test
spec:
hosts:
- bbb.bbb.clustercfg.apne1.cache.amazonaws.com
ports:
- name: egress-redis-2
number: 6379
protocol: TCP
location: MESH_EXTERNAL
resolution: DNS
---
apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
name: egress-redis-2
namespace: test
spec:
hosts:
- bbb.bbb.clustercfg.apne1.cache.amazonaws.com
gateways:
- istio-egressgateway-redis-2
- mesh
tcp:
- match:
- gateways:
- mesh
port: 6379
route:
- destination:
host: istio-egressgateway.istio-system.svc.cluster.local
subset: egress-redis-2
port:
number: 6379
- match:
- gateways:
- istio-egressgateway-redis-2
port: 6379
route:
- destination:
host: bbb.bbb.clustercfg.apne1.cache.amazonaws.com
port:
number: 6379
weight: 100
---
apiVersion: networking.istio.io/v1alpha3
kind: DestinationRule
metadata:
name: egress-redis-2
namespace: test
spec:
host: istio-egressgateway.istio-system.svc.cluster.local
subsets:
- name: egress-redis-2
Istio error logs:
2020-07-14T08:24:42.803875Z#011info#011ads#011Push Status: {
"pilot_conflict_outbound_listener_tcp_over_current_tcp": {
"0.0.0.0:6379": {
"proxy": "member-11111-22222.test",
"message": "Listener=0.0.0.0:6379 AcceptedTCP=aaa.aaa.clustercfg.apne1.cache.amazonaws.com RejectedTCP=bbb.bbb.ng.0001.apne1.cache.amazonaws.com TCPServices=1"
}
}
}
Version
Kubernetes: 1.18.5
Istio: 1.6.4
outboundTrafficPolicy
REGISTRY_ONLY
After updated port names of Gateway to unique, it still doesn't work.
apiVersion: networking.istio.io/v1alpha3
kind: Gateway
metadata:
name: istio-egressgateway-redis-1
namespace: qa2
spec:
selector:
istio: egressgateway
servers:
- port:
name: egress-redis-1
number: 6379
protocol: TCP
hosts:
- "aaa.aaa.ng.0001.apne1.cache.amazonaws.com"
---
apiVersion: networking.istio.io/v1alpha3
kind: Gateway
metadata:
name: istio-egressgateway-redis-2
namespace: qa2
spec:
selector:
istio: egressgateway
servers:
- port:
name: egress-redis-2
number: 6379
protocol: TCP
hosts:
- "bbb.bbb.clustercfg.apne1.cache.amazonaws.com"