Skip to main content

Encrypt Traffic Https Load Balancers With Tls Certificates

More Info:

Encrypt traffic to HTTPS load balancers using TLS certificates.

Risk Level

Low

Address

Security

Compliance Standards

  • APRA CPS 234 (Australia)
  • AWS Startup Security Baseline
  • BSI C5 (Germany)
  • Brazil LGPD
  • CCPA / CPRA (California)
  • CIS Critical Security Controls v8
  • CIS EKS
  • CMMC 2.0
  • CSA Cloud Controls Matrix v4
  • DPDPA
  • Digital Operational Resilience Act (EU)
  • ISO/IEC 27017
  • ISO/IEC 27018
  • ISO/IEC 27701
  • KSA PDPL
  • MAS Technology Risk Management (Singapore)
  • MITRE ATT&CK (Cloud)
  • NIST SP 800-171
  • NYDFS 23 NYCRR 500
  • SWIFT Customer Security Controls Framework
  • Sarbanes-Oxley IT General Controls
  • Securities and Exchange Board of India (SEBI) - Cloud Security Adoption Framework
  • UK NCSC Cyber Assessment Framework

Triage and Remediation

Remediation

Manual Steps
  1. Inventory all external load balancers

    • On any machine with access to your cloud CLI, list load balancers fronting Kubernetes services / APIs:
      • AWS (ELB/NLB/ALB):
        aws elbv2 describe-load-balancers --output table
      • GCP (GCLB):
        gcloud compute forwarding-rules list
      • Azure (ALB):
        az network lb list -o table
    • Correlate these with Kubernetes Services of type LoadBalancer (run from any machine with kubectl configured):
      kubectl get svc -A -o wide
  2. Identify which listeners are using HTTPS/TLS vs plaintext

    • For each external load balancer identified, inspect its listeners:
      • AWS:
        aws elbv2 describe-listeners --load-balancer-arn <LB_ARN> --output table
        Check Protocol (must be HTTPS or TLS, not HTTP or TCP for HTTP apps).
      • GCP:
        gcloud compute target-https-proxies list
        gcloud compute ssl-certificates list
        Ensure public-facing rules use target-https-proxies, not target-http-proxies.
      • Azure:
        az network lb rule list --lb-name <LB_NAME> --resource-group <RG_NAME> -o table
        For Application Gateway/WAF:
        az network application-gateway http-listener list \
        --gateway-name <APPGW_NAME> \
        --resource-group <RG_NAME> -o table
        Verify listeners are Https.
  3. Verify TLS certificate presence and validity

    • For each HTTPS/TLS listener, confirm a certificate is configured and valid:
      • AWS:
        aws elbv2 describe-listeners --listener-arn <LISTENER_ARN> \
        --query "Listeners[].Certificates[]" --output table
        aws acm list-certificates --certificate-statuses ISSUED
      • GCP:
        gcloud compute target-https-proxies describe <PROXY_NAME> \
        --format="yaml(sslCertificates)"
        gcloud compute ssl-certificates list
      • Azure:
        az network application-gateway ssl-cert list \
        --gateway-name <APPGW_NAME> \
        --resource-group <RG_NAME> -o table
    • Check certificate CN/SAN matches the public hostname, is not expired, and is issued by a trusted CA.
  4. Reconfigure non-encrypted or misconfigured listeners to use HTTPS with TLS

    • For any public-facing endpoint using HTTP/plaintext, change it to HTTPS and attach a valid certificate using your provider’s documented steps (console, CLI, or IaC). Examples (adapt to your environment):
      • AWS – switch an ALB listener to HTTPS:
        aws elbv2 modify-listener \
        --listener-arn <LISTENER_ARN> \
        --protocol HTTPS \
        --port 443 \
        --certificates CertificateArn=<ACM_CERT_ARN> \
        --default-actions Type=forward,TargetGroupArn=<TARGET_GROUP_ARN>
      • GCP – create HTTPS proxy and bind certificate:
        gcloud compute target-https-proxies create <PROXY_NAME> \
        --ssl-certificates=<CERT_NAME> \
        --url-map=<URL_MAP_NAME>
      • Azure – configure HTTPS listener on Application Gateway:
        az network application-gateway http-listener create \
        --gateway-name <APPGW_NAME> \
        --resource-group <RG_NAME> \
        --name <LISTENER_NAME> \
        --frontend-ip <FRONTEND_IP_NAME> \
        --frontend-port 443 \
        --ssl-cert <SSL_CERT_NAME> \
        --protocol Https
  5. Enforce HTTPS-only access and redirect HTTP if needed

    • For endpoints that must remain reachable on HTTP for legacy reasons, configure an HTTP listener only to redirect to HTTPS (provider-specific redirect rules).
    • Ensure security groups / firewall rules only expose HTTPS ports (e.g., 443) externally where feasible:
      • AWS example:
        aws ec2 describe-security-groups --output table
        Review rules allowing 0.0.0.0/0 on ports 80/443 and restrict HTTP where possible.
  6. Verify remediation and document the decision

    • Re-run the earlier listing commands to confirm all public-facing load balancer listeners are HTTPS/TLS and have certificates attached.
    • Optionally, test from a client:
      curl -v https://<PUBLIC_HOSTNAME>/
      Confirm SSL connection using is shown and no certificate errors occur.
    • Record which endpoints are intentionally HTTP (if any), with risk justification and planned migration path to TLS.
Using kubectl

kubectl cannot configure TLS or HTTPS on cloud load balancers; this must be done in your cloud provider’s load balancer or ingress configuration (console, CLI, or IaC). Refer to the Manual Steps section for provider‑specific guidance on enabling TLS and attaching certificates to your HTTPS load balancers.

Automation
#!/usr/bin/env bash
#
# Audit HTTPS load balancers and TLS usage for an EKS cluster
# Requirements: kubectl, jq
#
# Run from: any machine with kubectl access and cluster context set

set -euo pipefail

echo "=== 1) List Services of type LoadBalancer and their ports ==="
kubectl get svc -A -o json | jq -r '
.items[]
| select(.spec.type=="LoadBalancer")
| {
ns: .metadata.namespace,
name: .metadata.name,
type: .spec.type,
ports: .spec.ports,
ingClass: .metadata.annotations."kubernetes.io/ingress.class",
scheme: .metadata.annotations."service.beta.kubernetes.io/aws-load-balancer-scheme",
lbType: .metadata.annotations."service.beta.kubernetes.io/aws-load-balancer-type"
}
' | jq -c '.'

cat <<'EOF'

Interpretation:
- Any Service of type LoadBalancer exposing TCP port 80 *without* a corresponding HTTPS/TLS termination
(such as port 443 or annotation-driven TLS) is a potential problem.
- For AWS NLBs, TLS is configured outside Kubernetes; this script only flags that plain TCP 80 is in use.

EOF

echo "=== 2) List Ingresses and TLS configuration ==="
kubectl get ingress -A -o json | jq -r '
.items[]
| {
ns: .metadata.namespace,
name: .metadata.name,
class: (
.spec.ingressClassName
// .metadata.annotations."kubernetes.io/ingress.class"
),
rules: (
.spec.rules
| map({host, paths: (.http.paths | map({path, backend}))})
),
tls: .spec.tls
}
' | jq -c '.'

cat <<'EOF'

Interpretation (Ingress):
- PROBLEM indicators:
* An Ingress with hosts under .spec.rules but .spec.tls is null or empty.
* An Ingress using HTTP (port 80) only, with no TLS section, while it fronts internet‑facing apps.
- OK indicators:
* .spec.tls is present with at least one host and a secretName (certificate reference).
* Provider‑specific annotations indicate managed TLS (e.g., ACM certificates), even if .spec.tls is empty.
You must confirm in the cloud console/IaC that certificates are attached and enforcing HTTPS.

EOF

echo "=== 3) Highlight likely-problem Ingresses (no TLS block) ==="
kubectl get ingress -A -o json | jq -r '
.items[]
| select(.spec.rules != null and (.spec.rules | length > 0))
| select((.spec.tls // []) | length == 0)
| {
ns: .metadata.namespace,
name: .metadata.name,
class: (
.spec.ingressClassName
// .metadata.annotations."kubernetes.io/ingress.class"
),
reason: "Ingress has rules but no .spec.tls block"
}
' | jq -c '.'

echo
echo "=== 4) Highlight Services of type LoadBalancer exposing port 80 ==="
kubectl get svc -A -o json | jq -r '
.items[]
| select(.spec.type=="LoadBalancer")
| select(
([.spec.ports[]?.port] | contains([80]))
)
| {
ns: .metadata.namespace,
name: .metadata.name,
ports: .spec.ports,
annotations: .metadata.annotations,
reason: "LoadBalancer Service exposes port 80; verify HTTPS/TLS termination at LB"
}
' | jq -c '.'

cat <<'EOF'

How to read section 4:
- Entries listed here *may* be problems:
* If they front internet‑facing applications and only expose HTTP (80) with no TLS termination
at the cloud load balancer, they violate the control.
* If a managed LB listener redirects 80 -> 443 or terminates TLS with a certificate,
this is acceptable, but must be verified in the cloud provider console/CLI/IaC.

Next steps (manual review):
- For each flagged Ingress or Service:
* Check the corresponding load balancer in the cloud provider:
- Ensure HTTPS listener(s) (e.g., port 443) exist with valid TLS certificates.
- Ensure HTTP listener (80) is either disabled or redirects to HTTPS.
- This script cannot verify certificates or LB listeners directly; use it to triage
Kubernetes‑side resources that require cloud‑side inspection.

EOF

Additional Reading: