NAT
NAT简介
我们在iptables、firewalld中都介绍过有关NAT的相关部分。那么在nftables中,我们继续介绍nftables中NAT的功能实现方式,配置方法和与前两者的区别。
我们先简单回顾一下NAT的类型和其功能:
这些是不同的网络地址转换(NAT)类型:
伪装和源 NAT(SNAT)
使用以上 NAT 类型之一更改数据包的源 IP 地址。例如,互联网服务提供商(ISP)不会路由私有 IP 范围,如 10.0.0.0/8
。如果在网络中使用私有 IP 范围,并且用户可以访问互联网上的服务器,需要将这些范围内的数据包的源 IP 地址映射到公共 IP 地址。
伪装和 SNAT 相互类似。不同之处是:
- 伪装自动使用传出接口的 IP 地址。因此,如果传出接口使用了动态 IP 地址,则使用伪装。
- SNAT 将数据包的源 IP 地址设置为指定的 IP 地址,且不会动态查找传出接口的 IP 地址。如果传出接口使用了固定 IP 地址,则使用 SNAT。
目标 NAT(DNAT)
使用此 NAT 类型重写传入数据包的目标地址和端口。例如,如果你的 Web 服务器使用私有 IP 范围内的 IP 地址,因此无法直接从互联网访问,则可以在防火墙上设置 DNAT 规则,将传入的流量重定向到此服务器。
重定向
这个类型是 IDT 的特殊示例,它根据链 hook 将数据包重定向到本地机器。例如,如果服务运行在与其标准端口不同的端口上,可以将传入的流量从标准端口重定向到此特定端口。
测试环境
配置参数
snat [[ip | ip6] [ prefix ] to] ADDR_SPEC [:PORT_SPEC] [FLAGS]
dnat [[ip | ip6] [ prefix ] to] ADDR_SPEC [:PORT_SPEC] [FLAGS]
masquerade [to :PORT_SPEC] [FLAGS]
redirect [to :PORT_SPEC] [FLAGS]
ADDR_SPEC := address | address - address
PORT_SPEC := port | port - port
FLAGS := FLAG [, FLAGS]
FLAG := persistent | random | fully-random
SNAT(Source NAT)
语法:snat [[ip | ip6] [prefix] to] ADDR_SPEC [:PORT_SPEC] [FLAGS]
作用:修改数据包的源地址(和可选的源端口)。仅在postrouting和input链中有效。
用途:常用于私有网络访问公网时,将内部网络的源地址转换为公共IP地址。
DNAT(Destination NAT)
语法:dnat [[ip | ip6] [prefix] to] ADDR_SPEC [:PORT_SPEC] [FLAGS]
作用:修改数据包的目的地址(和可选的目的端口)。仅在prerouting和output链中有效。
用途:常用于将外部流量重定向到内部网络中的特定服务器或服务。
MASQUERADE
语法:masquerade [to :PORT_SPEC] [FLAGS]
作用:类似于SNAT,但自动使用出口接口的IP地址进行转换。仅在postrouting链中有效。
用途:特别适用于具有动态(公共)IP地址的网关,因为它不需要手动指定源地址。
REDIRECT
语法:redirect [to :PORT_SPEC] [FLAGS]
作用:特殊形式的DNAT,将数据包的目的地址转换为本地主机地址。可以修改目的端口。
用途:当您只想在不同接口上更改传入流量的目的端口时非常有用。
注意事项
地址和端口规范:ADDR_SPEC可以是单个地址或地址范围(address - address),PORT_SPEC可以是单个端口或端口范围(port - port)。
标志:FLAGS可以是persistent(持久化)、random(随机选择地址/端口)或fully-random(完全随机选择地址/端口)。
前缀关键字:prefix关键字允许映射多个源地址到多个目的地址。
内核版本:在内核5.2及更高版本中,对于IPv4和IPv6地址,dnat和snat语句需要明确指定ip或ip6关键字。在内核4.18之前,需要同时存在prerouting和postrouting基本链,以确保回程数据包能被netfilter看到并进行反向转换。
配置伪装masquerade
在我们的环境中,此时主机A是无法和主机C通信的,因为主机C没有到达主机A的路由。那么我们在主机B上配置SNAT,将数据包出接口转换为主机B的192.168.170.200,那么主机C看到的数据包的源地址就为192.168.170.200,是可以回包的,此时就可以通信。
配置表和链
配置rule规则
测试
也可以通过日志查看该条nat规则是否命中
配置SNAT
源 NAT(SNAT)可让将通过接口发送的数据包 IP 改为专门的 IP 地址。然后,防火墙会替换传出数据包的源 IP。在我们的环境中,在主机B上配置SNAT,将数据包出接口转换为主机B的192.168.170.200。mqsquerade是转换为接口地址,SNAT需要手动指定IP地址。
测试
配置DNAT
目标 NAT (DNAT)可让将防火墙上的流量重定向到无法从互联网直接访问的主机。
在本例中,可以通过配置DNAT实现,访问防火墙接口的22000端口然后重定向到内网主机192.168.140.248的22端口。
配置表和链
配置rule规则
测试
配置重定向
重定向功能是目标网络地址转换(DNAT)的一种特殊情况,它根据链 hook 将数据包重定向到本地计算机。
例如,可以将发送到本地主机端口 20000 的流量重定向到端口 2017
FLOWTABLES
flowtables简介
在 nftables
或类似的网络过滤和流量控制框架中,flowtables
是一种高级特性,用于加速软件中的数据包转发。flowtables
通过存储和缓存转发决策来优化性能,这些决策基于数据包的某些关键属性(如源和目的地址、端口以及层3/4协议)来做出。这种方式可以显著减少对每个数据包都进行完整路由查找和决策。
Flowtables 的基本概念
条目(Entries):flowtables
中的每个条目都代表了一个特定的流量模式,由输入接口、源和目的地址、源和目的端口以及层3/4协议组成。这些条目还缓存了目的接口和网关地址,以便更新目的链路层地址并转发数据包。
缓存和更新:当数据包第一次匹配到 flowtable
中的一个条目时,转发决策(如目的接口和网关)会被缓存。后续具有相同元组的数据包将直接使用这个缓存的决策,而无需再次进行完整的查找过程。这减少了处理时间和CPU负载。
TTL 和 Hop Limit:在转发过程中,flowtables
还会处理TTL(Time to Live,生存时间)和Hop Limit字段的递减。
优先级(Priority):flowtables
可以配置优先级,以确定它们在网络处理过程中的顺序。优先级可以是一个整数,其中较低的数字表示较高的优先级。
地址族(Address Family):flowtables
可以配置为仅处理特定地址族的数据包,如IPv4(ip
)、IPv6(ip6
)或混合IPv4/IPv6(inet
,这是一个虚拟地址族,用于创建同时支持IPv4和IPv6的表)。
配置参数
{add | create} flowtable [family] table flowtable { hook hook priority priority ; devices = { device[, ...] } ; }
list flowtables [family]
{delete | destroy | list} flowtable [family] table flowtable
delete flowtable [family] table handle handle
添加(Add):使用 add 或 create 命令可以为一个给定的地址族添加一个新的 flowtable。需要指定 flowtable 的名称、钩子(hook)、优先级以及可选的设备列表。
列出(List):list 命令用于列出所有已定义的 flowtables,包括它们的名称、地址族和优先级等信息。
删除(Delete/Destroy):delete 命令用于删除指定的 flowtable,如果该 flowtable 不存在,则操作会失败。而 destroy 命令也用于删除 flowtable,但即使指定的 flowtable 不存在,也不会报错。此外,还可以使用 delete flowtable [family] table handle handle 命令通过句柄来删除 flowtable。
配置
nftables
工具使用 netfilter
框架为网络流量提供网络地址转换(NAT),并且提供了基于快速路径功能的 flowtable
机制来加快数据包转发。
table ip nat-flowtable { ... }: 定义了一个名为 nat-flowtable 的 IP 表。
flowtable flowtable-chain { ... }: 在 nat-flowtable 表中定义了一个名为 flowtable-chain 的流表。
hook ingress priority filter: 指定了该流表在数据包流入时触发,且优先级为 filter。这表示该流表将在数据包进入系统时被触发。
nftables 中 flowtable 的 hook 参数后可用的参数取决于使用场景和网络功能,常见的参数包括:
ingress:数据包进入系统时触发。
egress:数据包离开系统时触发。
forward:数据包在系统内部进行路由转发时触发。
input:数据包目的地为本地系统时触发。
output:数据包来源于本地系统时触发。
prerouting:数据包进入路由流程之前触发。
postrouting:数据包离开路由流程之后触发。
devices = { ens33, ens36 }: 指定了应用于此流表的网络设备列表,其中数据包将被处理。设备列表包括 ens33 和 ens36,即仅针对这两个网络接口上的数据包进行处理。
测试
要看到详细的日志信息可以给上面配置的规则添加日志记录功能