Kubernetes istio security - ghdrako/doc_snipets GitHub Wiki

When deployed in Kubernetes, Istio relies on Kubernetes service accounts to identify the roles of workloads in a Service Mesh. The Istio CA watches the Kubernetes API server for the addition/deletion/modification of any service accounts in the namespace with Istio injection enabled. It creates a key and certificates for each service account and, during Pod creation, the certificate and key are mounted onto the sidecar. The Istio CA is responsible for managing the life cycle of the certificates distributed to the sidecars, including the rotation and management of private keys. Using the Secure Production Identity Framework for Everyone (SPIFFE) format identities, Istio provides a strong identity to each service along with service naming, which represents the role that can be taken up by the identity assigned to the service.

SPIFFE is a set of open source standards for software identity. SPIFFE provides platform-agnostic interoperable software identities along with interfaces and documents required to obtain and validate cryptographic identity in a fully automated fashion.

In Istio, each workload is automatically assigned an identity represented in the X.509 certificate format. The creation and signing of certificate signing request (CSRs) are managed by the Istio control plane

$ istioctl proxy-config all po/envoydummy-2-7488b58cd7-m5vpv -n 
utilities -o json | jq -r '.. |."secret"?' | jq -r 'select(. 
name == "default")' | jq -r '.tls_certificate.certificate_ 
chain.inline_bytes' | base64 -d - | step certificate
inspect --short
step CLI

You will need to install step CLI to be able to run the preceding command. To install it, please follow the documentation at https://smallstep.com/docs/step-cli.

In the output of the preceding command, you will notice that the Subject Alternative Name (SAN) is spiffe://cluster.local/ns/utilities/sa/default. This is the SPIFFE ID, which functions as the unique name:

  • spifee is the URI scheme
  • cluster.local is the trust domain
  • /ns/utilities/sa/default is the URI identifying the service account associated with the workload:
  • ns stands for namespace
  • sa stands for service account
$ kubectl get po/envoydummy-2-7488b58cd7-m5vpv -n utilities -o json | jq .spec.serviceAccountName
"default"

The value default for service accounts comes from the service account attached to the workload.If we didn’t associate any service accounts then by default, Kubernetes associated the default service account. Kubernetes creates a service account named default in every namespace:

% kubectl get sa -n utilities

obraz

These are the key concepts to remember:

  • The Istio CA manages keys and certificates and the SANs in certificates are in SPIFFE format
  • Istiod distributes authentication and authorization security policies to all sidecars in the mesh
  • Sidecars enforce authentication and authorization as per security policies distributed by Istiod

Authentication using mutual TLS

mTLS is one of the most frequently used authentication mechanisms for implementing the zero-trust security framework, in which no party trusts another party by default, irrespective of where the other party is placed in the network. Zero trust assumes that there are no traditional network edges and boundaries and hence every party needs to be authenticated and authorized. This helps to eliminate many security vulnerabilities that arise because of the assumption-based trust model.

Service-to-service authentication

Istio provides service-to-service authentication by using mTLS for transport authentication. During traffic processing, Istio performs the following:

  • All outbound traffic from Pods is rerouted to istio-proxy.
  • istio-proxy starts an mTLS handshake with the server-side istio-proxy. During the handshake, it also does a secure naming check to verify that the service account presented in the server certificate can run the Pod.
  • The server-side istio-proxy verifies the client-side istio-proxy in the same fashion and if all is okay, a secure channel is established between the two proxies.

Istio provides the following two options when implementing mTLS:

  • Permissive mode: In permissive mode, Istio allows traffic in both mTLS and non-mTLS mode. This feature is primarily to improve the onboarding of clients to mTLS. Clients who are not yet ready to communicate over mTLS can continue communicating over TLS with the view that they will eventually migrate to mTLS whenever they are ready.

  • Strict mode: In strict mode, Istio enforces strict mTLS and any non-mTLS traffic is not allowed.

  • The PeerAuthentication resource configures the proxy to authenticate service-to-service traffic. On successful authentication, the proxy extracts the information encoded in the peer’s certificate and makes it available to authorize the request.\

  • The RequestAuthentication resource configures the proxy to authenticate end-user credentials against the servers that issued them. On successful authentication, it also extracts the information encoded in the credential and makes it available for authorizing the request.

  • The AuthorizationPolicy resource configures the proxy to authorize or reject requests by making decisions based on the data extracted by the previous two resources.

PeerAuthentication

apiVersion: "security.istio.io/v1beta1"
kind: "PeerAuthentication"
metadata:
  name: "default"
  namespace: "istio-system"
  spec:
    mtls:
      mode: STRICT

we can prohibit clear-text traffic by creating a mesh-wide policy that enforces the STRICT mutually authentication mode. A mesh wide PeerAuthentication policy must fulfill two conditions: it must be applied in the Istio installation namespace, and it must be named "default".

apiVersion: security.istio.io/v1beta1
kind: PeerAuthentication
metadata:
  name: "httpbin-strict-tls"
  namespace: appns
spec:
  mtls:
    mode: STRICT
  selector:
    matchLabels:
      app: httpbin

In the PeerAuthentication policy, we defined the following configuration parameters:

  • mtls: This defines the mTLS setting. If not specified, the value is inherited from the default mesh-wide setting. It has one field called mode, which can have the following values:
    • UNSET: With this value, the mTLS settings are inherited from the parent and if the parent does not have any settings, then the value is set to PERMISSIVE.
    • MTLS: With this value, the sidecar accepts both mTLS and non-mTLS connections.
    • STRICT: This enforces strict mTLS – any non-mTLS connection will be dropped.
    • DISABLE: mTLS is disabled and connections are not tunneled.
    • Selector: This defines the criteria that need to be satisfied by a workload to be part of this per authentication policy. It has a field named matchLabels, which takes label information in the key:value format.
Authentication with clients outside the mesh

For clients outside the mesh, Istio supports mTLS with the Ingress gateway. The steps are as follows:

  1. Create a CA. Here, we are creating a CA with a Common Name (CN) of sock.inc:
$ openssl req -x509 -sha256 -nodes -days 365 -newkey
rsa:2048 -subj '/O=sock Inc./CN=sock.inc' -keyout sock.
inc.key -out sock.inc.crt
  1. Generate a CSR for httpbin.org. Here, we are generating a Certificate Signing Request (CSR) for httpbin.org, which also generates a private key:
$ openssl req -out httpbin.org.csr -newkey rsa:2048 -nodes -keyout httpbin.org.key -subj "/CN=httpbin.org/O=sockshop.inc"
Generating a 2048 bit RSA private key
.........+++
..+++
writing new private key to 'httpbin.org.key'
  1. Sign the CSR using the CA created in step 1:
$ openssl x509 -req -sha256 -days 365 -CA sock.inc.crt -CAkey sock.inc.key -set_serial 0 -in httpbin.org.csr -out httpbin.org.crt
Signature ok
subject=/CN=httpbin.org/O=sockshop.inc
Getting CA Private Key
  1. Load the certificate and private key as a Kubernetes secret along with the CA certificate against which client certificates must be verified:
$ kubectl create -n istio-system secret generic httpbin-
credential --from-file=tls.key=httpbin.org.key --from-
file=tls.crt=httpbin.org.crt --from-file=ca.crt=sock.inc.
crt
secret/httpbin-credential created
  1. Configure the Ingress gateway to enforce mTLS for all incoming connections and use the secret created in step 4 as the secret containing TLS certificate and the CA certificate:
tls:
mode: MUTUAL
credentialName: httpbin-credential
  1. Deploy the httpbin Pod, the Ingress gateway, and the virtual service
  2. To perform mTLS, you also need to generate client certificates that can be used to prove the client’s identity. For that, perform the following steps:
$ openssl req -out bootstrapistio.packt.com.csr -newkey
rsa:2048 -nodes -keyout bootstrapistio.packt.com.key
-subj "/CN= bootstrapistio.packt.com/O=packt.com"
$ openssl x509 -req -sha256 -days 365 -CA sock.inc.crt
-CAkey sock.inc.key -set_serial 0 -in bootstrapistio.
packt.com.csr -out bootstrapistio.packt.com.crt
  1. Test the connection to httpbin.org by passing client certificates in the request:
% curl -v -HHost:httpbin.org --connect-to "httpbin.
org:443:a816bb2638a5e4a8c990ce790b47d429-1565783620.
us-east-1.elb.amazonaws.com" --cacert sock.inc.crt --cert
bootstrapistio.packt.com.crt --key bootstrapistio.packt.
com.key https://httpbin.org:443/get

Configuring RequestAuthentication

The RequestAuthentication policy is used to specify what authentication methods are supported by a workload. This policy identifies the authenticated identity but doesn’t enforce whether the request should be allowed or denied. Rather, it provides information about the authenticated identity to the authorization policy, which we will go through in the next section. In this section, we will learn how to make use of the Istio RequestAuthentication policy to validate an end user who has been authenticated by Auth0 and is providing a bearer token as security credentials to Istio.

When using the RequestAuthentication policy, it is best practice to also configure the RequestAuthentication and AuthorizationPolicy together and enforce a rule that any request with an empty principal should not be allowed.

Configuring RequestAuthorization

NOTE Naming mesh-wide resources "default" is not a requirement but rather a convention so that only one mesh-wide PeerAuthentication resource is created.