<p>I am wanting to achieve the follow redirections and ensure that they all happen in one step:</p>

<ul>
<li><a href="http://example.com" rel="nofollow noreferrer">http://example.com</a> -> <a href="https://www.example.com" rel="nofollow noreferrer">https://www.example.com</a></li>
<li><a href="https://example.com" rel="nofollow noreferrer">https://example.com</a> -> <a href="https://www.example.com" rel="nofollow noreferrer">https://www.example.com</a></li>
<li><a href="http://www.example.com" rel="nofollow noreferrer">http://www.example.com</a> -> <a href="https://www.example.com" rel="nofollow noreferrer">https://www.example.com</a></li>
</ul>

<p>I have a Kubernetes (1.15.5) cluster on Digital Ocean using <code>stable/nginx-ingress</code> (installed via helm) and also using <code>cert-manager</code> to handle SSLs.</p>

<p>In my Ingress config I have disabled ssl redirection as I want to handle this in the services themselves:</p>

<pre><code>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
</code></pre>

<p>One of my services is a nginx server:</p>

<pre><code>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;
    }
}
</code></pre>

<p>However, <code>$scheme</code> 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?</p>

Thomas Nadin
<p>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.</p>

<p>For nginx you can use <code>$http_x_forwarded_proto</code>:</p>

<pre><code>  if ($http_x_forwarded_proto != "https") {
    return 301 https://$host$request_uri;
  }
</code></pre>
