标签 nftables 下的文章

我创建了 Linux nftwatch 命令来观察防火墙的流量统计。

Netfilter 表(nftables)是现代 Linux 发行版中的默认防火墙。它在 Fedora 和 RHEL 8、最新的 Debian 和许多其他版本上都有。它取代了早期发行版中捆绑的旧版 iptables。它是一个强大的、值得的 iptables 替代品,作为一个广泛使用它的人,我欣赏它的能力和功能。

nftables 的一个特点是能够为许多元素添加计数器,例如规则。这些都是按需启用的。你需要使用 counter 参数,在每一行明确地要求它。我为我的防火墙中的特定规则启用了这些计数器,这使我能够看到这些规则。

这让我开始思考。我怎样才能实时查看这些计数器?一开始我尝试了 watch,它允许诸如刷新率之类的东西,但我不喜欢默认格式,而且它不能滚动。我发现使用 headtail 以及 awk 也不理想,并不存在一个用户友好的解决方案。所以我自己写了一个,我想与开源社区分享。

Linux 上的 nftwatch 介绍

我的解决方案,我称之为 nftwatch,做了几件事:

  • 它对 nftables 的输出进行重新排序和改写,使其更具有可读性。
  • 它允许向上或向下滚动输出。
  • 可以由用户定义的刷新率(可以实时改变)。
  • 它可以暂停显示。

你得到的不是一个表格的转储,而是显示每个规则活动的输出。

Image of nftwatch

你可以从它的 Git 仓库下载它。

它是 100% 的 Python 代码,100% 的开源,100% 的免费。它满足了所有免费的高质量程序的要求。

在 Linux 上安装 nftwatch

以下是手动安装说明:

  1. 克隆或从 git 仓库下载该项目。
  2. nftwatch.yml 复制到 /etc/nftwatch.yml
  3. nftwatch 复制到 /usr/local/bin/nftwatch 并使用 chmod a+x 授予其可执行权限。
  4. 使用 nftwatch,不带任何参数来运行它。
  5. 参见 nftwatch -m 的手册。

你也可以在没有 YAML 配置文件的情况下运行 nftwatch,在这种情况下它使用内置的默认值。

使用

nftwatch 命令显示 nftables 规则。大多数控制都是为此目的而设计的。

箭头键和等效的 Vim 的按键控制滚动。使用 FS 键来改变刷新速度。使用 P 键来暂停显示。

运行 nftwatch -m 以获得完整的说明,以及交互式按键控制的列表。

防火墙的新观点

即使你花费了时间去配置防火墙,它也会显得晦涩难懂和模糊不清。除了从日志条目中推断指标外,很难判断你的防火墙实际看到的活动类型。 使用 nftwatch,你可以看到你的防火墙在工作,并且可以更好地了解你的网络每天需要处理的流量类型。

(文内图片来自 Kenneth Aaron,CC BY-SA 4.0)


via: https://opensource.com/article/22/7/nftwatch-linux-firewall

作者:Kenneth Aaron 选题:lkxed 译者:geekpi 校对:wxy

本文由 LCTT 原创编译,Linux中国 荣誉推出

这是有关 网络地址转换 network address translation (NAT)的系列文章中的第一篇。这一部分将展示如何使用 iptables/nftables 报文跟踪功能来定位 NAT 相关的连接问题。

引言

网络地址转换(NAT)是一种将容器或虚拟机暴露在互联网中的一种方式。传入的连接请求将其目标地址改写为另一个地址,随后被路由到容器或虚拟机。相同的技术也可用于负载均衡,即传入的连接被分散到不同的服务器上去。

当网络地址转换没有按预期工作时,连接请求将失败,会暴露错误的服务,连接最终出现在错误的容器中,或者请求超时,等等。调试此类问题的一种方法是检查传入请求是否与预期或已配置的转换相匹配。

连接跟踪

NAT 不仅仅是修改 IP 地址或端口号。例如,在将地址 X 映射到 Y 时,无需添加新规则来执行反向转换。一个被称为 “conntrack” 的 netfilter 系统可以识别已有连接的回复报文。每个连接都在 conntrack 系统中有自己的 NAT 状态。反向转换是自动完成的。

规则匹配跟踪

nftables 工具(以及在较小的程度上,iptables)允许针对某个报文检查其处理方式以及该报文匹配规则集合中的哪条规则。为了使用这项特殊的功能,可在合适的位置插入“跟踪规则”。这些规则会选择被跟踪的报文。假设一个来自 IP 地址 C 的主机正在访问一个 IP 地址是 S 以及端口是 P 的服务。我们想知道报文匹配了哪条 NAT 转换规则,系统检查了哪些规则,以及报文是否在哪里被丢弃了。

由于我们要处理的是传入连接,所以我们将规则添加到 prerouting 钩子上。prerouting 意味着内核尚未决定将报文发往何处。修改目标地址通常会使报文被系统转发,而不是由主机自身处理。

初始配置

# nft 'add table inet trace_debug'
# nft 'add chain inet trace_debug trace_pre { type filter hook prerouting priority -200000; }'
# nft "insert rule inet trace_debug trace_pre ip saddr $C ip daddr $S tcp dport $P tcp flags syn limit rate 1/second meta nftrace set 1"

第一条规则添加了一张新的规则表,这使得将来删除和调试规则可以更轻松。一句 nft delete table inet trace_debug 命令就可以删除调试期间临时加入表中的所有规则和链。

第二条规则在系统进行路由选择之前(prerouting 钩子)创建了一个基本钩子,并将其优先级设置为负数,以保证它在连接跟踪流程和 NAT 规则匹配之前被执行。

然而,唯一最重要的部分是第三条规则的最后一段:meta nftrace set 1。这条规则会使系统记录所有匹配这条规则的报文所关联的事件。为了尽可能高效地查看跟踪信息(提高信噪比),考虑对跟踪的事件增加一个速率限制,以保证其数量处于可管理的范围。一个好的选择是限制每秒钟最多一个报文或一分钟最多一个报文。上述案例记录了所有来自终端 $C 且去往终端 $S 的端口 $P 的所有 SYN 报文和 SYN/ACK 报文。限制速率的配置语句可以防范事件过多导致的洪泛风险。事实上,大多数情况下只记录一个报文就足够了。

对于 iptables 用户来讲,配置流程是类似的。等价的配置规则类似于:

# iptables -t raw -I PREROUTING -s $C -d $S -p tcp --tcp-flags SYN SYN  --dport $P  -m limit --limit 1/s -j TRACE

获取跟踪事件

原生 nft 工具的用户可以直接运行 nft 进入 nft 跟踪模式:

# nft monitor trace

这条命令会将收到的报文以及所有匹配该报文的规则打印出来(用 CTRL-C 来停止输出):

trace id f0f627 ip raw prerouting  packet: iif "veth0" ether saddr ..

我们将在下一章详细分析该结果。如果你用的是 iptables,首先通过 iptables –version 命令检查一下已安装的版本。例如:

# iptables --version
iptables v1.8.5 (legacy)

(legacy) 意味着被跟踪的事件会被记录到内核的环形缓冲区中。你可以用 dmesgjournalctl 命令来查看这些事件。这些调试输出缺少一些信息,但和新工具提供的输出从概念上来讲很类似。你将需要首先查看规则被记录下来的行号,并与活跃的 iptables 规则集合手动关联。如果输出显示 (nf_tables),你可以使用 xtables-monitor 工具:

# xtables-monitor --trace

如果上述命令仅显示版本号,你仍然需要查看 dmesg/journalctl 的输出。xtables-monitor 工具和 nft 监控跟踪工具使用相同的内核接口。它们之间唯一的不同点就是,xtables-monitor 工具会用 iptables 的语法打印事件,且如果你同时使用了 iptables-nftnft,它将不能打印那些使用了 maps/sets 或其他只有 nftables 才支持的功能的规则。

示例

我们假设需要调试一个到虚拟机/容器的端口不通的问题。ssh -p 1222 10.1.2.3 命令应该可以远程连接那台服务器上的某个容器,但连接请求超时了。

你拥有运行那台容器的主机的登录权限。现在登录该机器并增加一条跟踪规则。可通过前述案例查看如何增加一个临时的调试规则表。跟踪规则类似于这样:

nft "insert rule inet trace_debug trace_pre ip daddr 10.1.2.3 tcp dport 1222 tcp flags syn limit rate 6/minute meta nftrace set 1"

在添加完上述规则后,运行 nft monitor trace,在跟踪模式下启动 nft,然后重试刚才失败的 ssh 命令。如果规则集较大,会出现大量的输出。不用担心这些输出,下一节我们会做逐行分析。

trace id 9c01f8 inet trace_debug trace_pre packet: iif "enp0" ether saddr .. ip saddr 10.2.1.2 ip daddr 10.1.2.3 ip protocol tcp tcp dport 1222 tcp flags == syn
trace id 9c01f8 inet trace_debug trace_pre rule ip daddr 10.2.1.2 tcp dport 1222 tcp flags syn limit rate 6/minute meta nftrace set 1 (verdict continue)
trace id 9c01f8 inet trace_debug trace_pre verdict continue
trace id 9c01f8 inet trace_debug trace_pre policy accept
trace id 9c01f8 inet nat prerouting packet: iif "enp0" ether saddr .. ip saddr 10.2.1.2 ip daddr 10.1.2.3 ip protocol tcp  tcp dport 1222 tcp flags == syn
trace id 9c01f8 inet nat prerouting rule ip daddr 10.1.2.3  tcp dport 1222 dnat ip to 192.168.70.10:22 (verdict accept)
trace id 9c01f8 inet filter forward packet: iif "enp0" oif "veth21" ether saddr .. ip daddr 192.168.70.10 .. tcp dport 22 tcp flags == syn tcp window 29200
trace id 9c01f8 inet filter forward rule ct status dnat jump allowed_dnats (verdict jump allowed_dnats)
trace id 9c01f8 inet filter allowed_dnats rule drop (verdict drop)
trace id 20a4ef inet trace_debug trace_pre packet: iif "enp0" ether saddr .. ip saddr 10.2.1.2 ip daddr 10.1.2.3 ip protocol tcp tcp dport 1222 tcp flags == syn

对跟踪结果作逐行分析

输出结果的第一行是触发后续输出的报文编号。这一行的语法与 nft 规则语法相同,同时还包括了接收报文的首部字段信息。你也可以在这一行找到接收报文的接口名称(此处为 enp0)、报文的源和目的 MAC 地址、报文的源 IP 地址(可能很重要 - 报告问题的人可能选择了一个错误的或非预期的主机),以及 TCP 的源和目的端口。同时你也可以在这一行的开头看到一个“跟踪编号”。该编号标识了匹配跟踪规则的特定报文。第二行包括了该报文匹配的第一条跟踪规则:

trace id 9c01f8 inet trace_debug trace_pre rule ip daddr 10.2.1.2 tcp dport 1222 tcp flags syn limit rate 6/minute meta nftrace set 1 (verdict continue)

这就是刚添加的跟踪规则。这里显示的第一条规则总是激活报文跟踪的规则。如果在这之前还有其他规则,它们将不会在这里显示。如果没有任何跟踪输出结果,说明没有抵达这条跟踪规则,或者没有匹配成功。下面的两行表明没有后续的匹配规则,且 trace_pre 钩子允许报文继续传输(判定为接受)。

下一条匹配规则是:

trace id 9c01f8 inet nat prerouting rule ip daddr 10.1.2.3  tcp dport 1222 dnat ip to 192.168.70.10:22 (verdict accept)

这条 DNAT 规则设置了一个到其他地址和端口的映射。规则中的参数 192.168.70.10 是需要收包的虚拟机的地址,目前为止没有问题。如果它不是正确的虚拟机地址,说明地址输入错误,或者匹配了错误的 NAT 规则。

IP 转发

通过下面的输出我们可以看到,IP 路由引擎告诉 IP 协议栈,该报文需要被转发到另一个主机:

trace id 9c01f8 inet filter forward packet: iif "enp0" oif "veth21" ether saddr .. ip daddr 192.168.70.10 .. tcp dport 22 tcp flags == syn tcp window 29200

这是接收到的报文的另一种呈现形式,但和之前相比有一些有趣的不同。现在的结果有了一个输出接口集合。这在之前不存在的,因为之前的规则是在路由决策之前(prerouting 钩子)。跟踪编号和之前一样,因此仍然是相同的报文,但目标地址和端口已经被修改。假设现在还有匹配 tcp dport 1222 的规则,它们将不会对现阶段的报文产生任何影响了。

如果该行不包含输出接口(oif),说明路由决策将报文路由到了本机。对路由过程的调试属于另外一个主题,本文不再涉及。

trace id 9c01f8 inet filter forward rule ct status dnat jump allowed_dnats (verdict jump allowed_dnats)

这条输出表明,报文匹配到了一个跳转到 allowed_dnats 链的规则。下一行则说明了连接失败的根本原因:

trace id 9c01f8 inet filter allowed_dnats rule drop (verdict drop)

这条规则无条件地将报文丢弃,因此后续没有关于该报文的日志输出。下一行则是另一个报文的输出结果了:

trace id 20a4ef inet trace_debug trace_pre packet: iif "enp0" ether saddr .. ip saddr 10.2.1.2 ip daddr 10.1.2.3 ip protocol tcp tcp dport 1222 tcp flags == syn

跟踪编号已经和之前不一样,然后报文的内容却和之前是一样的。这是一个重传尝试:第一个报文被丢弃了,因此 TCP 尝试了重传。可以忽略掉剩余的输出结果了,因为它并没有提供新的信息。现在是时候检查那条链了。

规则集合分析

上一节我们发现报文在 inet filter 表中的一个名叫 allowed_dnats 的链中被丢弃。现在我们来查看它:

# nft list chain inet filter allowed_dnats
table inet filter {
 chain allowed_dnats {
  meta nfproto ipv4 ip daddr . tcp dport @allow_in accept
  drop
   }
}

接受 @allow_in 集的数据包的规则没有显示在跟踪日志中。我们通过列出元素的方式,再次检查上述报文的目标地址是否在 @allow_in 集中:

# nft "get element inet filter allow_in { 192.168.70.10 . 22 }"
Error: Could not process rule: No such file or directory

不出所料,地址-服务对并没有出现在集合中。我们将其添加到集合中。

# nft "add element inet filter allow_in { 192.168.70.10 . 22 }"

现在运行查询命令,它将返回新添加的元素。

# nft "get element inet filter allow_in { 192.168.70.10 . 22 }"
table inet filter {
   set allow_in {
      type ipv4_addr . inet_service
      elements = { 192.168.70.10 . 22 }
   }
}

ssh 命令现在应该可以工作,且跟踪结果可以反映出该变化:

trace id 497abf58 inet filter forward rule ct status dnat jump allowed_dnats (verdict jump allowed_dnats)

trace id 497abf58 inet filter allowed_dnats rule meta nfproto ipv4 ip daddr . tcp dport @allow_in accept (verdict accept)

trace id 497abf58 ip postrouting packet: iif "enp0" oif "veth21" ether .. trace id 497abf58 ip postrouting policy accept

这表明报文通过了转发路径中的最后一个钩子 - postrouting

如果现在仍然无法连接,问题可能处在报文流程的后续阶段,有可能并不在 nftables 的规则集合范围之内。

总结

本文介绍了如何通过 nftables 的跟踪机制检查丢包或其他类型的连接问题。本系列的下一篇文章将展示如何检查连接跟踪系统和可能与连接跟踪流相关的 NAT 信息。


via: https://fedoramagazine.org/network-address-translation-part-1-packet-tracing/

作者:Florian Westphal 选题:lujun9972 译者:cooljelly 校对:wxy

本文由 LCTT 原创编译,Linux中国 荣誉推出

随着各 GNU/Linux 系统厂商以及社区逐步开始采用新的内核作为其发行版本的默认内核,防火墙机制采用了更新的 nftables 防火墙机制。

尽管红帽公司提供了 firewalld.service 防火墙服务组件以及相关的配置管理命令 firewall-configfirewall-cmd 来对防火墙进行管理,但该服务组件目前还没有在其他发行版或者社区版本内得到统一使用。

为了更好的帮助读者朋友们理解该防火墙机制,笔者将自己在工作中直接使用 nftables 进行手工创建配置,从而使系统具有本地 IPS 能力的过程进行总结。

目前多数主流的新发行版 GNU/Linux 系统,默认安装完成后 systemd 系统和服务管理器中已经添加了新的 nftables.serivce 子服务配置文件。同时依然支持 iptables 规则和 iptables 命令,不过为了彻底将防火墙升级到 nftables 机制,我们可以在没有 firewalld.service 的发行版系统中直接启用 nftables.service 服务来使用新的防火墙。

通过执行命令 vi /lib/systemd/system/nftables.service,从该文件中的语句 ExecStart=/usr/sbin/nft -f /etc/nftables.conf 我们可以清楚的看到,nftables 防火墙的默认配置和规则文件一般都放置在系统的 /etc/nftables.conf 目录中,不过该默认配置文件中只包含一个名为 inet filter 的简单 IPv4/IPv6 防火墙列表。

inet 过滤器可以同时适用于 IPv4 和 IPv6 的规则,但不能用于 NAT 类型的链,只能用于过滤器类型的链。

为了保持和 iptables 防火墙的规则类比,便于用户熟悉,我们可以使用如下 nftables 命令创建相应的表和链来建立一个类似于传统 iptables 防火墙框架,创建过程如下:

1、创建 nft 表

与 iptables 中的表不同,nftables 中没有内置表,表的数量和名称由用户决定。但是,每个表只有一个地址簇,并且只适用于该簇的数据包。

表可以指定五个(ip、ip6、inet、arp、bridge)簇中的一个,用户可以依次执行如下命令:

nft add table ip filter
nft add table ip6 filter
nft add table bridge filter”

nftables 将为我们分别建立三个 ipipv6bridge 簇并且表名均为 filter 的防火墙框架。

2、创建链

表包含链,链的目的是保存规则。

与 iptables 中的链不同,nftables 也没有内置链。这意味着与 iptables 不同,如果链不匹配 nftables 框架中的簇或钩子,则流经这些链的数据包不会被 nftables 触及。

链有两种类型。基础链是来自网络栈的数据包的入口点,其中指定了钩子,其实可以理解为 iptables 防火墙的默认规则。常规链可以理解为其它用户自定义的规则链。

使用如下命令为每一个表建立 INPUTFORWARDOUTPUT 链,并且设置基础链,其中 ipfilterINPUT 链默认为丢弃所有数据包的相应的命令格式如下。

添加 ipfilter 表相应链命令集:

nft add chain ip filter INPUT { type filter hook input priority 0\; policy drop\; }  

nft add chain ip filter FORWARD { type filter hook forward priority 0\; policy accept\; }  

nft add chain ip filter OUTPUT { type filter hook output priority 0\; policy accept\; }

添加 ipv6filter 表相应链命令集:

nft add chain ip6 filter INPUT { type filter hook input priority 0\; policy accept\; }  

nft add chain ip6 filter FORWARD { type filter hook forward priority 0\; policy accept\; }  

nft add chain ip6 filter OUTPUT { type filter hook output priority 0\; policy accept\; }

添加 bridgefilter 表相应链命令集:

nft add chain bridge filter INPUT { type filter hook input priority 0\; policy accept\; }  

nft add chain bridge filter FORWARD { type filter hook forward priority 0\; policy accept\; }  

nft add chain bridge filter OUTPUT { type filter hook forward priority 0\; policy accept\; }

3、添加规则

规则由语句或表达式构成,包含在链中。

将一条规则添加到链中使用如下语法:

nft add rule family table chain handle statement

规则添加到 handle 处,这是可选的。如果不指定,则规则添加到链的末尾,类似于 iptables -A 方法。

将规则插入到指定位置使用如下语法:

nft insert rule family table chain handle statement

如果未指定handle,则规则插入到链的开头,类似于 iptables -I 方法。

以下是用户根据自己的实际情况添加的具体规则:

放行本地回环接口 lo 的所有流量:

nft add rule ip filter INPUT iif lo accept

放行 establishedrelated 状态的数据包,这一点很重要,因为多数对外访问的数据包在收到对端主机回包时多为这两种状态,如果在 INPUT 链中不放行该类型数据包,即使本机的 OUTPUT 链默认为 ACCEPT,让所有数据包出站,系统也会主动在 INPUT 链中丢弃掉相应的回包而导致数据无法交互。具体命令如下:

nft add rule ip filter INPUT ct state established,related accept

阻断存在重大安全隐患的系统端口,包括已经公布的比如勒索病毒等端口。nftables 在配置过程中,当用户使用端口进行添加后,nftables 会自动将端口转换为 service 模式,用户可以通过使用命令 nft describe tcp dport 对照查看。阻断安全隐患的系统端口具体命令如下:

nft add rule ip filter INPUT meta l4proto tcp tcp dport { loc-srv, 136, netbios-ns, netbios-dgm, netbios-ssn, microsoft-ds, 3389, radmin-port } counter drop

nft add rule ip filter INPUT meta l4proto udp udp dport { loc-srv, 136, netbios-ns, netbios-dgm, netbios-ssn, microsoft-ds, 3389, radmin-port } counter drop

对服务进行限流控制,防止 DDoS 攻击或者 CC 攻击造成系统服务中断,可以通过 limit 限制通信速率,以下是接受一个每秒最多 10 个 web 或者 https 或者 dns 查询请求的数据包,同时可以有 2 个包超出限制的规则具体命令:

nft add rule ip filter INPUT meta l4proto tcp tcp dport { 80,443,53 } ct state new limit rate 10/second burst 4 packets accept
  
nft add rule ip filter INPUT meta l4proto udp udp dport { 80,443,53 } ct state new limit rate 10/second burst 4 packets accept

总结

经过以上配置后,我们的主机就具有了很好的本机 IPS 能力。应对不论是面向南北跨路由器的访问流量,还是本地网络内的东西访问流量,常规的恶意扫描或者恶意攻击基本是够用了。

之后用户可以使用命令 nft list ruleset > /etc/nftables.conf 将这些规则保存在 nftables 的默认配置文件中,并使用 systemctl enable nftables.service 打开该服务的默认启动模式,之后系统将在开机时自动启动 nftables 防火墙并应用相应规则。

用户也可以通过命令 vi /etc/nftables.conf 来直接按照相应规则编辑该文件来修改防火墙配置,以确保自己的系统处于本机防火墙 IPS 能力的保护之下。

希望本文对你有用并能帮助到你。

开源世界中的每个主要发行版都在演进,逐渐将 nftables 作为了默认防火墙。换言之,古老的 iptables 现在已经消亡。本文是有关如何构建 nftables 的教程。

当前,有一个与 nftables 兼容的 iptables-nft 后端,但是很快,即使是它也不再提供了。另外,正如 Red Hat 开发人员所指出的那样,有时它可能会错误地转换规则。我们需要知道如何构建自己的 nftables,而不是依赖于 iptables 到 nftables 的转换器。

在 nftables 中,所有地址族都遵循一个规则。与 iptables 不同,nftables 在用户空间中运行,iptables 中的每个模块都运行在内核(空间)中。它很少需要更新内核,并带有一些新功能,例如映射、地址族和字典。

地址族

地址族确定要处理的数据包的类型。在 nftables 中有六个地址族,它们是:

  • ip
  • ipv6
  • inet
  • arp
  • bridge
  • netdev

在 nftables 中,ipv4 和 ipv6 协议可以被合并为一个称为 inet 的单一地址族。因此,我们不需要指定两个规则:一个用于 ipv4,另一个用于 ipv6。如果未指定地址族,它将默认为 ip 协议,即 ipv4。我们感兴趣的领域是 inet 地址族,因为大多数家庭用户将使用 ipv4 或 ipv6 协议。

nftables

典型的 nftables 规则包含三个部分:表、链和规则。

表是链和规则的容器。它们由其地址族和名称来标识。链包含 inet/arp/bridge/netdev 等协议所需的规则,并具有三种类型:过滤器、NAT 和路由。nftables 规则可以从脚本加载,也可以在终端键入,然后另存为规则集。

对于家庭用户,默认链为过滤器。inet 系列包含以下钩子:

  • Input
  • Output
  • Forward
  • Pre-routing
  • Post-routing

使用脚本还是不用?

最大的问题之一是我们是否可以使用防火墙脚本。答案是:这是你自己的选择。这里有一些建议:如果防火墙中有数百条规则,那么最好使用脚本,但是如果你是典型的家庭用户,则可以在终端中键入命令,然后(保存并在重启时)加载规则集。每种选择都有其自身的优缺点。在本文中,我们将在终端中键入它们以构建防火墙。

nftables 使用一个名为 nft 的程序来添加、创建、列出、删除和加载规则。确保使用以下命令将 nftables 与 conntrackd 和 netfilter-persistent 软件包一起安装,并删除 iptables:

apt-get install nftables conntrackd netfilter-persistent
apt-get purge iptables

nft 需要以 root 身份运行或使用 sudo 运行。使用以下命令分别列出、刷新、删除规则集和加载脚本。

nft list ruleset
nft flush ruleset
nft delete table inet filter
/usr/sbin/nft -f /etc/nftables.conf

输入策略

就像 iptables 一样,防火墙将包含三部分:输入(input)、转发(forward)和输出(output)。在终端中,为输入(input)策略键入以下命令。在开始之前,请确保已刷新规则集。我们的默认策略将会删除所有内容。我们将在防火墙中使用 inet 地址族。将以下规则以 root 身份添加或使用 sudo 运行:

nft add table inet filter
nft add chain inet filter input { type filter hook input priority 0 \; counter \; policy drop \; }

你会注意到有一个名为 priority 0 的东西。这意味着赋予该规则更高的优先级。挂钩通常赋予负整数,这意味着更高的优先级。每个挂钩都有自己的优先级,过滤器链的优先级为 0。你可以检查 nftables Wiki 页面以查看每个挂钩的优先级。

要了解你计算机中的网络接口,请运行以下命令:

ip link show

它将显示已安装的网络接口,一个是本地主机、另一个是以太网端口或无线端口。以太网端口的名称如下所示:enpXsY,其中 XY 是数字,无线端口也是如此。我们必须允许本地主机的流量,并且仅允许从互联网建立的传入连接。

nftables 具有一项称为裁决语句的功能,用于解析规则。裁决语句为 acceptdropqueuejumpgotocontinuereturn。由于这是一个很简单的防火墙,因此我们将使用 acceptdrop 处理数据包。

nft add rule inet filter input iifname lo accept
nft add rule inet filter input iifname enpXsY ct state new, established, related accept

接下来,我们必须添加规则以保护我们免受隐秘扫描。并非所有的隐秘扫描都是恶意的,但大多数都是。我们必须保护网络免受此类扫描。第一组规则列出了要测试的 TCP 标志。在这些标志中,第二组列出了要与第一组匹配的标志。

nft add rule inet filter input iifname enpXsY tcp flags \& \(syn\|fin\) == \(syn\|fin\) drop
nft add rule inet filter input iifname enpXsY tcp flags \& \(syn\|rst\) == \(syn\|rst\) drop
nft add rule inet filter input iifname enpXsY tcp flags \& \(fin\|rst\) == \(fin\|rst\) drop
nft add rule inet filter input iifname enpXsY tcp flags \& \(ack\|fin\) == fin drop
nft add rule inet filter input iifname enpXsY tcp flags \& \(ack\|psh\) == psh drop
nft add rule inet filter input iifname enpXsY tcp flags \& \(ack\|urg\) == urg drop

记住,我们在终端中键入这些命令。因此,我们必须在一些特殊字符之前添加一个反斜杠,以确保终端能够正确解释该斜杠。如果你使用的是脚本,则不需要这样做。

关于 ICMP 的警告

互联网控制消息协议(ICMP)是一种诊断工具,因此不应完全丢弃该流量。完全阻止 ICMP 的任何尝试都是不明智的,因为它还会导致停止向我们提供错误消息。仅启用最重要的控制消息,例如回声请求、回声应答、目的地不可达和超时等消息,并拒绝其余消息。回声请求和回声应答是 ping 的一部分。在输入策略中,我们仅允许回声应答、而在输出策略中,我们仅允许回声请求。

nft add rule inet filter input iifname enpXsY icmp type { echo-reply, destination-unreachable, time-exceeded } limit rate 1/second accept
nft add rule inet filter input iifname enpXsY ip protocol icmp drop

最后,我们记录并丢弃所有无效数据包。

nft add rule inet filter input iifname enpXsY ct state invalid log flags all level info prefix \”Invalid-Input: \”
nft add rule inet filter input iifname enpXsY ct state invalid drop

转发和输出策略

在转发和输出策略中,默认情况下我们将丢弃数据包,仅接受已建立连接的数据包。

nft add chain inet filter forward { type filter hook forward priority 0 \; counter \; policy drop \; }
nft add rule inet filter forward ct state established, related accept
nft add rule inet filter forward ct state invalid drop
nft add chain inet filter output { type filter hook output priority 0 \; counter \; policy drop \; }

典型的桌面用户只需要端口 80 和 443 即可访问互联网。最后,允许可接受的 ICMP 协议并在记录无效数据包时丢弃它们。

nft add rule inet filter output oifname enpXsY tcp dport { 80, 443 } ct state established accept
nft add rule inet filter output oifname enpXsY icmp type { echo-request, destination-unreachable, time-exceeded } limit rate 1/second accept
nft add rule inet filter output oifname enpXsY ip protocol icmp drop
nft add rule inet filter output oifname enpXsY ct state invalid log flags all level info prefix \”Invalid-Output: \”
nft add rule inet filter output oifname enpXsY ct state invalid drop

现在我们必须保存我们的规则集,否则重新启动时它将丢失。为此,请运行以下命令:

sudo nft list ruleset. > /etc/nftables.conf

我们须在引导时加载 nftables,以下将在 systemd 中启用 nftables 服务:

sudo systemctl enable nftables

接下来,编辑 nftables 单元文件以删除 Execstop 选项,以避免在每次引导时刷新规则集。该文件通常位于 /etc/systemd/system/sysinit.target.wants/nftables.service。现在重新启动nftables:

sudo systemctl restart nftables

在 rsyslog 中记录日志

当你记录丢弃的数据包时,它们直接进入 syslog,这使得读取该日志文件非常困难。最好将防火墙日志重定向到单独的文件。在 /var/log 目录中创建一个名为 nftables 的目录,并在其中创建两个名为 input.logoutput.log 的文件,分别存储输入和输出日志。确保系统中已安装 rsyslog。现在转到 /etc/rsyslog.d 并创建一个名为 nftables.conf 的文件,其内容如下:

:msg,regex,”Invalid-Input: “ -/var/log/nftables/Input.log
:msg,regex,”Invalid-Output: “ -/var/log/nftables/Output.log & stop

现在,我们必须确保日志是可管理的。为此,使用以下代码在 /etc/logrotate.d 中创建另一个名为 nftables 的文件:

/var/log/nftables/* { rotate 5 daily maxsize 50M missingok notifempty delaycompress compress postrotate invoke-rc.d rsyslog rotate > /dev/null endscript }

重新启动 nftables。现在,你可以检查你的规则集。如果你觉得在终端中键入每个命令很麻烦,则可以使用脚本来加载 nftables 防火墙。我希望本文对保护你的系统有用。


via: https://opensourceforu.com/2019/10/transition-to-nftables/

作者:Vijay Marcel D 选题:lujun9972 译者:wxy 校对:wxy

本文由 LCTT 原创编译,Linux中国 荣誉推出