2023-10-14 13:00:22 +02:00
..
2023-10-14 13:00:22 +02:00
2023-10-14 13:00:22 +02:00
2023-10-14 13:00:22 +02:00
2023-10-14 13:00:22 +02:00
2023-10-14 13:00:22 +02:00
2023-10-14 13:00:22 +02:00
2023-10-14 13:00:22 +02:00

Table of Contents

Based on

Description

This example contains a backend that serves HTTPS traffic and can be accessed from both HTTP and HTTPS requests through the gateway resource.

Note:
For more information about the image used refer to here

Configuration

Gateway

The gateway is configured to listen to the port 80 for HTTP traffic, and to the port 443 for HTTPS traffic.

The TLS configuration is set to simple, and the credentials (the object that contains the certificates/TLS configuration) is set to my-tls-cert-secret.

Any of the configured ports has limited the hosts.

apiVersion: networking.istio.io/v1alpha3
kind: Gateway
metadata:
  name: helloworld-gateway
spec:
  selector:
    istio: ingressgateway
  servers:
    - port:
        number: 80
        name: http
        protocol: HTTP
      hosts:
        - "*"
    - port:
        number: 443
        name: https
        protocol: HTTPS
      hosts:
        - "*"
      tls:
        credentialName: my-tls-cert-secret
        mode: SIMPLE

Note:
The credentials resource is created further bellow through the Walkthrough steps.

Note:
For more information regarding the TLS mode configuration, refer to the following Istio documentation regarding the TLS mode field.

VirtualService

The rule that contains, will receive traffic from the port 443 and 80.

This traffic will be directed towards destination of such is the service helloworld.default.svc.cluster.local, with port destination 8443.

This destination is the service that contains the HTTPS deployment, running over the port 8443

apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
  name: helloworld-vs
spec:
  hosts:
    - "*"
  gateways:
    - helloworld-gateway
  http:
    - name: https-vs
      match:
        - port: 80
        - port: 443
      route:
        - destination:
            host: helloworld.default.svc.cluster.local
            port:
              number: 8443

DestinationRule

This DestinationRule, will interject the traffic destined to the service helloworld.default.svc.cluster.local with port 8443.

As mentioned in the Virtual Service section, the destination is the HTTPS service.

By default, the call would be made with HTTP protocol, yet, as the destination is an HTTPS service, the request would result in the status code 400 Bad Request, due sending HTTP traffic to an HTTPS service.

To avoid this, we need to specify that the destination handles HTTPS traffic.

By setting the tls.mode field with simple, it means that there will be an attempt to initialize a TLS handshake.

Note: For more information about the TLS mode, refer to the Istio official documentation from the DestinationRule object regarding the TLS mode field.

apiVersion: networking.istio.io/v1alpha3
kind: DestinationRule
metadata:
  name: helloworld
  namespace: default
spec:
    host: helloworld.default.svc.cluster.local
    trafficPolicy:
      portLevelSettings:
        - port:
            number: 8443
          tls:
            mode: SIMPLE

Service

The service will forward incoming TCP traffic from the port 8443, towards the deployment port 443.

It's been specified the protocol expected to service, it being HTTPS.

apiVersion: v1
kind: Service
metadata:
  name: helloworld
  labels:
    app: helloworld
    service: helloworld
spec:
  ports:
    - name: https
      port: 8443
      targetPort: 443
      protocol: TCP
      appProtocol: HTTPS
  selector:
    app: helloworld

Deployment

Deployment listens to port 80 and 443.

Note:
For more information about the image used refer to here

apiVersion: apps/v1
kind: Deployment
metadata:
  name: helloworld-nginx
  labels:
    app: helloworld
spec:
  replicas: 1
  selector:
    matchLabels:
      app: helloworld
  template:
    metadata:
      labels:
        app: helloworld
    spec:
      containers:
        - name: helloworld
          image: oriolfilter/https-nginx-demo
          resources:
            requests:
              cpu: "100m"
          imagePullPolicy: IfNotPresent
          ports:
            - containerPort: 80
            - containerPort: 443

PeerAuthentication

Due to the deployment having an HTTPS, and already initializing a TLS termination towards that service, we need to disable the mTLS tool for that specific service/deployment.

On the Destination Rule section we set the tls to simple, meaning that the service is expecting to receive HTTPS traffic, if mTLS is enabled, it will perform the handshake with the mTLS service, instead of with the destination HTTPS service.

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

Note

:
As this configuration is very board, and targets the whole namespace, I would strongly recommend referring to the following example 06-Internal-Authentication/02-AuthorizationPolicy-Target-Service-Accounts, which shows how to target service accounts set to resources, limiting the scope of this rule set.

Walkthrough

Generate client and server certificate and key files

First step will be to generate the certificate and key files to be able to set them to the Gateway resource.

Create a folder to store files.

Create the folder to contain the files that will be generated.

mkdir certfolder

Create a certificate and a private key.

openssl req -x509 -sha256 -nodes -days 365 -subj '/O=Internet of things/CN=lb.net' -newkey rsa:2048 -keyout certfolder/istio.cert.key -out certfolder/istio.cert.crt

The files generated are the following:

private-key: certfolder/istio.cert.key
root-certificate: certfolder/istio.cert.crt

The information set to the certificate generated is the following:

Organization-name: Internet of things
CN: lb.net

Create a TLS secret

At this step we create the tls secret my-tls-cert-secret on the namespace istio-system.

kubectl create -n istio-system secret tls my-tls-cert-secret \
  --key=certfolder/istio.cert.key \
  --cert=certfolder/istio.cert.crt
secret/my-tls-cert-secret created
service/helloworld created
deployment.apps/helloworld-nginx created
gateway.networking.istio.io/helloworld-gateway created
virtualservice.networking.istio.io/helloworld-vs created

Note:
It's Important that the secret is located in the same namespace as the Load Balancer used. In my case is the istio-system, but it will vary based on the environment.

Deploy resources

kubectl apply -f ./
peerauthentication.security.istio.io/default-mtls created
service/helloworld created
deployment.apps/helloworld-nginx created
gateway.networking.istio.io/helloworld-gateway created
virtualservice.networking.istio.io/helloworld-vs created
destinationrule.networking.istio.io/helloworld created

Test the service

Get LB IP

kubectl get svc -l istio=ingressgateway -A
NAME                   TYPE           CLUSTER-IP     EXTERNAL-IP    PORT(S)                                      AGE
istio-ingressgateway   LoadBalancer   10.97.47.216   192.168.1.50   15021:31316/TCP,80:32012/TCP,443:32486/TCP   39h

curl HTTP gateway

Well, it works as expected.

curl --insecure 192.168.1.50 -I 
HTTP/1.1 200 OK
server: istio-envoy
date: Tue, 25 Apr 2023 04:41:19 GMT
content-type: text/html
content-length: 15
last-modified: Tue, 25 Apr 2023 00:47:17 GMT
etag: "64472315-f"
strict-transport-security: max-age=7200
accept-ranges: bytes
x-envoy-upstream-service-time: 28

curl HTTPS gateway

Well, it works as expected.

curl --insecure https://192.168.1.50 -I 
HTTP/2 200 
server: istio-envoy
date: Tue, 25 Apr 2023 04:42:07 GMT
content-type: text/html
content-length: 15
last-modified: Tue, 25 Apr 2023 00:47:17 GMT
etag: "64472315-f"
strict-transport-security: max-age=7200
accept-ranges: bytes
x-envoy-upstream-service-time: 13

Cleanup

kubectl delete -f ./
peerauthentication.security.istio.io "default-mtls" deleted
service "helloworld" deleted
deployment.apps "helloworld-nginx" deleted
gateway.networking.istio.io "helloworld-gateway" deleted
virtualservice.networking.istio.io "helloworld-vs" deleted
destinationrule.networking.istio.io "helloworld" deleted

Links of Interest