> ## Documentation Index
> Fetch the complete documentation index at: https://cloudanix.com/docs/llms.txt
> Use this file to discover all available pages before exploring further.

# Encrypt Traffic To HTTPS Load Balancers With TLS Certificates

### More Info:

Configure HTTPS load balancers with TLS certificates so that traffic to the cluster is encrypted in transit.

### Risk Level

Medium

### Address

Security

### Compliance Standards

* CIS EKS

### Triage and Remediation

<Tabs>
  <Tab title="Remediation">
    ### Remediation

    <AccordionGroup>
      <Accordion title="Manual Steps" defaultOpen="true">
        1. **Inventory all external-facing load balancers**
           * On any machine with cloud CLI access, list load balancers that front your EKS cluster (adjust region):
           * AWS:
             ```bash theme={null}
             aws elbv2 describe-load-balancers --region us-east-1 \
               --query 'LoadBalancers[].{Name:LoadBalancerName,DNS:DNSName,Scheme:Scheme,Type:Type}'
             ```
             ```bash theme={null}
             aws elb describe-load-balancers --region us-east-1 \
               --query 'LoadBalancerDescriptions[].{Name:LoadBalancerName,DNS:DNSName,Scheme:Scheme}'
             ```
           * From each returned LB, identify those used by the cluster (via tags or target groups):
             ```bash theme={null}
             aws elbv2 describe-tags --region us-east-1 \
               --resource-arns <lb-arn-1> <lb-arn-2>
             ```

        2. **Determine listener protocols and TLS configuration**
           * For each Application/Network Load Balancer ARN:
             ```bash theme={null}
             aws elbv2 describe-listeners --region us-east-1 --load-balancer-arn <lb-arn>
             ```
             Review each listener: confirm that internet-facing listeners use `Protocol: HTTPS` (or `TLS` for NLB) with a certificate (`SslPolicy` and `Certificates` set).
           * For each Classic Load Balancer name:
             ```bash theme={null}
             aws elb describe-load-balancers --region us-east-1 \
               --load-balancer-names <elb-name>
             ```
             Confirm at least one `Listener` has `Protocol: HTTPS` and `SSLCertificateId` set.

        3. **Verify certificates and TLS policies**
           * For each HTTPS/TLS listener, list the referenced certificate from ACM:
             ```bash theme={null}
             aws acm list-certificates --region us-east-1 \
               --certificate-statuses ISSUED
             ```
             ```bash theme={null}
             aws acm describe-certificate --region us-east-1 \
               --certificate-arn <cert-arn>
             ```
             Ensure:
             * Certificate is `ISSUED`, not expired, and covers the LB DNS name or custom domain.
             * `SslPolicy` on listeners is a modern one (e.g., `ELBSecurityPolicy-TLS13-1-2-Ext1-2021-06` or similar per your security standard).

        4. **Remediate non-encrypted or misconfigured listeners**
           * For any internet-facing listener using HTTP/TCP without TLS:
             * Create or import a valid certificate in ACM (if not already present).
             * Modify or add an HTTPS/TLS listener and (optionally) redirect HTTP to HTTPS:
               ```bash theme={null}
               aws elbv2 create-listener --region us-east-1 \
                 --load-balancer-arn <lb-arn> \
                 --protocol HTTPS --port 443 \
                 --default-actions Type=forward,TargetGroupArn=<tg-arn> \
                 --certificates CertificateArn=<cert-arn> \
                 --ssl-policy ELBSecurityPolicy-TLS13-1-2-Ext1-2021-06
               ```
               ```bash theme={null}
               aws elbv2 modify-listener --region us-east-1 \
                 --listener-arn <http-listener-arn> \
                 --default-actions Type=redirect,RedirectConfig='{"Protocol":"HTTPS","Port":"443","StatusCode":"HTTP_301"}'
               ```
           * For Classic ELB:
             ```bash theme={null}
             aws elb create-load-balancer-listeners --region us-east-1 \
               --load-balancer-name <elb-name> \
               --listeners Protocol=HTTPS,LoadBalancerPort=443,InstanceProtocol=HTTP,InstancePort=80,SSLCertificateId=<cert-arn>
             ```

        5. **Update IaC definitions (if used)**
           * In Terraform/CloudFormation/CDK, ensure:
             * `aws_lb_listener` / `AWS::ElasticLoadBalancingV2::Listener` uses `HTTPS`/`TLS` with ACM certificate ARNs and secure SSL policies.
             * Any `HTTP` listener has a `redirect` action to HTTPS.
           * Re-apply your IaC so the configuration is managed declaratively and not drift-prone.

        6. **Verification (post-change)**
           * Re-run listener inspection to confirm only HTTPS/TLS is exposed externally and certificates are attached:
             ```bash theme={null}
             aws elbv2 describe-listeners --region us-east-1 --load-balancer-arn <lb-arn>
             aws elb describe-load-balancers --region us-east-1 --load-balancer-names <elb-name>
             ```
           * From a client, test that the endpoint negotiates TLS and matches the expected certificate:
             ```bash theme={null}
             openssl s_client -connect <lb-dns-name>:443 -servername <your-domain> -showcerts </dev/null 2>/dev/null | openssl x509 -noout -subject -issuer -dates
             ```
      </Accordion>

      <Accordion title="Using kubectl">
        kubectl cannot be used to configure TLS on HTTPS load balancers, because this setting is managed at the cloud provider / managed control-plane level (console, cloud CLI, or IaC). To remediate this finding, follow the provider-specific guidance in the **Manual Steps** section for configuring TLS certificates on your load balancers.
      </Accordion>

      <Accordion title="Automation">
        ```bash theme={null}
        #!/usr/bin/env bash
        #
        # Check ingress and service frontends for use of HTTPS/TLS
        # Run on: any machine with kubectl access and context set to the target cluster

        set -euo pipefail

        echo "=== Cluster-wide TLS Frontend Report ==="
        echo "Context: $(kubectl config current-context)"
        echo

        ############################################
        # 1. Ingress resources (networking.k8s.io)
        ############################################
        echo ">>> Ingress resources (expect tls: configured and HTTPS rules in most cases)"
        kubectl get ingress --all-namespaces -o json | jq -r '
          .items[] |
          {
            ns: .metadata.namespace,
            name: .metadata.name,
            class: (.spec.ingressClassName // "N/A"),
            tls_hosts: ([.spec.tls[].hosts[]] // []),
            rules: [.spec.rules[]? | {host, paths: [.http.paths[]? | {path, backend: .backend.service.name}]}]
          } |
          "NAMESPACE=\(.ns)\nNAME=\(.name)\nINGRESS_CLASS=\(.class)\nTLS_HOSTS=\(.tls_hosts|join(","))\nRULES=\(.rules)\n---"
        '
        echo

        ############################################
        # 2. Services of type LoadBalancer
        ############################################
        echo ">>> Services of type LoadBalancer (look for HTTPS ports and annotations)"
        kubectl get svc --all-namespaces -o json | jq -r '
          .items[] |
          select(.spec.type == "LoadBalancer") |
          {
            ns: .metadata.namespace,
            name: .metadata.name,
            lb_ip: (.status.loadBalancer.ingress[0].ip // .status.loadBalancer.ingress[0].hostname // "pending"),
            ports: [.spec.ports[] | {name, port, targetPort, protocol}],
            annotations: (.metadata.annotations // {})
          } |
          "NAMESPACE=\(.ns)\nNAME=\(.name)\nEXTERNAL=\(.lb_ip)\nPORTS=\(.ports)\nANNOTATIONS=\(.annotations)\n---"
        '
        echo

        ############################################
        # 3. IngressClasses (to infer controller / cloud LB type)
        ############################################
        echo ">>> IngressClasses (to understand which controller / LB is used)"
        kubectl get ingressclass -o wide || echo "No IngressClasses found"
        echo

        ############################################
        # 4. Optional: known TLS-related annotations per major cloud providers
        ############################################
        echo ">>> Quick summary: LoadBalancer Services missing common TLS/HTTPS hints"
        kubectl get svc --all-namespaces -o json | jq -r '
          .items[] |
          select(.spec.type == "LoadBalancer") |
          . as $svc |
          {
            ns: .metadata.namespace,
            name: .metadata.name,
            ports: [.spec.ports[] | {port, name}],
            annotations: (.metadata.annotations // {})
          } |
          . as $o |
          (
            # Heuristic: flag if any port is 80/http and no indication of HTTPS/SSL
            ([$o.ports[] | select((.port==80) or ((.name // "")|test("http";"i")))] | length) as $has_http
            |
            ([$o.ports[] | select((.port==443) or ((.name // "")|test("https|ssl|tls";"i")))] | length) as $has_https_port
            |
            ($o.annotations|tostring|test("tls|ssl|https";"i")) as $has_tls_ann
            |
            select($has_http == 1 and ($has_https_port == 0 and $has_tls_ann == false))
          ) |
          "POTENTIAL_ISSUE: NAMESPACE=\(.ns) NAME=\(.name) PORTS=\(.ports)"
        '
        echo
        echo "=== Interpretation ==="
        cat <<'EOF'
        This script does NOT confirm cloud LB TLS configuration; review is manual:

        Potential problems in the output:
        - Ingress:
          - Ingress objects with no 'tls' section and rules that should be exposed securely.
          - IngressClass/controller that maps to HTTP-only or non-TLS-terminated frontends.
        - LoadBalancer Services:
          - Services exposing port 80 / HTTP-only ports, with no corresponding 443/HTTPS port.
          - Services whose annotations do not indicate TLS/SSL configuration for the provider.
        Next steps:
        - For each flagged or suspicious resource, locate the corresponding load balancer
          in your cloud provider console/CLI and verify:
          - An HTTPS listener is configured.
          - A valid TLS certificate is attached.
          - HTTP (port 80) is either disabled or redirects to HTTPS.
        EOF
        ```
      </Accordion>
    </AccordionGroup>
  </Tab>
</Tabs>
