我在 ubuntu 机器上运行了一台装有 apache2 的服务器。这是一个加密货币挖矿池。即使有大量用户访问我们的网站,一切运行正常。然后突然之间,我们所有 8 个核心的 CPU 使用率都达到了 98% 到 100%
我在服务器前使用反向代理来帮助减轻 DDOS 攻击,但这是我从未遇到过的事情。
当这种情况发生时,netstat -an | grep :80 | grep SYN | wc -l 给出 100+ 的输出。
关闭 Apache 后,负载会立即降至正常水平,我的客户端可以继续使用服务器上的其他服务。但我们必须确保前端正常运行。
我尝试了几个 iptables 规则,但是它们不起作用。我根据一些建议修改了我的 sysctl:
net.ipv4.conf.default.rp_filter = 1
net.ipv4.conf.all.rp_filter = 1
net.ipv4.tcp_syncookies = 1
net.ipv4.conf.all.accept_redirects = 0
net.ipv6.conf.all.accept_redirects = 0
net.ipv4.conf.all.send_redirects = 0
net.ipv4.conf.all.accept_source_route = 0
net.ipv6.conf.all.accept_source_route = 0
net.core.wmem_max = 16777216
net.core.rmem_max = 16777216
net.ipv4.tcp_rmem = 4096 87380 16777216
net.ipv4.tcp_wmem = 4096 65536 16777216
net.ipv4.tcp_mem = 128000 200000 262144
net.ipv4.tcp_syncookies = 1
net.ipv4.tcp_synack_retries = 1
net.ipv4.ip_local_port_range = 1024 65000
net.ipv4.tcp_max_syn_backlog = 8192
net.ipv4.tcp_max_tw_buckets = 1800000
net.ipv4.tcp_fin_timeout = 30
net.ipv4.tcp_tw_reuse = 1
net.ipv4.tcp_timestamps = 0
net.ipv4.tcp_tw_recycle = 1
vm.swappiness = 5
net.ipv4.tcp_syncookies = 1
但这似乎并不能缓解问题。
我已经筋疲力尽了,我需要让网站重新启动并运行。
任何建议都将受到赞赏。
谢谢。
答案1
您可以使用以下命令查找每个 IP 当前前 10 个(或其他数字)的 TCP 连接数
netstat -tan| grep -v 'LISTEN'| awk '{print $5}'| grep -v 'and' |grep -v 'Address' |cut -d':' -f1 |sort -n | uniq -c | sort -rn | head -n10
Apache 日志文件中排名前 10 的 IP 如下:cd /var/log/apache2; for i in ./access.log*; do echo $i; cat $i | awk '{print $1}'| sort -n | uniq -c | sort -rn | head -n10; done
一旦确定了滥用的 IP,您就可以使用 来阻止它们iptables -A INPUT -s 1.2.3.4 -j DROP
。
您还可以使用 iptables 对连接进行速率限制,例如,如果您不希望某个源每分钟的连接数超过 20 个:
iptables -I INPUT -p tcp --dport 80 -m state --state NEW -m recent --set
iptables -I INPUT -p tcp --dport 80 -m state --state NEW -m recent --update --seconds 60 --hitcount 20 -j DROP
答案2
您的问题对于“答案”来说有点太笼统,但我确实有几点建议:
第一的,使用您的 hosts.deny 文件,要么只允许好人,要么排除选定的坏人。请记住将您的本地网络放入 hosts.allow 文件中,该文件优先。您可以在 Apache 日志中找到坏人,或者通过这样做(来自今天日志的真实示例)
# BADGUYS=(`grep "authentication failure.*rhost=" /var/log/auth.log | \
sed 's/.*rhost=\(\S*\).*/\1/' | \
sort -u`)
# echo ${BADGUYS[0]}
109.228.29.199
现在阻止他们
# for GUY in ${BADGUYS[*]}; do
> echo "ALL: $GUY" >> /etc/hosts.deny
> done
当您找出最佳的防火墙协议时,这可能足以帮助保持一切正常运转。免责声明:以上代码片段只是示例,并非完整的讨论或解决方案。如上所示,它可能会阻止一些在输入密码时遇到困难的合法用户,因此请审核结果。这就是您希望本地网络处于 中的原因hosts.allow
。
第二,安装DenyHosts
或fail2ban
,它们会自动执行上述操作。我对 DenyHosts 更有经验,但它似乎不再受欢迎了。它针对攻击您的 ssh 服务的主机,但可以阻止所有服务。
第三,解决 iptables 规则问题。Ubuntu 默认不加载规则,但有几种方法可以使其持久化。查看软件包iptables-persistent
。