I am wanting to achieve the follow redirections and ensure that they all happen in one step:
I have a Kubernetes (1.15.5) cluster on Digital Ocean using stable/nginx-ingress
(installed via helm) and also using cert-manager
to handle SSLs.
In my Ingress config I have disabled ssl redirection as I want to handle this in the services themselves:
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
name: proxy
namespace: default
annotations:
kubernetes.io/tls-acme: "true"
kubernetes.io/ingress.class: "nginx"
certmanager.k8s.io/issuer: "letsencrypt-prod"
certmanager.k8s.io/acme-challenge-type: http01
nginx.ingress.kubernetes.io/ssl-redirect: "false"
spec:
tls:
- hosts:
- example.com
- www.example.com
secretName: tls-example-com
rules:
- host: example.com
http:
paths:
- backend:
serviceName: nginx-service
servicePort: 80
- host: www.example.com
http:
paths:
- backend:
serviceName: nginx-service
servicePort: 80
One of my services is a nginx server:
server {
server_name example.com;
return 301 https://wwww.$host$request_uri;
}
server {
server_name www.example.com;
if ($scheme != "https") {
return 301 https://$host$request_uri;
}
# app
location / {
root /usr/share/nginx/html;
index index.html index.htm;
}
}
However, $scheme
here, is always '"http"', which makes sense as my service only receives requests on port 80. But just as the original address (host information) is forwarded to my service, how can I find out what the original port was?
The nginx set up by the ingress controller acts as a reverse proxy and inserts X-Forwarded-* headers for the services behind it to read. Your service has to use those to get the correct client ip, port or scheme.
For nginx you can use $http_x_forwarded_proto
:
if ($http_x_forwarded_proto != "https") {
return 301 https://$host$request_uri;
}