nginx k8s ingress - 强制www和https?

时间:2018-02-07 03:20:19

标签: nginx kubernetes

我有一个kubernetes设置,如下所示:

nginx ingress - >负载均衡器 - > nginx app

获得 www .foo.com的SSL证书后,我已将其作为机密安装在我的nginx入口中,并且按预期工作 - 到www.foo.com的流量被重定向改为https版本,浏览器显示安全连接指示符。大。

没有很简单,但是,要获得入口将非www 流量重定向到网站的www版本。 我尝试使用kubernetes.io/from-to-www-redirect: "true",但它似乎没有做任何事情 - 导航到foo.com并不会将我重定向到网址的 www 版本,但要么将我带到我网站的不安全版本,要么导航我到default backend - 404,具体取决于我是否将foo.com作为主机包含在我的入口中的自己的路径。

我已经能够通过将以下内容添加到我的实际应用程序的nginx配置中来设置补丁重定向 -

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

更新: from-to-www-redirect正在运作;您只需要使用nginx.ingress.kubernetes.io而不是kubernetes.io来引用它。但是,这仅适用于foo.com - 在https://foo.com中输入明确会导致浏览器显示安全警告,并且不会重定向到https://www.foo.com的正确网址。

这是我目前对nginx入口本身的配置:

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

5 个答案:

答案 0 :(得分:2)

我发现这里的文档也令人困惑。以下是我正在工作的示例。我认为您需要在tls证书中定义裸露的网址,以避免出现证书错误(您的证书对于foo.com和www.foo.com都必须有效)。您无法根据以下规则列出裸机网址:主机,因为它将在重定向之前被拾取。

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

答案 1 :(得分:1)

您需要为要重定向的域添加证书:

from-to-www-redirect

我不确定 nginx.ingress.kubernetes.io/configuration-snippet: | if ($host = 'foo.com' ) { rewrite ^ https://www.foo.com$request_uri permanent; } 是否适用于此设置,但是您可以将其替换为有效的以下行:

$res = array();
foreach($stud_averages as $student => $av)
{
    $data=array('student_matricule'=>"$student",'average'=>"$av");
    array_push($res, $data);
}
print json_encode($res);

答案 2 :(得分:1)

以下是我使用最新的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

答案 3 :(得分:0)

这是ssl证书的问题,而不是nginx入口配置。我的猜测是,您的证书仅对foo.com有效,而对www.foo.com无效。如果您访问www.foo.com,则您的浏览器会显示安全警告,因为该证书对您正在访问的域无效。

答案 4 :(得分:0)

我必须先解决一个问题:

对我有用的解决方案是来自@demisx 的解决方案,但在我第一次尝试时,该解决方案由于其他原因而不起作用。我有多个参考“示例”的入口。 com”根主机,如 documentation 中所述,这省略了我的 www 重定向规则。

文档指出“如果在某个时候创建​​了一个新的 Ingress,其主机等于其中一个选项(如 domain.com),则注释将被省略。”

这是错误的例子:

Ingress 1 - 处理 example.com

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

Ingress 2 - 处理 example.com/news

apiVersion: extensions/v1beta1
kind: Ingress
metadata:
  name: example-https-ingress-news
spec:
  rules:
    - host: example.com. # <--------- I HAD ANOTHER REFERENCE
      http:
        paths:
          - backend:
              serviceName: example-news
              servicePort: 80
            path: /news
     - host: www.example.com
       http:
         paths:
           - backend:
              serviceName: example-news
              servicePort: 80
            path: /news
  tls:
      - hosts:
          - example.com
          - www.example.com
        secretName: tls-secret

解决方案 - 正确配置

确保您没有使用根域创建任何其他入口,否则重定向将无法作为文档所指的那样工作。我在入口 2 上删除了对 example.com 主机的引用,然后立即开始工作。

Ingress 1 - 处理 example.com

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

Ingress 2 - 处理 example.com/news

apiVersion: extensions/v1beta1
kind: Ingress
metadata:
  name: example-https-ingress-news
spec:
  rules:
     # <--------- removed the other reference to the root host 
     - host: www.example.com
       http:
         paths:
           - backend:
              serviceName: example-news
              servicePort: 80
            path: /news
  tls:
      - hosts:
          - example.com
          - www.example.com
        secretName: tls-secret

注意:顺便说一句,我不需要向第二个入口添加前向注释,因为第一个入口已经处理了。不过,我不确定,如果部署顺序对 nginx 入口控制器很重要,请仅将其作为注释并尝试确认自己。