Security
The security of a K8S cluster is a central topic when designing your infrastructure. By using some advanced Istio’s features, you can simultaneously simplify your code base, stay focused on your business logic and shield your application more effectively.
Mutual TLS
Description
Istio can administer communications between microservices by using a secured link between any component in the mesh. Connections are established using mutual TLS and are entirely handled by the sidecar proxy running inside your pods.
By definition, the mTLS is activated globally in the namespace. There are two ways to test its behaviour:
-
Attach to a running sidecar proxy and run a
tcpdump
command to see live traffic ; -
Create an unproxified pod, attach to it and
curl
a service which has mTLS enabled ;
The first process is the most rigorous, but you would have to run the proxy as a privileged
user to be able to
inspect network traffic. To do so, you would need to own the VM running the process (or use minikube
or kind
on
your local machine), and install Istio properly on the cluster. For security reasons, both these requirements are
impossible to meet on Google Kubernetes Engine and its managed version of Istio.
Therefore, we will use the second approach, by creating another namespace. You will configure it to be unsecured
regarding mTLS, and you will try to reach the middleware
component.
Execution
Before proceeding any further, make sure you are back with the base behaviour. To do so, you may run the following command:
|
Let’s start by creating a sloppy namespace:
Λ\: $ kubectl create namespace workshop-unsecured
namespace/workshop-unsecured created
Then, let’s create a one-time pod with curl
command installed:
Λ\: $ kubectl run --rm --restart Never -it shell --namespace workshop-unsecured --image tutum/curl -- bash
root@shell:/#
If you don’t see a command prompt, try pressing enter |
Now we can try to reach the middleware
service which is running in the workshop
namespace:
Λ\: $ curl -vvv "middleware.workshop:8080"; echo;
* Rebuilt URL to: middleware.workshop:8080/
* Hostname was NOT found in DNS cache
* Trying 10.121.6.186...
* Connected to middleware.workshop (10.121.6.186) port 8080 (#0)
> GET / HTTP/1.1
> User-Agent: curl/7.35.0
> Host: middleware.workshop:8080
> Accept: */*
>
< HTTP/1.1 200 OK
< content-type: application/json
< content-length: 77
< x-envoy-upstream-service-time: 268
< date: Mon, 01 Jun 2020 11:47:38 GMT
* Server istio-envoy is not blacklisted
< server: istio-envoy
< x-envoy-decorator-operation: middleware.workshop.svc.cluster.local:8080/*
<
* Connection #0 to host middleware.workshop left intact
{"from":"middleware (v1) => database (v1)","date":"2020-06-01T11:47:38.911Z"}
As expected, we are able to reach the middleware
service without the sidecar proxy.
Now, from another terminal instance, let’s activate communication encryption in the workshop
namespace. To enable
mTLS at the namespace level, you need to apply the following YAML:
apiVersion: authentication.istio.io/v1alpha1
kind: Policy
metadata:
name: default
namespace: workshop
spec:
peers:
- mtls:
mode: STRICT
---
apiVersion: networking.istio.io/v1alpha3
kind: DestinationRule
metadata:
name: default
namespace: workshop
spec:
host: "*.workshop.svc.cluster.local"
trafficPolicy:
tls:
mode: ISTIO_MUTUAL
---
apiVersion: networking.istio.io/v1alpha3
kind: DestinationRule (1)
metadata:
namespace: workshop
name: front
spec:
host: front
trafficPolicy:
tls:
mode: ISTIO_MUTUAL
subsets:
- name: version-1
labels:
version: v1
1 | We have to redeclare the previous DestinationRule to allow secured communication between the Gateway and the
front component |
# Run in another terminal instance
Λ\: $ kubectl apply --filename 07_security/01_mutual-tls/01_workshop-namespace-as-mtls.yml
Back in the one-time curl
pod attached terminal, if you try to reach the middleware
service again:
# Run in the pod with curl command in the workshop-unsecured namespace
Λ\: $ curl -vvv middleware.workshop:8080
* Rebuilt URL to: middleware.workshop:8080/
* Hostname was NOT found in DNS cache
* Trying 10.121.7.48...
* Connected to middleware.workshop (10.121.7.48) port 8080 (#0)
> GET / HTTP/1.1
> User-Agent: curl/7.35.0
> Host: middleware.workshop:8080
> Accept: */*
>
* Recv failure: Connection reset by peer
* Closing connection 0
curl: (56) Recv failure: Connection reset by peer
You should see a Recv failure: Connection reset by peer
, meaning you reached the service, but cannot communicate since
the mTLS is not configured on both ends.
Therefore, you were able enforce network security by leveraging the capabilities of the sidecar proxy. This improves the safety of your application by delegating internal communications encrypting to the infrastructure.