I have an Angular App, running in a nginx docker container, that is running in Google Kubernetes and behind a Google Kubernetes Ingress with a Google Managed Certificate. I cannot seem to get the Ingress to automatically redirect to HTTPS if the request comes in on HTTP / port 80.
Apparently the Google Ingress "can't do it" so I've been trying to get the nginx instance to do it for me. But I think in that case I'd need actual certificate which I also can't figure out how to get out of Google.
But...there has to be a simple way to do this. HTTPS works fine on the site, I just can't get it to redirect away from HTTP to HTTPS...
This is my Ingress YAML:
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
name: ui-ingress
annotations:
kubernetes.io/ingress.global-static-ip-name: my-ip
networking.gke.io/managed-certificates: my-certificate
spec:
rules:
- host: example.com
http:
paths:
- backend:
serviceName: web-ui
servicePort: 80
And my nginx.conf with a commented-out redirect that didn't work:
worker_processes 1;
events {
worker_connections 1024;
}
http {
server {
listen 80 default_server;
server_name example.com;
root /usr/share/nginx/html;
index index.html index.htm;
include /etc/nginx/mime.types;
gzip on;
gzip_min_length 1000;
gzip_proxied expired no-cache no-store private auth;
gzip_types text/plain text/css application/json application/javascript application/x-javascript text/xml application/xml application/xml+rss text/javascript;
location / {
try_files $uri $uri/ /index.html;
}
#if ($scheme = http) {
# return 301 https://$server_name$request_uri;
#}
}
}
I also tried this longer nginx.conf that resulted in a 502 error from Google / Ingress:
worker_processes 1;
events {
worker_connections 1024;
}
http {
server {
listen 80;
server_name example.com;
return 301 https://example.com$request_uri;
}
server {
listen 443 ssl http2;
server_name example.com;
return 301 $scheme://example.com$request_uri;
}
server {
listen 443 ssl http2 default_server;
listen [::]:443 ssl http2 default_server;
server_name example.com;
root /usr/share/nginx/html;
index index.html index.htm;
include /etc/nginx/mime.types;
gzip on;
gzip_min_length 1000;
gzip_proxied expired no-cache no-store private auth;
gzip_types text/plain text/css application/json application/javascript application/x-javascript text/xml application/xml application/xml+rss text/javascript;
location / {
try_files $uri $uri/ /index.html;
}
}
}
The error from the pod is looking for the certificate to be installed but I don't know how to get the certificate out of Google Managed Certs to copy to the nginx image:
"textPayload": "2019/05/08 21:02:13 [emerg] 1#1: no \"ssl_certificate\" is defined for the \"listen ... ssl\" directive in /etc/nginx/nginx.conf:27\n"
I was reading about setting up other load balancers and stumbled across the answer I was looking for. Instead of redirecting based on the $scheme in nginx you have to instead redirect on $http_x_forwarded_proto
. This prevents the Google Health checks from failing because they do not pass the http_x_forwarded_proto header so it will never hit that redirect when it's a health check.
if ($http_x_forwarded_proto = "http") {
return 301 https://$host$request_uri;
}
You’re right, for now, Google Cloud HTTPS Load Balancer doesn't allow http-->https redirects.
I don't know how to get the certificate out of Google Managed Certs to copy to the nginx image.
You can't. Google manages the certificates and renews them for you. Therefore you will not have access to your TLS key.
And since a Google Cloud HTTPS LB can listen on either HTTPS or HTTP, you can't redirect from HTTP to HTTPS.
My recommendation to get this done the quickest way would be:
nginx-ingress
controller to your GKE cluster and just put the https redirect annotation it offers on your Ingress object.Secret
from your nginx Ingress ’s tls:
field, which the nginx-ingress controller will configure on its nginx.conf.