Reputation: 33
I have a django application running in Google cloud run (in a Kube cluster), via Docker served by uwsgi (but I've tried manage.py runserver and it's the same). By default cloud run accepts connections on both http and https.
I would like to redirect the user to the https version but cloud run does not seen to be setting the headers correctly.
I have a handler that returns the headers via: json.dumps(request.headers.__dict__['_store'])
And the relevant headers returned are:
"x-forwarded-proto": ["X-Forwarded-Proto", "http"]
But the value http never changes even when I visit the https version of the site.
How should django correctly detect http requests on cloud run? I am unable to use
SECURE_PROXY_SSL_HEADER
to detect and redirect http requests to https as they all appear to be http requests, so you end up in a redirect loop.
However if I follow the links in this post: https://www.jhanley.com/google-cloud-run-https-part-2/
to their "show me the headers" link the value does indeed change from http to https. Is it a django thing? Or a "cloud run on kube" thing?
Hosting the app in question on pure cloud run and visiting the http version does an internal redirect to the HTTPS version and gives the reason: Non-Authoritative-Reason: HSTS
Which is exactly what I'm trying to achieve. It seems the headers I am getting are from the internal routing, not the original request itself when running in Anthos mode.
Upvotes: 3
Views: 588
Reputation: 182
The issue is known and I have reported it a couple of months ago. You can track it here on Google Cloud Run for Anthos issue tracker.
A workaround I found for this issue is to do the redirection on your frontend with JavaScript by checking if the value of window.location.protocol
is http
and rewriting the location as such:
window.location = "https://" + window.location.hostname + window.location.pathname + window.location.search;
Upvotes: 1
Reputation: 45214
The article you linked seems to be about "Cloud Run (fully managed)" but you aren't using that. Cloud Run for Anthos (Knative) has a fairly different stack for handling the requests and HTTPS termination. So please ignore that.
Here's how to create a domain with a TLS certificate managed by Knative (issued from Let's Encrypt) and do a HTTP→ HTTPS redirect.
This procedure is explained in official Cloud Run documentation: https://cloud.google.com/run/docs/gke/managed-tls
Ensure your cluster is 1.17.7-gke.15 and newer versions. With these versions "managed certificates" feature is enabled by default.
Create a domain mapping for your service. (You can do this on Cloud Console)
Point your domain’s DNS records to the IP address given to you (the gateway IP service that can be found in gke-system
Kubernetes namespace)
A TLS certificate will be automatically provisioned for your domain in the background (and will be renewed every 80 days or so)
To set up HTTP→HTTPS redirect, follow these instructions which requires you to run:
kubectl annotate domainmappings [YOUR_DOMAIN] domains.cloudrun.com/httpsRedirect=Enabled
which is basically adding an annotation to the DomainMapping object in Kubernetes.
This configures the ingress gateway in your cluster to do the redirect for you. You don't need to read the x-forwarded-proto
header and take action.
Upvotes: 1