×

出站防火墙在项目中的工作原理

作为集群管理员,您可以使用出站防火墙来限制某些或所有 Pod 可以从集群内部访问的外部主机。出站防火墙支持以下场景:

  • Pod 只能连接到内部主机,并且不能启动与公共互联网的连接。

  • Pod 只能连接到公共互联网,并且不能启动与 OpenShift Container Platform 集群外部的内部主机的连接。

  • Pod 无法访问 OpenShift Container Platform 集群外部的指定内部子网或主机。

  • Pod 只能连接到特定的外部主机。

例如,您可以允许一个项目访问指定的 IP 范围,但拒绝另一个项目访问相同的范围。或者,您可以限制应用程序开发人员从 Python pip 镜像更新,并强制仅从批准的来源进行更新。

出站防火墙不适用于主机网络命名空间。启用了主机网络的 Pod 不受出站防火墙规则的影响。

您可以通过创建 EgressFirewall 自定义资源 (CR) 对象来配置出站防火墙策略。出站防火墙匹配满足以下任何条件的网络流量:

  • CIDR 格式的 IP 地址范围

  • 解析为 IP 地址的 DNS 名称

  • 端口号

  • 协议,其中协议为以下协议之一:TCP、UDP 和 SCTP

如果您的出站防火墙包含对0.0.0.0/0的拒绝规则,则会阻止对 OpenShift Container Platform API 服务器的访问。您必须为每个 IP 地址添加允许规则,或者在出站策略规则中使用nodeSelector类型允许规则来连接到 API 服务器。

以下示例说明了确保 API 服务器访问所需的出站防火墙规则的顺序:

apiVersion: k8s.ovn.org/v1
kind: EgressFirewall
metadata:
  name: default
  namespace: <namespace> (1)
spec:
  egress:
  - to:
      cidrSelector: <api_server_address_range> (2)
    type: Allow
# ...
  - to:
      cidrSelector: 0.0.0.0/0 (3)
    type: Deny
1 出站防火墙的命名空间。
2 包含 OpenShift Container Platform API 服务器的 IP 地址范围。
3 全局拒绝规则阻止对 OpenShift Container Platform API 服务器的访问。

要查找 API 服务器的 IP 地址,请运行oc get ep kubernetes -n default

更多信息,请参见 BZ#1988324

出站防火墙规则不适用于通过路由器传输的流量。任何有权创建 Route CR 对象的用户都可以通过创建指向禁止目标的路由来绕过出站防火墙策略规则。

出站防火墙的局限性

出站防火墙具有以下局限性:

  • 任何项目都不能拥有多个 EgressFirewall 对象。

  • 每个项目最多可以定义一个具有最多 8,000 条规则的 EgressFirewall 对象。

  • 如果您在 Red Hat OpenShift Networking 中使用具有共享网关模式的 OVN-Kubernetes 网络插件,则返回的入站回复会受到出站防火墙规则的影响。如果出站防火墙规则删除入站回复目标 IP,则会丢弃流量。

违反任何这些限制都会导致项目的出站防火墙损坏。因此,所有外部网络流量都会被丢弃,这可能会对您的组织造成安全风险。

可以在kube-node-leasekube-publickube-systemopenshiftopenshift-项目中创建 Egress Firewall 资源。

出站防火墙策略规则的匹配顺序

出站防火墙策略规则按照定义顺序进行评估,从前到后。第一个与 Pod 的出站连接匹配的规则适用。该连接的任何后续规则都将被忽略。

域名服务器 (DNS) 解析的工作原理

如果您在任何出站防火墙策略规则中使用域名,则域名解析会受到以下限制:

  • 域名更新基于生存时间 (TTL) 周期轮询。默认情况下,持续时间为 30 分钟。当出站防火墙控制器查询本地名称服务器以获取域名时,如果响应包含 TTL 且 TTL 小于 30 分钟,则控制器会将该域名的持续时间设置为返回的值。每个域名都在 DNS 记录 TTL 到期后进行查询。

  • 如有必要,Pod 必须从相同的本地名称服务器解析域名。否则,出站防火墙控制器和 Pod 已知的域名的 IP 地址可能不同。如果主机名的 IP 地址不同,则出站防火墙可能无法始终如一地执行。

  • 由于出站防火墙控制器和 Pod 异步轮询相同的本地名称服务器,因此 Pod 可能会在出站控制器之前获取更新的 IP 地址,从而导致竞争条件。由于此当前限制,仅建议将 EgressFirewall 对象中的域名用于 IP 地址更改不频繁的域名。

在出站防火墙策略中使用域名不会影响通过 CoreDNS 进行的本地 DNS 解析。

但是,如果您的出站防火墙策略使用域名,并且外部 DNS 服务器处理受影响 Pod 的 DNS 解析,则必须包含允许访问 DNS 服务器 IP 地址的出站防火墙规则。

改进的 DNS 解析和通配符域名解析

在某些情况下,与 DNS 记录关联的 IP 地址可能会频繁更改,或者您可能希望在出站防火墙策略规则中指定通配符域名。

在这种情况下,OVN-Kubernetes 集群管理器会为出站防火墙策略规则中使用的每个唯一域名创建一个DNSNameResolver自定义资源对象。此自定义资源存储以下信息:

出站防火墙规则的改进 DNS 解析仅为技术预览功能。技术预览功能不受 Red Hat 生产服务级别协议 (SLA) 的支持,并且可能功能不完整。Red Hat 不建议在生产环境中使用它们。这些功能可让您抢先体验即将推出的产品功能,从而能够在开发过程中测试功能并提供反馈。

有关 Red Hat 技术预览功能的支持范围的更多信息,请参阅技术预览功能支持范围

DNSNameResolver CR 定义示例
apiVersion: networking.openshift.io/v1alpha1
kind: DNSNameResolver
spec:
  name: www.example.com. (1)
status:
  resolvedNames:
  - dnsName: www.example.com. (2)
    resolvedAddress:
    - ip: "1.2.3.4" (3)
      ttlSeconds: 60 (4)
      lastLookupTime: "2023-08-08T15:07:04Z" (5)
1 DNS 名称。这可以是标准 DNS 名称或通配符 DNS 名称。对于通配符 DNS 名称,DNS 名称解析信息包含与通配符 DNS 名称匹配的所有 DNS 名称。
2 spec.name字段匹配的已解析 DNS 名称。如果spec.name字段包含通配符 DNS 名称,则会创建多个包含与通配符 DNS 名称匹配的标准 DNS 名称(解析后)的dnsName条目。如果通配符 DNS 名称也可以成功解析,则此字段还会存储通配符 DNS 名称。
3 与 DNS 名称关联的当前 IP 地址。
4 上次生存时间 (TTL) 持续时间。
5 上次查找时间。

如果在 DNS 解析期间,查询中的 DNS 名称与DNSNameResolver CR 中定义的任何名称匹配,则会相应地更新 CRstatus字段中的先前信息。对于不成功的 DNS 通配符名称查找,将在默认 TTL 30 分钟后重试请求。

OVN-Kubernetes 集群管理器监视EgressFirewall自定义资源对象的更新,并在更新发生时创建、修改或删除与这些出站防火墙策略关联的DNSNameResolver CR。

请勿直接修改DNSNameResolver自定义资源。这可能会导致出站防火墙出现意外行为。

EgressFirewall 自定义资源 (CR) 对象

您可以为出站防火墙定义一个或多个规则。规则可以是Allow规则或Deny规则,并指定规则适用的流量。

以下 YAML 描述了 EgressFirewall CR 对象:

EgressFirewall 对象
apiVersion: k8s.ovn.org/v1
kind: EgressFirewall
metadata:
  name: <name> (1)
spec:
  egress: (2)
    ...
1 对象的名称必须为default
2 如下一节所述,包含一个或多个出站网络策略规则的集合。

EgressFirewall 规则

以下 YAML 描述了出站防火墙规则对象。用户可以选择 CIDR 格式的 IP 地址范围、域名或使用nodeSelector来允许或拒绝出站流量。egress部分需要一个或多个对象的数组。

出站策略规则部分
egress:
- type: <type> (1)
  to: (2)
    cidrSelector: <cidr> (3)
    dnsName: <dns_name> (4)
    nodeSelector: <label_name>: <label_value> (5)
  ports: (6)
      ...
1 规则类型。值必须为AllowDeny
2 描述出站流量匹配规则的部分,该规则指定cidrSelector字段或dnsName字段。您不能在同一规则中同时使用这两个字段。
3 CIDR 格式的 IP 地址范围。
4 DNS 域名。
5 标签是用户定义的键值对。标签附加到对象(例如 Pod)。nodeSelector允许选择一个或多个节点标签并将其附加到 Pod。
6 可选:描述规则的网络端口和协议集合的部分。
端口部分
ports:
- port: <port> (1)
  protocol: <protocol> (2)
1 网络端口,例如80443。如果您为此字段指定值,则还必须为protocol指定值。
2 网络协议。值必须为TCPUDPSCTP

EgressFirewall CR 对象示例

以下示例定义了几个出站防火墙策略规则:

apiVersion: k8s.ovn.org/v1
kind: EgressFirewall
metadata:
  name: default
spec:
  egress: (1)
  - type: Allow
    to:
      cidrSelector: 1.2.3.0/24
  - type: Deny
    to:
      cidrSelector: 0.0.0.0/0
1 出站防火墙策略规则对象的集合。

以下示例定义了一个策略规则,如果流量使用 TCP 协议和目标端口80或任何协议和目标端口443,则拒绝到172.16.1.1 IP 地址主机的流量。

apiVersion: k8s.ovn.org/v1
kind: EgressFirewall
metadata:
  name: default
spec:
  egress:
  - type: Deny
    to:
      cidrSelector: 172.16.1.1
    ports:
    - port: 80
      protocol: TCP
    - port: 443

EgressFirewall 的 nodeSelector 示例

作为集群管理员,您可以通过使用nodeSelector指定标签来允许或拒绝对集群中节点的出站流量。标签可以应用于一个或多个节点。以下是一个使用region=east标签的示例:

apiVersion: k8s.ovn.org/v1
kind: EgressFirewall
metadata:
  name: default
spec:
    egress:
    - to:
        nodeSelector:
          matchLabels:
            region: east
      type: Allow

不要为每个节点 IP 地址添加手动规则,请使用节点选择器创建允许出站防火墙后面的 Pod 访问主机网络 Pod 的标签。

创建出站防火墙策略对象

作为集群管理员,您可以为项目创建出站防火墙策略对象。

如果项目已定义 EgressFirewall 对象,则必须编辑现有策略才能更改出站防火墙规则。

先决条件
  • 使用 OVN-Kubernetes 网络插件的集群。

  • 安装 OpenShift CLI (oc)。

  • 您必须以集群管理员身份登录集群。

步骤
  1. 创建策略规则

    1. 创建一个<policy_name>.yaml文件,其中<policy_name>描述出站策略规则。

    2. 在您创建的文件中,定义一个出站策略对象。

  2. 输入以下命令以创建策略对象。将<policy_name>替换为策略的名称,并将<project>替换为规则适用的项目。

    $ oc create -f <policy_name>.yaml -n <project>

    在以下示例中,在名为project1的项目中创建了一个新的EgressFirewall对象。

    $ oc create -f default.yaml -n project1
    示例输出
    egressfirewall.k8s.ovn.org/v1 created
  3. 可选:保存<policy_name>.yaml文件,以便您以后可以进行更改。