我有 CentOS 7 VPS。
IPtables 包含 2000 个 IP 阻止规则。重新加载时需要 80 秒才能完成重新加载。
在这 80 秒内,我注意到大约 15 秒后,我的网站变得无响应,并且无法从浏览器访问任何页面。重新加载完成后,站点返回并且可以访问页面。
我想问再次重新加载 IPTables 规则时是否会出现网络无响应?
这是主要结构:
/sbin/iptables -F FORWARD
/sbin/iptables -F OUTPUT
/sbin/iptables -Z FORWARD
/sbin/iptables -Z OUTPUT
/sbin/iptables -P INPUT DROP
/sbin/iptables -A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT
/sbin/iptables -A INPUT -p tcp ! --syn -m state --state NEW -j REJECT --reject-with tcp-reset
/sbin/iptables -A INPUT -m state --state INVALID -j DROP
/sbin/iptables -P OUTPUT DROP
/sbin/iptables -A OUTPUT -m state --state ESTABLISHED,RELATED -j ACCEPT
/sbin/iptables -A OUTPUT -p tcp ! --syn -m state --state NEW -j REJECT --reject-with tcp-reset
/sbin/iptables -A OUTPUT -m state --state INVALID -j DROP
/sbin/iptables -P FORWARD DROP
/sbin/iptables -A FORWARD -m state --state ESTABLISHED,RELATED -j ACCEPT
/sbin/iptables -A FORWARD -p tcp ! --syn -m state --state NEW -j REJECT --reject-with tcp-reset
/sbin/iptables -A FORWARD -m state --state INVALID -j DROP
/sbin/iptables -A INPUT -i lo -j ACCEPT
/sbin/iptables -A OUTPUT -o lo -j ACCEPT
/sbin/iptables -A FORWARD -i lo -o lo -j ACCEPT
/sbin/iptables -t mangle -F
/sbin/iptables -t mangle -Z
/sbin/iptables -t mangle -P PREROUTING ACCEPT
/sbin/iptables -t mangle -P OUTPUT ACCEPT
/sbin/iptables -t mangle -P INPUT ACCEPT
/sbin/iptables -t mangle -P FORWARD ACCEPT
/sbin/iptables -t mangle -P POSTROUTING ACCEPT
/sbin/iptables -t nat -F
/sbin/iptables -t nat -Z
/sbin/iptables -t nat -P PREROUTING ACCEPT
/sbin/iptables -t nat -P OUTPUT ACCEPT
/sbin/iptables -t nat -P POSTROUTING ACCEPT
#
# ACCEPT RULES. JUST A FEW
#
#
/sbin/iptables -I INPUT -s 95.104.79.33 -j ACCEPT
/sbin/iptables -I INPUT -s 108.161.176.0/20 -p tcp -m multiport --dports 80,443 -j ACCEPT
#
# BLOCK RULES. EXCERPT. 2000 RULES MORE
#
#
/sbin/iptables -A INPUT -s 9.101.144.4 -j DROP
/sbin/iptables -A INPUT -s 94.229.64.6 -j DROP
/sbin/iptables -A INPUT -s 973.209.49.7 -j DROP
/sbin/iptables -A INPUT -s 98.150.131.8 -j DROP
/sbin/iptables -A INPUT -s 98.168.114.5 -j DROP
/sbin/iptables -A INPUT -p tcp --dport 12443 -j ACCEPT
/sbin/iptables -A INPUT -p tcp --dport 11443 -j ACCEPT
/sbin/iptables -A INPUT -p tcp --dport 11444 -j ACCEPT
/sbin/iptables -A INPUT -p tcp --dport 8447 -j ACCEPT
/sbin/iptables -A INPUT -p tcp --dport 8443 -j ACCEPT
/sbin/iptables -A INPUT -p tcp --dport 8880 -j ACCEPT
/sbin/iptables -A INPUT -p tcp --dport 80 -j ACCEPT
/sbin/iptables -A INPUT -p tcp --dport 443 -j ACCEPT
/sbin/iptables -A INPUT -p tcp --dport 21 -j ACCEPT
/sbin/iptables -A INPUT -p tcp --dport 22 -j ACCEPT
/sbin/iptables -A INPUT -p tcp --dport 587 -j ACCEPT
/sbin/iptables -A INPUT -p tcp --dport 25 -j ACCEPT
/sbin/iptables -A INPUT -p tcp --dport 465 -j ACCEPT
/sbin/iptables -A INPUT -p tcp --dport 110 -j ACCEPT
/sbin/iptables -A INPUT -p tcp --dport 995 -j ACCEPT
/sbin/iptables -A INPUT -p tcp --dport 143 -j ACCEPT
/sbin/iptables -A INPUT -p tcp --dport 993 -j ACCEPT
/sbin/iptables -A INPUT -p tcp --dport 106 -j ACCEPT
/sbin/iptables -A INPUT -p tcp --dport 3306 -j ACCEPT
/sbin/iptables -A INPUT -p tcp --dport 5432 -j ACCEPT
/sbin/iptables -A INPUT -p tcp --dport 9008 -j ACCEPT
/sbin/iptables -A INPUT -p tcp --dport 9080 -j ACCEPT
/sbin/iptables -A INPUT -p udp --dport 137 -j ACCEPT
/sbin/iptables -A INPUT -p udp --dport 138 -j ACCEPT
/sbin/iptables -A INPUT -p tcp --dport 139 -j ACCEPT
/sbin/iptables -A INPUT -p tcp --dport 445 -j ACCEPT
/sbin/iptables -A INPUT -p udp --dport 1194 -j ACCEPT
/sbin/iptables -A INPUT -p udp --dport 53 -j ACCEPT
/sbin/iptables -A INPUT -p tcp --dport 53 -j ACCEPT
/sbin/iptables -A INPUT -p icmp --icmp-type 8/0 -j ACCEPT
/sbin/iptables -A INPUT -j DROP
/sbin/iptables -A OUTPUT -j ACCEPT
/sbin/iptables -A FORWARD -j DROP
实际上我正在使用Plesk
防火墙重新加载 shell 脚本:firewall-active.sh
防火墙-active.sh
#!/bin/bash
#ATTENTION!
#
#DO NOT MODIFY THIS FILE BECAUSE IT WAS GENERATED AUTOMATICALLY,
#SO ALL YOUR CHANGES WILL BE LOST THE NEXT TIME THE FILE IS GENERATED.
set -e
echo 0 > /proc/sys/net/ipv4/ip_forward
([ -f /var/lock/subsys/ipchains ] && /etc/init.d/ipchains stop) >/dev/null 2>&1 || true
(rmmod ipchains) >/dev/null 2>&1 || true
apply_rule()
{
iptables_bin="$1"
shift
iptables_version=`/sbin/iptables --version | awk -F '.' '{print $2$3}'`
# Use the native --wait option since v1.4.20
if [ $iptables_version -gt 420 ]; then
$iptables_bin -w $@ 2>/dev/null
return $?
fi
# Emulate --wait for elderly versions
for i in `seq 10`; do
$iptables_bin $@ 2>&1 | grep -q xtable || return 0
sleep 1
done
return 1
}
#
# CREATE DELETE RULES BY USING IPTABLES-SAVE
#
#
/sbin/iptables-save -t filter | grep -- "-A INPUT" | grep -v "fail2ban-\|f2b-" | sed -e "s#^-A#apply_rule /sbin/iptables -D#g" | (echo -e "`declare -f apply_rule`\n" && cat ) | /bin/bash
apply_rule /sbin/iptables -F FORWARD
apply_rule /sbin/iptables -F OUTPUT
apply_rule /sbin/iptables -Z FORWARD
apply_rule /sbin/iptables -Z OUTPUT
apply_rule /sbin/iptables -P INPUT DROP
apply_rule /sbin/iptables -A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT
apply_rule /sbin/iptables -A INPUT -p tcp ! --syn -m state --state NEW -j REJECT --reject-with tcp-reset
apply_rule /sbin/iptables -A INPUT -m state --state INVALID -j DROP
apply_rule /sbin/iptables -P OUTPUT DROP
apply_rule /sbin/iptables -A OUTPUT -m state --state ESTABLISHED,RELATED -j ACCEPT
apply_rule /sbin/iptables -A OUTPUT -p tcp ! --syn -m state --state NEW -j REJECT --reject-with tcp-reset
apply_rule /sbin/iptables -A OUTPUT -m state --state INVALID -j DROP
apply_rule /sbin/iptables -P FORWARD DROP
apply_rule /sbin/iptables -A FORWARD -m state --state ESTABLISHED,RELATED -j ACCEPT
apply_rule /sbin/iptables -A FORWARD -p tcp ! --syn -m state --state NEW -j REJECT --reject-with tcp-reset
apply_rule /sbin/iptables -A FORWARD -m state --state INVALID -j DROP
apply_rule /sbin/iptables -A INPUT -i lo -j ACCEPT
apply_rule /sbin/iptables -A OUTPUT -o lo -j ACCEPT
apply_rule /sbin/iptables -A FORWARD -i lo -o lo -j ACCEPT
apply_rule /sbin/iptables -t mangle -F
apply_rule /sbin/iptables -t mangle -Z
apply_rule /sbin/iptables -t mangle -P PREROUTING ACCEPT
apply_rule /sbin/iptables -t mangle -P OUTPUT ACCEPT
apply_rule /sbin/iptables -t mangle -P INPUT ACCEPT
apply_rule /sbin/iptables -t mangle -P FORWARD ACCEPT
apply_rule /sbin/iptables -t mangle -P POSTROUTING ACCEPT
apply_rule /sbin/iptables -t nat -F
apply_rule /sbin/iptables -t nat -Z
apply_rule /sbin/iptables -t nat -P PREROUTING ACCEPT
apply_rule /sbin/iptables -t nat -P OUTPUT ACCEPT
apply_rule /sbin/iptables -t nat -P POSTROUTING ACCEPT
#
# ACCEPT RULES. JUST A FEW
#
#
apply_rule /sbin/iptables -I INPUT -s 95.104.79.33 -j ACCEPT
apply_rule /sbin/iptables -I INPUT -s 108.161.176.0/20 -p tcp -m multiport --dports 80,443 -j ACCEPT
#
# BLOCK RULES. EXCERPT. 2000 RULES MORE
#
#
apply_rule /sbin/iptables -A INPUT -s 9.101.144.4 -j DROP
apply_rule /sbin/iptables -A INPUT -s 94.229.64.6 -j DROP
apply_rule /sbin/iptables -A INPUT -s 973.209.49.7 -j DROP
apply_rule /sbin/iptables -A INPUT -s 98.150.131.8 -j DROP
apply_rule /sbin/iptables -A INPUT -s 98.168.114.5 -j DROP
apply_rule /sbin/iptables -A INPUT -p tcp --dport 12443 -j ACCEPT
apply_rule /sbin/iptables -A INPUT -p tcp --dport 11443 -j ACCEPT
apply_rule /sbin/iptables -A INPUT -p tcp --dport 11444 -j ACCEPT
apply_rule /sbin/iptables -A INPUT -p tcp --dport 8447 -j ACCEPT
apply_rule /sbin/iptables -A INPUT -p tcp --dport 8443 -j ACCEPT
apply_rule /sbin/iptables -A INPUT -p tcp --dport 8880 -j ACCEPT
apply_rule /sbin/iptables -A INPUT -p tcp --dport 80 -j ACCEPT
apply_rule /sbin/iptables -A INPUT -p tcp --dport 443 -j ACCEPT
apply_rule /sbin/iptables -A INPUT -p tcp --dport 21 -j ACCEPT
apply_rule /sbin/iptables -A INPUT -p tcp --dport 22 -j ACCEPT
apply_rule /sbin/iptables -A INPUT -p tcp --dport 587 -j ACCEPT
apply_rule /sbin/iptables -A INPUT -p tcp --dport 25 -j ACCEPT
apply_rule /sbin/iptables -A INPUT -p tcp --dport 465 -j ACCEPT
apply_rule /sbin/iptables -A INPUT -p tcp --dport 110 -j ACCEPT
apply_rule /sbin/iptables -A INPUT -p tcp --dport 995 -j ACCEPT
apply_rule /sbin/iptables -A INPUT -p tcp --dport 143 -j ACCEPT
apply_rule /sbin/iptables -A INPUT -p tcp --dport 993 -j ACCEPT
apply_rule /sbin/iptables -A INPUT -p tcp --dport 106 -j ACCEPT
apply_rule /sbin/iptables -A INPUT -p tcp --dport 3306 -j ACCEPT
apply_rule /sbin/iptables -A INPUT -p tcp --dport 5432 -j ACCEPT
apply_rule /sbin/iptables -A INPUT -p tcp --dport 9008 -j ACCEPT
apply_rule /sbin/iptables -A INPUT -p tcp --dport 9080 -j ACCEPT
apply_rule /sbin/iptables -A INPUT -p udp --dport 137 -j ACCEPT
apply_rule /sbin/iptables -A INPUT -p udp --dport 138 -j ACCEPT
apply_rule /sbin/iptables -A INPUT -p tcp --dport 139 -j ACCEPT
apply_rule /sbin/iptables -A INPUT -p tcp --dport 445 -j ACCEPT
apply_rule /sbin/iptables -A INPUT -p udp --dport 1194 -j ACCEPT
apply_rule /sbin/iptables -A INPUT -p udp --dport 53 -j ACCEPT
apply_rule /sbin/iptables -A INPUT -p tcp --dport 53 -j ACCEPT
apply_rule /sbin/iptables -A INPUT -p icmp --icmp-type 8/0 -j ACCEPT
apply_rule /sbin/iptables -A INPUT -j DROP
apply_rule /sbin/iptables -A OUTPUT -j ACCEPT
apply_rule /sbin/iptables -A FORWARD -j DROP
echo 1 > /proc/sys/net/ipv4/ip_forward
#
# End of script
#
它的实际作用是:
- 首先检查
iptables-save
, - 找
-A INPUT
规律, - 将它们转换为
-D
规则以删除它们。
然后重新加载防火墙,如上图所示。因为有 2000 条单独的规则,所以哪个站点无响应需要 80 秒和 15 秒。
我试图通过并排指定 IP 将那些 2000 条单独的规则合并为 1 条规则,但这没有意义。因为 iptables 无论如何都在表中添加了 2000 条规则。重新加载减少到 40 秒,但仍然很慢。
请问脚本的哪一部分正在创建无响应?
首先,是的,反应迟钝是意料之中的;原因是重新加载通过设置策略和刷新规则集开始。你的脚本做的第一件事是刷新
INPUT
链(实际上,它没有这样的事情,但我怀疑你刚刚离开了前两行),然后将策略设置为DROP
. 设置策略并刷新现有规则集后,您将获得一个带有DROP
策略的空链,该策略立即不允许任何流量通过。随着随后重新加载规则,恢复正常行为。更大的问题是您的规则集的大小。恕我直言,2000 条规则是疯狂的。多年来,我管理了一些非常大
iptables
的防火墙——针对整个站点,而不仅仅是单台机器——并且从未达到 500 条规则,即使在服务十年之后也是如此。2000 条规则对我来说是多年以来“噢,开发者只需要能够从这个地址到这个端口上的这个地址”的味道,没有任何回击、整合,也没有任何规则集上的垃圾收集/清理。坦率地说,具有 2000 个拒绝策略例外的防火墙与其说是防火墙不如说是劣质跳线。我强烈的感觉是,您需要呼吁您的用户社区证明该规则集中的每条规则的合理性,并明确日期,任何尚未使用和业务需要的规则将在该日期前执行。
-m multiport
您可能会发现可以使用用户定义的链、使用 CIDR 后缀-s
和/或等来合并一些需要保留的规则-d
。除非您对该规则集进行大量修剪,否则重新加载它需要一段时间,并且在您执行此操作时防火墙将无法正常运行。