GKE 400 Bad Request HTTP request was sent to HTTPS

I’m having issues configuring Kong API to be secure. I followed all the documentation and deployed the helm chart. The curl -vvv output I’m getting is below.

*   Trying <IP Address>:443...
* Connected to <url> (<IP Address>) port 443 (#0)
* ALPN, offering h2
* ALPN, offering http/1.1
* successfully set certificate verify locations:
*  CAfile: /etc/ssl/cert.pem
*  CApath: none
* (304) (OUT), TLS handshake, Client hello (1):
* (304) (IN), TLS handshake, Server hello (2):
* (304) (IN), TLS handshake, Unknown (8):
* (304) (IN), TLS handshake, Certificate (11):
* (304) (IN), TLS handshake, CERT verify (15):
* (304) (IN), TLS handshake, Finished (20):
* (304) (OUT), TLS handshake, Finished (20):
* SSL connection using TLSv1.3 / AEAD-CHACHA20-POLY1305-SHA256
* ALPN, server accepted to use h2
* Server certificate:
*  subject: CN=*
*  start date: Mar 22 13:10:09 2022 GMT
*  expire date: Mar 19 18:05:35 2023 GMT
*  subjectAltName: host "<host>" matched cert's "*
*  issuer: <>
*  SSL certificate verify ok.
* Using HTTP2, server supports multiplexing
* Connection state changed (HTTP/2 confirmed)
* Copying HTTP/2 data in stream buffer to connection buffer after upgrade: len=0
* Using Stream ID: 1 (easy handle 0x125011000)
> GET / HTTP/2
> Host: <host>
> user-agent: curl/7.79.1
> accept: */*
> 
* Connection state changed (MAX_CONCURRENT_STREAMS == 128)!
< HTTP/2 400 
< content-type: text/html; charset=UTF-8
< content-length: 220
< date: Thu, 11 Aug 2022 01:03:32 GMT
< x-kong-upstream-latency: 0
< x-kong-proxy-latency: 1
< via: kong/2.8.1.3-enterprise-edition
< 
<html>
<head><title>400 The plain HTTP request was sent to HTTPS port</title></head>
<body>
<center><h1>400 Bad Request</h1></center>
<center>The plain HTTP request was sent to HTTPS port</center>
</body>
</html>
* Connection #0 to host <host> left intact

It seems like whatever annotation I input to redirect http I’m still getting the bad request.

What exactly is the expected behavior?

Since you didnt provide much details as to what you configured or what curl command you ran, there is a lot of guessing…

From what I understand you do curl ip:443 and you get 400 (client error - error in your request) with error The plain HTTP request was sent to HTTPS port.

By default curl uses http protocol so if you omitted protocol from curl - my guess this is what causing your problem. Next thing you want to do is to add redirect to https from http by adding following annotations: konghq.com/https-redirect-status-code: "301" and konghq.com/protocol: "https"

So the expected behavior is to be able to access kong-admin and kong-manager using tls the same way I have accessed it using http.

kong-admin http

kong-manager http

I added the annotations that you specified and it’s still giving me the same 400 Bad Request
image

My yaml configs are below

deployment:
  kong:
    enabled: true
  serviceAccount:
    create: true
    automountServiceAccountToken: false
  test:
    enabled: false
  daemonset: false
  hostNetwork: false
  prefixDir:
    sizeLimit: 256Mi
  tmpDir:
    sizeLimit: 1Gi

env:
  database: "postgres"
  pg_user: kong
  pg_password: kong
  pg_database: kong
  pg_hostname: postgresql
  nginx_worker_processes: "2"
  proxy_access_log: /dev/stdout
  admin_access_log: /dev/stdout
  admin_gui_access_log: /dev/stdout
  portal_api_access_log: /dev/stdout
  proxy_error_log: /dev/stderr
  admin_error_log: /dev/stderr
  admin_gui_error_log: /dev/stderr
  portal_api_error_log: /dev/stderr
  prefix: /kong_prefix/
  admin_api_uri: "https://admin.example.com"
  admin_gui_url: "https://manager.example.com"
  trusted_ips: "0.0.0.0/0,::/0"

# Specify Kong's Docker image and repository details here
image:
  #repository: kong
  tag: "2.8"
  # Kong Enterprise
  repository: kong/kong-gateway
  # tag: "2.8"

  pullPolicy: IfNotPresent
 
# Specify Kong admin API service and listener configuration
admin:
  enabled: true
  type: NodePort
  annotations: {
    #konghq.com/protocols: https
  }
  labels: {}

  http:
    enabled: false
    servicePort: 8001
    containerPort: 8001
    parameters: []

  tls:
    # Enable HTTPS listen for the admin API
    enabled: true
    servicePort: 8444
    containerPort: 8444
    parameters:
    - http2

  # Kong admin ingress settings. Useful if you want to expose the Admin
  # API of Kong outside the k8s cluster.
  ingress:
    # Enable/disable exposure using ingress.
    enabled: true
    ingressClassName: kong
    # TLS secret name.
    tls: tls-secret
    # Ingress hostname
    hostname: admin.example.com
    # Map of ingress annotations.
    annotations: {
      konghq.com/protocols: https,
      konghq.com/https-redirect-status-code: "302"
      #konghq.com/preserve-host: false,
      #kubernetes.io/ingress.allow-http: false
    }
    # Ingress path.
    path: /
    # Each path in an Ingress is required to have a corresponding path type. (ImplementationSpecific/Exact/Prefix)
    pathType: ImplementationSpecific

# Specify Kong status listener configuration
# This listen is internal-only. It cannot be exposed through a service or ingress.
status:
  enabled: true
  http:
    # Enable plaintext HTTP listen for the status listen
    enabled: true
    containerPort: 8100
    parameters: []

# Specify Kong proxy service configuration
proxy:
  # Enable creating a Kubernetes service for the proxy
  enabled: true
  type: LoadBalancer
  # To specify annotations or labels for the proxy service, add them to the respective
  # "annotations" or "labels" dictionaries below.
  annotations: {
    konghq.com/protocols: "https"
  }
  labels:
    enable-metrics: "true"

  tls:
    # Enable HTTPS listen for the proxy
    enabled: true
    servicePort: 443
    containerPort: 8443
    parameters:
    - http2


ingressController:
  enabled: true
  installCRDs: false
  image:
    repository: kong/kubernetes-ingress-controller
    tag: "2.5"
    effectiveSemver:
  args: []
  watchNamespaces: []
  env:
    kong_admin_tls_skip_verify: true

  ingressClass: kong
  ingressClassAnnotations: {}
  rbac:
    # Specifies whether RBAC resources should be created
    create: true

postgresql:
  enabled: true
  auth:
    username: kong
    database: kong
    password: kong
    postgresPassword: postgres
  image:
    # use postgres < 14 until is https://github.com/Kong/kong/issues/8533 resolved and released
    # enterprise (kong-gateway) supports postgres 14
    tag: 13.6.0-debian-10-r52
  service:
    ports:
      postgresql: "5432"
resources: {}

# Annotation to be added to Kong pods
podAnnotations:
  kuma.io/gateway: enabled
  traffic.sidecar.istio.io/includeInboundPorts: ""
  prometheus.io/scrape: true
  prometheus.io/port: 8100

serviceMonitor:
   enabled: true
 
enterprise:
  enabled: true
  vitals:
    enabled: false
  portal:
    enabled: false
  rbac:
    enabled: true
    admin_gui_auth: basic-auth
    session_conf_secret: kong-session-config
    admin_gui_auth_conf_secret: CHANGEME-admin-gui-auth-conf-secret


manager:
  # Enable creating a Kubernetes service for Kong Manager
  enabled: true
  type: NodePort
  # To specify annotations or labels for the Manager service, add them to the respective
  # "annotations" or "labels" dictionaries below.
  annotations: {
    konghq.com/protocols: "https"
  }

  labels: {}

  tls:
    # Enable HTTPS listen for Kong Manager
    enabled: true
    servicePort: 8445
    containerPort: 8445
    parameters:
    - http2

  ingress:
    # Enable/disable exposure using ingress.
    enabled: true
    ingressClassName: kong
    # TLS secret name.
    tls: tls-secret
    # Ingress hostname
    hostname: manager.example.com
    # Map of ingress annotations.
    annotations: {
      konghq.com/protocols: "https",
      konghq.com/https-redirect-status-code: "301"
      #konghq.com/preserve-host: false
      #kubernetes.io/ingress.allow-http: false
    }
    # Ingress path.
    path: /
    # Each path in an Ingress is required to have a corresponding path type. (ImplementationSpecific/Exact/Prefix)
    pathType: ImplementationSpecific