【问题标题】:Exclude specific hosts from ssl redirect in Kubernetes Nginx Ingress从 Kubernetes Nginx Ingress 中的 ssl 重定向中排除特定主机
【发布时间】:2019-06-18 09:22:50
【问题描述】:

我在我的 kubernetes 集群上设置了一个 Nginx 入口控制器,默认情况下它会对其接收到的任何请求进行 https 重定向,因此 http://example.com 会自动转发到 https://example.com

我现在有一个主机,我需要通过 http 而不是 https 提供服务,基本上将其从 ssl 重定向中排除。我发现我可以禁用整个入口的 ssl 重定向,但不能禁用特定主机。

我的入口 yaml:

apiVersion: extensions/v1beta1
kind: Ingress
metadata:
   name: ingress
annotations:
    kubernetes.io/ingress.class: nginx
spec:
  tls:
  - hosts:
    - mysslsite.co.uk
secretName: tls-secret

rules:
 - host: my-ssl-site.co.uk
   http:
    paths:
    - path: /
      backend:
        serviceName: my-service
        servicePort: 80
 - host: my-non-ssl-site.co.uk
   http:
      paths:
      - path: /
        backend:
          serviceName: my-other-service
          servicePort: 80

我的配置图:

apiVersion: v1
kind: ConfigMap
metadata:
  labels:
    app: nginx-ingress
    chart: nginx-ingress-0.28.3
    component: controller
    heritage: Tiller
    release: nginx-ingress
  name: undercooked-moth-nginx-ingress-controller
  namespace: default
data:
  proxy-buffer-size: "512k"
  client-header-buffer-size: "512k"
  proxy-body-size: "100m"
  large-client-header-buffers: "4 512k"
  http2-max-field-size: "512k"
  http2-max-header-size: "512k"
  fastcgi_buffers: "16 16k" 
  fastcgi_buffer_size: "32k"

我尝试过的:

  1. 尝试通过设置注释nginx.ingress.kubernetes.io/ssl-redirect: "false"并添加以下配置sn-p来全面关闭ssl重定向并设置规则以重定向到需要ssl到https的站点:

    nginx.ingress.kubernetes.io/configuration-snippet: |
          if ($host = 'my-ssl-site.co.uk' ) {
            rewrite ^ https://my-ssl-site.co.uk$request_uri permanent;
          }
    

    这确实会删除 https 重定向,但会导致需要 ssl 的站点出现 too many redirects 错误。

  2. 尝试按照this answer 在 ConfigMap 中添加规则以关闭 ssl 重定向并在服务器配置 sn-p 中处理条件重定向,但这仍然导致 ssl 重定向。

    李>
  3. 尝试添加第二个入口控制器,以便一个可以启用 ssl 重定向,另一个可以将其关闭。我创建了控制器,但我认为我还需要创建第二个 nginx 入口并配置和标记将返回给每个应用程序的应用程序?当我只想从 ssl 重定向中排除集群上的一项服务时,这似乎有点过头了。

我有什么明显的遗漏吗?感觉好像添加一个简单的规则来从 ssl 重定向中排除一个主机应该不难。

【问题讨论】:

    标签: ssl nginx https kubernetes kubernetes-ingress


    【解决方案1】:

    您可以创建两个 Ingress 对象,一个用于同一命名空间中的每个站点。

    对 SSL 站点使用注释 nginx.ingress.kubernetes.io/ssl-redirect: "true"

    对非 SSL 站点使用注释 nginx.ingress.kubernetes.io/ssl-redirect: "false"

    apiVersion: extensions/v1beta1
    kind: Ingress
    metadata:
       name: cmac-ingress
       namespace: ns1
       annotations:
        kubernetes.io/ingress.class: nginx
        nginx.ingress.kubernetes.io/ssl-redirect: "true"
    spec:
      tls:
      - hosts:
        - my-ssl-site.co.uk
        secretName: testsecret-tls
      rules:
      - host: my-ssl-site.co.uk
        http:
          paths:
          - path: /
            backend: 
              serviceName: my-service
              servicePort: 80
    ---
    apiVersion: extensions/v1beta1
    kind: Ingress
    metadata:
       name: cmac-ingress1
       namespace: ns1
       annotations:
        kubernetes.io/ingress.class: nginx
        nginx.ingress.kubernetes.io/ssl-redirect: "false"
    spec:
      tls:
      - hosts:
        - my-site.co.uk
        secretName: testsecret-tls
      rules:
      - host: my-site.co.uk
        http:
          paths:
          - path: /
            backend: 
              serviceName: my-service
              servicePort: 80
    

    这是来自 ingress-controller nginx.conf 文件的结果:

        ## start server my-site.co.uk
        server {
                server_name my-site.co.uk ;
    
                listen 80;
    
                set $proxy_upstream_name "-";
    
                listen 443  ssl http2;
    
                # PEM sha: ffa288482443e529d72a0984724f79d5267a2a22
                ssl_certificate                         /etc/ingress-controller/ssl/default-fake-certificate.pem;
                ssl_certificate_key                     /etc/ingress-controller/ssl/default-fake-certificate.pem;
    
                location / {
    
                        <some lines skipped>
    
                        if ($scheme = https) {
                                more_set_headers                        "Strict-Transport-Security: max-age=15724800; includeSubDomains";
                        }
    
                        <some lines skipped>
    
                }
    
        }       
        ## end server my-site.co.uk
    
        ## start server my-ssl-site.co.uk
        server {
                server_name my-ssl-site.co.uk ;
    
                listen 80;
    
                set $proxy_upstream_name "-";
    
                listen 443  ssl http2;
    
                # PEM sha: ffa288482443e529d72a0984724f79d5267a2a22
                ssl_certificate                         /etc/ingress-controller/ssl/default-fake-certificate.pem;
                ssl_certificate_key                     /etc/ingress-controller/ssl/default-fake-certificate.pem;
    
                location / {
    
    
                        <some lines skipped>
    
                        if ($scheme = https) {
                                more_set_headers                        "Strict-Transport-Security: max-age=15724800; includeSubDomains";
                        }
    
                        # enforce ssl on server side
                        if ($redirect_to_https) {
    
                                return 308 https://$best_http_host$request_uri;
    
                        }
    
                        <some lines skipped>
    
                }
    
        }    
        ## end server my-ssl-site.co.uk
    

    您可以在 SSL 强制站点定义中找到其他重定向部分:

    # enforce ssl on server side
    if ($redirect_to_https) {
    
            return 308 https://$best_http_host$request_uri;
    
    }
    

    【讨论】:

    • 谢谢你,我需要为第二个入口创建一个单独的入口控制器吗?如果是这样,我该如何配置它以指向新的入口?我使用 nginx-ingress helm chart 创建了现有的入口控制器,它似乎没有可以传入的参数来指定要使用的现有入口资源
    • 您不需要额外的入口控制器。一个就够了。它从集群中读取所有命名空间中的所有入口对象,并将配置部分添加到它的 nginx.conf 文件中。如果需要,您可以安装其他不同类的入口控制器,例如 nginx 和 traefik 或 haproxy。他们每个人都只抓取特定类的入口对象:(kubernetes.io/ingress.class: nginx)如果你安装同一个类的额外控制器,它会从集群中读取相同的入口对象,所以我猜他们都会有相同的配置。
    • 太棒了,现在一切正常,感谢您的帮助
    猜你喜欢
    • 1970-01-01
    • 2021-11-28
    • 1970-01-01
    • 2019-09-28
    • 1970-01-01
    • 2022-10-26
    • 2018-09-26
    • 2022-06-21
    • 1970-01-01
    相关资源
    最近更新 更多