Force_https not working with GCP Ingress

I’ve got a kubernetes instance on GCP. Everything seems fine, but somehow force_https isn’t forcing a redirect and the sill can be retrieved on http://.

My solution for now has been to add this stanza to app.yml.

    - replace:
        filename: /etc/nginx/conf.d/discourse.conf
        from: '    add_header ETag "";'
        to: |
                  add_header ETag "";
                  if ($thescheme = "http") {
                    return 301 https://$host$request_uri;
                  }

(And I’d love to understand how to get pups to indent those lines I inserted, but I digress.)

Sometime after that change the ingres controller appears to have stopped serving the site, though it seemed to have been working–and properly redirecting–for at least a while.

Obviously this is #unsupported-install, but if anyone has an idea where to look next, I’d appreciate it.

Are you using a HTTP loadbalancer or a TCP loadbalancer? If HTTP, the protocol seen on ingress may be stuffed in a nonstandard header that Discourse isn’t looking for.

1 Like

Looks like the fully-managed setup looks like this:

$ gcloud compute addresses create discourse-ip-address --global
#                                 ^~~~~~~~~~~~~~~~~~~~ custom name
# WARNING: reserving an IP address but not using it incurs a 0.010USD/hr penalty charge
---
apiVersion: networking.gke.io/v1beta1
kind: ManagedCertificate
metadata:
  name: discourse-cert
spec:
  domains:
    - discourse.example.com  # customize
---
apiVersion: extensions/v1beta1
# if v1.14 or later:
# apiVersion: networking.k8s.io/v1beta1
kind: Ingress
metadata:
  name: discourse-web-ingress
  annotations:
    networking.gke.io/managed-certificates: discourse-cert
    kubernetes.io/ingress.global-static-ip-name: discourse-ip-address
spec:
  backend:
    serviceName: discourse-web  # verify this is correct
    servicePort: 80

sources:
https://cloud.google.com/kubernetes-engine/docs/concepts/ingress#setting_up_https_tls_between_client_and_load_balancer
https://cloud.google.com/kubernetes-engine/docs/how-to/managed-certs

3 Likes

Thanks very much, @riking! Yes, it’s the load balancer that seems to be my issue. I think ingress is OK (and now I have some idea that there is a difference). I switched to the setup that you show and am getting the same results as I was with a somewhat more complicated configuration. I guess one next step would be to figure out tcpdump and see what’s in those headers. . .

EDIT: It looks like it should work. Here’s what I see:

GET /thisisatest HTTP/1.1
User-Agent: Wget/1.19.4 (linux-gnu)
Accept: */*
Accept-Encoding: identity
Host: community.example.com
X-Cloud-Trace-Context: 72c9f7219e6b541cad01153c52fb92c5/13509441707361831434
Via: 1.1 google
X-Forwarded-For: MY-IP-ADDRESS, INGRESS-IP
X-Forwarded-Proto: http
Connection: Keep-Alive

I have a set_real_ip_from with the ingress IP (and IP numbers are getting logged properly).

1 Like

@pfaffman I could help with that - I’m on GCP and have solved this issue before. I’m tied up for a few hours though but if you can send me your load balancer setup (along with the health check stuff) here or privately, I can try and find the issue.

PS: TCP and HTTP will both work

1 Like

Thanks a zillion, @p16!

Well, here’s the health check. I changed the path to /srv/status but I still see “GoogleHC/1.0” hitting /.

1 Like

Thanks, is the backend showing up as healthy in the load balancer? Please also add www.yoursite.com to the host (under more).

Also, here is what I add to my app.yml:

  after_web_config:
    - replace:
       filename: "/etc/nginx/conf.d/discourse.conf"
       from: /server.+{/
       to: |
         server {
           if ($http_x_forwarded_proto = 'http'){
            return 301 https://$host$request_uri;
           }

It won’t be necessary for too long as Google will be adding an http to https redirector this quarter.

2 Likes

Yes. It seems to be working now! I guess I’m confused about the magic port 30182, but I suppose that’s some kind of k8s magic that I’ll understand another day.
I’ll give your after_web_config: stanza a go. It seems a bit cleaner than what I was doing.

Thanks very much.

2 Likes