Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

希望higress-https中的全局https证书配置可以用于ingress中secret不存在时的兜底 #978

Closed
1 task done
zzjin opened this issue May 20, 2024 · 21 comments · Fixed by #1020
Closed
1 task done
Assignees

Comments

@zzjin
Copy link

zzjin commented May 20, 2024

  • I have searched the issues of this repository and believe that this is not a duplicate.

Ⅰ. Issue Description

When update to 1.4.0-rc1, and setting #854 (without auto cert, just self-signed cert), users cannot access https ingress.

Ⅱ. Describe what happened

Users can only access one https route.

Ⅲ. Describe what you expected to happen

All ingress route over https can access normally.

Ⅳ. How to reproduce it (as minimally and precisely as possible)

Apply higress version 1.4.0-rc1, apply CRs below:

apiVersion: v1
data:
  cert: |
    automaticHttps: true
    renewBeforeDays: 1
    credentialConfig:
    - domains:  
        - "*.34.84.109.10.nip.io"
        - "34.84.109.10.nip.io"
      tlsSecret: wildcard-cert
kind: ConfigMap
metadata:
  name: higress-https
  namespace: higress-system
apiVersion: v1
data:
  ca.crt: aaa(replace with any valid cert)
  tls.crt: bbb
  tls.key: ccc
kind: Secret
metadata:
  annotations:
    cert-manager.io/alt-names: 34.84.109.10.nip.io,*.34.84.109.10.nip.io
    cert-manager.io/certificate-name: sealos-cloud
    cert-manager.io/common-name: 34.84.109.10.nip.io
    cert-manager.io/ip-sans: ""
    cert-manager.io/issuer-group: ""
    cert-manager.io/issuer-kind: ClusterIssuer
    cert-manager.io/issuer-name: selfsigned-issuer
    cert-manager.io/uri-sans: ""
  name: wildcard-cert
  namespace: higress-system
type: kubernetes.io/tls
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  annotations:
    kubernetes.io/ingress.class: nginx
  name: sealos-desktop
  namespace: sealos
spec:
  rules:
    - host: 34.84.109.10.nip.io
      http:
        paths:
          - backend:
              service:
                name: desktop-frontend
                port:
                  number: 3000
            path: /
            pathType: Prefix
  tls:
    - hosts:
        - 34.84.109.10.nip.io
      secretName: wildcard-cert
---
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  annotations:
    kubernetes.io/ingress.class: nginx
  name: applaunchpad-frontend
  namespace: applaunchpad-frontend
spec:
  rules:
    - host: applaunchpad.34.84.109.10.nip.io
      http:
        paths:
          - backend:
              service:
                name: applaunchpad-frontend
                port:
                  number: 3000
            path: /
            pathType: Prefix
  tls:
    - hosts:
        - applaunchpad.34.84.109.10.nip.io
      secretName: wildcard-cert

There are 3 ns and one secret higress-system/wildcard-cert exists, no other secrets exists.

Ⅴ. Anything else we need to know?

Ⅵ. Environment:

  • Higress version: 1.4.0-rc1
  • OS : kubernetes 1.25.6
  • Others:
@johnlanni
Copy link
Collaborator

cc @2456868764

@johnlanni johnlanni added the type/bug Something isn't working label May 20, 2024
@johnlanni johnlanni changed the title Cannot serve https route on 1.4.0-rc1 Configuration for higress-https is not taking effect. May 20, 2024
@2456868764
Copy link
Collaborator

2456868764 commented May 20, 2024

  • I have searched the issues of this repository and believe that this is not a duplicate.

Ⅰ. Issue Description

When update to 1.4.0-rc1, and setting #854 (without auto cert, just self-signed cert), users cannot access https ingress.

Ⅱ. Describe what happened

Users can only access one https route.

Ⅲ. Describe what you expected to happen

All ingress route over https can access normally.

Ⅳ. How to reproduce it (as minimally and precisely as possible)

Apply higress version 1.4.0-rc1, apply CRs below:

apiVersion: v1
data:
  cert: |
    automaticHttps: true
    renewBeforeDays: 1
    credentialConfig:
    - domains:  
        - "*.34.84.109.10.nip.io"
        - "34.84.109.10.nip.io"
      tlsSecret: wildcard-cert
kind: ConfigMap
metadata:
  name: higress-https
  namespace: higress-system
apiVersion: v1
data:
  ca.crt: aaa(replace with any valid cert)
  tls.crt: bbb
  tls.key: ccc
kind: Secret
metadata:
  annotations:
    cert-manager.io/alt-names: 34.84.109.10.nip.io,*.34.84.109.10.nip.io
    cert-manager.io/certificate-name: sealos-cloud
    cert-manager.io/common-name: 34.84.109.10.nip.io
    cert-manager.io/ip-sans: ""
    cert-manager.io/issuer-group: ""
    cert-manager.io/issuer-kind: ClusterIssuer
    cert-manager.io/issuer-name: selfsigned-issuer
    cert-manager.io/uri-sans: ""
  name: wildcard-cert
  namespace: higress-system
type: kubernetes.io/tls
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  annotations:
    kubernetes.io/ingress.class: nginx
  name: sealos-desktop
  namespace: sealos
spec:
  rules:
    - host: 34.84.109.10.nip.io
      http:
        paths:
          - backend:
              service:
                name: desktop-frontend
                port:
                  number: 3000
            path: /
            pathType: Prefix
  tls:
    - hosts:
        - 34.84.109.10.nip.io
      secretName: wildcard-cert
---
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  annotations:
    kubernetes.io/ingress.class: nginx
  name: applaunchpad-frontend
  namespace: applaunchpad-frontend
spec:
  rules:
    - host: applaunchpad.34.84.109.10.nip.io
      http:
        paths:
          - backend:
              service:
                name: applaunchpad-frontend
                port:
                  number: 3000
            path: /
            pathType: Prefix
  tls:
    - hosts:
        - applaunchpad.34.84.109.10.nip.io
      secretName: wildcard-cert

There are 3 ns and one secret higress-system/wildcard-cert exists, no other secrets exists.

Ⅴ. Anything else we need to know?

Ⅵ. Environment:

  • Higress version: 1.4.0-rc1
  • OS : kubernetes 1.25.6
  • Others:

在ingress tls 下不要配置 secretName, 如果配置 secretName 会在当前 namespace 查找,如果没有配置 secretName, 会在 higress-https configmap 查找。

@johnlanni
Copy link
Collaborator

johnlanni commented May 20, 2024

@2456868764 但是我理解不应该导致443访问不通?
我再看一下, 现在上面配置secret 不存在,现在做法有secetName 配置,用当前 ingress ns 下 secret, 如果没有配置,就在 configmap 下找 higress-system ns 下 secret

@zzjin
Copy link
Author

zzjin commented May 20, 2024

如果配置 secretName 会在当前 namespace 查找,如果没有配置 secretName, 会在 higress-https configmap 查找。

这个地方是不是应该找不到去全局再查一次?只有本地没有+全局没有才会当作不存在

  1. 本地ns有,用本地
  2. 本地没有,查全局
  3. 全局有,用全局的
  4. 全局没有, 报错tls不存在,而不是路由不存在

场景,全局ns下是一个wildcard的cert,本地ns可以用户用一个单域名的cert覆盖全局的cert(时间.cn等)

@johnlanni
Copy link
Collaborator

@zzjin 目前的实现机制是如果ingress里有申明secret,就会直接用这个secret,只有当ingress里没有申明的时候才会用全局配置里的。这样提供用户灵活性,可以通过ingress配置强制指定走特定的secret。

@johnlanni
Copy link
Collaborator

如果ingress里指定的secret实际不存在,这个行为我们视作是用户自己的配置错误,我们觉得程序不应该为用户的配置错误兜底,应该让配置错误尽早暴露,以避免未来可能的其他未预期行为。

@johnlanni johnlanni removed the type/bug Something isn't working label May 22, 2024
@zzjin
Copy link
Author

zzjin commented May 22, 2024

@zzjin 目前的实现机制是如果ingress里有申明secret,就会直接用这个secret,只有当ingress里没有申明的时候才会用全局配置里的。这样提供用户灵活性,可以通过ingress配置强制指定走特定的secret。

是指Ingress的CR里面,只配置tls.hosts,不配置secretName吗?
还是说Ingress里面整个tls的spec都不写=>带来个隐患的问题就是Ingress里面没有任何地方能知道这个CR是支持tls的(只看Ingress这一个CR的话)=>或者说如果没有tls字段,表示不需要https支持

@zzjin
Copy link
Author

zzjin commented May 22, 2024

测试Ingress-nginx的话是会查找默认证书,还是希望能与这块逻辑对齐,或者通过参数开关

@johnlanni
Copy link
Collaborator

@zzjin 是的只配tls.hosts不配置secretName,您是说ingress-nginx在发现secret不存在时会用默认证书来兜底是吗

@johnlanni
Copy link
Collaborator

我想了下。其实tls是域名级的,看单个ingress的tls spec也并不能判断这个域名是否开启HTTPS,依赖tls spec才开启HTTPS,管理起来反而麻烦。

不如就在这个higress-https里整体管理哪些域名要开启https(就配置secret)。

@zzjin
Copy link
Author

zzjin commented May 23, 2024

@zzjin 是的只配tls.hosts不配置secretName,您是说ingress-nginx在发现secret不存在时会用默认证书来兜底是吗

对的,ingress-nginx会在configmap里面做全局的兜底(如果ingress的cr配了tls,但是对应的ns下面的tls的secret找不到,就会用这个兜底) https://kubernetes.github.io/ingress-nginx/user-guide/tls/#default-ssl-certificate

@CH3CHO
Copy link
Collaborator

CH3CHO commented May 23, 2024

对的,ingress-nginx会在configmap里面做全局的兜底(如果ingress的cr配了tls,但是对应的ns下面的tls的secret找不到,就会用这个兜底) https://kubernetes.github.io/ingress-nginx/user-guide/tls/#default-ssl-certificate

你指的是这一句吗?

The default certificate will also be used for ingress tls: sections that do not have a secretName option.

@johnlanni johnlanni changed the title Configuration for higress-https is not taking effect. 希望higress-https中的全局https证书配置可以用于ingress中secret不存在时的兜底 May 23, 2024
@johnlanni
Copy link
Collaborator

@zzjin 是的只配tls.hosts不配置secretName,您是说ingress-nginx在发现secret不存在时会用默认证书来兜底是吗

对的,ingress-nginx会在configmap里面做全局的兜底(如果ingress的cr配了tls,但是对应的ns下面的tls的secret找不到,就会用这个兜底) https://kubernetes.github.io/ingress-nginx/user-guide/tls/#default-ssl-certificate

这个需求在你们的场景下是必须的吗,是不是希望在切换到全局域名配置的时候,不用逐个修改ingress,直接批量删除secret是吗

@zzjin
Copy link
Author

zzjin commented May 23, 2024

我想了下。其实tls是域名级的,看单个ingress的tls spec也并不能判断这个域名是否开启HTTPS,依赖tls spec才开启HTTPS,管理起来反而麻烦。

不如就在这个higress-https里整体管理哪些域名要开启https(就配置secret)。

逻辑上是合理的,不过在我们场景下应用会分散到很多不同的ns下,由不同的用户去管理,教导/引导实际用户在使用不同的域名的时候去理解, A域名是全局兜底的,不要配置tls,B域名是需要自己配置证书的,这件事情比较麻烦.

从系统层面来说这个应该是对用户无感知的

@zzjin
Copy link
Author

zzjin commented May 23, 2024

对的,ingress-nginx会在configmap里面做全局的兜底(如果ingress的cr配了tls,但是对应的ns下面的tls的secret找不到,就会用这个兜底) https://kubernetes.github.io/ingress-nginx/user-guide/tls/#default-ssl-certificate

你指的是这一句吗?

The default certificate will also be used for ingress tls: sections that do not have a secretName option.

The secret referred to by this flag contains the default certificate to be used when accessing the catch-all server.

这一句

@zzjin
Copy link
Author

zzjin commented May 23, 2024

@zzjin 是的只配tls.hosts不配置secretName,您是说ingress-nginx在发现secret不存在时会用默认证书来兜底是吗

对的,ingress-nginx会在configmap里面做全局的兜底(如果ingress的cr配了tls,但是对应的ns下面的tls的secret找不到,就会用这个兜底) https://kubernetes.github.io/ingress-nginx/user-guide/tls/#default-ssl-certificate

这个需求在你们的场景下是必须的吗,是不是希望在切换到全局域名配置的时候,不用逐个修改ingress,直接批量删除secret是吗

可以这么理解,新老系统兼容也是需要考虑的

@CH3CHO
Copy link
Collaborator

CH3CHO commented May 23, 2024

when accessing the catch-all server.

但如果配置了单独的路由,就不属于“accessing the catch-all server”了吧?这部分你实测下来是什么行为呢?

@johnlanni
Copy link
Collaborator

我想了下。其实tls是域名级的,看单个ingress的tls spec也并不能判断这个域名是否开启HTTPS,依赖tls spec才开启HTTPS,管理起来反而麻烦。
不如就在这个higress-https里整体管理哪些域名要开启https(就配置secret)。

逻辑上是合理的,不过在我们场景下应用会分散到很多不同的ns下,由不同的用户去管理,教导/引导实际用户在使用不同的域名的时候去理解, A域名是全局兜底的,不要配置tls,B域名是需要自己配置证书的,这件事情比较麻烦.

从系统层面来说这个应该是对用户无感知的

这个到还好,我的意思是tls不是强制配置,如果配置了也没问题,就是secret要配对。你的意思是说用户可能会配不存在的secret,这个时候需要用全局配置的secret来兜底是吗。

@zzjin
Copy link
Author

zzjin commented May 23, 2024

我想了下。其实tls是域名级的,看单个ingress的tls spec也并不能判断这个域名是否开启HTTPS,依赖tls spec才开启HTTPS,管理起来反而麻烦。
不如就在这个higress-https里整体管理哪些域名要开启https(就配置secret)。

逻辑上是合理的,不过在我们场景下应用会分散到很多不同的ns下,由不同的用户去管理,教导/引导实际用户在使用不同的域名的时候去理解, A域名是全局兜底的,不要配置tls,B域名是需要自己配置证书的,这件事情比较麻烦.
从系统层面来说这个应该是对用户无感知的

这个到还好,我的意思是tls不是强制配置,如果配置了也没问题,就是secret要配对。你的意思是说用户可能会配不存在的secret,这个时候需要用全局配置的secret来兜底是吗。

对的

@zzjin
Copy link
Author

zzjin commented May 23, 2024

when accessing the catch-all server.

但如果配置了单独的路由,就不属于“accessing the catch-all server”了吧?这部分你实测下来是什么行为呢?

实际效果其实还是有点偏差的:
就是不管用户的server_name配置了啥,配没配tls,配置的tls的证书是否存在,都会去configmap里面用配置的secret去兜底(如果配置了的话)
这个时候,只要是ingress的cr里面找不到/出错的域名证书都会从configmap里面这个证书去兜底,比如a.example.com和b.sample.io都会用这个secret
但是实际上,configmap里面的证书是只有一个域名a.example.com,或者是一个*.example.com的泛域名证书
导致这个兜底效果也不是完美的<=但是刚刚好满足我们“给我们需要的泛域名证书兜底”的需求


从实现来说,我认可higress-https的方案确实可以更灵活的支持多域名的兜底,就是兜底的逻辑希望能和ingress-nginx尽量匹配下

@johnlanni
Copy link
Collaborator

ok 我这边考虑下 @zzjin

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging a pull request may close this issue.

4 participants