- Using an External HTTPS Proxy
- Before you begin
- Deploy an HTTPS proxy
- Configure traffic to external HTTPS proxy
- Understanding what happened
- Cleanup
- See also
Using an External HTTPS Proxy
The Configure an Egress Gateway example shows how to directtraffic to external services from your mesh via an Istio edge component called Egress Gateway. However, somecases require an external, legacy (non-Istio) HTTPS proxy to access external services. For example, yourcompany may already have such a proxy in place and all the applications within the organization may be required todirect their traffic through it.
This example shows how to enable access to an external HTTPS proxy. Since applications use the HTTP CONNECT method to establish connections with HTTPS proxies,configuring traffic to an external HTTPS proxy is different from configuring traffic to external HTTP and HTTPSservices.
Before you begin
Setup Istio by following the instructions in the Installation guide.
Deploy the sleep sample app to use as a test source for sending requests.If you haveautomatic sidecar injectionenabled, run the following command to deploy the sample app:
Zip
$ kubectl apply -f @samples/sleep/sleep.yaml@
Otherwise, manually inject the sidecar before deploying the sleep application with the following command:
Zip
$ kubectl apply -f <(istioctl kube-inject -f @samples/sleep/sleep.yaml@)
You can use any pod with curl installed as a test source.
- Set the
SOURCE_PODenvironment variable to the name of your source pod:
$ export SOURCE_POD=$(kubectl get pod -l app=sleep -o jsonpath={.items..metadata.name})
- Enable Envoy’s access logging
Deploy an HTTPS proxy
To simulate a legacy proxy and only for this example, you deploy an HTTPS proxy inside your cluster.Also, to simulate a more realistic proxy that is running outside of your cluster, you will address the proxy’s podby its IP address and not by the domain name of a Kubernetes service.This example uses Squid but you can use any HTTPS proxy that supports HTTP CONNECT.
- Create a namespace for the HTTPS proxy, without labeling it for sidecar injection. Without the label, sidecarinjection is disabled in the new namespace so Istio will not control the traffic there.You need this behavior to simulate the proxy being outside of the cluster.
$ kubectl create namespace external
- Create a configuration file for the Squid proxy.
$ cat <<EOF > ./proxy.confhttp_port 3128acl SSL_ports port 443acl CONNECT method CONNECThttp_access deny CONNECT !SSL_portshttp_access allow localhost managerhttp_access deny managerhttp_access allow allcoredump_dir /var/spool/squidEOF
- Create a Kubernetes ConfigMapto hold the configuration of the proxy:
$ kubectl create configmap proxy-configmap -n external --from-file=squid.conf=./proxy.conf
- Deploy a container with Squid:
$ kubectl apply -f - <<EOFapiVersion: apps/v1kind: Deploymentmetadata:name: squidnamespace: externalspec:replicas: 1template:metadata:labels:app: squidspec:volumes:- name: proxy-configconfigMap:name: proxy-configmapcontainers:- name: squidimage: sameersbn/squid:3.5.27imagePullPolicy: IfNotPresentvolumeMounts:- name: proxy-configmountPath: /etc/squidreadOnly: trueEOF
- Deploy the sleep sample in the
externalnamespace to test traffic to theproxy without Istio traffic control.
Zip
$ kubectl apply -n external -f @samples/sleep/sleep.yaml@
- Obtain the IP address of the proxy pod and define the
PROXY_IPenvironment variable to store it:
$ export PROXY_IP=$(kubectl get pod -n external -l app=squid -o jsonpath={.items..podIP})
- Define the
PROXY_PORTenvironment variable to store the port of your proxy. In this case, Squid uses port3128.
$ export PROXY_PORT=3128
- Send a request from the
sleeppod in theexternalnamespace to an external service via the proxy:
$ kubectl exec -it $(kubectl get pod -n external -l app=sleep -o jsonpath={.items..metadata.name}) -n external -- sh -c "HTTPS_PROXY=$PROXY_IP:$PROXY_PORT curl https://en.wikipedia.org/wiki/Main_Page" | grep -o "<title>.*</title>"<title>Wikipedia, the free encyclopedia</title>
- Check the access log of the proxy for your request:
$ kubectl exec -it $(kubectl get pod -n external -l app=squid -o jsonpath={.items..metadata.name}) -n external -- tail -f /var/log/squid/access.log1544160065.248 228 172.30.109.89 TCP_TUNNEL/200 87633 CONNECT en.wikipedia.org:443 - HIER_DIRECT/91.198.174.192 -
So far, you completed the following tasks without Istio:
- You deployed the HTTPS proxy.
- You used
curlto access thewikipedia.orgexternal service through the proxy.
Next, you must configure the traffic from the Istio-enabled pods to use the HTTPS proxy.
Configure traffic to external HTTPS proxy
- Define a TCP (not HTTP!) Service Entry for the HTTPS proxy. Although applications use the HTTP CONNECT method toestablish connections with HTTPS proxies, you must configure the proxy for TCP traffic, instead of HTTP. Once theconnection is established, the proxy simply acts as a TCP tunnel.
$ kubectl apply -f - <<EOFapiVersion: networking.istio.io/v1alpha3kind: ServiceEntrymetadata:name: proxyspec:hosts:- my-company-proxy.com # ignoredaddresses:- $PROXY_IP/32ports:- number: $PROXY_PORTname: tcpprotocol: TCPlocation: MESH_EXTERNALEOF
- Send a request from the
sleeppod in thedefaultnamespace. Because thesleeppod has a sidecar,Istio controls its traffic.
$ kubectl exec -it $SOURCE_POD -c sleep -- sh -c "HTTPS_PROXY=$PROXY_IP:$PROXY_PORT curl https://en.wikipedia.org/wiki/Main_Page" | grep -o "<title>.*</title>"<title>Wikipedia, the free encyclopedia</title>
- Check the Istio sidecar proxy’s logs for your request:
$ kubectl logs $SOURCE_POD -c istio-proxy[2018-12-07T10:38:02.841Z] "- - -" 0 - 702 87599 92 - "-" "-" "-" "-" "172.30.109.95:3128" outbound|3128||my-company-proxy.com 172.30.230.52:44478 172.30.109.95:3128 172.30.230.52:44476 -
- Check the access log of the proxy for your request:
$ kubectl exec -it $(kubectl get pod -n external -l app=squid -o jsonpath={.items..metadata.name}) -n external -- tail -f /var/log/squid/access.log1544160065.248 228 172.30.109.89 TCP_TUNNEL/200 87633 CONNECT en.wikipedia.org:443 - HIER_DIRECT/91.198.174.192 -
Understanding what happened
In this example, you took the following steps:
- Deployed an HTTPS proxy to simulate an external proxy.
- Created a TCP service entry to enable Istio-controlled traffic to the external proxy.Note that you must not create service entries for the external services you access through the external proxy, like
wikipedia.org. This is because from Istio’s point of view the requests are sent to the external proxy only; Istio isnot aware of the fact that the external proxy forwards the requests further.
Cleanup
- Shutdown the sleep service:
Zip
$ kubectl delete -f @samples/sleep/sleep.yaml@
- Shutdown the sleep service in the
externalnamespace:
Zip
$ kubectl delete -f @samples/sleep/sleep.yaml@ -n external
- Shutdown the Squid proxy, remove the
ConfigMapand the configuration file:
$ kubectl delete -n external deployment squid$ kubectl delete -n external configmap proxy-configmap$ rm ./proxy.conf
- Delete the
externalnamespace:
$ kubectl delete namespace external
- Delete the Service Entry:
$ kubectl delete serviceentry proxy
See also
Secure Control of Egress Traffic in Istio, part 3
Comparison of alternative solutions to control egress traffic including performance considerations.
Secure Control of Egress Traffic in Istio, part 2
Use Istio Egress Traffic Control to prevent attacks involving egress traffic.
Secure Control of Egress Traffic in Istio, part 1
Attacks involving egress traffic and requirements for egress traffic control.
Egress Gateway Performance Investigation
Verifies the performance impact of adding an egress gateway.
Consuming External MongoDB Services
Describes a simple scenario based on Istio's Bookinfo example.
Monitoring and Access Policies for HTTP Egress Traffic
Describes how to configure Istio for monitoring and access policies of HTTP egress traffic.
