从Kubernetes Nginx Ingress的SSL重定向中排除特定主机

时间:2019-01-24 15:27:38

标签: ssl nginx https kubernetes kubernetes-ingress

我在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"并添加以下配置片段来全面关闭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重定向并处理服务器配置代码段中的条件重定向,但这仍然会导致ssl重定向。

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

有什么明显的我想念的吗?似乎添加一个简单的规则从ssl-redirect中排除一个主机似乎并不难。

1 个答案:

答案 0 :(得分:2)

您可以创建两个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

这是来自入口控制器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;

}