创建 ACL 以使用 TCP 标志阻止新的 TCP 会话
问题
如何应用访问控制列表 (ACL) 以允许已建立的 TCP 会话流量,并基于 TCP 标志阻止入口端口上的新 TCP 会话?
环境
- Cumulus Linux,所有版本
概述
此解决方案基于以下理论运行:TCP 会话通过由 SYN、SYN-ACK 和 ACK 组成的三次握手建立。只有 SYN 可能存在于新连接中。新连接中不允许 ACK、FIN 和 RST。对于现有会话,SYN 可能存在,但只能与 ACK 一起存在。
默认情况下,Cumulus Linux 在默认目录 /etc/cumulus/acl/policy.d
下的多个 *.rules
文件中对交换机的 ACL 规则进行编码。Cumulus Linux 按排序的文件顺序处理 *.rules 文件。每个 ACL 策略规则文件可能包含标记 [iptables]
、[ip6tables]
和 [etables]
下的 iptables
、ip6tables
和 etables
类别。请注意,您仅将 etables
类别用于第 2 层,因此以下示例未引用它们。
编码规则后,使用 cl-acltool
在硬件中安装并同步它们。
以下示例解决方案在 INPUT 和 FORWARD 链上创建规则,以在设置 SYN 位且 RST、ACK 和 FIN 位重置时,丢弃入口 IPv4 和 IPv6 TCP 数据包。INPUT 和 FORWARD 链的默认设置允许所有其他数据包。cl-acltool
将 ACL 应用于端口 swp20 和 swp21。配置此 ACL 可防止创建源自入口端口 swp20 和 swp21 的新 TCP 会话。ACL 为创建源自任何其他端口的 TCP 会话执行所有操作。
配置 ACL 规则
创建 /etc/cumulus/acl/policy.d/50tcp_established.rules
并添加以下配置
INGRESS_INTF = swp20,swp21
[iptables]
-A INPUT,FORWARD --in-interface $INGRESS_INTF -p tcp --syn -j DROP
[ip6tables]
-A INPUT,FORWARD --in-interface $INGRESS_INTF -p tcp --syn -j DROP
上述规则中的 --syn
标志匹配设置了 SYN 位且清除了 ACK、RST 和 FIN 位的包。
它等效于使用 -tcp-flags SYN,RST,ACK,FIN SYN.
例如,上述规则可以重写为
-A INPUT,FORWARD --in-interface $INGRESS_INTF -p tcp --tcp-flags SYN,RST,ACK,FIN SYN -j DROP
运行 cl-acltool -i
以安装规则。如果 Cumulus Linux 未检测到错误,它将安装规则并与硬件同步。以下输出指示 cl-acltool
已成功安装规则
Reading rule file /etc/cumulus/acl/policy.d/50tcp_established.rules ...
Processing rules in file /etc/cumulus/acl/policy.d/50tcp_established.rules ...
Installing acl policy
done.
验证规则
安装规则后,使用 cl-acltool -L all
检查规则是否存在,以及数据包和字节计数器是否按预期递增。
Chain FORWARD (policy ACCEPT 41224 packets, 4653K bytes)
pkts bytes target prot opt in out source destination
29 1856 DROP tcp -- swp20 any anywhere anywhere tcpflags: FIN,SYN,RST,ACK/SYN
0 0 DROP tcp -- swp21 any anywhere anywhere tcpflags: FIN,SYN,RST,ACK/SYN