End-to-end encryption using EnRoute and Istio
Istio Integration
Introduction
This document describes how easy it is to integrate Istio with EnRoute. Istio is a service mesh based on Envoy Proxy that encrypts traffic between micro-services inside a Kubernetes Cluster
Enabling EnRoute integration with Istio can be done in one step by setting a flag and running a container along with EnRoute (to serve secrets) to participate in Istio trust framework.
An End-to-end encryption of traffic using EnRoute and istio includes -
- Encryption from client to EnRoute
- Encryption from EnRoute to mTLS inside the mesh
We install EnRoute and Istio, enable cluster-wide mTLS, configure EnRoute for Istio environment and make the secrets available to EnRoute. We will go through each of these steps by -
- Setting up a cluster, installing Istio, setting up example workload (bookinfo app)
- Next we install EnRoute, a container to serve Istio secrets to EnRoute to make it a part of the mesh
- Enable mesh-wide mTLS enforce strict zero-trust environment and make EnRoute a part of Istio mesh
- We install a certificate on the
GatewayHost
to achieve end-to-end encryption
We trace through each of the above steps while monitoring the cluster to verify end-to-end encrypted traffic.
We also verify some of the steps above using the open source Kiali project for observing a Kubernetes Istio deployment
Pre-requisites
Check Kubernetes Cluster
kubectl get nodes
NAME STATUS ROLES AGE VERSION
k3s-feature-test-03c4-fa116a-node-pool-f572-w4zm6 Ready <none> 54d v1.22.11+k3s1
k3s-feature-test-03c4-fa116a-node-pool-f572-nnm4h Ready <none> 54d v1.22.11+k3s1
Install and Check Istio Installation
The installation steps for Istio are covered on the Istio website, they arenβt covered here. Once Istio is installed, we can verify the installation.
We installed Istio using helm, and the installation can be verified using helm
helm status istiod -n istio-system
NAME: istiod
LAST DEPLOYED: Wed Nov 23 01:10:47 2022
NAMESPACE: istio-system
STATUS: deployed
REVISION: 1
TEST SUITE: None
NOTES:
"istiod" successfully installed!
To learn more about the release, try:
$ helm status istiod
$ helm get all istiod
Next steps:
* Deploy a Gateway: https://istio.io/latest/docs/setup/additional-setup/gateway/
* Try out our tasks to get started on common configurations:
* https://istio.io/latest/docs/tasks/traffic-management
* https://istio.io/latest/docs/tasks/security/
* https://istio.io/latest/docs/tasks/policy-enforcement/
* https://istio.io/latest/docs/tasks/policy-enforcement/
* Review the list of actively supported releases, CVE publications and our hardening guide:
* https://istio.io/latest/docs/releases/supported-releases/
* https://istio.io/latest/news/security/
* https://istio.io/latest/docs/ops/best-practices/security/
For further documentation see https://istio.io website
Tell us how your install/upgrade experience went at https://forms.gle/99uiMML96AmsXY5d6
We will be running the bookinfo sample application packaged with istio. Ensure that the bookinfo sample app is installed (if not already installed)
kubectl get pods
NAME READY STATUS RESTARTS AGE
details-v1-7d88846999-d7q4w 2/2 Running 0 4d
reviews-v1-55b668fc65-mb28q 2/2 Running 0 4d
reviews-v3-7886dd86b9-7k5tp 2/2 Running 0 4d
ratings-v1-754f9c4975-s7wv2 2/2 Running 0 4d
productpage-v1-7795568889-cl9sw 2/2 Running 0 4d
reviews-v2-858f99c99-tpjbt 2/2 Running 0 4d
Install and Check Kiali Installation
Installing kiali is optional, but it makes it easier to ensure mesh-wide TLS and other aspects of visualizing istio. We will use kiali to check traffic flow graph, mTLS and security aspects of our installation.
kubectl apply -f https://raw.githubusercontent.com/istio/istio/release-1.16/samples/addons/kiali.yaml
serviceaccount/kiali created
configmap/kiali created
clusterrole.rbac.authorization.k8s.io/kiali-viewer created
clusterrole.rbac.authorization.k8s.io/kiali created
clusterrolebinding.rbac.authorization.k8s.io/kiali created
role.rbac.authorization.k8s.io/kiali-controlplane created
rolebinding.rbac.authorization.k8s.io/kiali-controlplane created
service/kiali created
deployment.apps/kiali create
Ensure automatic injection of Istio sidecar is enabled
Istio installs a side-car in every container (just like linkerd-proxy) to create a mesh. These proxies are a part of the Istio trust system that can fetch and use Istio secrets.
For EnRoute to be a part of this Istio trust system, we have an Istio proxy injected in the EnRoute pod. This helps EnRoute work with the Istio trust framework, to enforce a zero-trust environment.
To make the EnRoute pod a part of the Istio mesh, we enable automatic sidecar injection for EnRoute namespace
Create Namespace
kubectl create namespace enroute-system
namespace/enroute-system created
Label Namespace for automatic SideCar injection
kubectl label namespace enroute-system istio-injection=enabled
namespace/enroute-system labeled
Install EnRoute in Istio environment
EnRoute helm chart has support for installation in Istio environment. The helm chart sets up EnRoute in an Istio environment creating all the necessary environment variables while also installing a cert-server
pod for serving secrets to EnRoute
Note the istio.enable
flag during EnRoute installation. This flag ensures that all the necessary artifacts are setup for EnRoute to be a part of Istio trust framework.
helm install --set istio.enable=true -n enroute-system \
enroute-istio saaras/enroute
NAME: enroute-istio
LAST DEPLOYED: Sun Nov 27 20:10:38 2022
NAMESPACE: enroute-system
STATUS: deployed
REVISION: 1
TEST SUITE: None
NOTES:
π΄ππππππ Ingress API Gateway Community Edition Installed!
-------------------------------------------------------
Request a free evaluation license for enterprise version
by sending an email to contact@saaras.io
Slack Channel - https://slack.saaras.io
Getting Started Guide - https://getenroute.io/docs/getting-started-enroute-ingress-controller/
EnRoute Features - https://getenroute.io/features/
Ensure that Istio proxy got injected in EnRoute pod
kubectl get pods -n enroute-system
NAME READY STATUS RESTARTS AGE
enroute-b94698958-dg84n 5/5 Running 0 8m50s
Get the list of containers in the pod
kubectl get pods -n enroute-system enroute-b94698958-dg84n -o jsonpath='{.spec.containers[*].name}'
enroute cert-server redis envoy istio-proxy
Note that istio-proxy
and cert-server
got setup along with enroute
envoy
and redis
containers
EnRoute is now installed in an Istio environment, and setup to use secrets generated by Istio (through cert-server
) for traffic inside the cluster.
Next, we lock down the cluster by enforcing strict traffic policies inside the cluster. We enable a cluster wide mTLS inside the cluster where the identity of all cluster traffic is verified.
Enable EnRoute to use Istio Secrets for upstream traffic
The above steps setup a mechanism to make Istio secrets accessible to EnRoute. We now need to instruct EnRoute to use these secrets when communicating with service (bookinfo) inside the cluster.
We use the GlobalConfig
type of resource for this -
apiVersion: enroute.saaras.io/v1
kind: GlobalConfig
metadata:
labels:
app: web
name: enable-istio
namespace: default
spec:
config: |
{
"tlsContext" : { "alpnProtos" : ["istio", "http/1.1", "h2"] },
"istio_enabled": true
}
name: global-config
type: globalconfig_globals
The above configuration programs EnRoute use mTLS to communicate with service inside the cluster.
Enable strict mTLS for Istio
Next we force all traffic inside the cluster to be mTLS. We do this by creating istio configuration to only allow mTLS type of traffic globally
kubectl apply -f - <<EOF
apiVersion: security.istio.io/v1beta1
kind: PeerAuthentication
metadata:
name: global
namespace: istio-system
spec:
mtls:
mode: STRICT
EOF
One the above policy is configured, we can verify it by checking the Kiali console. Note the lock sign on the top right corner of the kiali console. It indicates that mesh-wide mTLS is enabled.
Istio Settings
Controlling Istio Certificate Validity Interval
Environment variables can be used to control the validity duration of certificates loaded by EnRoute. One such environment variable is SECRET_TTL
which controls how long the secrets should be valid. They can be set in EnRoute annotations. Starting istio 1.6, such annotations will be honored by istio -
proxy.istio.io/config: |
proxyMetadata:
SECRET_TTL: 60m
Controlling Certificate output directory
When we need to access the key and certificate for a workload, we can provide a path to save them. This is applicable in case of workloads that are not natively a part of Istio system. An example of such a workload would be the one running on a Virtual Machine.
The path specified in OUTPUT_CERTS
is used to persist the latest key and certificate of the workload.
proxy.istio.io/config: |
proxyMetadata:
OUTPUT_CERTS: /etc/istio-certs
Send traffic to test application
The productpage front page for the bookinfo application is setup to receive traffic on port 9080
kubectl get svc productpage
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
productpage ClusterIP 10.43.116.119 <none> 9080/TCP 4d2h
We setup a GatewayHost
to send traffic to the the productpage app.
apiVersion: enroute.saaras.io/v1
kind: GatewayHost
metadata:
labels:
app: productpage
app.kubernetes.io/managed-by: Helm
name: productpage-9080-gatewayhost
namespace: default
spec:
routes:
- conditions:
- prefix: /
services:
- name: productpage
port: 9080
virtualhost:
fqdn: '*'
This can also be done easily using the helm chart for service-host-route
helm install product-host saaras/service-host-route \
--namespace=default \
--set service.prefix=/ \
--set service.name=productpage \
--set service.port=9080
Note that this GatewayHost is setup without SSL termination. Weβll add a certificate in the next-step, to ensure end-to-end encryption.
Get the public IP of EnRoute
kubectl get svc -n enroute-system
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
enroute LoadBalancer 10.43.177.204 212.2.241.93 80:31411/TCP,443:30422/TCP 39m
Send test traffic
curl -sS 212.2.241.93/productpage | grep -o "<title>.*</title>"
<title>Simple Bookstore App</title>
Ensure mTLS on kiali console
While we can access the productpage above, we verify mTLS on the kiali console. There are couple of ways to check that -
- We note that only mTLS traffic allowed in the cluster with the lock on the upper right
- There is a lock sign on top of the edge from EnRoute to productpage
- We note that when the edge to productpage is selected, we can verify the namespace
enroute-system
principals
Encrypt traffic from client to EnRoute
To encrypt traffic from client to EnRoute, we create a kubernetes TLS secret and install it on the GatewayHost
Create a Kubernetes secret using Key and Certificate
kubectl create secret tls bookinfo-saaraslabs \
--cert=bookinfo-saaraslabs-cert.pem \
--key=bookinfo-saaraslabs-key.pem
secret/bookinfo-saaraslabs created
Associate the secret with GatewayHost
apiVersion: enroute.saaras.io/v1
kind: GatewayHost
metadata:
labels:
app: productpage
name: productpage-9080-gatewayhost
namespace: default
spec:
routes:
- conditions:
- prefix: /
services:
- name: productpage
port: 9080
virtualhost:
fqdn: bookinfo.saaraslabs.com
tls:
secretName: bookinfo-saaraslabs
Send some traffic over HTTPs
curl -sS https://bookinfo.saaraslabs.com/productpage | grep -o "<title>.*</title>"
<title>Simple Bookstore App</title>
Conclusion
EnRoute provides an extremely easy integration with Istio
EnRoute integrates with Istio and Linkerd. The integration with Linkerd is described in another article.