400 Bad Request when Exposing external HTTPS service

I’m trying to expose an external API using Kong in Kubernetes, but when I hit the endpoint with insomnia, I get a 400 Bad Request error message saying that a plain HTTP request has been sent to an HTTPS server. I checked that both the Service and Ingress resources are targeting port 443 and I also added the konghq.com/protocol annotation to the service, but I can’t find what I’m doing wrong.

Service:

apiVersion: v1
kind: Service
metadata:
  name: admin-api-service
  namespace: admin
  annotations:
    konghq.com/protocol: “https”
spec:
  ports:
    - protocol: TCP
      port: 443
  type: ExternalName
  externalName: <target-API-URL>

Ingress:

apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: admin-api-ingress
  namespace: admin
  annotations:
    konghq.com/strip-path: "true"
    konghq.com/protocols: "https"
    kubernetes.io/ingress.class: kong
    konghq.com/plugins: jwt-auth
spec:
  rules:
  - host: <secure-gateway-URL>
    http:
      paths:
      - path: /*
        pathType: ImplementationSpecific
        backend:
          service:
            name: admin-api-service
            port:
              number: 443

Insomnia request:

This looks correct. Do you see the service protocol set correctly when inspecting the admin API? If not, which controller version are you using, and do its log indicate any issue syncing configuration?

I’m sorry but I couldn’t understand what you mean by inspecting the admin API, how should I inspect it?

The admin API is an external service running outside of Kubernetes and what I want to do is proxy traffic through Kong, applying a JWT validation I already have in place

I’m using Kong KIC version 2.1 with Kong version 2.7. I checked the controller logs and the last messages says that the configuration was successfully synched to kong.

The Kong admin API. With the default configuration, you need to port-forward to it:

kubectl port-forward KONG_POD 8444:8444

and then:

curl -ks https://localhost:8444/routes

Oh, right. After running a JSON formatter to the route object:

{
         "paths":[
            "/*"
         ],
         "methods":null,
         "id":"9157a2fe-ba88-554b-a427-07adedea17ba",
         "destinations":null,
         "strip_path":true,
         "response_buffering":true,
         "https_redirect_status_code":426,
         "preserve_host":true,
         "protocols":[
            "https"
         ],
         "snis":null,
         "created_at":1643811464,
         "updated_at":1643811464,
         "tags":null,
         "request_buffering":true,
         "hosts":[
           #host_url
         ],
         "service":{
            "id":"fcebb42d-b7da-5236-afcc-235c926b1bfe"
         },
         "path_handling":"v0",
         "regex_priority":100,
         "sources":null,
         "headers":null,
         "name":"admin.admin-api-ingress.00"
      }

Also I forgot which half I actually wanted to check :person_facepalming:

curl -ks https://localhost:8444/services/fcebb42d-b7da-5236-afcc-235c926b1bfe

If that does show protocol: https, it’d indicate that there’s something (presumably the ELB) upstream terminating TLS and forwarding the request onward to the HTTPS-expecting application.

I got this result. Is there a config I missed or that I should add?

{
   "port":80,
   "tls_verify_depth":null,
   "id":"fcebb42d-b7da-5236-afcc-235c926b1bfe",
   "protocol":"http",
   "connect_timeout":60000,
   "read_timeout":60000,
   "enabled":true,
   "host":"admin-api-service.admin.443.svc",
   "created_at":1643829455,
   "updated_at":1643829455,
   "tags":null,
   "ca_certificates":null,
   "path":"/",
   "write_timeout":60000,
   "client_certificate":null,
   "retries":5,
   "tls_verify":null,
   "name":"admin.admin-api-service.pnum-443"
}

Looks like the quotes are tripping it up. YAML :person_shrugging:

With:

konghq.com/protocol: https

it’s set correctly.

I just tried that but didn’t work.

So, I’ve been trying another approach to solve my problem but I’m not sure if that would work in Kong DBless.

I have a couple of services running on AWS ECS and in my DNS I have SRV records pointing to them. I want to create an Ingress resource that will direct traffic to those services using the DNS SRV records, is that possible?

SRV answer is in the other thread: Direct traffic to AWS ECS services using SRV records

Lack of change is odd, is it still showing up as HTTP when you inspect the admin API, with no errors in the controller logs indicating that the sync failed?

Sorry, I had confused

kind: Service
konghq.com/protocol: https

with

kind: Ingress
konghq.com/protocols: https

after removing double quotes from both of them it worked. Thanks!