# HTTPS/TLS Setup

## HTTPS Configuration

## Prerequisites

- A DNS name.
- A static external IP address, associated with the DNS host name
  - GKE
  - AWS

Reserve a static external IP.
See Google documentation on how to [Configure static external IP addresses](https://cloud.google.com/compute/docs/ip-addresses/reserve-static-external-ip-address).

Allocate IP addresses from AWS Elastic IP.
See AWS documentation on [Elastic IP addresses](https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/elastic-ip-addresses-eip.html).

- A certificate, either a [new SSL certificate](https://docs.kloudfuse.com/platform/4.1.0/setup/network/https/#new) created as part of Kloudfuse installation, or an [existing SSL certificate](https://docs.kloudfuse.com/platform/4.1.0/setup/network/https/#existing).

### New Certificate

If the SSL certificate is created as part of Kloudfuse installation, then cert-manager using lets-encrypt creates the Certificate. The cert-manager must be installed already in the Kubernetes cluster. See cert-manager documentation on [Installation](https://cert-manager.io/docs/installation/).

Create certificate during install

```yml
helm repo add jetstack https://charts.jetstack.io
helm repo update
helm install cert-manager jetstack/cert-manager --create-namespace --namespace kfuse --version v1.7.1 --set installCRDs=true
```

### Existing Certificate

Create a Kubernetes secret of type TLS, with `server.crt` and `server.key` files (SSL certificates).

Use an existing certificate

```yaml
kubectl create secret tls kfuse-tls --namespace kfuse --key server.key --cert server.crt
```

## Configure Helm Values

Depending on the cloud provider, ingress type, and certificate method, add the following entries in the `custom_values.yaml` file:

For migrating from ingress-nginx to Envoy Gateway, see [Configure Envoy Ingress](https://docs.kloudfuse.com/platform/4.1.0/setup/network/envoy/).

- Envoy Gateway — GCP, New Certificate
- Envoy Gateway — GCP, Existing Certificate
- Envoy Gateway — AWS, New Certificate
- ingress-nginx — GCP, New Certificate
- ingress-nginx — GCP, Existing Certificate

```yaml
tls:
  enabled: true
  host: <REPLACE DNS HOST HERE>
  email: <REPLACE EMAIL>
  clusterIssuer: <PROVIDE A CLUSTER ISSUER NAME>

envoy-gateway:
  enabled: true
  installGatewayRoutes: true
  envoyService:
    patch:
      loadBalancerIP: <REPLACE PRE-ALLOCATED STATIC IP HERE>
    external:
      enabled: true

ingress-nginx:
  enabled: false
  installIngressRules: false
```

```yaml
tls:
  enabled: true
  host: <REPLACE DNS HOST HERE>
  secretName: <PROVIDE secret name containing SSL certificate, such as kfuse-tls>

envoy-gateway:
  enabled: true
  installGatewayRoutes: true
  envoyService:
    patch:
      loadBalancerIP: <REPLACE PRE-ALLOCATED STATIC IP HERE>
    external:
      enabled: true

ingress-nginx:
  enabled: false
  installIngressRules: false
```

|     |     |
| --- | --- |
| **1** | **secretName** created in [Use an existing certificate](https://docs.kloudfuse.com/platform/4.1.0/setup/network/https/#secret-https). |

```yaml
tls:
  enabled: true
  host: <REPLACE DNS HOST HERE>
  email: <REPLACE EMAIL>
  clusterIssuer: <PROVIDE A CLUSTER ISSUER NAME>

envoy-gateway:
  enabled: true
  installGatewayRoutes: true
  envoyService:
    annotations:
      service.beta.kubernetes.io/aws-load-balancer-type: nlb
      service.beta.kubernetes.io/aws-load-balancer-cross-zone-load-balancing-enabled: 'true'
      service.beta.kubernetes.io/aws-load-balancer-eip-allocations: <REPLACE EIP ALLOC IDS>
    patch:
      externalTrafficPolicy: Local
    external:
      enabled: true

ingress-nginx:
  enabled: false
  installIngressRules: false
```

```yaml
tls:
  enabled: true
  host: <REPLACE DNS HOST HERE>
  email: <REPLACE EMAIL>
  clusterIssuer: <LEAVE BLANK because providing own ssl certificate>
  secretName: <PROVIDE secret name containing SSL certificate, such as kfuse-tls> (1)

ingress-nginx:
  controller:
    ingressClassResource:
        enabled: true
        name: kfuse-ingress
    ingressClass: kfuse-ingress
    watchIngressWithoutClass: false
    service:
      loadBalancerIP: <REPLACE PRE-ALLOCATED STATIC IP HERE>
      external:
        enabled: true
```

## Disable HTTP Traffic

|     |     |
| --- | --- |
|  | 1. This step disables HTTP traffic on both internal and external `ingress`. Use the following if you plan to disable HTTP and not use internal ingress.<br>   <br>2. You must enable http traffic for `letsencrypt` to generate certificate during installation.<br>   <br>3. Use either an externally-provided certificate (acm, and so on), or disable http traffic _**after**_ generating a tls certificate. |

If you plan to disable HTTP traffic completely:

- Envoy Gateway
- ingress-nginx

```yaml
envoy-gateway:
  enableHttp: false
```

```yaml
ingress-nginx:
  controller:
    service:
      enableHttp: false
```

## TLS Termination

You can configure the Kloudfuse stack to work on clusters that have TLS Termination, such as OKTA and AWS ACM.

### Minimal Configuration

Add the following entries to the `custom_values.yaml` file:

- Envoy Gateway
- ingress-nginx

With Envoy Gateway, TLS termination at the load balancer (e.g., AWS ACM) is configured via the `tls.awsAcmEnabled` flag and envoy service annotations:

```yaml
tls:
  enabled: false
  awsAcmEnabled: true
  host: <REPLACE DNS HOST HERE>

envoy-gateway:
  enabled: true
  installGatewayRoutes: true
  envoyService:
    annotations:
      service.beta.kubernetes.io/aws-load-balancer-type: nlb
      service.beta.kubernetes.io/aws-load-balancer-ssl-cert: <ACM_CERTIFICATE_ARN>
      service.beta.kubernetes.io/aws-load-balancer-ssl-ports: "443"
      service.beta.kubernetes.io/aws-load-balancer-backend-protocol: tcp
      service.beta.kubernetes.io/aws-load-balancer-cross-zone-load-balancing-enabled: 'true'
    external:
      enabled: true

ingress-nginx:
  enabled: false
  installIngressRules: false
```

To configure separate internal (ingest) and external (query) hosts with Envoy Gateway, use the symmetric `tls.internalIngest` and `tls.externalQuery` fields:

```yaml
tls:
  enabled: false
  awsAcmEnabled: true
  host: <REPLACE DNS HOST HERE>
  internalIngest:
    hosts:
      - <INTERNAL INGEST DNS HOST>
    secretName: ""
    hostOnly: false
  externalQuery:
    hosts:
      - <EXTERNAL QUERY DNS HOST>
    secretName: ""
    hostOnly: false

envoy-gateway:
  enabled: true
  installGatewayRoutes: true
  envoyService:
    annotations:
      service.beta.kubernetes.io/aws-load-balancer-type: nlb
      service.beta.kubernetes.io/aws-load-balancer-ssl-cert: <ACM_CERTIFICATE_ARN>
      service.beta.kubernetes.io/aws-load-balancer-ssl-ports: "443"
      service.beta.kubernetes.io/aws-load-balancer-backend-protocol: tcp
      service.beta.kubernetes.io/aws-load-balancer-cross-zone-load-balancing-enabled: 'true'
    external:
      enabled: true
    internal:
      enabled: true
      annotations:
        service.beta.kubernetes.io/aws-load-balancer-internal: "true"

ingress-nginx:
  enabled: false
  installIngressRules: false
```

| Field | Description |
| --- | --- |
| `tls.internalIngest.hosts` | List of DNS hostnames for internal ingestion routes. |
| `tls.internalIngest.secretName` | Kubernetes TLS secret for the ingest hosts (leave empty for ACM termination). |
| `tls.internalIngest.hostOnly` | If `true`, ingest routes only match `internalIngest.hosts` and exclude `tls.host`. |
| `tls.externalQuery.hosts` | List of DNS hostnames for external query/browser routes. |
| `tls.externalQuery.secretName` | Kubernetes TLS secret for the query hosts (leave empty for ACM termination). |
| `tls.externalQuery.hostOnly` | If `true`, query routes only match `externalQuery.hosts` and exclude `tls.host`. |

### Configure TLS Termination on AWS NLB Using AWS Certificate Manager

AWS supports configurations with TLS termination directly on the AWS NLB that backs the Kloudfuse ingress service.

Complete these tasks to fully configure TLS termination with AWS Certificate Manager (ACM)

- [Prerequisites](https://docs.kloudfuse.com/platform/4.1.0/setup/network/https/#prerequisites-tls)
- [Configure with Helm](https://docs.kloudfuse.com/platform/4.1.0/setup/network/https/#helm-tls)

### Prerequisites

- A DNS hostname.
- An AWS issued Certificate [(AWS Certificate Manager)](https://docs.aws.amazon.com/acm/latest/userguide/acm-overview.html).
- An Elastic IP address [(User Guide to Elastic IP)](https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/elastic-ip-addresses-eip.html).

### Configure with Helm

There are three options for configuring Helm values:

#### Minimal configuration with ACM

```yaml
tls:
  enabled: false
  awsAcmEnabled: true

ingress-nginx:
  controller:
    service:
      annotations:
        service.beta.kubernetes.io/aws-load-balancer-type: external
        service.beta.kubernetes.io/aws-load-balancer-nlb-target-type: ip
        service.beta.kubernetes.io/aws-load-balancer-scheme: internet-facing
        service.beta.kubernetes.io/aws-load-balancer-cross-zone-load-balancing-enabled: 'true'
        service.beta.kubernetes.io/aws-load-balancer-eip-allocations: <REPLACE ELASTIC IP ALLOCATION IDs HERE, comma separated>
        service.beta.kubernetes.io/aws-load-balancer-ssl-cert: "<REPLACE AWS ACM CERTIFICATE ARN HERE>"
        service.beta.kubernetes.io/aws-load-balancer-ssl-ports: "443"
        service.beta.kubernetes.io/aws-load-balancer-backend-protocol: "tcp"
      external:
        enabled: true
      targetPorts:
        https: http
```

#### Host-based routing (External Load Balancer only)

This configuration restricts Kloudfuse access to the hostname specified in the configuration.

```yaml
tls:
  enabled: false
  awsAcmEnabled: true
  host: <<External facing DNS host>>

#### Host-based routing (Internal and External Load Balancers)

This configuration restricts Kloudfuse access to the specified hostnames on both internal and external load balancers.

- The internal load balancer handles the ingest path for MELT data.
- The external load balancer handles the query path.

```yaml
tls:
  enabled: false
  awsAcmEnabled: true
  host: <<External facing DNS host>>
  internalIngest:
    hosts:
      - <<Internal DNS host>>
    secretName: ""
    hostOnly: false
  externalQuery:
    hosts:
      - <<External facing DNS host>>
    secretName: ""
    hostOnly: false

envoy-gateway:
  enabled: true
  installGatewayRoutes: true
  envoyService:
    annotations:
      service.beta.kubernetes.io/aws-load-balancer-type: nlb
      service.beta.kubernetes.io/aws-load-balancer-ssl-cert: "<REPLACE AWS ACM CERTIFICATE ARN HERE>"
      service.beta.kubernetes.io/aws-load-balancer-ssl-ports: "443"
      service.beta.kubernetes.io/aws-load-balancer-backend-protocol: tcp
      service.beta.kubernetes.io/aws-load-balancer-cross-zone-load-balancing-enabled: 'true'
    external:
      enabled: true
    internal:
      enabled: true
      annotations:
        service.beta.kubernetes.io/aws-load-balancer-internal: "true"
        service.beta.kubernetes.io/aws-load-balancer-type: nlb
        service.beta.kubernetes.io/aws-load-balancer-cross-zone-load-balancing-enabled: 'true'
        service.beta.kubernetes.io/aws-load-balancer-ssl-cert: "<REPLACE AWS ACM CERTIFICATE ARN HERE>"
        service.beta.kubernetes.io/aws-load-balancer-ssl-ports: "443"
        service.beta.kubernetes.io/aws-load-balancer-backend-protocol: tcp

ingress-nginx:
  enabled: false
  installIngressRules: false
```

```yaml
tls:
  enabled: false
  awsAcmEnabled: true
  host: <<External facing DNS host>>
  ingestInternalHost: <<Internal DNS host>>

### Load Balancer

You must configure the internal load balancer to send agent data over an internal network.

Update the certificate for the external load balancer to ensure it contains the domain name for the internal load balancer, then update DNS entries as required.

ACM only allows wildcard subdomains, such as `*.domain.com`, or sibling domains, such as `internal.domain.com`. For example, if `observability.domain.com` hosts the Kloudfuse stack, you can route internal traffic to `internal.observability.domain.com`. The certificate can cover both domain names.

After provisioning the [ACM](https://docs.kloudfuse.com/platform/4.1.0/reference/misc/glossary/#acm) certificate, update the `custom-values.yaml` file’s ingress section for the internal controller.

Internal load balancer configuration in custom-values.yaml

```yaml
ingress-nginx:
  controller:
    service:
      annotations:
        # ... see external annotations above
      external:
        enabled: true
      internal:
        enabled: true
        annotations:
          service.beta.kubernetes.io/aws-load-balancer-internal: "true"
          service.beta.kubernetes.io/aws-load-balancer-type: nlb
          service.beta.kubernetes.io/aws-load-balancer-cross-zone-load-balancing-enabled: 'true'
          service.beta.kubernetes.io/aws-load-balancer-ssl-cert: "<REPLACE AWS ACM CERTIFICATE ARN HERE>"
          service.beta.kubernetes.io/aws-load-balancer-ssl-ports: "443"
          service.beta.kubernetes.io/aws-load-balancer-backend-protocol: "http"
      targetPorts:
        https: http
```

### Configure with Helm

There are three options for configuring Helm values:

- Minimal configuration with ACM
- Host-based routing (External Load Balancer only)
- Host-based routing (Internal and External Load Balancers)
