# NGINX Ingress控制器插件升级检查
#### 检查项内容
对于NGINX Ingress控制器插件，在升级时除通用检查项中包括的[插件状态异常检查](https://support.huaweicloud.com/usermanual-cce/cce_10_1031.html#cce_10_1031__section16401621161915)、[插件配置异常检查](https://support.huaweicloud.com/usermanual-cce/cce_10_1031.html#cce_10_1031__section8719325184717)、[模板检查](https://support.huaweicloud.com/usermanual-cce/cce_10_1031.html#cce_10_1031__section1330111488475)外，还需对以下资源进行额外检查：
- [证书密钥长度检查]
- [默认后端服务检查]
- [IngressClass缺失检查]
- [Snippet兼容性检查]
 
 #### 证书密钥长度检查
**检查说明：**
检查NGINX Ingress控制器指定的默认服务器证书密钥长度是否安全。
**检测范围：**
- 支持检查类型：插件编辑/升级前检查
- 支持集群范围：1.15及以上集群版本
- 支持插件范围：NGINX Ingress控制器插件从3.0.7以下版本升级到3.0.7及以上版本时。
**风险说明：**
在NGINX Ingress控制器插件从3.0.7以下版本升级到3.0.7及以上版本时，对应的社区ingress-nginx版本将升级至1.25.5或更高版本。升级后，OpenSSL的安全加密等级从SECLEVEL=1提升到 SECLEVEL=2，会加强证书密钥长度的校验。不符合密钥长度要求的证书会导致插件启动失败，从而影响业务流量。
**解决方案：**
- 方案一：兼容更低安全等级证书 通过在ssl-ciphers参数中添加@SECLEVEL字段，以启用更低安全等级证书的支持，详细操作请参见[NGINX Ingress控制器插件升级后无法使用TLS v1.0和v1.1](https://support.huaweicloud.com/cce_faq/cce_faq_00442.html)。
  
- 方案二：更新服务器默认证书
  1. 在NGINX Ingress控制器部署的命名空间内查看是否指定有默认服务器证书。
     ```
     kubectl get pod cceaddon-nginx-ingress-<controller-name>-controller-*** -n <namespace> -oyaml | grep 'default-ssl-certificate'
     ```
     其中cceaddon-nginx-ingress-\<controller-name\>-controller-\*\*\*为Controller Pod名称，\<controller-name\>为安装插件时指定的控制器名称，\<namespace\>为Controller部署的命名空间。
     回显如下：
     ```
     - '--default-ssl-certificate=<namespace>/<secret-name>'
     ```
     其中\<secret-name\>为NGINX Ingress控制器对应的默认服务器证书所在Secret名称。
     
  
  2. 检查NGINX Ingress控制器对应的默认证书是否存在加密长度不足的安全风险。
     ```
     kubectl get secret <secret-name> -n <namespace> -o=custom-columns=:'data.tls\.key' | base64 -d | openssl <encryption-algorithm> -noout -text
     ```
     其中\<encryption-algorithm\>为证书使用的加密算法，常见加密算法有：rsa、dsa等。
     - RSA密钥长度要求：SECLEVEL=2要求RSA密钥长度不低于2048。 ![](https://support.huaweicloud.com/usermanual-cce/zh-cn_image_0000002441506017.png "点击放大")
       
     
     - DSA密钥长度要求：SECLEVEL=2要求DSA密钥长度不低于2048。 ![](https://support.huaweicloud.com/usermanual-cce/zh-cn_image_0000002441506065.png "点击放大")
       
      
  
  3. 生成符合SECLEVEL=2要求的服务器默认证书（例如RSA ≥ 2048 bit、DSA ≥ 2048 bit、ECDSA使用P-224或更高安全强度曲线）。SECLEVEL等级与密钥长度关系详请参见[OpenSSL官方文档](https://docs.openssl.org/3.3/man3/SSL_CTX_set_security_level/#default-callback-behaviour)。
  
  4. 修改[1]中用于指定服务器默认证书的Secret，重新配置符合密钥长度要求的证书，同时确保证书链及私钥文件匹配。
   
 
 #### 默认后端服务检查
**检查说明：**
检查NGINX Ingress控制器后端指定的DefaultBackend Service是否存在。
**检测范围：**
- 支持检查类型：
  - 插件运行中巡检
  
  - 插件编辑/升级前检查
   
- 支持集群范围：1.15及以上集群版本
- 支持插件范围：所有版本的NGINX Ingress控制器插件
**风险说明：**
如 DefaultBackend Service缺失，NGINX Ingress控制器在启动过程中无法加载默认后端配置，将导致控制器Pod启动失败或持续重启。
**解决方案：**
1. 确认DefaultBackend Service名称。 
   ```
   kubectl get pod cceaddon-nginx-ingress-<controller-name>-controller-*** -n <namespace> -oyaml | grep 'default-backend'
   ```
   其中cceaddon-nginx-ingress-\<controller-name\>-controller-\*\*\*为Controller Pod名称，\<controller-name\>为安装插件时指定的控制器名称，\<namespace\>为Controller部署的命名空间。
   回显如下：
   ```
   - '--default-backend-service=<namespace>/<backend-svc-name>'
   ```
   其中\<backend-svc-name\>为Controller对应的DefaultBackend Service名称。
   
   
2. 检查DefaultBackend Service是否存在。 
   ```
   kubectl get svc <backend-svc-name> -n <namespace>
   ```
   如果不存在将无法通过该项检查。
   
   
3. 重新创建DefaultBackend Service。 
   - 如果安装插件时，在"默认404服务"配置项中指定了自定义的DefaultBackend Service，请您自行重新创建相同的Service。
   
   - 如果安装插件时使用默认的DefaultBackend Service，则重新创建的YAML示例如下。
     ```
     apiVersion: v1
     kind: Service
     metadata:
       name: cceaddon-nginx-ingress-<controller-name>-default-backend   # <controller-name>为控制器名称
       namespace: kube-system
       labels:
         app: nginx-ingress-<controller-name>
         app.kubernetes.io/managed-by: Helm
         chart: nginx-ingress-<version>    # <version>为插件版本
         component: default-backend
         heritage: Helm
         release: cceaddon-nginx-ingress-<controller-name>
       annotations:
         meta.helm.sh/release-name: cceaddon-nginx-ingress-<controller-name>
         meta.helm.sh/release-namespace: kube-system    # 插件安装的命名空间
     spec:
       ports:
         - name: http
           protocol: TCP
           port: 80
           targetPort: http
       selector:
         app: nginx-ingress-<controller-name>
         component: default-backend
         release: cceaddon-nginx-ingress-<controller-name>
       type: ClusterIP
       sessionAffinity: None
       ipFamilies:
         - IPv4
       ipFamilyPolicy: SingleStack
       internalTrafficPolicy: Cluster
     ```
     
   
   
   
   
 
 #### IngressClass缺失检查
**检查说明：**
检查集群中是否存在未指定Ingress类型的Nginx Ingress路由（即未在Ingress的YAML中设置metadata.annotations\["kubernetes.io/ingress.class"\]，也未在spec.ingressClassName中指定）。关于该问题的触发原因详情，请参见[问题根因](https://support.huaweicloud.com/cce_faq/cce_faq_00430.html#section3)。
**检测范围：**
- 支持检查类型：插件编辑/升级前检查
- 支持集群范围：1.15及以上集群版本
- 支持插件范围：NGINX Ingress控制器插件从2.0.0以下的版本升级到2.0.0及以上版本时。
**风险说明：**
如果在创建Ingress时没有显示指定Ingress类别，该资源将被高版本NGINX Ingress Controller忽略，Ingress规则失效，导致服务中断。详情请参见[社区代码](https://github.com/kubernetes/ingress-nginx/blob/f207702c3080d679ae86307eafbc16b0d3098e6c/internal/ingress/controller/store/store.go#L830)。
**解决方案：**
- 1.18以下集群版本： 为Nginx类型的Ingress添加注解，方式如下：
  ```
  kubectl annotate ingress -n <ingress-namespace> <ingress-name> kubernetes.io/ingress.class=<class-name>
  ```
  
- 1.18及以上集群版本： 为Nginx类型的Ingress添加spec.ingressClassName，方式如下：
  ```
  kubectl patch ingress -n <ingress-namespace> <ingress-name> --type='strategic' -p '{"spec": {"ingressClassName": "<class-name>"}}'
  ```
  
 
 #### Snippet兼容性检查
**检查说明：**
检查集群中对接NGINX Ingress控制器的Ingress资源是否配置了snippet类注解。
**检测范围：**
- 支持检查类型：
  - 插件运行中巡检
  
  - 插件编辑/升级前检查
   
- 支持集群范围：1.15及以上集群版本
- 支持插件范围：NGINX Ingress控制器插件版本在2.4.6及以上。
**风险说明：**
- 为提升安全性与配置稳定性，自2.4.6版本起，NGINX Ingress控制器插件将默认禁用所有snippet类注解。 禁用后，相关Ingress资源中的snippet注解将失效，不再对NGINX配置生效。
  涉及的 snippet 注解包括：
  - nginx.ingress.kubernetes.io/configuration-snippet
  
  - nginx.ingress.kubernetes.io/server-snippet
  
  - nginx.ingress.kubernetes.io/stream-snippet
  
  - nginx.ingress.kubernetes.io/auth-snippet
  
  - nginx.ingress.kubernetes.io/modsecurity-snippet
   
- 开启snippet注解功能可能允许用户直接在Ingress中注入任意NGINX配置片段，存在配置错误导致服务不可用或安全漏洞（如绕过访问控制、注入恶意配置）的风险。
**解决方案：**
- 方案一（推荐）：整改Ingress中的snippet配置，改用其他官方支持的注解或插件配置项实现需求。
- 方案二：手动开启snippet注释功能（需充分评估安全风险）。
  如您仍需要使用snippet注解能力，请在充分评估风险后，可以在插件配置中的"nginx配置参数 \> YAML配置"中添加以下配置，手动开启snippet注解的功能。
  - *"allow-snippet-annotations": "true"*
  
  - *"annotations-risk-level": "Critical"*
    ![](https://support.huaweicloud.com/usermanual-cce/public_sys-resources/note_3.0-zh-cn.png)
    在4.0.4及以上NGINX Ingress控制器插件版本需同时添加annotations-risk-level配置。
    这是因为在该版本中annotations-risk-level默认值降级为High，详情请参见[社区ChangeLog](https://github.com/kubernetes/ingress-nginx/releases/tag/controller-v1.12.0)。由于snippet注解为Critical级别，需要同时调整annotations-risk-level的参数值为Critical，否则snippet注解仍不可用。
    
  
  
  图1添加NGINX配置参数启用snippet注解   
  ![](https://support.huaweicloud.com/usermanual-cce/zh-cn_image_0000002408805528.png "点击放大")
  
  
 
