防火墙iptables完整篇

2022-07-0179

先决条件

注意: 您的内核需要使用iptables支持进行编译。所有股票Arch Linux内核都有iptables支持。

首先,安装userland实用程序iptables或验证它们是否已经安装。

本文假设当前没有设置iptables规则。要检查当前规则集并验证当前没有运行以下规则的规则:

#iptables-save
#生成的iptables-save v1.4.19.1在Thu Aug 1 19:28:53 2013
*过滤
:INPUT ACCEPT [50:3763]
:FORWARD ACCEPT [0:0]
:OUTPUT ACCEPT [30:3472]
承诺
#完成于8月1日19:28:53 2013

要么

#iptables -nvL --line-numbers
链输入(策略ACCEPT 156数据包,12541字节)num pkts字节目标prot opt输出源目的地

链前进(策略ACCEPT 0数据包,0字节)
num pkts字节目标prot opt输出源目的地

链输出(策略ACCEPT 82数据包,8672字节)
num pkts字节目标prot opt输出源目的地

如果有规则,您可以通过加载默认规则集来重置规则:

#iptables-restore </etc/iptables/empty.rules

否则,请参阅Iptables#重置规则

单机的防火墙

注意:因为iptables以线性顺序处理规则,从链中的顶部到底部,建议将频繁命中规则放在链的开头附近。当然有一个限制,取决于正在实施的逻辑。此外,规则具有相关联的运行时成本,因此不应仅基于对字节/分组计数器的经验观察来重新排序规则。

创建必要的链

对于这个基本设置,我们将创建两个用户定义的链,我们将使用它们来打开防火墙中的端口。

#iptables -N TCP
#iptables -N UDP

链当然可以具有任意名称。我们选择这些只是为了匹配我们想要处理的协议,在后面的规则中,它们是用协议选项指定的,例如-p tcpalways。

FORWARD链

如果您要将设备设置为NAT网关,请查看#设置NAT网关。然而,对于单个机器,我们简单地将FORWARD链的策略设置为DROP并继续:

#iptables -P FORWARD DROP

OUTPUT链

我们不打算过滤任何传出的流量,因为这将使设置更复杂,需要一些额外的思考。在这种简单的情况下,我们将OUTPUT策略设置为ACCEPT

#iptables -P OUTPUT ACCEPT

INPUT链

类似于以前的链,我们将INPUT链的默认策略设置为DROP,以防万一某些原因违反我们的规则。删除所有流量并指定允许的是创建安全防火墙的最佳方法。

警告: 如果您通过SSH登录,以下将立即断开SSH会话。要避免它:(1)添加下面的第一个INPUT链规则(它将保持会话打开),(2)添加一个常规规则以允许入站SSH(在连接断开的情况下能够重新连接)和(3 )设置策略。
#iptables -P INPUT DROP

任何网络接口接收到的每个数据包都将首先通过INPUT链,如果它是发往本机的。在这个链中,我们确保只接受我们想要的数据包。

添加到INPUT链的第一个规则将允许属于已建立连接的流量,或与这些连接相关的新有效流量,例如ICMP错误或回应应答(主机在ping时返回的数据包)。ICMP代表Internet控制消息协议。一些ICMP消息是非常重要的,并且帮助管理拥塞和MTU,并且被这条规则接受。

连接状态ESTABLISHED意味着在设置规则时,其他规则先前允许initial(--ctstate NEW)连接尝试或连接已处于活动状态(例如活动的远程SSH连接)

#iptables -A INPUT -m conntrack --ctstate RELATED,ESTABLISHED -j ACCEPT

第二个规则将接受来自“环回”(lo)接口的所有流量,这对于许多应用和服务是必要的。

注意:如果您不想/需要由防火墙过滤的流量,您可以在此处添加更多受信任的接口(例如“eth1”),但警告,如果您有一个NAT设置,任何类型的流量重定向到此接口从任何其他地方在网络(让我们说一个路由器),它会通过,无论你可能有任何其他设置。
#iptables -A INPUT -i lo -j ACCEPT

第三个规则将删除所有具有“INVALID”状态匹配的流量。流量可以分为四个“状态”类别:新建,已建立,相关或无效,这是什么使得这是一个“有状态”防火墙,而不是不安全的“无状态”。使用“nf_conntrack_ *”内核模块跟踪状态,在添加规则时由内核自动加载。

注意:
  • 此规则将丢弃具有无效标头或校验和,无效TCP标记,无效的ICMP消息(例如,当我们没有向主机发送任何东西时端口不可达)的所有分组,以及可能由序列预测或其他类似的攻击。“DROP”目标将丢弃一个数据包而没有任何响应,与拒绝该数据包的REJECT相反。我们使用DROP,因为没有对INVALID的数据包的正确的“REJECT”响应,我们不想确认我们收到这些数据包。
  • ICMPv6邻居发现分组保持未被跟踪,并且将总是被分类为“INVALID”,尽管它们没有被破坏等。记住这一点,并在此规则之前接受他们!iptables -A INPUT -p 41 -j ACCEPT
#iptables -A INPUT -m conntrack --ctstate INVALID -j DROP

下一个规则将接受所有新的传入ICMP回显请求,也称为ping。只有第一个数据包计数为NEW,其余数据包将由RELATED,ESTABLISHED规则处理。由于计算机不是路由器,不需要允许具有状态NEW的其他ICMP流量。

#iptables -A INPUT -p icmp --icmp-type 8 -m conntrack --ctstate NEW -j ACCEPT

现在我们将TCP和UDP链连接到INPUT链以处理所有新的传入连接。一旦连接被TCP或UDP链接受,它由RELATED / ESTABLISHED流量规则处理。TCP和UDP链将接受新的传入连接,或礼貌地拒绝它们。必须使用SYN数据包启动新的TCP连接。

注意: NEW,但不是SYN是唯一无效的TCP标志不被INVALID状态覆盖。原因是因为它们很少是恶意数据包,并且它们不应该被丢弃。相反,我们根本不接受它们,因此它们被下一个规则的TCP复位拒绝。
#iptables -A INPUT -p udp -m conntrack --ctstate NEW -j UDP
#iptables -A INPUT -p tcp --syn -m conntrack --ctstate NEW -j TCP

如果端口未打开,我们拒绝TCP连接与TCP RESET数据包和UDP数据流与ICMP端口不可达消息。这模仿默认的Linux行为(符合RFC),并允许发送方快速关闭连接和清理。

#iptables -A INPUT -p udp -j REJECT --reject-with icmp-port-unreachable
#iptables -A INPUT -p tcp -j REJECT --reject-with tcp-reset

对于其他协议,我们向INPUT链添加最终规则,以使用icmp协议不可达消息拒绝所有剩余的传入流量。这模仿了Linux的默认行为。

#iptables -A INPUT -j REJECT --reject-with icmp-proto-unreachable

示例iptables.rules文件

iptables.rules运行上面所有命令后的文件示例:

/etc/iptables/iptables.rules
#生成的iptables-save v1.4.18在Sun Mar 17 14:21:12 2013
*过滤
:INPUT DROP [0:0]
:FORWARD DROP [0:0]
:OUTPUT ACCEPT [0:0]
:TCP  -  [0:0]
:UDP  -  [0:0]
-A INPUT -m conntrack -ctstate RELATED,ESTABLISHED -j ACCEPT
-A INPUT -i lo -j ACCEPT
-A INPUT -m conntrack --ctstate INVALID -j DROP
-A INPUT -p icmp -m icmp --icmp-type 8 -m conntrack --ctstate NEW -j ACCEPT
-A INPUT -p udp -m conntrack --ctstate NEW -j UDP
-A INPUT -p tcp --tcp-flags FIN,SYN,RST,ACK SYN -m conntrack --ctstate NEW -j TCP
-A INPUT -p udp -j REJECT --reject-with icmp-port-unreachable
-A INPUT -p tcp -j REJECT --reject-with tcp-reset
-A INPUT -j REJECT --reject-with icmp-proto-unreachable
承诺
#完成于2013年3月17日14:21:12 2013

此文件可以使用以下命令生成:

#iptables-save> /etc/iptables/iptables.rules

并可用于继续以下部分。如果您通过SSH远程设置防火墙,请在继续之前附加以下规则以允许新的SSH连接(根据需要调整端口):

-A TCP -p tcp --dport 22 -j ACCEPT

TCP和UDP链

TCP和UDP链包含用于接受新的传入TCP连接和UDP流到特定端口的规则。

注意:在这里您需要添加规则以接受传入连接,例如SSH,HTTP或您要远程访问的其他服务。

打开端口到传入连接

要在Web服务器的端口80上接受传入TCP连接:

#iptables -A TCP -p tcp --dport 80 -j ACCEPT

要在Web服务器(HTTPS)的端口443上接受传入TCP连接:

#iptables -A TCP -p tcp --dport 443 -j ACCEPT

允许远程SSH连接(在端口22上):

#iptables -A TCP -p tcp --dport 22 -j ACCEPT

要在DNS服务器的端口53上接受传入的UDP流:

#iptables -A UDP -p udp --dport 53 -j ACCEPT

查看man iptables更多高级规则,如匹配多个端口。

港口爆震

端口敲击是一种外部打开端口的方法,默认情况下,防火墙保持关闭。它通过要求连接尝试到一系列预定义的封闭端口来工作。当接收到正确的端口“敲击”序列(连接尝试)时,防火墙打开某些端口以允许连接。有关详细信息,请参阅港口爆破。

防止欺骗攻击

注意: rp_filter当前默认设置为 1in  /usr/lib/sysctl.d/50-default.conf,因此不需要执行以下步骤。

阻止来自互联网或本地网络的保留本地地址通常通过将rp_filtersysctl中的(反向路径过滤器)设置为1.为此,请将以下行添加到您的/etc/sysctl.d/90-firewall.conf文件中(有关详细信息,请参阅sysctl)以启用源地址验证内置于Linux内核本身。内核的验证将针对每种情况处理比个别iptables规则更好的欺骗。

net.ipv4.conf.all.rp_filter = 1

如果需要统计(和更好的日志记录),可以使用netfilter:

#iptables -t raw -I PREROUTING -m rpfilter --invert -j DROP
注意:没有理由在两个地方启用此功能。netfilter方法是现代选择,并且与IPv6一起工作。

对于使用异步路由的特定设置,rp_filter=2需要使用sysctl选项。将--loose开关传递给rpfilter模块将完成与netfilter相同的事情。

“隐藏”您的计算机

如果您正在运行桌面计算机,最好阻止一些传入请求。

阻止ping请求

“Ping”请求是发送到目的地址的ICMP分组,以确保设备之间的连接。如果您的网络工作正常,您可以安全地阻止所有ping请求。要注意,这是很重要的给您发送的数据包将被拒绝,这样你就会仍处在一个IP范围的简单的nmap的“ping扫描”显示-实际上隐藏在您的计算机。

这是基本的“保护”,并使生活困难时调试问题在未来。你应该只为教育目的这样做。

要阻止回显请求,请将以下行添加到您的/etc/sysctl.d/90-firewall.conf文件(有关详细信息,请参阅sysctl):

net.ipv4.icmp_echo_ignore_all = 1

更多信息在iptables的手册页,或阅读网页上的文档和示例http://www.snowman.net/projects/ipt_recent/

Tricking端口扫描仪

注意:这将打开一个形式的 DoS。攻击可以发送带有欺骗IP的数据包,并阻止它们连接到您的服务。

攻击者使用端口扫描来识别计算机上的打开端口。这允许他们识别和指纹你正在运行的服务,并可能针对他们发动攻击。

INVALID状态规则将处理除UDP,ACK和SYN扫描之外的每种类型的端口扫描(分别是nmap中的-sU,-sA和-sS)。

ACK扫描不用于标识打开的端口,而是用于标识由防火墙过滤的端口。由于对具有状态NEW的所有TCP连接的SYN检查,由ACK扫描发送的每个单个分组将被TCP RESET分组正确拒绝。一些防火墙丢弃这些数据包,这允许攻击者映射出防火墙规则。

最近的模块可以用来欺骗剩余的两种类型的端口扫描。最近的模块用于将主机添加到“最近”列表,可用于指纹和停止某些类型的攻击。可以查看当前最近的列表/proc/net/xt_recent/

SYN扫描

在SYN扫描中,端口扫描器向每个端口发送SYN数据包。封闭端口返回TCP RESET数据包,或者被严格的防火墙丢弃。打开的端口返回SYN ACK数据包,而不管防火墙是否存在。

最近的模块可用于跟踪具有拒绝连接尝试的主机,并返回它们发送到打开端口的任何SYN数据包的TCP重置,就像端口被关闭一样。如果打开的端口是第一个被扫描的端口,仍将返回SYN ACK,因此需要在非标准端口上运行诸如ssh等应用程序,以使其始终如一地工作。

首先,在TCP链的顶部插入一个规则。此规则用TCP RESET对过去六十秒内进入TCP-PORTSCAN列表的任何主机做出响应。该--update开关使得最近的列表被更新,意味着60秒计数器被重置。

#iptables -I TCP -p tcp -m recent --update --seconds 60 --name TCP-PORTSCAN -j REJECT --reject-with tcp-reset

接下来,需要修改拒绝TCP分组的规则,以将具有被拒绝分组的主机添加到TCP-PORTSCAN列表。

#iptables -D INPUT -p tcp -j REJECT --reject-with tcp-reset
#iptables -A INPUT -p tcp -m recent --set --name TCP-PORTSCAN -j REJECT --reject-with tcp-reset
UDP扫描

UDP端口扫描类似于TCP SYN扫描,除了UDP是“无连接”协议。没有握手或致谢。相反,扫描器向每个UDP端口发送UDP数据包。Closed端口应返回ICMP端口不可达消息,并且打开的端口不返回响应。由于UDP不是“可靠”协议,因此扫描器无法知道数据包是否丢失,并且必须对不返回响应的每个端口执行多个检查。

Linux内核发出ICMP端口不可达消息的速度非常慢,因此针对Linux机器的完整UDP扫描将花费10个小时。但是,仍然可以识别公共端口,因此对SYN扫描使用与UDP扫描相同的对策是一个好主意。

首先,添加一条规则,以拒绝来自UDP-PORTSCAN列表中主机的数据包到UDP链的顶部。

#iptables -I UDP -p udp -m recent --update --seconds 60 --name UDP-PORTSCAN -j REJECT --reject-with icmp-port-unreachable

接下来,修改UDP的拒绝数据包规则:

#iptables -D INPUT -p udp -j REJECT --reject-with icmp-port-unreachable
#iptables -A INPUT -p udp -m recent --set --name UDP-PORTSCAN -j REJECT --reject-with icmp-port-unreachable
还原最终规则

如果使用上述端口扫描技巧之一或两者,则最终默认规则不再是INPUT链中的最后一个规则。它需要是最后的规则,否则它会拦截你刚才添加的特技端口扫描器规则,它们将永远不会被使用。只需删除规则(-D),然后再次使用append(-A)将其添加到链的末尾。

#iptables -D INPUT -j REJECT --reject-with icmp-proto-unreachable
#iptables -A INPUT -j REJECT --reject-with icmp-proto-unreachable

防止其他攻击

请参阅sysctl#TCP / IP堆栈硬化相关的内核参数。

暴力攻击

不幸的是,对通过外部IP地址可访问的服务的强力攻击是常见的。这样做的一个原因是,使用许多可用工具很容易进行攻击。幸运的是,有一些方法来保护服务免受他们。一个是使用适当的iptables规则,其在设定数量的分组尝试发起连接之后激活和黑名单IP。另一个是使用专门的守护程序监视失败的尝试的日志文件和黑名单相应。

警告:使用IP黑名单将阻止轻微的攻击,但它依赖于一个额外的守护进程和成功的日志记录(分区包含/ var可能变满,特别是如果攻击者在服务器上冲击)。此外,如果攻击者知道您的IP地址,他们可以发送带有欺骗性源头的数据包,并让您锁定服务器。 SSH密钥为没有这些问题的暴力强制的问题提供了一个优雅的解决方案。

两个在密码失败过多之后禁止IP的程序包是Fail2bansshd特别是Sshguard。这两个应用程序更新iptables规则以拒绝来自列入黑名单的IP地址的未来连接。

以下规则提供了一个示例配置,以减轻使用的SSH强力攻击iptables

#iptables -N IN_SSH
#iptables -A INPUT -p tcp --dport ssh -m conntrack --ctstate NEW -j IN_SSH
#iptables -A IN_SSH -m recent --name sshbf --rttl --rcheck --hitcount 3 --seconds 10 -j DROP#iptables -A IN_SSH -m recent --name sshbf --rttl --rcheck --hitcount 4 --seconds 1800 -j DROP #iptables -A IN_SSH -m recent --name sshbf --set -j ACCEPT

大多数选项应该是不言自明的,它们允许在十秒内三个连接包。在那段时间的进一步尝试将黑名单的IP。下一个规则通过在30分钟内允许总共四次尝试来添加一个怪癖。这是因为一些暴力攻击实际上执行得很慢,而不是一连串的尝试。规则采用了一些附加选项。要阅读有关它们的更多信息,请检查此示例的原始引用:compilefailure.blogspot.com

使用上述规则,现在确保:

#iptables -A INPUT -p tcp --dport ssh -m conntrack --ctstate NEW -j IN_SSH

在iptables.rules文件中的适当位置。

Tango-edit-clear.png本文或部分需要语言,wiki语法或样式改进。Tango-edit-clear.png

原因:以下代码段显示INPUT链中哪一点应该跳到IN_SSH,但描述不清楚。(讨论在 谈话:简单状态防火墙#

这个安排适用于IN_SSH规则,如果你遵循了整个wiki到目前为止:

*:
-A INPUT -p icmp -m icmp --icmp-type 8 -m conntrack --ctstate NEW -j ACCEPT
-A INPUT -p tcp --dport 22 -m conntrack --ctstate NEW -j IN_SSH
-A INPUT -p udp -m conntrack --ctstate NEW -j UDP
*:

上述规则当然可以用于保护任何服务,尽管保护SSH守护程序可能是最常用的一种。

提示:为了在设置后自动测试规则,实际的黑名单发生可能减慢测试,使其难以微调参数。可以通过观看传入的尝试 cat /proc/net/xt_recent/sshbf。要在测试期间解除自己的IP,需要root # echo / > /proc/net/xt_recent/sshbf

保存规则

规则集现在完成,应该保存到您的硬盘驱动器,以便它可以在每次启动时加载。

systemd单元文件指向将保存规则配置的位置:

iptables = / etc / iptables / iptables.rules
ip6tables = / etc / iptables / ip6tables.rules

使用此命令保存规则:

#iptables-save> /etc/iptables/iptables.rules

并确保您的规则在启动时加载启用iptables systemd服务。

通过启动 iptables.service,然后检查服务的状态,检查规则加载是否正确。

IPv6

如果你不使用IPv6(大多数ISP不支持它),你应该禁用它

否则,应启用IPv6的防火墙规则。在复制IPv4规则作为基础之后:

#cp /etc/iptables/iptables.rules /etc/iptables/ip6tables.rules

第一步是将规则中引用的IP从IPv4格式更改为IPv6格式。

接下来,一些规则(作为本文中针对IPv4的示例构建)必须进行调整。IPv6获得了新的ICMPv6协议,取代了ICMP。因此,拒绝错误返回码--reject-with icmp-port-unreachable--reject-with icmp-proto-unreachable必须转换为ICMPv6码。

RFC 4443中列出了可用的ICMPv6错误代码,它指定了防火墙规则应该使用的连接尝试--reject-with icmp6-adm-prohibited。这样做将基本上通知远程系统连接被防火墙拒绝,而不是侦听服务。

如果优选不明确通知防火墙过滤器的存在,则还可以拒绝该分组,而没有消息:

 -A INPUT -j REJECT

上面将拒绝与默认返回错误--reject-with icmp6-port-unreachable。您应该注意,识别防火墙是端口扫描应用程序的基本功能,大多数将识别它。

Tango-view-fullscreen.png本文或部分需要扩展。Tango-view-fullscreen.png

原因:应该添加哪些ICMPv6特性以使规则与本文使用的IPv4规则相同?(讨论在 谈话:Simple_stateful_firewall#ICMP阻塞

在下一步中,确保协议和扩展名更改为IPv6适用于有关所有新的传入ICMP回显请求(ping)的规则:

#ip6tables -A INPUT -p ipv6-icmp --icmpv6-type 128 -m conntrack --ctstate NEW -j ACCEPT

Netfilter conntrack似乎不跟踪ICMPv6邻居发现协议(IPv6的等效ARP),因此我们需要允许ICMPv6流量,不管所有直接连接的子网的状态。在删除之后--ctstate INVALID,但在任何其他DROP或REJECT目标之前插入以下内容,以及每个直接连接的子网的相应行:

#ip6tables -A INPUT -s fe80 :: / 10 -p icmpv6 -j ACCEPT

由于没有用于IPv6的内核反向路径过滤器,您可能需要在ip6tables中启用以下内容:

#ip6tables -t raw -A PREROUTING -m rpfilter -j ACCEPT
#ip6tables -t raw -A PREROUTING -j DROP

配置完成后,使ip6tables服务,它的目的是在并行运行的iptables

设置NAT网关

本指南的本部分涉及NAT网关。假定您已经阅读了指南第一部分,并设置了INPUTOUTPUTTCPUDP链,如上所述。到目前为止,所有规则都已在过滤器表中创建。在本节中,我们还将使用nat表。

设置过滤器表

创建必要的链

在我们的设置中,我们将使用过滤表中的另外两个链,fw-interfacesfw-open链。使用命令创建它们

#iptables -N fw-interfaces
#iptables -N fw-open

设置FORWARD链

设置FORWARD链与第一部分中的INPUT链类似。

现在我们使用conntrack匹配设置一个规则,与INPUT链中的规则相同:

#iptables -A FORWARD -m conntrack --ctstate RELATED,ESTABLISHED -j ACCEPT

下一步是启用对可信接口的转发,并使所有数据包通过fw-open链。

#iptables -A FORWARD -j fw-interfaces 
#iptables -A FORWARD -j fw-open 

剩余的数据包被拒绝与ICMP消息:

#iptables -A FORWARD -j REJECT --reject-with icmp-host-unreachable
#iptables -P FORWARD DROP

设置fw-interfaces和fw-open链

当我们分别处理nat表中的POSTROUTINGPREROUTING链时,fw-interfacesfw-open链的含义将在后面解释。

设置nat表

在本节中,我们假设出接口(具有公共互联网IP的接口)是ppp0。请记住,如果您的外出接口具有其他名称,则必须更改所有以下规则中的名称。

设置POSTROUTING链

现在,我们必须定义谁可以连接到互联网。假设我们有子网192.168.0.0/24(这意味着的形式192.168.0的所有地址。*)上的eth0。我们首先需要在FORWARD表中接受这个接口上的机器,这就是为什么我们在上面创建了fw-interfaces链:

#iptables -A fw-interfaces -i eth0 -j ACCEPT

现在,我们必须更改所有传出的数据包,以使它们具有我们的公共IP地址作为源地址,而不是本地LAN地址。为此,我们使用MASQUERADE目标:

#iptables -t nat -A POSTROUTING -s 192.168.0.0/24 -o ppp0 -j MASQUERADE

不要忘记上面的-o ppp0参数。如果你省略它,你的网络将被拧紧。

让我们假设我们在接口eth1上有另一个子网,10.3.0.0/16(意思是所有地址10.3。*。*)。我们再加上相同的规则:

#iptables -A fw-interfaces -i eth1 -j ACCEPT
#iptables -t nat -A POSTROUTING -s 10.3.0.0/16 -o ppp0 -j MASQUERADE

最后一步是启用数据包转发(如果尚未启用)。

来自这些子网的机器现在可以使用您的新NAT设备作为其网关。请注意,您可能想要设置DNS和DHCP服务器,如dnsmasqbinddhcpd的组合,以简化客户端计算机上的网络设置DNS解析。这不是本指南的主题。

设置PREROUTING链

有时,我们想要将来自网关的传入数据包的地址更改为LAN机器。要做到这一点,我们使用FW打开上面定义的链,以及在PREROUTING链中的NAT在以下两个简单的例子表。

首先,我们要将所有传入的SSH数据包(端口22)更改为机器192.168.0.5的ssh服务器:

#iptables -t nat -A PREROUTING -i ppp0 -p tcp --dport 22 -j DNAT --to 192.168.0.5
#iptables -A fw-open -d 192.168.0.5 -p tcp --dport 22 -j ACCEPT

第二个示例将向您展示如何将数据包更改为与传入端口不同的端口。我们要将端口8000上的任何传入连接更改为192.168.0.6端口80上的Web服务器:

#iptables -t nat -A PREROUTING -i ppp0 -p tcp --dport 8000 -j DNAT --to 192.168.0.6:80
#iptables -A fw-open -d 192.168.0.6 -p tcp --dport 80 -j ACCEPT

相同的设置也适用于udp数据包。

保存规则

保存规则:

#iptables-save> /etc/iptables/iptables.rules

并确保在启动启用iptables systemd服务时加载您的规则。