配置防火墙和数据包过滤器
管理 firewalld 服务、nftables 框架和 XDP 数据包过滤功能
摘要
对红帽文档提供反馈 复制链接链接已复制到粘贴板!
我们感谢您对我们文档的反馈。让我们了解如何改进它。
通过 Jira 提交反馈(需要帐户)
- 登录到 Jira 网站。
- 在顶部导航栏中点 Create
- 在 Summary 字段中输入描述性标题。
- 在 Description 字段中输入您对改进的建议。包括文档相关部分的链接。
- 点对话框底部的 Create。
第 1 章 使用和配置 firewalld 复制链接链接已复制到粘贴板!
防火墙是保护机器不受来自外部的、不需要的网络数据影响的一种方式。它允许用户通过定义一组防火墙规则 来控制主机上的入站网络流量。这些规则用于对传入流量进行排序,并阻止它或允许它通过。
firewalld 是一个防火墙服务守护进程,它提供带有 D-Bus 接口的动态的、可自定义的防火墙。由于是动态的,所以它可以创建、修改和删除规则,而无需在每次规则更改时重启防火墙守护进程。
您可以使用 firewalld 配置大多数典型情况要求的数据包过滤。如果 firewalld 没有涵盖您的场景,或者您想要完全控制规则,请使用 nftables 框架。如需更多信息,请参阅 nftables 入门。
firewalld 使用区域、策略和服务的概念来简化流量管理。区域在逻辑上分隔网络。网络接口和源可以分配给区。策略用于拒绝或允许区域间的流量流动。防火墙服务是预定义的规则,其覆盖所有必要设置,以允许特定服务的传入流量,并且它们在区域内应用。
服务使用一个或多个端口或地址进行网络通信。防火墙会根据端口过滤通讯。要允许服务的网络流量,必须打开其端口。firewalld 会阻止未明确设置为开放的端口上的所有流量。一些区(如可信区)默认允许所有流量。
firewalld 维护单独的运行时和永久配置。这允许仅运行时的更改。firewalld 重新加载或重启后,运行时配置不会保留。在启动时,它会从永久配置填充。
1.1. 防火墙区域 复制链接链接已复制到粘贴板!
您可以根据您与该网络中的接口和流量的信任级别,使用 firewalld 工具将网络划分为不同的区域。连接只能是区域的一部分,但您可以对许多网络连接使用这个区域。
firewalld 在区域方面遵循严格的原则:
- 流量只流入一个区域。
- 流量只流出一个区域。
- 一个区域定义一个信任级别。
- 默认允许区域内流量(在同一区域内)。
- 默认拒绝区域内流量(从区域到区域)。
原则 4 和 5 是原则 3 的结果。
原则 4 可以通过区域选项 --remove-forward 进行配置。原则 5 可以通过添加新策略进行配置。
NetworkManager 通知接口区的 firewalld。您可以使用以下工具将区域分配给接口:
-
NetworkManager -
firewall-config工具 -
firewall-cmd工具 - RHEL web 控制台
RHEL web 控制台、firewall-config 和 firewall-cmd 只能编辑合适的 NetworkManager 配置文件。如果您使用 Web 控制台、firewall-cmd 或 firewall-config 更改接口的区域,则请求被转发到 NetworkManager,且不会由 firewalld 处理。
/usr/lib/firewalld/zones/ 目录存储预定义的区域,您可以立即将它们应用到任何可用的网络接口。只有在修改后,这些文件才会被拷贝到 /etc/firewalld/zones/ 目录中。预定义区的默认设置如下:
block-
适合于:任何传入的网络连接都会被拒绝,并对
IPv4显示 icmp-host-prohibited 消息,对IPv6显示 icmp6-adm-prohibited 消息。 - 接受:只有从系统内启动的网络连接。
-
适合于:任何传入的网络连接都会被拒绝,并对
dmz- 适用于:您的 DMZ 中可使用访问您的内部网的有限权限公开访问的计算机。
- 接受: 只有所选的传入连接。
drop适合于:任何被丢失,但没有任何通知的传入网络数据包。
- 接受:只有传出的网络连接。
external- 适用于:启用了伪装的外部网络,特别是路由器。不信任网络上其他计算机的情况。
- 接受: 只有所选的传入连接。
home- 适用于:家庭环境,其中您基本上信任网络上的其他计算机。
- 接受: 只有所选的传入连接。
internal- 适用于:内部网络,其中您基本上信任网络上其他计算机的。
- 接受: 只有所选的传入连接。
public- 适用于:公共区域,其中您不信任网络上的其他计算机。
- 接受: 只有所选的传入连接。
trusted- 接受:所有网络连接。
work适用于:工作环境,其中您大多信任网络上的其他计算机。
- 接受: 只有所选的传入连接。
这些区中的一个被设置为 default 区。当接口连接被添加到 NetworkManager 中时,它们会被分配到默认区。安装时,firewalld 中的默认区域是 public 区域。您可以更改默认区域。
使网络区域名称一目了然,以帮助用户快速理解它们。
要避免安全问题,请查看默认区配置并根据您的需要和风险禁用任何不必要的服务。
详情请查看您系统上的 firewalld.zone (5) 手册页。
1.2. 防火墙策略 复制链接链接已复制到粘贴板!
防火墙策略指定网络所需的安全状态。它们概述了对不同类型的流量要采取的规则和操作。通常,策略包含以下类型流量的规则:
- 传入流量
- 传出流量
- 转发流量
- 特定服务和应用程序
- 网络地址转换(NAT)
防火墙策略使用防火墙区域的概念。每个区域都与一组特定的、决定允许的流量的防火墙规则相关联。策略以一种有状态的、单向的方式应用防火墙规则。这意味着您只考虑流量的一个方向。由于 firewalld 的有状态过滤,流量返回路径被隐式允许。
策略与入口区域和出口区域相关联。入口区域是流量起源(接收)的地方。出口区域是流量离开(发送)的地方。
策略中定义的防火墙规则可以引用防火墙区,以便在多个网络接口中应用一致的配置。
1.3. 防火墙规则 复制链接链接已复制到粘贴板!
您可以使用防火墙规则实现特定的配置,以允许或阻止网络流量。因此,您可以控制网络流量的流动,以防止系统受到安全威胁。
防火墙规则通常根据各种属性定义某些标准。属性可以是:
- 源 IP 地址
- 目标 IP 地址
- 传输协议(TCP、UDP、…)
- 端口
- 网络接口
firewalld 工具将防火墙规则组织到区域( 如 public、internal 等)和策略。每个区域都有自己的一组规则,其决定与特定区域关联的网络接口的流量自由度的级别。
1.4. 防火墙直接规则 复制链接链接已复制到粘贴板!
firewalld 服务提供多种配置规则的方法,包括:
- 常规规则
- 直接规则
这两者之间的一个区别是每种方法与底层后端(iptables 或 nftables)交互的方式。
直接规则是高级的、低级规则,其允许与 iptables 的直接交互。但是,iptables 组件是没有维护的,并将最终从 RHEL 中删除。因此,您可能会考虑使用 nftables 替换直接规则。如需了解更多详细信息,请参阅知识库文章解决方案 如何使用 nftables 替换 firewalld 直接规则?,以及 在区域之间过滤转发流量 中与策略对象有关的部分。
1.5. 预定义的 firewalld 服务 复制链接链接已复制到粘贴板!
预定义的 firewalld 服务在低级防火墙规则之上提供一个内置抽象层。它通过将常用的网络服务(如 SSH 或 HTTP)映射到其相应的端口和协议来实现。您可以引用一个命名的预定义服务,而不是每次手动指定它们。这使得防火墙管理变得更加简单、不易出错且更直观。
要查看可用的预定义服务:
# firewall-cmd --get-services RH-Satellite-6 RH-Satellite-6-capsule afp amanda-client amanda-k5-client amqp amqps apcupsd audit ausweisapp2 bacula bacula-client bareos-director bareos-filedaemon bareos-storage bb bgp bitcoin bitcoin-rpc bitcoin-testnet bitcoin-testnet-rpc bittorrent-lsd ceph ceph-exporter ceph-mon cfengine checkmk-agent cockpit collectd condor-collector cratedb ctdb dds...要进一步检查特定的预定义服务:
# sudo firewall-cmd --info-service=RH-Satellite-6 RH-Satellite-6 ports: 5000/tcp 5646-5647/tcp 5671/tcp 8000/tcp 8080/tcp 9090/tcp protocols: source-ports: modules: destination: includes: foreman helpers:示例输出显示
RH-Satellite-6预定义服务侦听端口 5000/tcp 5646-5647/tcp 5671/tcp 8000/tcp 8080/tcp 9090/tcp。另外,RH-Satellite-6继承了其他预定义服务中的规则。在本例中为foreman。
每个预定义的服务都以同名的 XML 文件存储在 /usr/lib/firewalld/services/ 目录中。
第 2 章 使用 firewalld 区域 复制链接链接已复制到粘贴板!
zones 代表一种更透明管理传入流量的概念。网络接口和源地址被分配给区域。您可以独立为每个区管理防火墙规则,这样就可以定义复杂的防火墙设置并将其应用到流量。
2.1. 更改默认区 复制链接链接已复制到粘贴板!
系统管理员在其配置文件中为网络接口分配区域。如果接口没有被分配给指定区,它将被分配给默认区。每次重启 firewalld 服务后,firewalld 会加载默认区的设置,并使其处于活动状态。请注意,所有其他区域的设置都被保留,并可使用。
通常,区域会被 NetworkManager 按照 NetworkManager 连接配置文件中的 connection.zone 设置分配给接口。另外,重启后,NetworkManager 会管理“激活”这些区域的分配。
先决条件
-
firewalld服务在运行。
流程
显示当前的默认区:
# firewall-cmd --get-default-zone设置新的默认区:
# firewall-cmd --set-default-zone <zone_name>注意按照此流程,设置是一个永久设置,即使没有
--permanent选项。
2.2. 创建一个新区 复制链接链接已复制到粘贴板!
要使用自定义区,创建一个新的区并使用它像预定义区一样。新区需要 --permanent 选项,否则命令无法工作。
先决条件
-
firewalld服务在运行。
流程
创建一个新区:
# firewall-cmd --permanent --new-zone=zone-name使新区域可用:
# firewall-cmd --reload命令将最新的更改应用到防火墙配置,而不中断已在运行的网络服务。
验证
检查是否在您的永久设置中添加了新的区:
# firewall-cmd --get-zones --permanent
2.3. 将网络接口分配给区 复制链接链接已复制到粘贴板!
可以为不同区定义不同的规则集,然后通过更改所使用的接口的区来快速改变设置。使用多个接口,可以为每个具体区设置一个区来区分通过它们的网络流量。
流程
列出活跃区以及分配给它们的接口:
# firewall-cmd --get-active-zones为不同的区分配接口:
# firewall-cmd --zone=zone_name --change-interface=interface_name --permanent
2.4. 添加源 复制链接链接已复制到粘贴板!
要将传入的流量路由到特定区,请将源添加到那个区。源可以是一个使用 CIDR 格式的 IP 地址或 IP 掩码。
如果您添加多个带有重叠网络范围的区域,则根据区名称排序,且只考虑第一个区。
在当前区中设置源:
# firewall-cmd --add-source=<source>要为特定区设置源 IP 地址:
# firewall-cmd --zone=zone-name --add-source=<source>
以下流程允许来自 受信任 区中 192.168.2.15 的所有传入的流量:
流程
列出所有可用区:
# firewall-cmd --get-zones将源 IP 添加到持久性模式的信任区中:
# firewall-cmd --zone=trusted --add-source=192.168.2.15使新设置具有持久性:
# firewall-cmd --runtime-to-permanent
2.5. 删除源 复制链接链接已复制到粘贴板!
当您从一个区域中删除源时,源自该源的流量不再通过为该源指定的规则进行引导。相反,流量会返回到与它源自的接口关联的区域的规则和设置,或转至默认区域。
流程
列出所需区的允许源:
# firewall-cmd --zone=zone-name --list-sources从区永久删除源:
# firewall-cmd --zone=zone-name --remove-source=<source>使新设置具有持久性:
# firewall-cmd --runtime-to-permanent
2.6. 使用 nmcli 为连接分配区域 复制链接链接已复制到粘贴板!
您可以使用 nmcli 工具将 firewalld 区域添加到 NetworkManager 连接。
流程
将区分配给
NetworkManager连接配置文件:# nmcli connection modify profile connection.zone zone_name激活连接:
# nmcli connection up profile
2.7. 使用区目标设定传入流量的默认行为 复制链接链接已复制到粘贴板!
对于每个区,您可以设置一种处理尚未进一步指定的传入流量的默认行为。此行为是通过设置区的目标来定义的。有四个选项:
-
ACCEPT:接受所有传入的数据包,除了特定规则禁止的。 -
REJECT:拒绝所有传入的数据包,除了特定规则允许的。当firewalld拒绝数据包时,会告知源机器有关拒绝的信息。 -
DROP:丢弃所有传入的数据包,除了特定规则允许的。当firewalld丢弃数据包时,不会告知源机器有关丢弃数据包的信息。 -
default:与REJECT相同,但隐式允许 Internet 控制消息协议(ICMP)。
先决条件
-
firewalld服务在运行。
流程
列出特定区的信息以查看默认目标:
# firewall-cmd --zone=zone-name --list-all在区中设置一个新目标:
# firewall-cmd --permanent --zone=zone-name --set-target=<default|ACCEPT|REJECT|DROP>
2.8. 为特定区域自定义防火墙设置来增强安全性 复制链接链接已复制到粘贴板!
您可以通过修改防火墙设置,并将特定的网络接口或连接与特定的防火墙区域关联来加强网络安全性。通过为一个区域定义细粒度规则和限制,您可以根据预期的安全级别控制入站和出站流量。
例如,您可以取得以下好处:
- 保护敏感数据
- 防止未授权访问
- 缓解潜在的网络威胁
先决条件
-
firewalld服务在运行。
流程
列出可用的防火墙区域:
# firewall-cmd --get-zonesfirewall-cmd --get-zones命令显示系统上所有可用的区,但不显示特定区的详情。要查看所有区域的详情,请使用firewall-cmd --list-all-zones命令。- 选择您要用于此配置的区域。
修改所选区域的防火墙设置。例如,要允许
SSH服务并删除ftp服务:# firewall-cmd --add-service=ssh --zone=<your_chosen_zone> # firewall-cmd --remove-service=ftp --zone=<same_chosen_zone>向防火墙区域分配一个网络接口:
列出可用的网络接口:
# firewall-cmd --get-active-zones区域的活动是由网络接口或匹配其配置的源地址范围的存在来确定的。默认区域对于未分类的流量是处于活跃状态的,但如果没有流量匹配其规则,则不总是处于活跃状态。
向所选区分配一个网络接口:
# firewall-cmd --zone=<your_chosen_zone> --change-interface=<interface_name> --permanent向区域分配一个网络接口更适合于将一致的防火墙设置应用到特定接口(物理的或虚拟的)上的所有流量。
当与
--permanent选项一起使用时,firewall-cmd命令通常涉及更新 NetworkManager 连接配置文件,以使对防火墙配置的更改永久。firewalld和 NetworkManager 之间的这种集成确保一致的网络和防火墙设置。
验证
显示您选择的区域的更新设置:
# firewall-cmd --zone=<your_chosen_zone> --list-all命令输出显示所有区域设置,包括分配的服务、网络接口和网络连接(源)。
2.9. 使用 IP 集为允许列表配置动态更新 复制链接链接已复制到粘贴板!
您可以进行接近实时的更新,来灵活地允许 IP 集中特定的 IP 地址或范围,即使在无法预计的情况下也是如此。这些更新可以被各种事件触发,如检测安全威胁或更改网络行为。通常,此类解决方案利用自动化来减少手工工作,并通过快速响应情况来提高安全性。
先决条件
-
firewalld服务在运行。
流程
创建一个有有意义名称的 IP 集:
# firewall-cmd --permanent --new-ipset=allowlist --type=hash:ip名为
allowlist的新 IP 集包含您希望防火墙允许的 IP 地址。向 IP 集添加动态更新:
# firewall-cmd --permanent --ipset=allowlist --add-entry=198.51.100.10此配置使用新添加的 IP 地址更新防火墙允许传输网络流量的
allowlistIP 集。创建一个引用之前创建的 IP 集的防火墙规则:
# firewall-cmd --permanent --zone=public --add-source=ipset:allowlist没有此规则,IP 集不会对网络流量有任何影响。默认防火墙策略将占先。
重新载入防火墙配置以应用更改:
# firewall-cmd --reload
验证
列出所有 IP 集:
# firewall-cmd --get-ipsets allowlist列出活跃的规则:
# firewall-cmd --list-all public (active) target: default icmp-block-inversion: no interfaces: enp0s1 sources: ipset:allowlist services: cockpit dhcpv6-client ssh ports: protocols: ...命令行输出的
sources部分提供了对哪些流量源(主机名、接口、IP 集、子网等)被允许或拒绝访问特定防火墙区域的见解。在这种情况下,包含在allowlistIP 集中的 IP 地址被允许通过防火墙,为public区域传输流量。探索 IP 集的内容:
# cat /etc/firewalld/ipsets/allowlist.xml <?xml version="1.0" encoding="utf-8"?> <ipset type="hash:ip"> <entry>198.51.100.10</entry> </ipset>
后续步骤
-
使用脚本或安全工具获取您的威胁情报源,并以一种自动化的方式更新
allowlist。
2.10. 使用 Web 控制台启用区域 复制链接链接已复制到粘贴板!
您可以通过 RHEL 10 web 控制台对特定接口或 IP 地址范围应用预定义和现有防火墙区域。
先决条件
- 您已安装了 RHEL 10 web 控制台。
流程
- 登录到 RHEL 10 web 控制台。
- 点 Networking。
点按钮。
如果没有看到 按钮,使用管理员权限登录到 web 控制台。
- 在 Firewall 部分,点 Add new zone。
在 Add zone 对话框中,从信任级别选项选择一个区。
Web 控制台显示
firewalld服务中预定义的所有区域。- 在接口部分,选择一个应用所选区的接口或接口。
在 Allowed Addresses 部分中,您可以选择是否应用该区:
- 整个子网
或者以以下格式表示的 IP 地址范围:
- 192.168.1.0
- 192.168.1.0/24
- 192.168.1.0/24, 192.168.1.0
点 按钮。
验证
检查 Firewall 部分中的配置:
2.11. 使用 Web 控制台禁用区域 复制链接链接已复制到粘贴板!
您可以使用 Web 控制台在防火墙配置中禁用一个防火墙区域。
先决条件
- 您已安装了 RHEL 10 web 控制台。
流程
- 登录到 RHEL 10 web 控制台。
- 点 Networking。
点按钮。
如果没有看到 按钮,使用管理员权限登录到 web 控制台。
点您要删除的区的 Options 图标。
- 点击 Delete。
第 3 章 使用 firewalld 控制网络流量 复制链接链接已复制到粘贴板!
firewalld 软件包安装了大量预定义的服务文件,您可以添加更多或自定义它们。然后,您可以使用这些服务定义为服务打开或关闭端口,而无需了解协议及它们使用的端口号。
3.1. 使用 CLI 控制预定义服务的流量 复制链接链接已复制到粘贴板!
控制流量的最简单的方法是在 firewalld 中添加预定义的服务。这会打开所有必需的端口并根据 服务定义文件 修改其他设置。
先决条件
-
firewalld服务在运行。
流程
检查
firewalld中的服务是否还没有被允许:# firewall-cmd --list-services ssh dhcpv6-client命令列出在默认区域中启用的服务。
列出
firewalld中所有预定义的服务:# firewall-cmd --get-services RH-Satellite-6 amanda-client amanda-k5-client bacula bacula-client bitcoin bitcoin-rpc bitcoin-testnet bitcoin-testnet-rpc ceph ceph-mon cfengine condor-collector ctdb dhcp dhcpv6 dhcpv6-client dns docker-registry ...命令显示默认区域的可用服务的列表。
将服务添加到
firewalld允许的服务的列表中:# firewall-cmd --add-service=<service_name>命令将指定的服务添加到默认区域中。
使新设置具有持久性:
# firewall-cmd --runtime-to-permanent命令将这些运行时更改应用到防火墙的永久配置中。默认情况下,它将这些更改应用到默认区域的配置中。
验证
列出所有永久的防火墙规则:
# firewall-cmd --list-all --permanent public target: default icmp-block-inversion: no interfaces: sources: services: cockpit dhcpv6-client ssh ports: protocols: forward: no masquerade: no forward-ports: source-ports: icmp-blocks: rich rules:命令显示默认防火墙区域(
public)的永久防火墙规则的完整配置。
3.2. 使用 Web 控制台在防火墙上启用服务 复制链接链接已复制到粘贴板!
默认情况下,服务添加到默认防火墙区域。如果在更多网络接口中使用更多防火墙区,您必须首先选择一个区域,然后添加带有端口的服务。
RHEL 10 web 控制台显示预定义的 firewalld 服务,您可以将其添加到活跃的防火墙区域中。
RHEL 10 web 控制台配置 firewalld 服务。
Web 控制台不允许没有在 web 控制台中列出的通用 firewalld 规则。
先决条件
- 您已安装了 RHEL 10 web 控制台。
流程
- 登录到 RHEL 10 web 控制台。
- 点 Networking。
点按钮。
如果没有看到 按钮,使用管理员权限登录到 web 控制台。
在 Firewall 部分,选择要添加该服务的区,然后点击 Add Services。
- 在 Add Services 对话框中,找到您要在防火墙中启用的服务。
根据您的场景启用服务:
- 点 Add Services。
3.3. 使用 Web 控制台配置自定义端口 复制链接链接已复制到粘贴板!
您可以通过 RHEL web 控制台为服务配置自定义端口。
先决条件
- 您已安装了 RHEL 10 web 控制台。
-
firewalld服务在运行。
流程
- 登录到 RHEL 10 web 控制台。
- 点 Networking。
点按钮。
如果没有看到 按钮,使用管理员权限登录到 web 控制台。
在 Firewall 部分,选择要配置自定义端口的区域,并点 Add Services。
- 在 Add services 对话框中,点 单选按钮。
在 TCP 和 UDP 字段中,根据示例添加端口。您可以使用以下格式添加端口:
- 端口号,如 22
- 端口号范围,如 5900-5910
- 别名,比如 nfs, rsync
注意您可以在每个字段中添加多个值。值必须用逗号分开,且没有空格,例如: 8080、8081、http
在 TCP 文件、UDP 文件或两者中添加端口号后,在 Name 字段中验证服务名称。
Name 字段显示保留此端口的服务名称。如果您确定这个端口可用,且不需要在该端口上通信,则可以重写名称。
- 在 Name 字段中,为服务添加一个名称,包括定义的端口。
点 按钮。
验证
要验证设置,请进入防火墙页面,并在区域的服务列表中找到该服务。
第 4 章 在区域间过滤转发的流量 复制链接链接已复制到粘贴板!
firewalld 可让您控制不同 firewalld 区域之间的网络数据流。通过定义规则和策略,您可以管理流量在这些区域之间移动时是如何被允许或被拒绝的。
策略对象功能在 firewalld 中提供转发和输出过滤。您可以使用 firewalld 过滤不同区域之间的流量,以允许访问本地托管的虚拟机来连接主机。
4.1. 策略对象和区域之间的关系 复制链接链接已复制到粘贴板!
策略对象允许用户将 firewalld 的原语(如服务、端口和富规则)附加到策略。您可以将策略对象应用到以有状态和单向的方式在区域间传输的流量上。
# firewall-cmd --permanent --new-policy myOutputPolicy
# firewall-cmd --permanent --policy myOutputPolicy --add-ingress-zone HOST
# firewall-cmd --permanent --policy myOutputPolicy --add-egress-zone ANY
HOST 和 ANY 是 ingress 和 egress 区域列表中使用的符号区域。
-
HOST符号区域对于来自运行 firewalld 的主机的流量,或具有到运行 firewalld 的主机的流量允许策略。 -
ANY符号区对所有当前和将来的区域应用策略。ANY符号区域充当所有区域的通配符。
4.2. 使用优先级对策略进行排序 复制链接链接已复制到粘贴板!
多个策略可以应用到同一组流量,因此应使用优先级为可能应用的策略创建优先级顺序。
要设置优先级来对策略进行排序:
# firewall-cmd --permanent --policy mypolicy --set-priority -500
在上例中,-500 是较低的优先级值,但具有较高的优先级。因此,-500 将在 -100 之前执行。
较低数字的优先级值具有较高的优先级,被首先应用。
4.3. 使用策略对象过滤本地托管的容器和物理连接到主机的网络之间的流量 复制链接链接已复制到粘贴板!
策略对象功能允许用户过滤 Podman 和 firewalld 区域之间的流量。
红帽建议默认阻止所有流量,并打开 Podman 工具所需的可选择的服务。
流程
创建一个新的防火墙策略:
# firewall-cmd --permanent --new-policy podmanToAny阻止从 Podman 到其它区域的所有流量,并只允许 Podman 上必要的服务:
# firewall-cmd --permanent --policy podmanToAny --set-target REJECT # firewall-cmd --permanent --policy podmanToAny --add-service dhcp # firewall-cmd --permanent --policy podmanToAny --add-service dns # firewall-cmd --permanent --policy podmanToAny --add-service https创建一个新的 Podman 区域:
# firewall-cmd --permanent --new-zone=podman为策略定义 ingress 区域:
# firewall-cmd --permanent --policy podmanToHost --add-ingress-zone podman为所有其他区域定义 egress 区域:
# firewall-cmd --permanent --policy podmanToHost --add-egress-zone ANY将 egress 区域设置为 ANY 意味着您可以从 Podman 过滤到其他区域。如果要过滤到主机,请将 egress 区域设置为 HOST。
重启 firewalld 服务:
# systemctl restart firewalld
验证
验证到其他区域的 Podman 防火墙策略:
# firewall-cmd --info-policy podmanToAny podmanToAny (active) ... target: REJECT ingress-zones: podman egress-zones: ANY services: dhcp dns https ...
4.4. 设置策略对象的默认目标 复制链接链接已复制到粘贴板!
您可以为策略指定 --set-target 选项。可用的目标如下:
-
ACCEPT- 接受数据包 -
DROP- 丢弃不需要的数据包 -
REJECT- 拒绝不需要的数据包,并带有 ICMP 回复 CONTINUE(默认)- 数据包将遵循以下策略和区域中的规则。# firewall-cmd --permanent --policy mypolicy --set-target CONTINUE
验证
验证有关策略的信息
# firewall-cmd --info-policy mypolicy
第 5 章 使用 firewalld 配置 NAT 复制链接链接已复制到粘贴板!
使用 firewalld,您可以配置以下网络地址转换(NAT)类型:
- 伪装
- 目标 NAT(DNAT)
- 重定向
5.1. 网络地址转换类型 复制链接链接已复制到粘贴板!
这些是不同的网络地址转换(NAT)类型:
- 伪装
使用以上 NAT 类型之一更改数据包的源 IP 地址。例如,互联网服务提供商(ISP)不会路由私有 IP 范围,如
10.0.0.0/8。如果您在网络中使用私有 IP 范围,用户应该能够访问互联网上的服务器,请将来自这些范围的数据包的源 IP 地址映射为公共 IP 地址。伪装自动使用传出接口的 IP 地址。因此,如果传出接口使用了动态 IP 地址,则使用伪装。
- 目标 NAT(DNAT)
- 使用此 NAT 类型重写传入数据包的目标地址和端口。例如,如果您的 Web 服务器使用来自私有 IP 范围的 IP 地址,因此无法直接从互联网访问,您可以在路由器上设置 DNAT 规则,来将传入的流量重定向到此服务器。
- 重定向
- 这个类型是 DNAT 的一种特殊情况,其将数据包重定向到本地计算机上的不同端口。例如,如果服务运行在与其标准端口不同的端口上,您可以将传入的流量从标准端口重定向到此特定端口。
5.2. 配置 IP 地址伪装 复制链接链接已复制到粘贴板!
您可以在系统上启用 IP 伪装。在访问互联网时,IP 伪装会隐藏网关后面的单个机器。
流程
要检查是否启用了 IP 伪装(例如,对于
external区),以root用户身份输入以下命令:# firewall-cmd --zone=external --query-masquerade如果已启用,命令将会打印
yes,且退出状态为0。否则,将打印no,且退出状态为1。如果省略了zone,则将使用默认区。要启用 IP 伪装,请以
root用户身份输入以下命令:# firewall-cmd --zone=external --add-masquerade-
要使此设置持久,请将
--permanent选项传给命令。 要禁用 IP 伪装,请以
root身份输入以下命令:# firewall-cmd --zone=external --remove-masquerade要使此设置永久生效,请将
--permanent选项传给命令。
5.3. 使用 DNAT 转发传入的 HTTP 流量 复制链接链接已复制到粘贴板!
您可以使用目标网络地址转换(DNAT)将传入的流量从一个目标地址和端口定向到另一个目标地址和端口。通常,这对于将来自外部网络接口的传入请求重定向到特定的内部服务器或服务非常有用。
先决条件
-
firewalld服务在运行。
流程
转发传入的 HTTP 流量:
# firewall-cmd --zone=public --add-forward-port=port=80:proto=tcp:toaddr=198.51.100.10:toport=8080 --permanent之前的命令使用以下设置定义 DNAT 规则:
-
--zone=public- 您为其配置 DNAT 规则的防火墙区域。您可以将其调整到您需要的任何区域。 -
--add-forward-port- 指示您正在添加端口转发规则的选项。 -
port=80- 外部目标端口。 -
proto=tcp- 表示您转发 TCP 流量的协议。 -
toaddr=198.51.100.10- 目标 IP 地址。 -
toport=8080- 内部服务器的目标端口。 -
--permanent- 使 DNAT 规则在重启后保持不变的选项。
-
重新载入防火墙配置以应用更改:
# firewall-cmd --reload
验证
验证您使用的用于防火墙区域的 DNAT 规则:
# firewall-cmd --list-forward-ports --zone=public port=80:proto=tcp:toport=8080:toaddr=198.51.100.10或者,查看相应的 XML 配置文件:
# cat /etc/firewalld/zones/public.xml <?xml version="1.0" encoding="utf-8"?> <zone> <short>Public</short> <description>For use in public areas. You do not trust the other computers on networks to not harm your computer. Only selected incoming connections are accepted.</description> <service name="ssh"/> <service name="dhcpv6-client"/> <service name="cockpit"/> <forward-port port="80" protocol="tcp" to-port="8080" to-addr="198.51.100.10"/> <forward/> </zone>
5.4. 将来自非标准端口的流量重定向,以使 Web 服务在标准端口上可访问 复制链接链接已复制到粘贴板!
您可以使用重定向机制使在非标准端口上内部运行的 Web 服务可访问,而无需用户在 URL 中指定端口。因此,URL 更简单,并提供更好的浏览体验,而非标准端口仍在内部或用于特定的要求。
先决条件
-
firewalld服务在运行。
流程
创建 NAT 重定向规则:
# firewall-cmd --zone=public --add-forward-port=port=<standard_port>:proto=tcp:toport=<non_standard_port> --permanent之前的命令使用以下设置定义 NAT 重定向规则:
-
--zone=public- 您为其配置规则的防火墙区域。您可以将其调整到您需要的任何区域。 -
--add-forward-port=port=<non_standard_port>- 指示您正在使用最初接收传入流量的源端口添加端口转发(重定向)规则。 -
proto=tcp- 表示您重定向 TCP 流量的协议。 -
toport=<standard_port>- 目标端口,在源端口上收到传入流量后,应将其重定向到的端口。 -
--permanent- 使规则在重启后保持不变的选项。
-
重新载入防火墙配置以应用更改:
# firewall-cmd --reload
验证
验证您使用的防火墙区域的重定向规则:
# firewall-cmd --list-forward-ports port=8080:proto=tcp:toport=80:toaddr=或者,查看相应的 XML 配置文件:
# cat /etc/firewalld/zones/public.xml <?xml version="1.0" encoding="utf-8"?> <zone> <short>Public</short> <description>For use in public areas. You do not trust the other computers on networks to not harm your computer. Only selected incoming connections are accepted.</description> <service name="ssh"/> <service name="dhcpv6-client"/> <service name="cockpit"/> <forward-port port="8080" protocol="tcp" to-port="80"/> <forward/> </zone>
第 6 章 丰富规则的优先级 复制链接链接已复制到粘贴板!
富规则提供了一种更高级且更灵活的方法来定义防火墙规则。当服务、端口等服务不足以表达复杂的防火墙规则时,富规则特别有用。
富规则背后的概念:
- 粒度和灵活性
- 您可以根据更具体的标准为网络流量定义详细的条件。
- 规则结构
富规则由一个系列(IPv4 或 IPv6)组成,后跟条件和操作。
rule family="ipv4|ipv6" [conditions] [actions]- conditions
- 它们允许富规则仅在某些条件满足时才应用。
- 操作
- 您可以定义对符合条件的网络流量发生什么。
- 组合多个条件
- 您可以创建更具体和更复杂的过滤。
- 分层控制和可重复使用
- 您可以将丰富的规则与其他防火墙机制(如区域或服务)相结合。
默认情况下,富规则是根据其规则操作进行组织的。例如,deny 规则优先于 allow 规则。富规则中的 priority 参数可让管理员对富规则及其执行顺序进行精细的控制。在使用 priority 参数时,规则首先按其优先级值以升序排序。当更多的规则有同样的 优先级 时,其顺序是由规则行动决定的,如果行动也相同,则顺序可以是未定义。
6.1. priority 参数如何将规则组织到不同的链 复制链接链接已复制到粘贴板!
您可以在富规则中将 priority 参数设置为 -32768 和 32767 之间的任意数,较低的数值具有较高的优先级。
firewalld 服务根据优先级值将规则组织到不同的链中:
-
优先级低于 0:规则被重定向到带有
_pre后缀的链中。 -
优先级高于 0:规则被重定向到带有
_post后缀的链中。 -
优先级等于 0:根据操作,规则会被重定向到带有
_log、_deny或_allow操作的链中。
在这些子链中,firewalld 根据其优先级值对规则进行排序。
如需更多信息,请参阅您系统上的手册页 'firewalld.richlanguage (5)。
6.2. 设置丰富的规则的优先级 复制链接链接已复制到粘贴板!
以下是如何创建一条富规则的示例,该规则使用 priority 参数来记录其他规则不允许或拒绝的所有流量。您可以使用此规则标记意非预期的流量。
流程
添加一个带有非常低优先级的丰富规则来记录未由其他规则匹配的所有流量:
# firewall-cmd --add-rich-rule='rule priority=32767 log prefix="UNEXPECTED: " limit value="5/m"'这个命令还将日志条目数量限制为每分钟
5条。详情请查看您系统上的"firewalld.richlanguage (5)手册页。
验证
显示命令在上一步中创建的
nftables规则:# nft list chain inet firewalld filter_IN_public_post table inet firewalld { chain filter_IN_public_post { log prefix "UNEXPECTED: " limit rate 5/minute } }
第 7 章 启用 firewalld 区域中不同接口或源之间的流量转发 复制链接链接已复制到粘贴板!
区域内转发是一个 firewalld 功能,它允许流量在 firewalld 区域内的接口或源间转发。
7.1. 区域内转发和默认目标设置为 ACCEPT 的区域间的区别 复制链接链接已复制到粘贴板!
启用区域内转发后,单个 firewalld 区域中的流量可以从一个接口或源流到另一个接口或源。区指定接口和源的信任级别。如果信任级别相同,流量会保持在同一区域内。
在 firewalld 的默认区域中启用区域内转发仅适用于添加到当前默认区域的接口和源。
firewalld 使用不同的区域管理传入和传出流量。每个区域都有自己的一组规则和行为。例如,trusted 区域默认允许所有转发的流量。
其他区域可以有不同的默认行为。在标准区域中,当区域的目标被设置为 default 时,转发的流量通常默认被丢弃。
要控制流量如何在区域内的不同接口或源之间转发,请确保您理解并相应地配置了区域的目标。
7.2. 使用区内转发来在以太网和 Wi-Fi 网络间转发流量 复制链接链接已复制到粘贴板!
您可以使用区内转发来在同一 firewalld 区内的接口和源之间转发流量。此功能带来以下好处:
-
有线设备和无线设备间的无缝连接(您可以在连接到
enp1s0的以太网网络和连接到wlp0s20的 Wi-Fi 网络之间转发流量) - 支持灵活的工作环境
- 可被网络中的多个设备或用户访问和使用的共享资源(如打印机、数据库、网络连接的存储等)
- 高效的内部网络(如顺畅通信、减少的延迟、资源可访问性等)
您可以为单个 firewalld 区域启用此功能。
详情请查看您系统上的 firewalld.zones (5) 手册页。
流程
在内核中启用数据包转发:
# echo "net.ipv4.ip_forward=1" > /etc/sysctl.d/95-IPv4-forwarding.conf # sysctl -p /etc/sysctl.d/95-IPv4-forwarding.conf确保您要在其间启用区域内转发的接口只分配到
internal区域:# firewall-cmd --get-active-zones如果接口当前被分配给了不是
internal的区,请重新分配它:# firewall-cmd --zone=internal --change-interface=interface_name --permanent将
enp1s0和wlp0s20接口添加到internal区:# firewall-cmd --zone=internal --add-interface=enp1s0 --add-interface=wlp0s20启用区域内部转发:
# firewall-cmd --zone=internal --add-forward
验证
以下验证要求 nmap-ncat 软件包已安装在两个主机上。
-
登录到与您启用了区域转发的主机的
enp1s0接口位于同一网络的主机。 使用
ncat启动 echo 服务来测试连接:# ncat -e /usr/bin/cat -l 12345-
登录到与
wlp0s20接口在同一网络的主机。 连接到在与
enp1s0在同一网络的主机上运行的 echo 服务器:# ncat <other_host> 12345- 输入一些内容并按 。验证文本是否被发送回来。
第 8 章 使用 RHEL 系统角色配置 firewalld 复制链接链接已复制到粘贴板!
RHEL 系统角色是 Ansible 自动化工具的一组内容。此内容与 Ansible 自动化工具一起提供一个一致的配置接口,来一次远程管理多个系统。
rhel-system-roles 软件包包含 rhel-system-roles.firewall RHEL 系统角色。此角色是为了自动化 firewalld 服务的配置而引入的。
使用 firewall RHEL 系统角色,您可以配置许多不同的 firewalld 参数,例如:
- 区域
- 应允许哪些数据包的服务
- 授予、拒绝或丢弃到端口的流量访问
- 区域的端口或端口范围的转发
8.1. 使用 firewall RHEL 系统角色重置 firewalld 设置 复制链接链接已复制到粘贴板!
随着时间的推移,对防火墙配置的更新可能会积累到一定程度,从而造成意外的安全风险。使用 firewall RHEL 系统角色,您可以以自动的方式将 firewalld 设置重置为其默认状态。这样,您可以有效地删除任何无意的或不安全的防火墙规则,并简化其管理。
先决条件
- 您已准备好控制节点和受管节点
- 以可在受管主机上运行 playbook 的用户登录到控制节点。
-
您用于连接到受管节点的帐户对它们具有
sudo权限。
流程
创建一个包含以下内容的 playbook 文件,如
~/playbook.yml:--- - name: Reset firewalld example hosts: managed-node-01.example.com tasks: - name: Reset firewalld ansible.builtin.include_role: name: rhel-system-roles.firewall vars: firewall: - previous: replaced示例 playbook 中指定的设置包括如下:
previous: replaced删除所有现有的用户定义的设置,并将
firewalld设置重置为默认值。如果将previous:replaced参数与其他设置相结合,则firewall角色会在应用新设置前删除所有现有设置。有关 playbook 中使用的所有变量的详情,请查看控制节点上的
/usr/share/ansible/roles/rhel-system-roles.firewall/README.md文件。
验证 playbook 语法:
$ ansible-playbook --syntax-check ~/playbook.yml请注意,这个命令只验证语法,不能防止错误的、但有效的配置。
运行 playbook:
$ ansible-playbook ~/playbook.yml
验证
在控制节点上运行这个命令,来远程检查受管节点上的所有防火墙配置是否被重置为其默认值:
# ansible managed-node-01.example.com -m ansible.builtin.command -a 'firewall-cmd --list-all-zones'
您可以使用 firewall RHEL 系统角色远程配置将传入流量从一个本地端口转发到另一个本地端口。
例如,如果您有一个环境,其中多个服务在同一台机器上共存,且需要同样的默认端口,则可能会出现端口冲突。这些冲突可能会破坏服务并导致停机。使用 firewall RHEL 系统角色,您可以高效地将流量转发到替代端口,以确保您的服务可以同时运行,而无需修改其配置。
先决条件
- 您已准备好控制节点和受管节点
- 以可在受管主机上运行 playbook 的用户登录到控制节点。
-
您用于连接到受管节点的帐户对它们具有
sudo权限。
流程
创建一个包含以下内容的 playbook 文件,如
~/playbook.yml:--- - name: Configure firewalld hosts: managed-node-01.example.com tasks: - name: Forward incoming traffic on port 8080 to 443 ansible.builtin.include_role: name: rhel-system-roles.firewall vars: firewall: - forward_port: 8080/tcp;443; state: enabled runtime: true permanent: true示例 playbook 中指定的设置包括如下:
forward_port: 8080/tcp;443- 使用 TCP 协议进入到本地端口 8080 的流量被转发到端口 443。
runtime: true启用运行时配置中的更改。默认值被设置为
true。有关 playbook 中使用的所有变量的详情,请查看控制节点上的
/usr/share/ansible/roles/rhel-system-roles.firewall/README.md文件。
验证 playbook 语法:
$ ansible-playbook --syntax-check ~/playbook.yml请注意,这个命令只验证语法,不能防止错误的、但有效的配置。
运行 playbook:
$ ansible-playbook ~/playbook.yml
验证
在控制节点上,运行以下命令来远程检查受管节点上的转发端口:
# ansible managed-node-01.example.com -m ansible.builtin.command -a 'firewall-cmd --list-forward-ports' managed-node-01.example.com | CHANGED | rc=0 >> port=8080:proto=tcp:toport=443:toaddr=
8.3. 使用 firewall RHEL 系统角色配置 firewalld DMZ 区域 复制链接链接已复制到粘贴板!
作为系统管理员,您可以使用 firewall RHEL 系统角色在 enp1s0 接口上配置一个 dmz 区域,以允许到区域的 HTTPS 流量。这样,您可以让外部用户访问您的 web 服务器。
先决条件
- 您已准备好控制节点和受管节点
- 以可在受管主机上运行 playbook 的用户登录到控制节点。
-
您用于连接到受管节点的帐户对它们具有
sudo权限。
流程
创建一个包含以下内容的 playbook 文件,如
~/playbook.yml:--- - name: Configure firewalld hosts: managed-node-01.example.com tasks: - name: Creating a DMZ with access to HTTPS port and masquerading for hosts in DMZ ansible.builtin.include_role: name: rhel-system-roles.firewall vars: firewall: - zone: dmz interface: enp1s0 service: https state: enabled runtime: true permanent: true有关 playbook 中使用的所有变量的详情,请查看控制节点上的
/usr/share/ansible/roles/rhel-system-roles.firewall/README.md文件。验证 playbook 语法:
$ ansible-playbook --syntax-check ~/playbook.yml请注意,这个命令只验证语法,不能防止错误的、但有效的配置。
运行 playbook:
$ ansible-playbook ~/playbook.yml
验证
在控制节点上,运行以下命令来远程检查有关受管节点上
dmz区域的信息:# ansible managed-node-01.example.com -m ansible.builtin.command -a 'firewall-cmd --zone=dmz --list-all' managed-node-01.example.com | CHANGED | rc=0 >> dmz (active) target: default icmp-block-inversion: no interfaces: enp1s0 sources: services: https ssh ports: protocols: forward: no masquerade: no forward-ports: source-ports: icmp-blocks:
第 9 章 加速 firewalld 转发流量 复制链接链接已复制到粘贴板!
firewalld 服务现在支持流表功能,这可以提高转发流量的性能。机制使用内核连接跟踪来绕过大多数网络堆栈。因此,您可以获得已建立连接的加速数据包。
flowtable 机制有以下功能:
- 使用连接跟踪来绕过典型的数据包转发路径。
- 避免通过绕过经典数据包处理来重新访问路由表。
- 只适用于 TCP 和 UDP 协议。
- 硬件独立软件快速路径。
流程
启用流表功能:
# sed -i 's/^NftablesFlowtable=.*/NftablesFlowtable=enp1s0 enp2s0/' /etc/firewalld/firewalld.conf命令在
/etc/firewalld/firewalld.conf文件中将NftablesFlowtable选项(默认为off)设置为您要启用的流表的网络接口的列表。在本例中,NftablesFlowtable=enp1s0 enp2s0。重新载入防火墙配置,以使更改生效:
# firewall-cmd --reload
第 10 章 nftables 入门 复制链接链接已复制到粘贴板!
如果您的场景不在 firewalld 涵盖的典型数据包过滤情况中,或者您希望完全控制规则,您可以使用 nftables 框架。
10.1. 什么是 nftables 复制链接链接已复制到粘贴板!
nftables 框架对数据包进行分类,它是 iptables、ip6tables、arptables、ebtables 和 ipset 工具的继承者。与之前的数据包过滤工具相比,它在方便、特性和性能方面提供了大量改进,最重要的是:
- 内置查找表而不是线性处理
-
IPv4和IPv6协议的单一框架 - 通过事务,而不是获取、更新和存储整个规则集来更新内核规则集
-
支持在规则集(
nftrace)和监控追踪事件(nft)中调试和追踪 - 更加一致和压缩的语法,没有特定协议的扩展
- 用于第三方应用程序的 Netlink API
nftables 框架使用表来存储链。链包含执行动作的独立规则。nft 工具替换了之前数据包过滤框架中的所有工具。您可以使用 libnftables 库,通过 libnftnl 库与 nftables Netlink API 进行低级交互。
要显示规则集变化的影响,请使用 nft list ruleset 命令。要清除内核规则集,请使用 nft flush ruleset 命令。请注意,这也可能会影响 iptables-nft 命令安装的规则集,因为它使用了同样的内核基础架构。
10.2. 何时使用 firewalld 或 nftables 复制链接链接已复制到粘贴板!
在 Red Hat Enterprise Linux 上,您可以根据您的场景使用以下数据包过滤工具:
-
firewalld:firewalld工具简化了常见用例的防火墙配置。 -
nftables:使用nftables工具来设置复杂和性能关键的防火墙,如用于整个网络。
要防止不同的与防火墙相关的服务(firewalld 或 nftables)相互影响,请在 RHEL 主机上只运行一个,并禁用其他服务。
10.3. nftables 框架中的概念 复制链接链接已复制到粘贴板!
与 iptables 框架相比,nftables 提供了更现代化、更高效且更灵活的替代方案。与 iptables 相比,nftables 框架提供了高级功能和改进,从而简化了规则管理,并增强了性能。这使得 nftables 成为复杂和高性能网络环境的一种现代替代方案。
- 表和命名空间
-
在
nftables中,表代表组织单元或命名空间,其将相关的防火墙链、集合、流表和其他对象分组在一起。在nftables中,表提供了一种更灵活的方法来构建防火墙规则和相关组件。在iptables中,表被更严格地定义,并具有特定用途。 - 表系列
-
nftables中的每个表都与特定的系列(ip、ip6、inet、arp、bridge或netdev)关联。此关联决定了表可以处理哪些数据包。例如,ip系列中的一个表只处理 IPv4 数据包。另一方面,inet是表系列的一个特例。它提供了一个跨协议的统一方法,因为 IPv4 数据包和 IPv6 数据包它都可以处理。特殊表系列的另一种情况是netdev,因为它用于直接应用到网络设备的规则,从而在设备级别上启用过滤。 - 基本链
nftables中的基本链是数据包处理管道中高度可配置的入口点,允许用户指定以下内容:- 链的类型,如 "filter"
- 数据包处理路径中的钩子点,例如 "input", "output", "forward"
- 链的优先级
通过这种灵活性,可以精确控制规则在通过网络堆栈时何时及如何应用到数据包。链的一种特殊情况是
route链,其用于根据数据包头,影响内核所做的路由决策。- 用于规则处理的虚拟机
nftables框架使用一个内部虚拟机来处理规则。此虚拟机执行与汇编语言操作类似的指令(将数据加载到寄存器,执行比较等)。这种机制可以实现高度灵活和有效的规则处理。nftables中的增强功能可以作为该虚拟机的新指令引入。这通常需要一个新的内核模块,以及对libnftnl库和nft命令行工具的更新。或者,您可以通过将现有指令以一种创新的方式结合来引进新功能,而无需进行内核修改。
nftables规则的语法反映了底层虚拟机的灵活性。例如,如果 TCP 目的地端口为 22,规则meta mark set tcp dport map { 22: 1, 80: 2 }将数据包的防火墙标记设置为 1 ,如果端口为 80,则设置为 2。这展示了如何简洁地表达复杂的逻辑。- 复杂的过滤和判决图
nftables框架集成并扩展了ipset工具的功能,其在iptables中用于对 IP 地址、端口、其他数据类型、最重要的是其中的组合进行批量匹配。此集成使您更容易直接管理nftables中的大型和动态的数据集。接下来,nftables原生支持根据任何数据类型的多个值或范围匹配数据包,这增强了其处理复杂过滤要求的能力。使用nftables,您可以操作数据包中的任何字段。在
nftables中,集合可以是命名的或匿名的。命名的集合可被多个规则引用和动态修改。匿名集合在规则内被内联定义,并且是不可变的。集合可以包含是不同类型组合的元素,如 IP 地址和端口号对。此功能在匹配复杂标准方面提供了更大的灵活性。要管理集合,内核可以根据特定要求(性能、内存效率等)选择最合适的后端。集合也可以作为具有键值对的映射。值部分可用作数据点(写入数据包头的值),或者作为要跳到的判决或链。这可启用复杂和动态的规则行为,称为"判决映射"。- 灵活的规则格式
nftables规则的结构非常简单。条件和操作从左到右顺序应用。这种直观的格式简化了规则创建和故障排除。规则中的条件在逻辑上连接(使用 AND 运算符)在一起,这意味着要使规则匹配,所有条件都必须被评估为 "true" 。如果有任何条件失败,评估将移到下一个规则。
nftables中的操作可以是最终的操作,如drop或accept,这停止对数据包的进一步规则处理。非终端操作,如counter log meta mark set 0x3,执行特定的任务(计算数据包、日志记录、设置标记等),但允许评估后续规则。
第 11 章 创建和管理 nftables 表、链和规则 复制链接链接已复制到粘贴板!
您可以显示 nftables 规则集并管理它们。
11.1. nftables 表的基础知识 复制链接链接已复制到粘贴板!
nftables 中的表是一个包含链、规则、集合和其他对象集合的名字空间。
每个表都必须分配一个地址系列。地址系列定义此表处理的数据包类型。在创建表时,您可以设置以下地址系列之一:
-
ip:仅匹配 IPv4 数据包。如果没有指定地址系列,这是默认设置。 -
ip6:仅匹配 IPv6 数据包。 -
inet:匹配 IPv4 和 IPv6 数据包。 -
arp:匹配 IPv4 地址解析协议(ARP)数据包。 -
bridge:匹配通过网桥设备的数据包。 -
netdev:匹配来自入口的数据包。
如果要添加表,所使用的格式取决于您的防火墙脚本:
在原生语法的脚本中,使用:
table <table_address_family> <table_name> { }在 shell 脚本中,使用:
nft add table <table_address_family> <table_name>
11.2. nftables 链的基础知识 复制链接链接已复制到粘贴板!
表包含链,而链又是规则的容器。存在以下两种链类型:
- Base chain :基本链充当来自网络堆栈的数据包的入口点。
-
Regular chain :您可以使用常规链作为
jump目标,来更好地组织规则。
如果要向表中添加基本链,所使用的格式取决于您的防火墙脚本:
在原生语法的脚本中,使用:
table <table_address_family> <table_name> { chain <chain_name> { type <type> hook <hook> priority <priority> policy <policy> ; } }在 shell 脚本中,使用:
nft add chain <table_address_family> <table_name> <chain_name> { type <type> hook <hook> priority <priority> \; policy <policy> \; }为了避免 shell 将分号解释为命令的结尾,请将
\转义字符放在分号前面。
这两个示例都创建 基本链。要创建 常规链,请不要在大括号中设置任何参数。
链类型:
以下是链类型以及您可以使用的地址系列和钩子的概述:
| 类型 | 地址系列 | 钩子 | 描述 |
|---|---|---|---|
|
| all | all | 标准链类型 |
|
|
|
| 这个类型的链根据连接跟踪条目执行原生地址转换。只有连接的第一个数据包会通过。 |
|
|
|
| 如果 IP 头的相关部分已更改,则接受的遍历此链类型的数据包会导致新的路由查找。 |
链优先级:
priority 参数指定数据包遍历具有相同 hook 值的链的顺序。您可以将此参数设为整数值,或使用标准优先级名称。
以下列表是标准优先级名称及其数字值的一个概述,以及您可以使用它们的哪个地址系列和钩子:
| 文本值 | 数字值 | 地址系列 | 钩子 |
|---|---|---|---|
|
|
|
| all |
|
|
|
| all |
|
|
|
|
|
|
|
|
| |
|
|
|
| all |
|
|
| all | |
|
|
|
| all |
|
|
|
|
|
|
|
|
| |
|
|
|
|
|
链策略:
如果此链中的规则没有指定任何操作,则链策略定义 nftables 是否应该接受或丢弃数据包。您可以在链中设置以下策略之一:
-
accept(默认) -
drop
11.3. nftables 规则的基础知识 复制链接链接已复制到粘贴板!
规则定义对通过包含此规则的链的数据包执行的操作。如果规则还包含匹配表达式,则 nftables 仅在所有之前的表达式都应用时才执行操作。
如果要在链中添加一条规则,所使用的格式取决于您的防火墙脚本:
在原生语法的脚本中,使用:
table <table_address_family> <table_name> { chain <chain_name> { type <type> hook <hook> priority <priority> ; policy <policy> ; <rule> } }在 shell 脚本中,使用:
nft add rule <table_address_family> <table_name> <chain_name> <rule>此 shell 命令在链的末尾附加新规则。如果要在链的开头添加一条规则,请使用
nft insert命令而不是nft add。
11.4. 使用 nft 命令管理表、链和规则 复制链接链接已复制到粘贴板!
要在命令行上或 shell 脚本中管理 nftables 防火墙,请使用 nft 工具。
此流程中的命令不代表典型的工作流,且没有被优化。此流程只演示了如何使用 nft 命令来管理表、链和规则。
流程
创建一个带有
inet地址系列的名为nftables_svc的表,以便表可以处理 IPv4 和 IPv6 数据包:# nft add table inet nftables_svc将处理传入网络流量的、名为
INPUT的基本链添加到inet nftables_svc表中:# nft add chain inet nftables_svc INPUT { type filter hook input priority filter \; policy accept \; }为了避免 shell 将分号解释为命令的结尾,请使用
\字符转义分号。向
INPUT链添加规则。例如,允许端口 22 和 443 上的传入 TCP 流量,并作为INPUT链的最后一条规则,拒绝其他传入的流量,并伴有互联网控制消息协议(ICMP)端口无法访问的消息:# nft add rule inet nftables_svc INPUT tcp dport 22 accept # nft add rule inet nftables_svc INPUT tcp dport 443 accept # nft add rule inet nftables_svc INPUT reject with icmpx type port-unreachable如果您输入
nft add rule命令,则nft会将按与运行命令相同的顺序将规则添加到链。显示包括句柄的当前规则集:
# nft -a list table inet nftables_svc table inet nftables_svc { # handle 13 chain INPUT { # handle 1 type filter hook input priority filter; policy accept; tcp dport 22 accept # handle 2 tcp dport 443 accept # handle 3 reject # handle 4 } }在句柄为 3 的现有规则前面插入一条规则。例如,要插入一个允许端口 636 上 TCP 流量的规则,请输入:
# nft insert rule inet nftables_svc INPUT handle 3 tcp dport 636 accept在句柄为 3 的现有规则后面附加一条规则。例如,要插入一个允许端口 80 上 TCP 流量的规则,请输入:
# nft add rule inet nftables_svc INPUT handle 3 tcp dport 80 accept再次显示带有 handle 的规则集。验证是否后添加的规则已添加到指定位置:
# nft -a list table inet nftables_svc table inet nftables_svc { # handle 13 chain INPUT { # handle 1 type filter hook input priority filter; policy accept; tcp dport 22 accept # handle 2 tcp dport 636 accept # handle 5 tcp dport 443 accept # handle 3 tcp dport 80 accept # handle 6 reject # handle 4 } }删除 handle 为 6 的规则:
# nft delete rule inet nftables_svc INPUT handle 6要删除规则,您必须指定 handle。
显示规则集,并验证删除的规则是否不再存在:
# nft -a list table inet nftables_svc table inet nftables_svc { # handle 13 chain INPUT { # handle 1 type filter hook input priority filter; policy accept; tcp dport 22 accept # handle 2 tcp dport 636 accept # handle 5 tcp dport 443 accept # handle 3 reject # handle 4 } }从
INPUT链中删除所有剩余的规则:# nft flush chain inet nftables_svc INPUT显示规则集,并验证
INPUT链是否为空:# nft list table inet nftables_svc table inet nftables_svc { chain INPUT { type filter hook input priority filter; policy accept } }删除
INPUT链:# nft delete chain inet nftables_svc INPUT您还可以使用此命令删除仍然包含规则的链。
显示规则集,并验证
INPUT链是否已被删除:# nft list table inet nftables_svc table inet nftables_svc { }删除
nftables_svc表:# nft delete table inet nftables_svc您还可以使用此命令删除仍然包含链的表。
注意要删除整个规则集,请使用
nft flush ruleset命令,而不是在单独的命令中手动删除所有规则、链和表。
第 12 章 使用 nftables 配置 NAT 复制链接链接已复制到粘贴板!
有了 nftables ,您就可以配置以下网络地址转换(NAT)类型:
- 伪装
- 源 NAT(SNAT)
- 目标 NAT(DNAT)
- 重定向
12.1. NAT 类型 复制链接链接已复制到粘贴板!
这些是不同的网络地址转换(NAT)类型:
- 伪装和源 NAT(SNAT)
使用以上 NAT 类型之一更改数据包的源 IP 地址。例如,互联网服务提供商(ISP)不会路由私有 IP 范围,如
10.0.0.0/8。如果您在网络中使用私有 IP 范围,用户应该能够访问互联网上的服务器,请将来自这些范围的数据包的源 IP 地址映射为公共 IP 地址。伪装和 SNAT 相互类似。不同之处是:
- 伪装自动使用传出接口的 IP 地址。因此,如果传出接口使用了动态 IP 地址,则使用伪装。
- SNAT 将数据包的源 IP 地址设置为指定的 IP 地址,且不会动态查找传出接口的 IP 地址。因此,SNAT 要比伪装更快。如果传出接口使用了固定 IP 地址,则使用 SNAT。
- 目标 NAT(DNAT)
- 使用此 NAT 类型重写传入数据包的目标地址和端口。例如,如果您的 Web 服务器使用来自私有 IP 范围的 IP 地址,因此无法直接从互联网访问,您可以在路由器上设置 DNAT 规则,来将传入的流量重定向到此服务器。
- 重定向
- 这个类型是 IDT 的特殊示例,它根据链 hook 将数据包重定向到本地机器。例如,如果服务运行在与其标准端口不同的端口上,您可以将传入的流量从标准端口重定向到此特定端口。
12.2. 使用 nftables 配置伪装 复制链接链接已复制到粘贴板!
伪装使路由器动态地更改通过接口到接口 IP 地址发送的数据包的源 IP。这意味着,如果接口被分配了一个新 IP,nftables 会在替换源 IP 时自动使用新的 IP。
将通过 ens3 接口离开主机的数据包源 IP 替换为 ens3 上设置的 IP。
流程
创建一个表:
# nft add table nat将
postrouting链添加到表中:# nft add chain nat postrouting { type nat hook postrouting priority 100 \; }向
postrouting链中添加一条规则,来匹配ens3接口上传出的数据包:# nft add rule nat postrouting oifname "ens3" masquerade
您只能在 iifname 和 oifname 参数中使用实际的接口名称,不支持替代名称(altname)。
12.3. 使用 nftables 配置源 NAT 复制链接链接已复制到粘贴板!
在路由器中,源 NAT(SNAT)可让您将通过接口发送的数据包 IP 改为专门的 IP 地址。然后,路由器会替换传出数据包的源 IP。
流程
创建一个表:
# nft add table nat将
postrouting链添加到表中:# nft add chain nat postrouting { type nat hook postrouting priority 100 \; }向
postrouting链中添加一条规则,该规则将使用192.0.2.1替换通过ens3的传出数据包的源 IP :# nft add rule nat postrouting oifname "ens3" snat to 192.0.2.1
12.4. 使用 nftables 配置目标 NAT 复制链接链接已复制到粘贴板!
目标 NAT (DNAT)可让您将路由器上的流量重定向到无法直接从互联网访问的主机。
例如,有了 DNAT,路由器将发送给端口 80 和 443 的传入流量重定向到 IP 地址为 192.0.2.1 的 Web 服务器。
流程
创建一个表:
# nft add table nat向表中添加
prerouting和postrouting链:# nft -- add chain nat prerouting { type nat hook prerouting priority -100 \; } # nft add chain nat postrouting { type nat hook postrouting priority 100 \; }请注意,您必须将
--选项传递给nft命令,以防止 shell 将负优先级值解释为nft命令的选项。向
prerouting链中添加一条规则,该规则将路由器的ens3接口上端口80和443的传入流量重定向到 IP 地址为192.0.2.1的 web 服务器:# nft add rule nat prerouting iifname ens3 tcp dport { 80, 443 } dnat to 192.0.2.1根据您的环境,添加 SNAT 或伪装规则,将从 Web 服务器返回的数据包的源地址改为发送者:
如果
ens3接口使用动态 IP 地址,请添加一条伪装规则:# nft add rule nat postrouting oifname "ens3" masquerade如果
ens3接口使用静态 IP 地址,请添加一条 SNAT 规则。例如,如果ens3使用198.51.100.1IP 地址:# nft add rule nat postrouting oifname "ens3" snat to 198.51.100.1
启用数据包转发:
# echo "net.ipv4.ip_forward=1" > /etc/sysctl.d/95-IPv4-forwarding.conf # sysctl -p /etc/sysctl.d/95-IPv4-forwarding.conf
12.5. 使用 nftables 配置重定向 复制链接链接已复制到粘贴板!
重定向 功能是目标网络地址转换(DNAT)的一种特殊情况,它根据链 hook 将数据包重定向到本地计算机。
例如,您可以将发送到本地主机端口 22 的流量重定向到端口 2222。
流程
创建一个表:
# nft add table nat向表中添加
prerouting链:# nft -- add chain nat prerouting { type nat hook prerouting priority -100 \; }请注意,您必须将
--选项传递给nft命令,以防止 shell 将负优先级值解释为nft命令的选项。向
prerouting链中添加一条规则,其将端口22上的传入流量重定向到端口2222:# nft add rule nat prerouting tcp dport 22 redirect to 2222
第 13 章 编写和执行 nftables 脚本 复制链接链接已复制到粘贴板!
使用 nftables 框架的主要优点是脚本的执行是原子的。这意味着,系统会应用整个脚本,或者在出现错误时防止执行。这样可保证防火墙始终处于一致状态。
另外,使用 nftables 脚本环境时,您可以:
- 添加评论
- 定义变量
- 包含其他规则集文件
安装 nftables 软件包时,RHEL 会自动在 /etc/nftables/ 目录中创建 *.nft 脚本。这些脚本包含为不同目的创建表和空链的命令。
13.1. 支持的 nftables 脚本格式 复制链接链接已复制到粘贴板!
您可以使用以下格式在 nftables 脚本环境中编写脚本:
与
nft list ruleset命令相同的格式显示规则集:#!/usr/sbin/nft -f # Flush the rule set flush ruleset table inet example_table { chain example_chain { # Chain for incoming packets that drops all packets that # are not explicitly allowed by any rule in this chain type filter hook input priority 0; policy drop; # Accept connections to port 22 (ssh) tcp dport ssh accept } }与
nft命令的语法相同:#!/usr/sbin/nft -f # Flush the rule set flush ruleset # Create a table add table inet example_table # Create a chain for incoming packets that drops all packets # that are not explicitly allowed by any rule in this chain add chain inet example_table example_chain { type filter hook input priority 0 ; policy drop ; } # Add a rule that accepts connections to port 22 (ssh) add rule inet example_table example_chain tcp dport ssh accept
13.2. 运行 nftables 脚本 复制链接链接已复制到粘贴板!
您可以通过将脚本传递给 nft 实用程序或直接执行脚本来运行 nftables 脚本。
流程
要通过将其传给
nft工具来运行nftables脚本,请输入:# nft -f /etc/nftables/<example_firewall_script>.nft要直接运行
nftables脚本:在进行这个时间时:
确保脚本以以下 shebang 序列开头:
#!/usr/sbin/nft -f重要如果省略了
-f参数,nft工具不会读取脚本,并显示Error: syntax error, unexpected newline, expecting string。可选:将脚本的所有者设为
root:# chown root /etc/nftables/<example_firewall_script>.nft使脚本可以被其所有者执行:
# chmod u+x /etc/nftables/<example_firewall_script>.nft
运行脚本:
# /etc/nftables/<example_firewall_script>.nft如果没有输出结果,系统将成功执行该脚本。
重要即使
nft成功地执行了脚本,在脚本中错误放置的规则、缺失的参数或其他问题都可能会导致防火墙的行为不符合预期。
详情请查看您系统上的 chown (1) 和 chmod (1) 手册页。
13.3. 使用 nftables 脚本中的注释 复制链接链接已复制到粘贴板!
nftables 脚本环境将 # 字符右侧的所有内容解释为行尾。
注释可在行首或命令旁边开始:
...
# Flush the rule set
flush ruleset
add table inet example_table # Create a table
...
13.4. 使用 nftables 脚本中的变量 复制链接链接已复制到粘贴板!
要在 nftables 脚本中定义一个变量,请使用 define 关键字。您可以在变量中存储单个值和匿名集合。对于更复杂的场景,请使用 set 或 verdict 映射。
- 只有一个值的变量
以下示例定义了一个名为
INET_DEV的变量,其值为enp1s0:define INET_DEV = enp1s0您可以通过输入
$符号后再输入变量名称来使用脚本中的变量:... add rule inet example_table example_chain iifname $INET_DEV tcp dport ssh accept ...- 包含匿名集合的变量
以下示例定义了一个包含匿名集合的变量:
define DNS_SERVERS = { 192.0.2.1, 192.0.2.2 }您可以通过在
$符号后跟变量名称来在脚本中使用变量:add rule inet example_table example_chain ip daddr $DNS_SERVERS accept注意当您在规则中使用大括号时具有特殊的语义,因为它们表示变量代表一个集合。
13.5. 在 nftables 脚本中包含文件 复制链接链接已复制到粘贴板!
在 nftables 脚本环境中,您可以使用 include 语句包含其他脚本。
如果您只指定一个没有绝对路径或相对路径的文件名,那么 nftables 将包含默认搜索路径中的文件,该搜索路径在 RHEL 上被设置为 /etc。
例 13.1. 包含默认搜索目录中的文件
从默认搜索目录中包含一个文件:
include "example.nft"
例 13.2. 包含目录中的所有 *.nft 文件
要包括所有存储在 /etc/nftables/rulesets/ 目录中、以 *.nft 结尾的文件:
include "/etc/nftables/rulesets/*.nft"
请注意,include 语句不匹配以点开头的文件。
详情请查看您系统上 nft (8) 手册页中的 Include files 部分。
13.6. 系统引导时自动载入 nftables 规则 复制链接链接已复制到粘贴板!
nftables systemd 服务加载包含在 /etc/sysconfig/nftables.conf 文件中的防火墙脚本。
先决条件
-
nftables脚本存储在/etc/nftables/目录中。
流程
编辑
/etc/sysconfig/nftables.conf文件。-
如果您使用
nftables软件包的安装修改了在/etc/nftables/中创建的*.nft脚本,请取消对这些脚本的include语句的注释。 如果您编写了新脚本,请添加
include语句以包含这些脚本。例如,要在nftables服务启动时加载/etc/nftables/example.nft脚本,请添加:include "/etc/nftables/example.nft"
-
如果您使用
可选:启动
nftables服务来加载防火墙规则,而无需重启系统:# systemctl start nftables启用
nftables服务。# systemctl enable nftables
第 14 章 使用 nftables 命令中的设置 复制链接链接已复制到粘贴板!
nftables 框架原生支持集合。您可以使用一个集合,例如,规则匹配多个 IP 地址、端口号、接口或其他匹配标准。
14.1. 在 nftables 中使用匿名集合 复制链接链接已复制到粘贴板!
匿名集合包含用逗号分开的值,如 { 22、80、443 },它们直接在规则中使用。您还可以将匿名集合用于 IP 地址以及任何其他匹配标准。
匿名集合的缺陷是,如果要更改集合,则需要替换规则。对于动态解决方案,使用命名集合,如 在 nftables 中使用命名集合 中所述。
先决条件
-
inet系列中的example_chain链和example_table表存在。
流程
例如,要向
example_table中的example_chain添加一条规则,其允许传入流量到端口22、80和443:# nft add rule inet example_table example_chain tcp dport { 22, 80, 443 } accept可选: 在
example_table中显示所有链及其规则:# nft list table inet example_table table inet example_table { chain example_chain { type filter hook input priority filter; policy accept; tcp dport { ssh, http, https } accept } }
14.2. 在 nftables 中使用命名集 复制链接链接已复制到粘贴板!
nftables 框架支持可变命名集合。命名集是您可以在表中的多个规则中使用的范围的一个列表。匿名集合的另外一个好处在于,您可以更新命名的集合而不必替换使用集合的规则。
当您创建一个命名集时,必须指定集合包含的元素类型。您可以设置以下类型:
-
包含 IPv4 地址或范围的集合的
ipv4_addr,如192.0.2.1或192.0.2.0/24。 -
包含 IPv6 地址或范围的集合的
ipv6_addr,如2001:db8:1::1或2001:db8:1::/64。 -
包含介质访问控制(MAC)地址列表的集合的
ether_addr,如52:54:00:6b:66:42。 -
包含互联网协议类型列表的集合的
inet_proto,如tcp。 -
包含互联网服务列表的集合的
inet_service,如ssh。 -
包含数据包标记列表的集合的
mark。数据包标记可以是任意正 32 位整数值(0到2147483647)。
先决条件
-
example_chain链和example_table表存在。
流程
创建一个空集。以下示例为 IPv4 地址创建了一个集合:
要创建可存储多个独立 IPv4 地址的集合:
# nft add set inet example_table example_set { type ipv4_addr \; }要创建可存储 IPv4 地址范围的集合:
# nft add set inet example_table example_set { type ipv4_addr \; flags interval \; }
重要要防止 shell 将分号解释为命令结尾,您必须使用反斜杠转义分号。
可选:创建使用集合的规则。例如,以下命令向
example_table中的example_chain中添加一条规则,该规则将丢弃example_set中来自 IPv4 地址的所有数据包。# nft add rule inet example_table example_chain ip saddr @example_set drop由于
example_set仍为空,所以该规则目前不起作用。向
example_set中添加 IPv4 地址:如果您创建存储单个 IPv4 地址的集合,请输入:
# nft add element inet example_table example_set { 192.0.2.1, 192.0.2.2 }如果您创建存储 IPv4 范围的集合,请输入:
# nft add element inet example_table example_set { 192.0.2.0-192.0.2.255 }当您指定 IP 地址范围时,您可以使用无类别域间路由(CIDR)表示法,如上例中的
192.0.2.0/24。
14.3. 使用动态集添加来自数据包路径的条目 复制链接链接已复制到粘贴板!
nftables 框架中的动态集允许自动添加来自数据包的元素。例如,IP 地址、目标端口、MAC 地址等。此功能使您能够实时收集这些元素,并使用它们创建拒绝列表、禁止列表等,以便您能够立即对安全威胁做出反应。
先决条件
-
inet系列中的example_chain链和example_table表存在。
流程
创建一个空集。以下示例为 IPv4 地址创建了一个集合:
要创建可存储多个独立 IPv4 地址的集合:
# nft add set inet example_table example_set { type ipv4_addr \; }要创建可存储 IPv4 地址范围的集合:
# nft add set inet example_table example_set { type ipv4_addr \; flags interval \; }重要要防止 shell 将分号解释为命令结尾,您必须使用反斜杠转义分号。
创建一条规则,将传入数据包的源 IPv4 地址添加到
example_set集中:# nft add rule inet example_table example_chain set add ip saddr @example_set命令在
example_chain规则链和example_table中创建了一个新规则,来将数据包的源 IPv4 地址动态添加到example_set中。
验证
确保规则已添加:
# nft list ruleset ... table ip example_table { set example_set { type ipv4_addr elements = { 192.0.2.250, 192.0.2.251 } } chain example_chain { type filter hook input priority 0 add @example_set { ip saddr } } }命令显示当前在
nftables中加载的整个规则集。它显示 IP 正在主动触发规则,并且正在使用相关地址更新example_set。
后续步骤
有动态 IP 集后,您可以将它用于各种安全性、过滤和流量控制目的。例如:
- 块、限制或记录网络流量
- 与允许列表结合,以避免禁止可信用户
- 使用自动超时来防止过度阻塞
第 15 章 在 nftables 命令中使用判决映射 复制链接链接已复制到粘贴板!
判决映射(也称为字典),使 nft 能够通过将匹配条件映射到某个操作来根据数据包信息执行操作。
15.1. 在 nftables 中使用匿名映射 复制链接链接已复制到粘贴板!
匿名映射是直接在规则中使用的 { match_criteria : action } 语句。这个语句可以包含多个用逗号分开的映射。
匿名映射的缺点是,如果要修改映射,则必须替换规则。对于动态解决方案,请使用命名映射,如 在 nftables 中使用命名映射 中所述。
例如,您可以使用匿名映射将 IPv4 和 IPv6 协议的 TCP 和 UDP 数据包路由到不同的链,以分别计算传入的 TCP 和 UDP 数据包。
流程
创建新表:
# nft add table inet example_table在
example_table中创建tcp_packets链:# nft add chain inet example_table tcp_packets向统计此链中流量的
tcp_packets中添加一条规则:# nft add rule inet example_table tcp_packets counter在
example_table中创建udp_packets链# nft add chain inet example_table udp_packets向统计此链中流量的
udp_packets中添加一条规则:# nft add rule inet example_table udp_packets counter为传入的流量创建一个链。例如,要在过滤传入的流量的
example_table中创建一个名为incoming_traffic的链:# nft add chain inet example_table incoming_traffic { type filter hook input priority 0 \; }添加一条带有到
incoming_traffic匿名映射的规则 :# nft add rule inet example_table incoming_traffic ip protocol vmap { tcp : jump tcp_packets, udp : jump udp_packets }匿名映射区分数据包,并根据它们的协议将它们发送到不同的计数链。
要列出流量计数器,请显示
example_table:# nft list table inet example_table table inet example_table { chain tcp_packets { counter packets 36379 bytes 2103816 } chain udp_packets { counter packets 10 bytes 1559 } chain incoming_traffic { type filter hook input priority filter; policy accept; ip protocol vmap { tcp : jump tcp_packets, udp : jump udp_packets } } }tcp_packets和udp_packets链中的计数器显示两者接收的数据包和字节数。
15.2. 在 nftables 中使用命名映射 复制链接链接已复制到粘贴板!
nftables 框架支持命名映射。您可以在表中的多个规则中使用这些映射。匿名映射的另一个好处在于,您可以更新命名映射而不比替换使用它的规则。
在创建命名映射时,您必须指定元素的类型:
-
匹配部分包含 IPv4 地址的映射的
ipv4_addr,如192.0.2.1。 -
匹配部分包含 IPv6 地址的映射的
ipv6_addr,如2001:db8:1::1。 -
匹配部分包含介质访问控制(MAC)地址的映射的
ether_addr,如52:54:00:6b:66:42。 -
匹配部分包含互联网协议类型的映射的
inet_proto,如tcp。 -
匹配部分包含互联网服务名称端口号的映射的
inet_service,如ssh或22。 -
匹配部分包含数据包的映射的
mark。数据包标记可以是任意正 32 位整数值(0到2147483647)。
例如,您可以根据其源 IP 地址允许或丢弃传入的数据包。使用命名映射时,您只需要一条规则来配置这种场景,而 IP 地址和操作被动态存储在映射中。
流程
创建表。例如,要创建一个处理 IPv4 数据包的、名为
example_table的表:# nft add table ip example_table创建链。例如,要在
example_table中创建一个名为example_chain的链:# nft add chain ip example_table example_chain { type filter hook input priority 0 \; }重要要防止 shell 将分号解释为命令结尾,您必须使用反斜杠转义分号。
创建一个空的映射。例如,要为 IPv4 地址创建映射:
# nft add map ip example_table example_map { type ipv4_addr : verdict \; }创建使用该映射的规则。例如,以下命令向
example_table中的example_chain添加了一条规则,该规则将操作应用到在example_map中定义的 IPv4 地址:# nft add rule example_table example_chain ip saddr vmap @example_map向
example_map添加 IPv4 地址和相应的操作:# nft add element ip example_table example_map { 192.0.2.1 : accept, 192.0.2.2 : drop }这个示例定义了 IPv4 地址到操作的映射。与以上创建的规则相结合,防火墙接受来自
192.0.2.1的数据包,丢弃来自192.0.2.2的数据包。可选:通过添加另一个 IP 地址和 action 语句来增强映射:
# nft add element ip example_table example_map { 192.0.2.3 : accept }可选:从映射中删除条目:
# nft delete element ip example_table example_map { 192.0.2.1 }可选:显示规则集:
# nft list ruleset table ip example_table { map example_map { type ipv4_addr : verdict elements = { 192.0.2.2 : drop, 192.0.2.3 : accept } } chain example_chain { type filter hook input priority filter; policy accept; ip saddr vmap @example_map } }
第 16 章 示例:使用 nftables 脚本保护 LAN 和 DMZ 复制链接链接已复制到粘贴板!
使用 RHEL 路由器上的 nftables 框架来编写和安装防火墙脚本,来保护内部 LAN 中的网络客户端和 DMZ 中的 Web 服务器免受来自互联网和其他网络的未授权访问。
这个示例仅用于演示目的,描述了一个具有特定要求的场景。
防火墙脚本高度依赖网络基础架构和安全要求。当您为自己的环境编写脚本时,请使用此示例了解 nftables 防火墙的概念。
16.1. 网络条件 复制链接链接已复制到粘贴板!
本例中的网络具有以下条件:
路由器连接到以下网络:
-
互联网通过接口
enp1s0 -
内部 LAN 通过接口
enp7s0 -
DMZ 通过
enp8s0
-
互联网通过接口
-
路由器的互联网接口分配了静态 IPv4 地址(
203.0.113.1)和 IPv6 地址(2001:db8:a::1)。 -
内部 LAN 中的客户端仅使用范围
10.0.0.0/24中的专用 IPv4 地址。因此,从 LAN 到互联网的流量需要源网络地址转换(SNAT)。 -
内部 LAN 中的管理员 PC 使用 IP 地址
10.0.0.100和10.0.0.200。 -
DMZ 使用范围
198.51.100.0/24和2001:db8:b::/56中的公共 IP 地址。 -
DMZ 中的 Web 服务器使用 IP 地址
198.51.100.5和2001:db8:b::5。 - 路由器为 LAN 和 DMZ 中的主机充当缓存 DNS 服务器。
16.2. 防火墙脚本的安全要求 复制链接链接已复制到粘贴板!
以下是示例网络中 nftables 防火墙的要求:
路由器必须能够:
- 递归解析 DNS 查询。
- 在回环接口上执行所有连接。
内部 LAN 中的客户端必须能够:
- 查询运行在路由器上的缓存 DNS 服务器。
- 访问 DMZ 中的 HTTPS 服务器。
- 访问互联网上的任何 HTTPS 服务器。
- 管理员的 PC 必须能够使用 SSH 访问 DMZ 中的路由器以及每个服务器。
DMZ 中的 Web 服务器必须能够:
- 查询运行在路由器上的缓存 DNS 服务器。
- 访问互联网上的 HTTPS 服务器以下载更新。
互联网上的主机必须能够:
- 访问 DMZ 中的 HTTPS 服务器。
另外,存在以下安全要求:
- 应丢弃未明确允许的连接尝试。
- 应记录丢弃的数据包。
16.3. 配置将丢弃的数据包记录到文件 复制链接链接已复制到粘贴板!
默认情况下,systemd 会将内核消息如,丢弃的数据包,记录到日志中。另外,您可以配置 rsyslog 服务,来将此类条目记录到单独的文件中。为确保日志文件不会无限增长,请配置轮转策略。
先决条件
-
rsyslog软件包已安装。 -
rsyslog服务正在运行。
流程
使用以下内容创建
/etc/rsyslog.d/nftables.conf文件::msg, startswith, "nft drop" -/var/log/nftables.log & stop使用这个配置,
rsyslog服务会将丢弃的数据包记录到/var/log/nftables.log文件,而不是/var/log/messages。重启
rsyslog服务:# systemctl restart rsyslog使用以下内容创建
/etc/logrotate.d/nftables文件,以便在大小超过 10 MB 时轮转/var/log/nftables.log:/var/log/nftables.log { size +10M maxage 30 sharedscripts postrotate /usr/bin/systemctl kill -s HUP rsyslog.service >/dev/null 2>&1 || true endscript }maxage 30设置定义了logrotate在下一次轮转操作过程中删除超过 30 天的轮转日志。
16.4. 编写并激活 nftables 脚本 复制链接链接已复制到粘贴板!
本例是运行在 RHEL 路由器上的一个 nftables 防火墙脚本,其保护内部 LAN 中的客户端以及 DMZ 中的 Web 服务器。有关示例中使用的防火墙的网络和要求的详情,请参阅 网络条件 和 对防火墙脚本的安全要求 。
此 nftables 防火墙脚本仅用于演示目的。不要在未经调整为适合您环境和安全要求的情况下使用它。
先决条件
- 网络已配置,如 网络条件 中所述。
流程
使用以下内容创建
/etc/nftables/firewall.nft脚本:# Remove all rules flush ruleset # Table for both IPv4 and IPv6 rules table inet nftables_svc { # Define variables for the interface name define INET_DEV = enp1s0 define LAN_DEV = enp7s0 define DMZ_DEV = enp8s0 # Set with the IPv4 addresses of admin PCs set admin_pc_ipv4 { type ipv4_addr elements = { 10.0.0.100, 10.0.0.200 } } # Chain for incoming trafic. Default policy: drop chain INPUT { type filter hook input priority filter policy drop # Accept packets in established and related state, drop invalid packets ct state vmap { established:accept, related:accept, invalid:drop } # Accept incoming traffic on loopback interface iifname lo accept # Allow request from LAN and DMZ to local DNS server iifname { $LAN_DEV, $DMZ_DEV } meta l4proto { tcp, udp } th dport 53 accept # Allow admins PCs to access the router using SSH iifname $LAN_DEV ip saddr @admin_pc_ipv4 tcp dport 22 accept # Last action: Log blocked packets # (packets that were not accepted in previous rules in this chain) log prefix "nft drop IN : " } # Chain for outgoing traffic. Default policy: drop chain OUTPUT { type filter hook output priority filter policy drop # Accept packets in established and related state, drop invalid packets ct state vmap { established:accept, related:accept, invalid:drop } # Accept outgoing traffic on loopback interface oifname lo accept # Allow local DNS server to recursively resolve queries oifname $INET_DEV meta l4proto { tcp, udp } th dport 53 accept # Last action: Log blocked packets log prefix "nft drop OUT: " } # Chain for forwarding traffic. Default policy: drop chain FORWARD { type filter hook forward priority filter policy drop # Accept packets in established and related state, drop invalid packets ct state vmap { established:accept, related:accept, invalid:drop } # IPv4 access from LAN and internet to the HTTPS server in the DMZ iifname { $LAN_DEV, $INET_DEV } oifname $DMZ_DEV ip daddr 198.51.100.5 tcp dport 443 accept # IPv6 access from internet to the HTTPS server in the DMZ iifname $INET_DEV oifname $DMZ_DEV ip6 daddr 2001:db8:b::5 tcp dport 443 accept # Access from LAN and DMZ to HTTPS servers on the internet iifname { $LAN_DEV, $DMZ_DEV } oifname $INET_DEV tcp dport 443 accept # Last action: Log blocked packets log prefix "nft drop FWD: " } # Postrouting chain to handle SNAT chain postrouting { type nat hook postrouting priority srcnat; policy accept; # SNAT for IPv4 traffic from LAN to internet iifname $LAN_DEV oifname $INET_DEV snat ip to 203.0.113.1 } }在
/etc/sysconfig/nftables.conf文件中包括/etc/nftables/firewall.nft脚本:include "/etc/nftables/firewall.nft"启用 IPv4 转发:
# echo "net.ipv4.ip_forward=1" > /etc/sysctl.d/95-IPv4-forwarding.conf # sysctl -p /etc/sysctl.d/95-IPv4-forwarding.conf启用并启动
nftables服务:# systemctl enable --now nftables
验证
可选:验证
nftables规则集:# nft list ruleset ...尝试执行防火墙阻止的访问。例如,尝试使用 SSH 从 DMZ 访问路由器:
# ssh router.example.com ssh: connect to host router.example.com port 22: Network is unreachable根据您的日志记录设置,搜索:
阻塞的数据包的
systemd日志:# journalctl -k -g "nft drop" Oct 14 17:27:18 router kernel: nft drop IN : IN=enp8s0 OUT= MAC=... SRC=198.51.100.5 DST=198.51.100.1 ... PROTO=TCP SPT=40464 DPT=22 ... SYN ...阻塞的数据包的
/var/log/nftables.log文件:Oct 14 17:27:18 router kernel: nft drop IN : IN=enp8s0 OUT= MAC=... SRC=198.51.100.5 DST=198.51.100.1 ... PROTO=TCP SPT=40464 DPT=22 ... SYN ...
第 17 章 使用 nftables 限制连接的数量 复制链接链接已复制到粘贴板!
您可以使用 nftables 来限制连接数或限制到建立给定数量连接的块 IP 地址,以防止它们使用太多的系统资源。
17.1. 使用 nftables 限制连接的数量 复制链接链接已复制到粘贴板!
通过使用 nft 工具的 ct count 参数,您可以限制每个 IP 地址的同时连接的数量。例如,您可以使用此功能配置每个源 IP 地址只能建立两个到主机的并行 SSH 连接。
流程
创建带有
inet地址系列的filter表:# nft add table inet filter将
input链添加到inet filter表中:# nft add chain inet filter input { type filter hook input priority 0 \; }为 IPv4 地址创建动态集合:
# nft add set inet filter limit-ssh { type ipv4_addr\; flags dynamic \;}在
input链中添加一条规则,该规则只允许从 IPv4 地址到 SSH 端口(22)的两个同时的传入连接,并拒绝来自同一 IP 的所有进一步的连接:# nft add rule inet filter input tcp dport ssh ct state new add @limit-ssh { ip saddr ct count over 2 } counter reject
验证
- 建立从同一 IP 地址到主机的两个以上的同时的 SSH 连接。如果已经建立了两个连接,则 nftables 会拒绝到 SSH 端口的连接。
显示
limit-ssh动态集:# nft list set inet filter limit-ssh table inet filter { set limit-ssh { type ipv4_addr size 65535 flags dynamic elements = { 192.0.2.1 ct count over 2 , 192.0.2.2 ct count over 2 } } }elements条目显示当前与该规则匹配的地址。在本例中,elements列出了与 SSH 端口有活动连接的 IP 地址。请注意,输出不会显示活跃连接的数量,或者连接是否被拒绝。
17.2. 在一分钟内尝试超过十个进入的 TCP 连接的 IP 地址 复制链接链接已复制到粘贴板!
您可以临时阻止在一分钟内建立十个 IPv4 TCP 连接的主机。
流程
创建具有
ip地址系列的filter表:# nft add table ip filter向
filter表中添加input链:# nft add chain ip filter input { type filter hook input priority 0 \; }在
filter表中添加一个名为denylist的集合:# nft add set ip filter denylist { type ipv4_addr \; flags dynamic, timeout \; timeout 5m \; }这个命令为 IPv4 地址创建动态设置。
timeout 5m参数定义nftables在五分钟后自动删除条目,以防止集合被过时的条目填满。添加一条规则,该规则将在一分钟内试图建立十多个新 TCP 连接的主机源 IP 地址添加到
denylist集中:# nft add rule ip filter input ip protocol tcp ct state new, untracked add @denylist { ip saddr limit rate over 10/minute } drop
第 18 章 调试 nftables 规则 复制链接链接已复制到粘贴板!
nftables 框架为管理员提供了不同的选项来调试规则,以及数据包是否匹配。
18.1. 创建带有计数器的规则 复制链接链接已复制到粘贴板!
在识别规则是否匹配时,可以使用计数器。
- 有关向现有规则添加计数器的流程的更多信息,请参阅 向现有规则添加计数器。
先决条件
- 您要添加该规则的链已存在。
流程
向链中添加一条带有
counter参数的新规则。以下示例添加一个带有计数器的规则,它允许端口 22 上的 TCP 流量,并计算与这个规则匹配的数据包和网络数据的数量:# nft add rule inet example_table example_chain tcp dport 22 counter accept显示计数器值:
# nft list ruleset table inet example_table { chain example_chain { type filter hook input priority filter; policy accept; tcp dport ssh counter packets 6872 bytes 105448565 accept } }
18.2. 在现有规则中添加计数器 复制链接链接已复制到粘贴板!
在识别规则是否匹配时,可以使用计数器。
- 有关使用计数器添加新规则的流程的更多信息,请参阅 使用计数器创建规则。
先决条件
- 您要添加计数器的规则已存在。
流程
在链中显示规则及其句柄:
# nft --handle list chain inet example_table example_chain table inet example_table { chain example_chain { # handle 1 type filter hook input priority filter; policy accept; tcp dport ssh accept # handle 4 } }通过使用
counter参数替换规则来添加计数器。以下示例替换了上一步中显示的规则并添加计数器:# nft replace rule inet example_table example_chain handle 4 tcp dport 22 counter accept显示计数器值:
# nft list ruleset table inet example_table { chain example_chain { type filter hook input priority filter; policy accept; tcp dport ssh counter packets 6872 bytes 105448565 accept } }
18.3. 监控与现有规则匹配的数据包 复制链接链接已复制到粘贴板!
nftables 中的追踪功能与 nft monitor 命令相结合,使管理员能够显示与某一规则匹配的数据包。您可以为规则启用追踪,用它来监控匹配此规则的数据包。
先决条件
- 您要添加计数器的规则已存在。
流程
在链中显示规则及其句柄:
# nft --handle list chain inet example_table example_chain table inet example_table { chain example_chain { # handle 1 type filter hook input priority filter; policy accept; tcp dport ssh accept # handle 4 } }通过使用
meta nftrace set 1参数替换规则来添加追踪功能。以下示例替换了上一步中显示的规则并启用追踪:# nft replace rule inet example_table example_chain handle 4 tcp dport 22 meta nftrace set 1 accept使用
nft monitor命令来显示追踪。以下示例过滤了命令的输出,来只显示包含inet example_table example_chain的条目:# nft monitor | grep "inet example_table example_chain" trace id 3c5eb15e inet example_table example_chain packet: iif "enp1s0" ether saddr 52:54:00:17:ff:e4 ether daddr 52:54:00:72:2f:6e ip saddr 192.0.2.1 ip daddr 192.0.2.2 ip dscp cs0 ip ecn not-ect ip ttl 64 ip id 49710 ip protocol tcp ip length 60 tcp sport 56728 tcp dport ssh tcp flags == syn tcp window 64240 trace id 3c5eb15e inet example_table example_chain rule tcp dport ssh nftrace set 1 accept (verdict accept) ...警告根据启用了追踪的规则数量以及匹配流量的数量,
nft monitor命令可以显示很多输出。使用grep或其他工具来过滤输出。
第 19 章 备份和恢复 nftables 规则集 复制链接链接已复制到粘贴板!
您可以将 nftables 规则备份到文件,并稍后恢复它们。此外,管理员可以使用带有规则的文件,来将规则传给其他服务器。
19.1. 将 nftables 规则集备份到文件 复制链接链接已复制到粘贴板!
您可以使用 nft 工具将 nftables 规则集备份到文件。
流程
要备份
nftables规则:以
nft list ruleset格式生成的格式:# nft list ruleset > file.nftJSON 格式:
# nft -j list ruleset > file.json
19.2. 从文件中恢复 nftables 规则集 复制链接链接已复制到粘贴板!
您可以从文件恢复 nftables 规则集。
流程
要恢复
nftables规则:如果要恢复的文件是
nft list ruleset生成的格式,或直接包含nft命令:# nft -f file.nft如果要恢复的文件采用 JSON 格式:
# nft -j -f file.json
第 20 章 使用流表加快 nftables 数据包转发 复制链接链接已复制到粘贴板!
nftables 工具使用 Netfilter 框架,它提供基于快速路径特性的 流表 机制来加快已建立连接的数据包。
flowtable 机制有以下功能:
- 使用连接跟踪来绕过典型的数据包转发路径。
- 避免通过绕过经典数据包处理来重新访问路由表。
- 只适用于 TCP 和 UDP 协议。
- 硬件独立软件快速路径。
流程
添加
inet系列的一个example-table:# nft add table inet <example-table>添加一个带有
ingress钩子和filter作为优先级类型的example-flowtableflowtable :# nft add flowtable inet <example-table> <example-flowtable> { hook ingress priority filter \; devices = { example_device_one, example_device_two } \; }将
example-forwardchain流添加到数据包处理表中的 flowtable :# nft add chain inet <example-table> <example-forwardchain> { type filter hook forward priority filter \; }此命令添加了一个带有
forward钩子和filter优先级的filter类型的 flowtable 。添加一个
established连接跟踪状态的规则,来卸载example-flowtable流:# nft add rule inet <example-table> <example-forwardchain> ct state { established, related } flow add @<example-flowtable>
验证
验证
example-table的属性:# nft list table inet <example-table> table inet example-table { flowtable example-flowtable { hook ingress priority filter devices = { example_device_one, example_device_two } } chain example-forwardchain { type filter hook forward priority filter; policy accept; ct state established flow add @example-flowtable } }
第 21 章 从 iptables 迁移到 nftables 复制链接链接已复制到粘贴板!
如果您的防火墙配置仍然使用 iptables 规则,则您可以将 iptables 规则迁移到 nftables。
ipset 和 iptables-nft 软件包已在 Red Hat Enterprise Linux 9 中弃用。这包括 nft-variants (如 iptables、ip6tables、arptables 和 ebtables 工具)的弃用。如果您使用其中任何一个工具,例如,因为您已从早期的 RHEL 版本升级,因此请迁移到 nftables 软件包提供的 nft 命令行工具。
21.1. 弃用的 iptables 框架中的概念 复制链接链接已复制到粘贴板!
与主动维护的 nftables 框架类似,弃用的 iptables 框架使您能够执行各种数据包过滤任务、日志记录和审计、与 NAT 相关的配置任务等。
iptables 框架由多个表组成,其中每个表都为特定目的而设计:
filter- 默认表确保常规数据包过滤
nat- 对于网络地址转换(NAT),包括更改数据包的源和目标地址
mangle- 对于特定的数据包更改,您可以为高级路由决策对数据包标头进行修改
raw- 对于需要在连接跟踪之前发生的配置
这些表作为单独的内核模块实现,其中每个表都提供一组固定的内置链,如 INPUT、OUTPUT 和 FORWARD。链是针对其评估数据包的规则的序列。这些将钩住内核中数据包处理流中的特定点。链在不同的表中有相同的名称,但它们的执行顺序由各自的钩子优先级决定。优先级由内核在内部管理,以确保规则以正确的顺序应用。
最初,iptables 被设计为处理 IPv4 流量。但是,随着 IPv6 协议的出现,需要引入 ip6tables 工具来提供可比较功能(如 iptables),并使用户能够创建和管理用于 IPv6 数据包的防火墙规则。使用相同的逻辑,创建 arptables 工具是为了处理地址解析协议(ARP),开发 ebtables 工具是为了处理以太网桥接帧。这些工具确保您可以在各种网络协议中应用 iptables 的数据包过滤功能,并提供全面的网络覆盖。
要增强 iptables 的功能,开始开发扩展。功能扩展通常作为与用户空间动态共享对象(DSO)配对的内核模块实现。扩展引入了"匹配"和"目标",您可以在防火墙规则中使用它们来执行更复杂的操作。扩展可以启用复杂的匹配和目标。例如,您可以匹配或操作特定的第 4 层协议标头值,执行速率限制、强制配额等。某些扩展旨在解决默认 iptables 语法中的限制,如"多端口"匹配扩展。此扩展允许单个规则匹配多个非连续端口,以简化规则定义,从而减少所需的单个规则的数量。
ipset 是 iptables 的一种特殊的功能扩展。这是一个内核级别的数据结构,它与 iptables 一起使用来创建 IP 地址、端口号和其他与网络有关的您可以匹配数据包的元素的集合。这些集合可显著简化、优化并加快编写和管理防火墙规则的过程。
详情请查看您系统上的 iptables (8) 手册页。
21.2. 将 iptables 和 ip6tables 规则集转换为 nftables 复制链接链接已复制到粘贴板!
使用 iptables-restore-translate 和 ip6tables-restore-translate 实用程序将 iptables 和 ip6tables 规则集转换为 nftables。
先决条件
-
已安装
nftables和iptables软件包。 -
系统配置了
iptables和ip6tables规则。
流程
将
iptables和ip6tables规则写入一个文件:# iptables-save >/root/iptables.dump # ip6tables-save >/root/ip6tables.dump将转储文件转换为
nftables指令:# iptables-restore-translate -f /root/iptables.dump > /etc/nftables/ruleset-migrated-from-iptables.nft # ip6tables-restore-translate -f /root/ip6tables.dump > /etc/nftables/ruleset-migrated-from-ip6tables.nft-
检查,如果需要,手动更新生成的
nftables规则。 要启用
nftables服务来加载生成的文件,请在/etc/sysconfig/nftables.conf文件中添加以下内容:include "/etc/nftables/ruleset-migrated-from-iptables.nft" include "/etc/nftables/ruleset-migrated-from-ip6tables.nft"停止并禁用
iptables服务:# systemctl disable --now iptables如果您使用自定义脚本加载
iptables规则,请确保脚本不再自动启动并重新引导以刷新所有表。启用并启动
nftables服务:# systemctl enable --now nftables
验证
显示
nftables规则集:# nft list ruleset
21.3. 将单个 iptables 和 ip6tables 规则转换为 nftables 复制链接链接已复制到粘贴板!
RHEL 提供了 iptables-translate 和 ip6tables-translate 工具,来将 iptables 或 ip6tables 规则转换为 nftables 的等效规则。
先决条件
-
已安装
nftables软件包。
流程
使用
iptables-translate或ip6tables-translate程序而不是iptables或ip6tables显示对应的nftables规则,例如:# iptables-translate -A INPUT -s 192.0.2.0/24 -j ACCEPT nft add rule ip filter INPUT ip saddr 192.0.2.0/24 counter accept请注意,一些扩展可能缺少响应的转换支持。在这些情况下,实用程序会输出以
#符号为前缀的未转换规则,例如:# iptables-translate -A INPUT -j CHECKSUM --checksum-fill nft # -A INPUT -j CHECKSUM --checksum-fill
21.4. 常见的 iptables 和 nftables 命令的比较 复制链接链接已复制到粘贴板!
以下是常见 iptables 和 nftables 命令的比较:
列出所有规则:
Expand iptables nftables iptables-savenft list ruleset列出某个表和链:
Expand iptables nftables iptables -Lnft list table ip filteriptables -L INPUTnft list chain ip filter INPUTiptables -t nat -L PREROUTINGnft list chain ip nat PREROUTINGnft命令不会预先创建表和链。只有当用户手动创建它们时它们才会存在。列出 firewalld 生成的规则:
# nft list table inet firewalld # nft list table ip firewalld # nft list table ip6 firewalld
第 22 章 使用 firewalld 为流量分类配置区域优先级 复制链接链接已复制到粘贴板!
使用区域优先级,您可以通过为 ingress 和 egress 流量指定优先级来控制数据包分类顺序。好处在于您可以在区域中指定流量分类顺序。因此,无论源地址或接口是什么,在区域 B 之前可能会考虑区域 A。具有较低优先级值的区域优先于具有更高优先级值的区域。此分类具有一个 ingress 优先级值和 egress 优先级值对。
22.1. 为区域中的两个流量类型设置相同的优先级值 复制链接链接已复制到粘贴板!
通过使用 --set-priority 选项,您可以在没有明确说明的情况下为 ingress 和 egress 流量分类设置一个通用值。
先决条件
创建一个新区:
# firewall-cmd --permanent --new-zone=example-zone为具有
--set-priority的example-zone区域设置一个通用区域优先级值:# firewall-cmd --permanent --zone example-zone --set-priority -10通过设置较低的值来确保较高的优先级。这确保为这个区域中两个流量类型配置的所有操作都将优先于其他区域中的操作。
将永久配置应用到运行时:
# firewall-cmd --reload
验证
显示两个流量类型的优先级值:
# firewall-cmd --permanent --info-zone example-zone example-zone target: default ingress-priority: -10 egress-priority: -10 ... icmp-block-inversion: no ... services: dhcpv6-client mdns samba-client ssh ... forward: yes masquerade: no ...此设置确保流量在被分类到其他区域之前先被分类到
example-zone。
22.2. 为区域中的每个流量类型设置不同的优先级值 复制链接链接已复制到粘贴板!
通过为 ingress 和 egress 流量设置不同的值,您可以为区域中流量分类设置优先级。
流程
创建一个新区:
# firewall-cmd --permanent --new-zone=example-zone为具有
--set-ingress-priority的example-zone区域中的ingress流量设置区域优先级值:# firewall-cmd --permanent --zone example-zone --set-ingress-priority -10为具有
--set-egress-priority的example-zone中的egress流量设置区域优先级值:# firewall-cmd --permanent --zone example-zone --set-egress-priority 100将永久配置应用到运行时:
# firewall-cmd --reload
验证
显示两个流量类型的优先级值:
# firewall-cmd --permanent --info-zone example-zone example-zone (active) target: default ingress-priority: -10 egress-priority: 100 icmp-block-inversion: no interfaces: eth0 ... services: dhcpv6-client mdns samba-client ssh ... forward: yes masquerade: no ...这些值表示在其它区域之前,
ingress流量在example-zone区域中优先于egress流量。
第 23 章 了解 RHEL 10 中的 eBPF 网络功能 复制链接链接已复制到粘贴板!
扩展的 Berkeley Packet 过滤器(eBPF)是一个内核中的虚拟机,允许在内核空间中执行代码。此代码运行在一个受限的沙箱环境中,仅可访问有限功能集。
在网络中,您可以使用 eBPF 来补充或替换内核数据包处理。根据您使用的 hook,eBPF 程序有:
- 对元数据的读和写的访问权限
- 可以查找套接字和路由
- 可以设置套接字选项
- 可以重定向数据包
23.1. RHEL 10 中网络 eBPF 功能的概述 复制链接链接已复制到粘贴板!
您可以将扩展的 Berkeley 数据包过滤器(eBPF)网络程序附加到 RHEL 中的以下钩子:
- Express Data Path(XDP):在内核网络堆栈处理它们之前,对接收的数据包提供早期的访问权限。
-
带有直接操作标志的
tceBPF 分类器:对入口和出口提供强大的数据包处理。程序可以作为带有直接操作标志的 eBPF 分类器附加在qdisc层次结构中,或使用基于链接的tcxAPI。 - 控制组版本 2(cgroup v2):在控制组中,对程序所执行的基于套接字的操作启用过滤和覆盖。
- 套接字过滤:启用对从套接字接收的数据包进行过滤。这个功能也可用于经典 Berkeley Packet Filter(cBPF),但已扩展为支持 eBPF 程序。
- 流解析器:启用将流分成单独的消息、过滤并将其重定向到套接字。
-
SO_REUSEPORT套接字选择:对来自reuseport套接字组的接收套接字提供可编程选择。 - 流程分析器:在某些情况下,启用覆盖内核解析数据包头的方式。
- TCP 拥塞控制回调:启用实现一个自定义 TCP 拥塞控制算法。
- 带有封装的路由: 允许创建自定义隧道封装。
Netfilter:启用实现自定义 Netfilter 钩子。
- XDP
您可以将
BPF_PROG_TYPE_XDP类型的程序附加到网络接口。然后,在内核网络堆栈开始处理之前,内核会在接收的数据包上执行该程序。在某些情况下,这允许快速数据包转发,如快速数据包丢弃以防止分布式拒绝服务(DDoS)攻击,以及负载均衡场景的快速数据包重定向。您还可以使用 XDP 进行不同类型的数据包监控和抽样。内核允许 XDP 程序修改数据包,并将其传送到内核网络堆栈进行进一步处理。
以下的 XDP 模式可用:
- 原生(驱动程序)XDP:内核在数据包接收过程从最早可能的点执行程序。目前,内核无法解析数据包,因此无法使用内核提供的元数据。这个模式要求网络接口驱动程序支持 XDP,但并非所有驱动程序都支持这种原生模式。
- 通用 XDP:内核网络栈在进程早期执行 XDP 程序。此时内核数据结构已被分配,数据包已被预先处理。如果数据包被丢弃或重定向,与原生模式相比,这需要大量开销。但是,通用模式不需要支持网络接口驱动,它可适用于所有网络接口。
- Offloaded XDP:内核在网络接口而不是主机 CPU 上执行 XDP 程序。请注意,这需要特定的硬件,这个模式中只有某些 eBPF 功能可用。
在 RHEL 上,使用
libxdp库加载所有 XDP 程序。这个程序库启用系统控制的 XDP 使用。注意目前,XDP 程序有一些系统配置限制。例如:您必须禁用接收接口中某些硬件卸载功能。另外,并非所有功能都可用于支持原生模式的所有驱动程序。
在 RHEL 10 中,红帽仅在使用
libxdp库将程序加载到内核中时支持 XDP 功能。- AF_XDP
-
使用过滤并将数据包重定向到给定的
AF_XDP套接字的 XDP 程序,您可以使用AF_XDP协议系列中的一个或多个套接字来快速将数据包从内核复制到用户空间。 - 流量控制
流量控制(
tc)子系统提供以下 eBPF 程序类型:-
BPF_PROG_TYPE_SCHED_CLS -
BPF_PROG_TYPE_SCHED_ACT
这些类型允许您在 eBPF 中编写自定义的
tc分类器和tc操作。与tc生态系统的各个部分一起,这为强大的数据包处理提供了能力,是一些容器编排解决方案的核心部分。在大多数情况下,只有类符被使用,与 direct-action 标记一样,eBPF 分类器可以直接从同一 eBPF 程序执行操作。
clsact排队规程(qdisc)被设计为在入口端启用此功能。请注意,使用流解析器 eBPF 程序可能会影响其他
qdiscs和tc分类器的操作,如flower。基于链接的
tcxAPI 与qdiscAPI 一起提供。它可让您的应用程序通过 BPF 程序维护所有权,以防止意外删除 BPF 程序。另外,tcxAPI 具有多程序支持,允许多个应用程序并行在tc层中附加 BPF 程序。-
- 套接字过滤器
一些实用程序会使用或在过去使用了 classic Berkeley Packet Filter(cBPF)过滤套接字上接收到的数据包。例如,
tcpdump工具允许用户指定表达式,tcpdump然后将它们转换为 cBPF 码。作为 cBPF 的替代方案,内核允许
BPF_PROG_TYPE_SOCKET_FILTER类型的 eBPF 程序实现相同的目的。- 控制组群
在 RHEL 中,您可以使用多种 eBPF 程序,供您附加到 cgroup。当给定 cgroup 中的某个程序执行某个操作时,内核会执行这些程序。请注意,您只能使用 cgroups 版本 2。
RHEL 中提供以下与网络相关的 cgroup eBPF 程序:
-
BPF_PROG_TYPE_SOCK_OPS:内核对各种 TCP 事件调用该程序。程序可以调整内核 TCP 堆栈的行为,包括自定义 TCP 头选项等。 -
BPF_PROG_TYPE_CGROUP_SOCK_ADDR:在connect、bind、sendto、recvmsg、getpeername和getockname操作过程中,内核调用该程序。该程序允许更改 IP 地址和端口。当您在 eBPF 中实现基于套接字的网络地址转换(NAT)时,这很有用。 -
BPF_PROG_TYPE_CGROUP_SOCKOPT:在setockopt和getsockopt过程中,内核调用该程序,并允许更改选项。 -
BPF_PROG_TYPE_CGROUP_SOCK:在套接字创建、套接字释放和绑定到地址的过程中,内核调用该程序。您可以使用这些程序来允许或拒绝操作,或者只检查套接字创建统计信息。 -
BPF_PROG_TYPE_CGROUP_SKB:该程序在入口和出口处过滤单个数据包,并可以接受或拒绝数据包。
-
- 流解析器(Stream Parser)
流解析器对添加到特殊 eBPF 映射中的一组套接字进行操作。然后 eBPF 程序处理内核在那些套接字上接收或发送的数据包。
RHEL 中提供了以下流解析程序 eBPF 程序:
-
BPF_PROG_TYPE_SK_SKB:eBPF 程序将套接字上收到的数据包解析到单个消息中,并指示内核丢弃这些消息,接受它们,或者将它们发送到另一个套接字。 -
BPF_PROG_TYPE_SK_MSG:此程序过滤出口消息。eBPF 程序解析数据包,并批准或拒绝它们。
-
- SO_REUSEPORT 套接字选择
-
使用这个套接字选项,您可以绑定多个套接字到相同的 IP 地址和端口。如果没有 eBPF,内核会根据连接散列选择接收套接字。有了
BPF_PROG_TYPE_SK_REUSEPORT程序,接收套接字的选择是完全可编程的。 - dissector 流程
-
当内核需要处理数据包头,而不需要查看全部协议解码时,会对它们进行
剖析。例如,这会在tc子系统、多路径路由、绑定或者计算数据包哈希时发生。在这种情况下,内核解析数据包的标头,并使用数据包标头中的信息填充内部结构。您可以使用BPF_PROG_TYPE_FLOW_DISSECTOR程序替换此内部解析。请注意,您只能在 RHEL 的 eBPF 的 IPv4 和 IPv6 上分离 TCP 和 UDP。 - TCP 阻塞控制
-
您可以使用一组实现
struct tcp_congestion_oops回调的BPF_PROG_TYPE_STRUCT_OPS程序来编写一个自定义的 TCP 阻塞控制算法。通过这种方法的算法可以和内置内核算法一起提供给系统。 - 带有封装的路由
您可以将以下 eBPF 程序类型之一附加到路由表中作为隧道封装属性的路由:
-
BPF_PROG_TYPE_LWT_IN -
BPF_PROG_TYPE_LWT_OUT -
BPF_PROG_TYPE_LWT_XMIT -
BPF_PROG_TYPE_LWT_SEG6LOCAL(技术预览)
-
这样的 eBPF 程序的功能仅限于特定的隧道配置,它不允许创建通用封装或封装解决方案。
- 套接字查找
-
要绕过
bind系统调用的限制,请使用BPF_PROG_TYPE_SK_LOOKUP类型的 eBPF 程序。此类程序可以为新传入的 TCP 连接选择侦听套接字,或为 UDP 数据包选择一个未连接的套接字。 - Netfilter
-
您可以使用
BPF_PROG_TYPE_NETFILTER类型来实现自定义 Netfilter 钩子。这些钩子集成到 Netfilter 基础设施中,对数据包有只读权限,并可丢弃或接受它们。另外,也可以在重新装配 IP 片段后对碎片化数据包运行 eBPF 程序。
23.2. 在 RHEL 10 中按网卡的 XDP 功能概述 复制链接链接已复制到粘贴板!
以下是启用了 XDP 的网卡和您可以使用的 XDP 特性的概述:
| 网卡 | 驱动 | 基本的 | 重定向 | 目标 | HW 卸载 | 零复制 | 大 MTU |
|---|---|---|---|---|---|---|---|
| Amazon Elastic Network Adapter |
| 是 | 是 | 是 [a] | 否 | 否 | 否 |
| aQuantia AQtion Ethernet card |
| 是 | 是 | 是 | 否 | 否 | 是 |
| Broadcom NetXtreme-C/E 10/25/40/50 gigabit Ethernet |
| 是 | 是 | 是 [a] | 否 | 否 | 是 |
| Cavium Thunder Virtual function |
| 是 | 否 | 否 | 否 | 否 | 否 |
| Freescale DPAA2 Ethernet |
| 是 | 是 | 是 | 否 | 是 [b] | 否 |
| Google Virtual NIC (gVNIC) support |
| 是 | 是 | 是 | 否 | 是 | 否 |
| Intel® 10GbE PCI Express Virtual Function Ethernet |
| 是 | 否 | 否 | 否 | 否 | 否 |
| Intel® 10GbE PCI Express adapters |
| 是 | 是 | 是 [a] | 否 | 是 | 是 [c] |
| Intel® Ethernet Connection E800 Series |
| 是 | 是 | 是 [a] | 否 | 是 | 是 |
| Intel® Ethernet Controller I225-LM/I225-V family |
| 是 | 是 | 是 [a] | 否 | 是 | 是 [c] |
| Intel® PCI Express Gigabit adapters |
| 是 | 是 | 是 [a] | 否 | 否 | 是 [c] |
| Intel® Ethernet Controller XL710 Family |
| 是 | 是 | 否 | 是 | 否 | |
| Marvell OcteonTX2 |
| 是 | 是 | 否 | 否 | 否 | |
| Mellanox 5th generation network adapters (ConnectX series) |
| 是 | 是 | 是 [d] | 否 | 是 | 是 |
| Mellanox Technologies 1/10/40Gbit Ethernet |
| 是 | 是 | 否 | 否 | 否 | 否 |
| Microsoft Azure Network Adapter |
| 是 | 是 | 是 | 否 | 否 | 否 |
| Microsoft Hyper-V virtual network |
| 是 | 是 | 是 | 否 | 否 | 否 |
| Netronome® NFP4000/NFP6000 NIC [e] |
| 是 | 是 | 否 | 是 | 是 | 否 |
| NXP ENETC Gigabit Ethernet |
| 是 | 是 | 是 | 否 | 否 | 是 |
| NXP Fast Ethernet Controller |
| 是 | 是 | 是 [a] | 否 | 否 | 否 |
| Pensando Ethernet Adapter |
| 是 | 是 | 是 | 否 | 否 | 是 |
| QEMU Virtio network |
| 是 | 是 | 是 [a] | 否 | 否 | 是 |
| QLogic QED 25/40/100Gb Ethernet NIC |
| 是 | 是 | 是 | 否 | 否 | 否 |
| QorIQ DPAA Ethernet |
| 是 | 是 | 是 | 否 | 否 | 否 |
| STMicroelectronics Multi-Gigabit Ethernet |
| 是 | 是 | 是 | 否 | 是 | 否 |
| Solarflare SFC9000/SFC9100/EF100-family |
| 是 | 是 | 是 [d] | 否 | 否 | 否 |
| Universal TUN/TAP device |
| 是 | 是 | 是 | 否 | 否 | 否 |
| Virtual Ethernet pair device |
| 是 | 是 | 是 | 否 | 否 | 是 |
| VMware VMXNET3 ethernet driver |
| 是 | 是 | 否 | 否 | 否 | |
| Xen paravirtual network device |
| 是 | 是 | 是 | 否 | 否 | 否 |
[a]
只有在接口上加载 XDP 程序时。
[b]
不适用于所有硬件修订。
[c]
仅传输侧。无法通过 XDP 接收大型数据包。
[d]
每个 CPU 至少需要一个 XDP TX 队列,例如,队列数必须大于最大 CPU 索引。
[e]
一些列出的功能不适用于 Netronome® NFP3800 NIC。
| |||||||
图例:
-
基本的:支持基本的返回代码:
DROP、PASS、ABORTED和TX。 -
重定向:支持
XDP_REDIRECT返回码。 -
目标 :可以是
XDP_REDIRECT返回码的目标。 - HW 卸载:支持 XDP 硬件卸载。
-
零-复制:支持
AF_XDP协议系列的零复制模式。 - 大 MTU:支持大于页大小的数据包。
第 24 章 使用 BPF 编译器集合进行网络追踪 复制链接链接已复制到粘贴板!
BPF Compiler Collection(BCC)是一个库,可帮助创建扩展的 Berkeley Packet Filter(eBPF)程序。eBPF 程序的主要工具是分析操作系统性能和网络性能,而不会遇到开销或安全问题。
BCC 不再需要用户了解 eBPF 的技术详情,并提供了许多开箱即用的起点,如带有预先创建的 eBPF 程序的 bcc-tools 软件包。
eBPF 程序在事件中触发,如磁盘 I/O、TCP 连接以及进程创建。程序不太可能导致内核崩溃、循环或者变得无响应,因为它们在内核的安全性虚拟机中运行。
24.1. 安装 bcc-tools 软件包 复制链接链接已复制到粘贴板!
安装 bcc-tools 软件包,该软件包还会将 BPF Compiler Collection (BCC)库作为依赖项安装。
流程
安装
bcc-tools:# dnf install bcc-toolsBCC 工具安装在
/usr/share/bcc/tools/目录中。
验证
检查安装的工具:
# ls -l /usr/share/bcc/tools/ ... -rwxr-xr-x. 1 root root 4198 Dec 14 17:53 dcsnoop -rwxr-xr-x. 1 root root 3931 Dec 14 17:53 dcstat -rwxr-xr-x. 1 root root 20040 Dec 14 17:53 deadlock_detector -rw-r--r--. 1 root root 7105 Dec 14 17:53 deadlock_detector.c drwxr-xr-x. 3 root root 8192 Mar 11 10:28 doc -rwxr-xr-x. 1 root root 7588 Dec 14 17:53 execsnoop -rwxr-xr-x. 1 root root 6373 Dec 14 17:53 ext4dist -rwxr-xr-x. 1 root root 10401 Dec 14 17:53 ext4slower ...上表中的
doc目录包含每个工具的文档。
24.2. 显示添加到内核的接受队列中的 TCP 连接 复制链接链接已复制到粘贴板!
内核在 TCP 3 向握手中接收 ACK 数据包后,内核会将来自 SYN 队列的连接移到 accept 队列,直到连接的状态变为 ESTABLISHED。因此,只有成功的 TCP 连接才能在此队列中看到。
tcpaccept 工具使用 eBPF 特性显示内核添加到 accept 队列的所有连接。该工具是轻量级的,因为它跟踪内核的 accept() 函数,而不是捕获和过滤数据包。例如,使用 tcpaccept 进行常规故障排除,来显示服务器已接受的新连接。
流程
输入以下命令来启动对内核
accept队列的追踪:# /usr/share/bcc/tools/tcpaccept PID COMM IP RADDR RPORT LADDR LPORT 843 sshd 4 192.0.2.17 50598 192.0.2.1 22 1107 ns-slapd 4 198.51.100.6 38772 192.0.2.1 389 1107 ns-slapd 4 203.0.113.85 38774 192.0.2.1 389 ...每次内核接受一个连接时,
tcpaccept都会显示连接的详情。详情请查看您系统上的
tcpaccept (8)手册页和/usr/share/bcc/tools/doc/tcpaccept_example.txt文件。- 按 Ctrl+C 停止追踪过程。
24.3. 追踪出去的 TCP 连接尝试 复制链接链接已复制到粘贴板!
tcpconnect 工具使用 eBPF 特性来跟踪出去的 TCP 连接尝试。该工具的输出还包括失败的连接。
tcpconnect 工具是轻量级的,例如,因为它跟踪内核的 connect() 函数,而不是捕获和过滤数据包。
流程
输入以下命令启动显示所有传出连接的追踪过程:
# /usr/share/bcc/tools/tcpconnect PID COMM IP SADDR DADDR DPORT 31346 curl 4 192.0.2.1 198.51.100.16 80 31348 telnet 4 192.0.2.1 203.0.113.231 23 31361 isc-worker00 4 192.0.2.1 192.0.2.254 53 ...每次内核处理一个出去的连接时,
tcpconnect都会显示连接的详情。详情请查看您系统上的
tcpconnect (8)手册页和/usr/share/bcc/tools/doc/tcpconnect_example.txt文件。- 按 Ctrl+C 停止追踪过程。
24.4. 测量出站 TCP 连接的延迟 复制链接链接已复制到粘贴板!
TCP 连接延迟是建立连接所需的时间。这通常涉及内核 TCP/IP 处理和网络往返时间,而不是应用程序运行时。
tcpconnlat 工具使用 eBPF 特性来测量发送 SYN 数据包和接收响应数据包之间的时间。
流程
开始测量出站连接的延迟:
# /usr/share/bcc/tools/tcpconnlat PID COMM IP SADDR DADDR DPORT LAT(ms) 32151 isc-worker00 4 192.0.2.1 192.0.2.254 53 0.60 32155 ssh 4 192.0.2.1 203.0.113.190 22 26.34 32319 curl 4 192.0.2.1 198.51.100.59 443 188.96 ...每次内核处理一个出去的连接时,
tcpconnlat都会在内核接收响应数据包后显示连接的详细信息。详情请查看您系统上的
tcpconnlat (8)手册页和/usr/share/bcc/tools/doc/tcpconnlat_example.txt文件。- 按 Ctrl+C 停止追踪过程。
24.5. 显示被内核丢弃的 TCP 数据包和片段详情 复制链接链接已复制到粘贴板!
tcpdrop 工具使管理员能够显示内核所丢弃的 TCP 数据包和段的详情。使用这个实用程序调试丢弃数据包的高速率,以便远程系统发送基于计时器的重新传输。释放数据包和片段的高速率可能会影响服务器的性能。
tcpdrop 工具使用 eBPF 特性,而不是捕获和过滤资源密集型的数据包,来直接从内核检索信息。
流程
输入以下命令来显示丢弃 TCP 数据包和片段详情:
# /usr/share/bcc/tools/tcpdrop TIME PID IP SADDR:SPORT > DADDR:DPORT STATE (FLAGS) 13:28:39 32253 4 192.0.2.85:51616 > 192.0.2.1:22 CLOSE_WAIT (FIN|ACK) b'tcp_drop+0x1' b'tcp_data_queue+0x2b9' ... 13:28:39 1 4 192.0.2.85:51616 > 192.0.2.1:22 CLOSE (ACK) b'tcp_drop+0x1' b'tcp_rcv_state_process+0xe2' ...每次内核丢弃 TCP 数据包和段时,
tcpdrop都会显示连接的详情,包括导致软件包丢弃的内核堆栈追踪。详情请查看您系统上的
tcpdrop (8)手册页和/usr/share/bcc/tools/doc/tcpdrop_example.txt文件。- 按 Ctrl+C 停止追踪过程。
24.6. 追踪 TCP 会话 复制链接链接已复制到粘贴板!
tcplife 工具使用 eBPF 跟踪打开和关闭的 TCP 会话,并打印一行输出来总结每一个会话。管理员可以使用 tcplife 来识别连接和传输的流量数。
例如,您可以显示到端口 22 (SSH)的连接来检索以下信息:
- 本地进程 ID(PID)
- 本地进程名称
- 本地 IP 地址和端口号
- 远程 IP 地址和端口号
- 接收和传输的流量的数量(以 KB 为单位)。
- 连接处于活跃状态的时间(毫秒)
流程
输入以下命令来开始追踪到本地端口
22的连接:# /usr/share/bcc/tools/tcplife -L 22 PID COMM LADDR LPORT RADDR RPORT TX_KB RX_KB MS 19392 sshd 192.0.2.1 22 192.0.2.17 43892 53 52 6681.95 19431 sshd 192.0.2.1 22 192.0.2.245 43902 81 249381 7585.09 19487 sshd 192.0.2.1 22 192.0.2.121 43970 6998 7 16740.35 ...每次关闭连接时,
tcplife都会显示连接的详情。详情请查看您系统上的
tcplife (8)手册页和/usr/share/bcc/tools/doc/tcplife_example.txt文件。- 按 Ctrl+C 停止追踪过程。
24.7. 追踪 TCP 重新传输 复制链接链接已复制到粘贴板!
tcpretrans 工具显示有关 TCP 重新传输的详细信息,如本地和远程的 IP 地址和端口号,以及重新传输时 TCP 的状态。
该工具使用 eBPF 功能,因此开销非常低。
流程
使用以下命令来显示 TCP 重新传输详情:
# /usr/share/bcc/tools/tcpretrans TIME PID IP LADDR:LPORT T> RADDR:RPORT STATE 00:23:02 0 4 192.0.2.1:22 R> 198.51.100.0:26788 ESTABLISHED 00:23:02 0 4 192.0.2.1:22 R> 198.51.100.0:26788 ESTABLISHED 00:45:43 0 4 192.0.2.1:22 R> 198.51.100.0:17634 ESTABLISHED ...每次内核调用 TCP 重新传输函数时,
tcpretrans都会显示连接的详情。详情请查看您系统上的
tcpretrans (8)手册页和/usr/share/bcc/tools/doc/tcpretrans_example.txt文件。- 按 Ctrl+C 停止追踪过程。
24.8. 显示 TCP 状态更改信息 复制链接链接已复制到粘贴板!
在 TCP 会话中,TCP 状态会改变。tcpstates 工具使用 eBPF 功能跟踪这些状态变化,并打印包括每个状态持续时间的详细信息。例如,使用 tcpstates 来确定连接是否在初始化状态中花费了太多时间。
流程
使用以下命令开始追踪 TCP 状态变化:
# /usr/share/bcc/tools/tcpstates SKADDR C-PID C-COMM LADDR LPORT RADDR RPORT OLDSTATE -> NEWSTATE MS ffff9cd377b3af80 0 swapper/1 0.0.0.0 22 0.0.0.0 0 LISTEN -> SYN_RECV 0.000 ffff9cd377b3af80 0 swapper/1 192.0.2.1 22 192.0.2.45 53152 SYN_RECV -> ESTABLISHED 0.067 ffff9cd377b3af80 818 sssd_nss 192.0.2.1 22 192.0.2.45 53152 ESTABLISHED -> CLOSE_WAIT 65636.773 ffff9cd377b3af80 1432 sshd 192.0.2.1 22 192.0.2.45 53152 CLOSE_WAIT -> LAST_ACK 24.409 ffff9cd377b3af80 1267 pulseaudio 192.0.2.1 22 192.0.2.45 53152 LAST_ACK -> CLOSE 0.376 ...每次连接改变其状态时,
tcpstates都会显示一个新行,其中包含更新的连接详情。如果多个连接同时改变了其状态,请使用第一列中的套接字地址(
SKADDR)来确定哪些条目属于同一个连接。详情请查看您系统上的
tcpstates (8)手册页和/usr/share/bcc/tools/doc/tcpstates_example.txt文件。- 按 Ctrl+C 停止追踪过程。
24.9. 聚合发送到特定子网的 TCP 流量 复制链接链接已复制到粘贴板!
tcpsubnet 工具汇总并合计了本地主机发往子网的 IPv4 TCP 流量,并按固定间隔显示输出。该工具使用 eBPF 功能来收集并总结数据,以减少开销。
默认情况下,tcpsubnet 为以下子网汇总流量:
-
127.0.0.1/32 -
10.0.0.0/8 -
172.16.0.0/12 -
192.0.2.0/24/16 -
0.0.0.0/0
请注意,最后一个子网(0.0.0.0/0)是一个全包括选项。tcpsubnet 工具计算与这个全包括条目中前四个不同的子网的所有流量。
按照以下流程计算 192.0.2.0/24 和 198.51.100.0/24 子网的流量。到其他子网的流量将在 0.0.0.0/0 全包括子网条目中跟踪。
流程
开始监控发送到
192.0.2.0/24、198.51.100.0/24和其他子网的流量数:# /usr/share/bcc/tools/tcpsubnet 192.0.2.0/24,198.51.100.0/24,0.0.0.0/0 Tracing... Output every 1 secs. Hit Ctrl-C to end [02/21/20 10:04:50] 192.0.2.0/24 856 198.51.100.0/24 7467 [02/21/20 10:04:51] 192.0.2.0/24 1200 198.51.100.0/24 8763 0.0.0.0/0 673 ...这个命令以字节为单位显示指定子网每秒一次的流量。
详情请查看您系统上的
tcpsubnet (8)手册页和/usr/share/bcc/tools/doc/tcpsubnet.txt文件。- 按 Ctrl+C 停止追踪过程。
24.10. 通过 IP 地址和端口显示网络吞吐量 复制链接链接已复制到粘贴板!
tcptop 工具以 KB 为单位显示主机发送并接收的 TCP 流量。这个报告会自动刷新并只包含活跃的 TCP 连接。该工具使用 eBPF 功能,因此开销非常低。
流程
要监控发送和接收的流量,请输入:
# /usr/share/bcc/tools/tcptop 13:46:29 loadavg: 0.10 0.03 0.01 1/215 3875 PID COMM LADDR RADDR RX_KB TX_KB 3853 3853 192.0.2.1:22 192.0.2.165:41838 32 102626 1285 sshd 192.0.2.1:22 192.0.2.45:39240 0 0 ...命令的输出只包括活跃的 TCP 连接。如果本地或者远程系统关闭了连接,则该连接在输出中不再可见。
详情请查看您系统上的
tcptop (8)手册页和/usr/share/bcc/tools/doc/tcptop.txt文件。- 按 Ctrl+C 停止追踪过程。
24.11. 追踪已建立的 TCP 连接 复制链接链接已复制到粘贴板!
tcptracer 工具跟踪连接、接受和关闭 TCP 连接的内核函数。该工具使用 eBPF 功能,因此开销非常低。
流程
使用以下命令启动追踪过程:
# /usr/share/bcc/tools/tcptracer Tracing TCP established connections. Ctrl-C to end. T PID COMM IP SADDR DADDR SPORT DPORT A 1088 ns-slapd 4 192.0.2.153 192.0.2.1 0 65535 A 845 sshd 4 192.0.2.1 192.0.2.67 22 42302 X 4502 sshd 4 192.0.2.1 192.0.2.67 22 42302 ...每当内核连接、接受或关闭连接时,
tcptracer都会显示连接的详情。详情请查看您系统上的
tcptracer (8)手册页和/usr/share/bcc/tools/doc/tcptracer_example.txt文件。- 按 Ctrl+C 停止追踪过程。
24.12. 追踪 IPv4 和 IPv6 侦听尝试 复制链接链接已复制到粘贴板!
solisten 工具追踪所有 IPv4 和 IPv6 侦听尝试。它跟踪尝试,包括最终失败的或者不接受连接的侦听程序。当程序希望侦听 TCP 连接时,工具会跟踪内核调用的函数。
流程
输入以下命令启动显示所有监听 TCP 尝试的追踪过程:
# /usr/share/bcc/tools/solisten PID COMM PROTO BACKLOG PORT ADDR 3643 nc TCPv4 1 4242 0.0.0.0 3659 nc TCPv6 1 4242 2001:db8:1::1 4221 redis-server TCPv6 128 6379 :: 4221 redis-server TCPv4 128 6379 0.0.0.0 ....详情请查看您系统上的
solisten (9)手册页和/usr/share/bcc/tools/doc/solisten_example.txt文件。- 按 Ctrl+C 停止追踪过程。
24.13. 软中断的服务时间概述 复制链接链接已复制到粘贴板!
softirqs 工具总结了服务软中断(soft IRQ)所花费的时间,并将这个时间显示为总计或直方图分布。这个工具使用 irq:softirq_enter 和 irq:softirq_exit 内核追踪点,是一个稳定的追踪机制。
流程
输入以下命令启动追踪
soft irq事件时间:# /usr/share/bcc/tools/softirqs Tracing soft irq event time... Hit Ctrl-C to end. ^C SOFTIRQ TOTAL_usecs tasklet 166 block 9152 net_rx 12829 rcu 53140 sched 182360 timer 306256详情请查看您系统上的
softirqs (8)和mpstat (1)手册页以及/usr/share/bcc/tools/doc/softirqs_example.txt文件。- 按 Ctrl+C 停止追踪过程。
24.14. 总结网络接口上的数据包大小和数量 复制链接链接已复制到粘贴板!
netqtop 工具显示有关特定网络接口的每个网络队列上收到的(RX)和传输的(TX)数据包属性的统计信息。统计包括:
- 每秒字节数(BPS)
- 每秒数据包数(PPS)
- 平均数据包大小
- 总数据包数
要生成这些统计数据,netqtop 会跟踪执行传输的数据包 net_dev_start_xmit 以及接收的数据包 netif_receive_skb 的事件的内核功能。
流程
显示
2秒时间间隔的字节大小范围内的数据包数:# /usr/share/bcc/tools/netqtop -n enp1s0 -i 2 Fri Jan 31 18:08:55 2023 TX QueueID avg_size [0, 64) [64, 512) [512, 2K) [2K, 16K) [16K, 64K) 0 0 0 0 0 0 0 Total 0 0 0 0 0 0 RX QueueID avg_size [0, 64) [64, 512) [512, 2K) [2K, 16K) [16K, 64K) 0 38.0 1 0 0 0 0 Total 38.0 1 0 0 0 0 ----------------------------------------------------------------------------- Fri Jan 31 18:08:57 2023 TX QueueID avg_size [0, 64) [64, 512) [512, 2K) [2K, 16K) [16K, 64K) 0 0 0 0 0 0 0 Total 0 0 0 0 0 0 RX QueueID avg_size [0, 64) [64, 512) [512, 2K) [2K, 16K) [16K, 64K) 0 38.0 1 0 0 0 0 Total 38.0 1 0 0 0 0 -----------------------------------------------------------------------------详情请查看您系统上的
netqtop (8)手册页和/usr/share/bcc/tools/doc/netqtop_example.txt文件。-
按 Ctrl+C 来停止
netqtop。
第 25 章 使用 xdp-filter 进行高性能流量过滤以防止 DDoS 攻击 复制链接链接已复制到粘贴板!
与 nftables 等数据包过滤器相比,Express Data Path (XDP)在网络接口上处理并丢弃网络数据包。因此,XDP 在到达防火墙或其他应用程序前决定了软件包的下一步。因此,XDP 过滤器需要较少的资源,处理网络数据包的速度要比传统数据包过滤器快得多,从而防止分布式拒绝服务(DDoS)攻击。例如,在测试过程中,红帽在单个核上每秒丢弃了 2,600万个网络数据包,这比同一硬件上 nftables 的丢弃率要高得多。
xdp-filter 工具使用 XDP 允许或丢弃传入的网络数据包。您可以创建规则来过滤与特定对象或特定命令的流量:
- IP 地址
- MAC 地址
- 端口
请注意,即使 xdp-filter 有非常高的数据包处理率,它也没有与 nftables 相同的能力。将 xdp-filter 视为一个概念性工具,来演示使用 XDP 进行数据包过滤。另外,您可以使用工具代码来更好地了解如何编写您自己的 XDP 应用程序。
在 AMD 和 Intel 64 位以外的其他构架上,xdp-filter 工具仅作为技术预览提供。红帽产品服务级别协议(SLA)不支持技术预览功能,且其功能可能并不完善,因此红帽不建议在生产环境中使用它们。这些预览可让用户早期访问将来的产品功能,让用户在开发过程中测试并提供反馈意见。
如需有关 技术预览功能支持范围 的信息,请参阅红帽客户门户网站中的技术预览功能支持范围。
25.1. 丢弃匹配 xdp-filter 规则的网络数据包 复制链接链接已复制到粘贴板!
您可以使用 xdp-filter 丢弃网络数据包:
- 到特定目的地端口
- 从一个指定的 IP 地址
- 从一个指定的 MAC 地址
xdp-filter 的 allow 策略定义所有流量都被允许,过滤器只丢弃与特定规则匹配的网络数据包。例如,如果您知道要丢弃的数据包的源 IP 地址,请使用这个方法。
前提条件
-
xdp-tools软件包已安装。 - 支持 XDP 程序的网络驱动程序。
流程
加载
xdp-filter来处理特定接口上传入的数据包,如enp1s0:# xdp-filter load enp1s0默认情况下,
xdp-filter使用allow策略,并且工具只丢弃与任何规则匹配的流量。(可选)使用
-f <feature>选项只启用特定的功能,如tcp、ipv4或ethernet。仅加载所需的功能而不是全部功能,可以提高数据包处理的速度。要启用多个功能,使用逗号分隔它们。如果该命令出错,则网络驱动程序不支持 XDP 程序。
添加规则来丢弃与它们匹配的数据包。例如:
要将传入数据包放到端口
22,请输入:# xdp-filter port 22这个命令添加一个匹配 TCP 和 UDP 流量的规则。要只匹配特定的协议,请使用
-p protocol选项。要丢弃来自
192.0.2.1的传入数据包,请输入:# xdp-filter ip 192.0.2.1 -m src请注意,
xdp-filter不支持 IP 范围。要丢弃来自 MAC 地址
00:53:00:AA:07:BE的传入数据包,请输入:# xdp-filter ether 00:53:00:AA:07:BE -m src
验证
使用以下命令显示丢弃和允许的数据包统计信息:
# xdp-filter status如果您是开发人员,并对
xdp-filter代码感兴趣,请从红帽客户门户网站下载并安装相应的源 RPM (SRPM)。
25.2. 丢弃所有与 xdp-filter 规则匹配的网络数据包 复制链接链接已复制到粘贴板!
您可以使用 xdp-filter 来只允许网络数据包:
- 来自和到一个特定目的地端口
- 来自和到一个特定 IP 地址
- 来自和到特定的 MAC 地址
要做到这一点,请使用 xdp-filter 的 deny 策略,其定义该过滤器会丢弃所有的网络数据包,与特定规则匹配的除外。例如,如果您不知道要丢弃的数据包的源 IP 地址,请使用这个方法。
如果您在接口上加载 xdp-filter 时将默认策略设为 deny,则内核会立即丢弃来自这个接口的所有数据包,直到您创建允许某些流量的规则。要避免从系统中锁定,在本地输入命令或者通过不同的网络接口连接到主机。
前提条件
-
xdp-tools软件包已安装。 - 您已在本地或通过使用您不打算过滤流量的网络接口登录到主机。
- 支持 XDP 程序的网络驱动程序。
流程
加载
xdp-filter来处理特定接口上的数据包,如enp1s0:# xdp-filter load enp1s0 -p deny(可选)使用
-f <feature>选项只启用特定的功能,如tcp、ipv4或ethernet。仅加载所需的功能而不是全部功能,可以提高数据包处理的速度。要启用多个功能,使用逗号分隔它们。如果该命令出错,则网络驱动程序不支持 XDP 程序。
添加规则以允许匹配它们的数据包。例如:
要允许数据包发送端口
22,请输入:# xdp-filter port 22这个命令添加一个匹配 TCP 和 UDP 流量的规则。要只匹配特定的协议,请将
-p protocol选项传给命令。要允许数据包发送到
192.0.2.1,请输入:# xdp-filter ip 192.0.2.1请注意,
xdp-filter不支持 IP 范围。要允许数据包发送到 MAC 地址
00:53:00:AA:07:BE,请输入:# xdp-filter ether 00:53:00:AA:07:BE
重要xdp-filter工具不支持有状态数据包检查。这要求您不使用-m mode选项设置模式,或者您添加显式规则来允许机器接收传入流量来作为对传出流量的答复。
验证
使用以下命令显示丢弃和允许的数据包统计信息:
# xdp-filter status如果您是开发人员,并且您对
xdp-filter的代码感兴趣,请从红帽客户门户网站下载并安装相应的源 RPM (SRPM)。
第 26 章 使用 xdpdump 捕获包括 XDP 程序丢弃的数据包在内的网络数据包 复制链接链接已复制到粘贴板!
xdpdump 工具捕获网络数据包。与 tcpdump 工具不同,xdpdump 为此使用扩展的 Berkeley 数据包过滤(eBPF)程序。这也可使 xdpdump 能够捕获快速数据路径(XDP)程序丢弃的数据包。用户空间工具(如 tcpdump )无法捕获这些被丢弃的数据包,以及 XDP 程序修改的原始数据包。
您可以使用 xdpdump 来调试已附加到接口上的 XDP 程序。因此,实用程序可以在 XDP 程序启动和完成后捕获数据包。在后一种情况下,xdpdump 也捕获 XDP 操作。默认情况下,xdpdump 会在 XDP 程序的入口处捕获传入的数据包。
在 AMD 和 Intel 64 位以外的其他构架上,xdpdump 工具仅作为技术预览提供。红帽产品服务级别协议(SLA)不支持技术预览功能,且其功能可能并不完善,因此红帽不建议在生产环境中使用它们。这些预览可让用户早期访问将来的产品功能,让用户在开发过程中测试并提供反馈意见。
如需有关 技术预览功能支持范围 的信息,请参阅红帽客户门户网站中的技术预览功能支持范围。
请注意,xdpdump 没有数据包过滤或解码功能。但是,您可以将它与 tcpdump 结合使用来解码数据包。
先决条件
- 支持 XDP 程序的网络驱动程序。
-
XDP 程序被加载到
enp1s0接口。如果没有程序载入,xdpdump会以与tcpdump类似的方式捕获数据包,以便向后兼容。
流程
要捕获
enp1s0接口上的数据包,并将它们写入到/root/capture.pcap文件,请输入:# xdpdump -i enp1s0 -w /root/capture.pcap如果您是开发人员,并且您对
xdpdump的源代码感兴趣,请从红帽客户门户网站下载并安装相应的源 RPM(SRPM)。- 要停止捕获数据包,请按 Ctrl+C。