我遇到了 DDoS 问题,我认为我解决了它,但是解决方案却给我带来了麻烦。
经过几个月的痛苦尝试和几乎所有尝试之后,我终于通过逐个阻止 IP 并使用以下命令拒绝它们解决了问题:
deny ip;
我将所有被拒绝的 IP 都包含在一个文件中,并将其包含到我的配置中。现在该文件包含超过 190 万个 IP,我无法阻止 IP 范围,只能阻止特定 IP。
Nginx 现在重新启动所需的时间太长了。如果我将包含的文件拆分为两个 900 000 的文件或四个 500 000 的文件,这会有什么不同吗?
有什么方法可以让 Nginx 更快地检查文件?
答案1
对于这种大小的文件,我不会在 nginx 中执行此操作,而是在 iptables 中执行:
#!/bin/bash
# here's your list of IPS
CURRENT_BL=/path/to/my/ip_black_list.txt
# create/flush recreate the tables
iptables -F BLACKHOLE
iptables -N BLACKHOLE
for BAD_IP in $(cat $CURRENT_BL)
do
ipset add ipset-blacklist $BAD_IP 2>/dev/null || \
echo "Failed to add ${BAD_IP}"
done
# REJECT the matching target
iptables -A BLACKHOLE -p all -m set --match-set ipset-blacklist src -j REJECT
iptables -A BLACKHOLE -j RETURN
# assume your nginx is on 80 and 443
iptables -A INPUT -p tcp -m multiport --destination-ports 80,443 -j BLACKHOLE
iptables -A INPUT -p tcp -m multiport --destination-ports 80,443 -j ACCEPT
这允许您附加新 IP:
ipset add ipset-blacklist X.X.X.X
无需重新加载 nginx 或整个列表。性能非常出色
编辑:
为了使上述所有功能正常工作,你需要安装 ipset 和 iptables
apt-get install iptables ipset
为了使这些规则永久生效,您可以使用 iptables-save 和 iptables-restore 将当前定义的 iptables 规则保存到文件中并(重新)加载它们(例如,在重新启动时)。
例如,你可以运行
sudo iptables-save | sudo tee /etc/iptables.conf
将当前的 iptables 规则保存到 /etc/iptables.conf,然后在 /etc/rc.local 中插入以下行:
# Load iptables rules from this file
iptables-restore < /etc/iptables.conf
不要忘记确保 /etc/rc.local 是可执行的
编辑 2:此版本将列表拆分为两个 ipset,一个用于 ipv4,另一个用于IPv6 协议,除了正则表达式之外没有检查任何内容的语法,但应该可以工作。
警告正则表达式非常非常长,请确保复制整行
#!/bin/bash
# here's your list of IPS
CURRENT_BL=/path/to/my/ip_black_list.txt
# create/flush recreate the tables
iptables -F BLACKHOLE
iptables -N BLACKHOLE
# inverse regex matches everything except ipv6 addresses
for IPV4 in $(egrep -v "(([0-9a-fA-F]{1,4}:){7,7}[0-9a-fA-F]{1,4}|([0-9a-fA-F]{1,4}:){1,7}:|([0-9a-fA-F]{1,4}:){1,6}:[0-9a-fA-F]{1,4}|([0-9a-fA-F]{1,4}:){1,5}(:[0-9a-fA-F]{1,4}){1,2}|([0-9a-fA-F]{1,4}:){1,4}(:[0-9a-fA-F]{1,4}){1,3}|([0-9a-fA-F]{1,4}:){1,3}(:[0-9a-fA-F]{1,4}){1,4}|([0-9a-fA-F]{1,4}:){1,2}(:[0-9a-fA-F]{1,4}){1,5}|[0-9a-fA-F]{1,4}:((:[0-9a-fA-F]{1,4}){1,6})|:((:[0-9a-fA-F]{1,4}){1,7}|:)|fe80:(:[0-9a-fA-F]{0,4}){0,4}%[0-9a-zA-Z]{1,}|::(ffff(:0{1,4}){0,1}:){0,1}((25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])\.){3,3}(25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])|([0-9a-fA-F]{1,4}:){1,4}:((25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])\.){3,3}(25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9]))" $CURRENT_BL)
do
ipset add ipset-blacklist-ipv4 $IPV4 family inet 2>/dev/null > /dev/null
done
# regular expression matches only ipv6 addresses
for IPV6 in $(egrep "(([0-9a-fA-F]{1,4}:){7,7}[0-9a-fA-F]{1,4}|([0-9a-fA-F]{1,4}:){1,7}:|([0-9a-fA-F]{1,4}:){1,6}:[0-9a-fA-F]{1,4}|([0-9a-fA-F]{1,4}:){1,5}(:[0-9a-fA-F]{1,4}){1,2}|([0-9a-fA-F]{1,4}:){1,4}(:[0-9a-fA-F]{1,4}){1,3}|([0-9a-fA-F]{1,4}:){1,3}(:[0-9a-fA-F]{1,4}){1,4}|([0-9a-fA-F]{1,4}:){1,2}(:[0-9a-fA-F]{1,4}){1,5}|[0-9a-fA-F]{1,4}:((:[0-9a-fA-F]{1,4}){1,6})|:((:[0-9a-fA-F]{1,4}){1,7}|:)|fe80:(:[0-9a-fA-F]{0,4}){0,4}%[0-9a-zA-Z]{1,}|::(ffff(:0{1,4}){0,1}:){0,1}((25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])\.){3,3}(25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])|([0-9a-fA-F]{1,4}:){1,4}:((25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])\.){3,3}(25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9]))" $CURRENT_BL)
do
ipset add ipset-blacklist-ipv6 $IPV6 family inet6 2>/dev/null > /dev/null
done
# REJECT the matching target
iptables -A BLACKHOLE -p all -m set --match-set ipset-blacklist-ipv4 src -j REJECT
ip6tables -A BLACKHOLE -p all -m set --match-set ipset-blacklist-ipv6 src -j REJECT
iptables -A BLACKHOLE -j RETURN
# assume your nginx is on 80 and 443
iptables -A INPUT -p tcp -m multiport --destination-ports 80,443 -j BLACKHOLE
iptables -A INPUT -p tcp -m multiport --destination-ports 80,443 -j ACCEPT