nginx k8s ingress - forcing www AND https?

安稳与你 提交于 2021-01-26 03:46:25

问题


I have a kubernetes setup that looks like this:

nginx ingress -> load balancer -> nginx app

after getting an SSL certificate for www.foo.com, I've installed it in my nginx ingress as a secret, and it works as expected - traffic to www.foo.com gets redirected to the https version instead, and browsers display a secure connection indicator. Great.

What hasn't been easy, however, is getting the ingress to redirect non-www traffic to the www version of the site. I've tried using kubernetes.io/from-to-www-redirect: "true", but it doesn't seem to do anything - navigating to foo.com doesn't redirect me to the www version of the url, but either takes me to an insecure version of my site, or navigates me to default backend - 404 depending on whether i include foo.com as a host with it's own path in my ingress.

I have been able to set up a patchy redirect by adding the following to my actual application's nginx config -

server {
  listen       80;
  server_name  foo.com;
  return       301 http://www.foo.com$request_uri;
}

UPDATE: from-to-www-redirect DOES work; you just have to reference it with nginx.ingress.kubernetes.io rather than kubernetes.io as I was. But, this only works for foo.com - typing in https://foo.com explicitly causes browsers to display a security warning and no redirect to the proper URL of https://www.foo.com occurs.

Here's my current config for the nginx ingress itself:

apiVersion: extensions/v1beta1
kind: Ingress
metadata:
  name: foo-https-ingress
  annotations:
    kubernetes.io/ingress.class: "nginx"
    nginx.ingress.kubernetes.io/from-to-www-redirect: "true"
spec:
  rules:
    - host: www.foo.com
      http:
        paths:
          - backend:
              serviceName: foo-prod-front
              servicePort: 80
            path: /
  tls:
      - hosts:
          - www.foo.com
        secretName: tls-secret

回答1:


You need to add the certificate for the domain you want to be redirected:

apiVersion: extensions/v1beta1
kind: Ingress
metadata:
  name: foo-https-ingress
  annotations:
    kubernetes.io/ingress.class: "nginx"
    nginx.ingress.kubernetes.io/from-to-www-redirect: "true"
spec:
  rules:
    - host: foo.com
      http:
        paths:
          - backend:
              serviceName: foo-prod-front
              servicePort: 80
            path: /
    - host: www.foo.com
      http:
        paths:
          - backend:
              serviceName: foo-prod-front
              servicePort: 80
            path: /
  tls:
      - hosts:
          - foo.com
          - www.foo.com
        secretName: tls-secret

I am not completely sure, whether from-to-www-redirect works with this setup, but you can replace it with the following lines, which do work:

    nginx.ingress.kubernetes.io/configuration-snippet: |
      if ($host = 'foo.com' ) {
        rewrite ^ https://www.foo.com$request_uri permanent;
      }



回答2:


I found the docs to be confusing here as well. Below is an example i have working. I believe you need to define the naked url in tls certs to avoid a cert error(your cert needs to be valid for both foo.com and www.foo.com). You CANNOT list the naked url under rules: hosts because that will get picked up prior to the redirect.

http://foo.com -> https://www.foo.com

https://foo.com -> https://www.foo.com

http://www.foo.com -> https://www.foo.com

apiVersion: extensions/v1beta1
kind: Ingress
metadata:
  name: foo-https-ingress
  annotations:
    kubernetes.io/ingress.class: "nginx"
    nginx.ingress.kubernetes.io/from-to-www-redirect: "true"
spec:
  rules:
    - host: www.foo.com
      http:
        paths:
          - backend:
              serviceName: foo-frontend
              servicePort: 80
            path: /
  tls:
      - hosts:
          - foo.com
          - www.foo.com
        secretName: tls-secret



回答3:


I have the following doing the job with the latest nginx-ingress 0.25.1:

apiVersion: extensions/v1beta1
kind: Ingress
metadata:
  name: ingress-rule-web
  annotations:
    kubernetes.io/ingress.class: nginx
    certmanager.k8s.io/cluster-issuer: letsencrypt-prod
    nginx.ingress.kubernetes.io/from-to-www-redirect: 'true'
spec:
  rules:
    - host: foo.org
      http:
        paths:
          - path: /
            backend:
              serviceName: web
              servicePort: 80
  tls:
    - hosts:
        - foo.org
        - www.foo.org
      secretName: letsencrypt-prod



回答4:


This is rather a problem with your ssl certificate than the nginx ingress configuration. My guess is that your certificate is only valid for foo.com and not for www.foo.com. If you access www.foo.com your browser shows a security warning because the certificate isn't valid for the domain you are visiting.



来源:https://stackoverflow.com/questions/48655450/nginx-k8s-ingress-forcing-www-and-https

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!