如何将 nginx 入口自定义端口列入白名单

问题描述

我在 Kubernetes 中有一个 Nginx 入口,带有白名单(由 Nginx.ingress.kubernetes.io/whitelist-source-range 注释处理)和自定义端口映射(通过 --tcp-services-configmap 配置映射公开 SFTP 服务器端口 22)。白名单适用于 80 和 443,但不适用于 22。如何将自定义端口列入白名单?

配置大致如下:

apiVersion: apps/v1
kind: Deployment
Metadata:
  name: nginx-ingress-controller
  namespace: ingress-Nginx
  labels:
    app.kubernetes.io/name: ingress-Nginx
    app.kubernetes.io/part-of: ingress-Nginx
spec:
  ...
    spec:
      serviceAccountName: nginx-ingress-serviceaccount
      containers:
        - name: nginx-ingress-controller
          image: quay.io/kubernetes-ingress-controller/nginx-ingress-controller:0.33.0
          args:
            - /nginx-ingress-controller
            - --configmap=$(POD_NAMESPACE)/Nginx-configuration
            - --tcp-services-configmap=$(POD_NAMESPACE)/tcp-services
            - --udp-services-configmap=$(POD_NAMESPACE)/udp-services
            - --publish-service=$(POD_NAMESPACE)/ingress-Nginx
            - --annotations-prefix=Nginx.ingress.kubernetes.io
          ports:
            - name: http
              containerPort: 80
            - name: https
              containerPort: 443
            - name: sftp
              containerPort: 22
        ...

kind: Ingress
Metadata:
  name: {{ .controllerName }}
  annotations:
    kubernetes.io/ingress.class: Nginx
    Nginx.ingress.kubernetes.io/whitelist-source-range: {{ .ipAllowList }}

kind: ConfigMap
apiVersion: v1
Metadata:
  name: tcp-services
  namespace: ingress-Nginx
  labels:
    app.kubernetes.io/name: ingress-Nginx
    app.kubernetes.io/part-of: ingress-Nginx
data:
  22: "default/sftp:22"

更新

感谢@jordanm,我发现我可以通过 LoadBalancer 中的 loadBalancerSourceRanges 而不是 Nginx 来限制所有端口的 IP 地址:

kind: Service
apiVersion: v1
Metadata:
  name: ingress-Nginx
  namespace: ingress-Nginx
  labels:
    app.kubernetes.io/name: ingress-Nginx
    app.kubernetes.io/part-of: ingress-Nginx
spec:
  externalTrafficPolicy: Local
  type: LoadBalancer
  loadBalancerIP: {{ .loadBalancerIp }}
  selector:
    app.kubernetes.io/name: ingress-Nginx
    app.kubernetes.io/part-of: ingress-Nginx
  ports:
    - name: http
      port: 80
      targetPort: http
    - name: https
      port: 443
      targetPort: https
    - name: sftp
      port: 22
      targetPort: sftp
  loadBalancerSourceRanges:
    {{ .ipAllowList }}

解决方法

首先看一下这个问题:ip-whitelist-support

IP 未列入 TCP 服务的白名单,另一种方法是为 TCP 服务创建单独的防火墙,并将 IP 列入防火墙级别的白名单。

对于特定位置 {{ $path }} 我们已经定义了 {{ if isLocationAllowed $location }}

查看官方 Ingress 文档:ingress-kubernetes

Ingress 将 HTTP 和 HTTPS 路由从集群外部暴露给集群内的服务。流量路由由 Ingress 资源上定义的规则控制。

Ingress 不会公开任意端口或协议。向互联网公开 HTTP 和 HTTPS 以外的服务通常使用 Service.Type=NodePort 或 Service.Type=LoadBalancer 类型的服务。

你必须有一个 Ingress 控制器才能满足一个 Ingress。仅有的 创建 Ingress 资源无效。

这种情况下Ingress资源仪表ingress-controller如何处理http/https请求。在这种方法中,nginx-ingress 控制器作为软件(引入第 7 层功能/负载平衡)。

如果您对 nginx ingress tcp 支持感兴趣:

Ingress 不支持 TCP 或 UDP 服务。为此,该入口控制器使用标志 --tcp-services-configmap 和 --udp-services-configmap

见:exposing-tcp-udp-services

如果您想在使用 tcp 服务时检查更精细的配置,您应该考虑使用您的云提供商提供的 L4 负载平衡/防火墙设置。