所以我认为我的服务器可能正在遭受拒绝服务攻击。
我们收到 pingdom(网站监控)的通知,我们的网站从凌晨 3 点左右开始不可用。今天早些时候,我们开始检查 Apache 错误日志,发现一大堆这样的错误:
AH00485:记分牌已满,未达到 MaxRequestWorkers
我们还发现我们的 PHP-FPM 进程池经常需要生成更多服务器:
[pool www] 似乎很忙(您可能需要增加 pm.start_servers 或 pm.min/max_spare_servers),生成 8 个子进程
我们尝试在 apache conf 中增加 MaxRequestWorkers 并采取一些其他补救措施,但这些都无法消除 apache 错误日志中的记分板错误,因此,我违背自己的判断,遵循了此主题并设置最小空闲线程数和最大空闲线程数等于最大请求工作者数。这些改变似乎已经消除了记分牌错误。
我还大大增加了 MaxRequestWorkers,因为我们有大量的 RAM 显然没有被利用。我们的服务器有 8 个核心,尽管这些配置值非常高,但似乎根本没有使用太多的 RAM:
$ free -h
total used free shared buff/cache available
Mem: 7.8G 1.8G 2.0G 38M 4.0G 5.8G
Swap: 0B 0B 0B
我对 apache conf 中的 MaxRequestWorkers 和 php-fpm 配置中的 pm.max_children 的这些高值感到非常紧张。
这是 mpm_event.conf 中的基本配置
<IfModule mpm_event_module>
StartServers 2
MinSpareThreads 800
MaxSpareThreads 800
ThreadLimit 64
ThreadsPerChild 25
ServerLimit 800
MaxRequestWorkers 800
MaxConnectionsPerChild 0
</IfModule>
以下是 php-fpm conf 文件中的一些设置:
pm.max_children = 256
pm.start_servers = 64
pm.min_spare_servers = 64
pm.max_spare_servers = 128
以下是一些基本的服务器信息:
Server version: Apache/2.4.18 (Ubuntu)
Server built: 2019-10-08T13:31:25
Server's Module Magic Number: 20120211:52
Server loaded: APR 1.5.2, APR-UTIL 1.5.4
Compiled using: APR 1.5.2, APR-UTIL 1.5.4
Architecture: 64-bit
Server MPM: event
threaded: yes (fixed thread count)
forked: yes (variable process count)
以下是来自 apache 服务器状态输出的一些数据:
Server Version: Apache/2.4.18 (Ubuntu) OpenSSL/1.0.2g
Server MPM: event
Server Built: 2019-10-08T13:31:25
Current Time: Friday, 10-Jan-2020 22:58:55 CST
Restart Time: Friday, 10-Jan-2020 22:26:32 CST
Parent Server Config. Generation: 1
Parent Server MPM Generation: 0
Server uptime: 32 minutes 22 seconds
Server load: 4.69 5.06 5.12
Total accesses: 78434 - Total Traffic: 1.5 GB
CPU Usage: u2970.53 s5037.34 cu0 cs0 - 412% CPU load
40.4 requests/sec - 0.8 MB/second - 19.7 kB/request
797 requests currently being processed, 3 idle workers
PID Connections Threads Async connections
total accepting busy idle writing keep-alive closing
6124 28 yes 25 0 0 0 3
6125 27 yes 25 0 0 0 2
6182 30 yes 25 0 0 1 4
6210 28 yes 25 0 0 0 3
6211 29 yes 25 0 0 0 5
6266 28 yes 25 0 0 2 1
6267 25 yes 25 0 0 0 1
6269 28 no 24 1 0 1 3
6276 28 yes 25 0 0 0 3
6378 28 yes 25 0 0 0 3
6379 31 no 24 1 0 4 3
6380 27 yes 25 0 0 0 3
6384 26 yes 25 0 0 0 2
6397 28 yes 25 0 0 2 1
6405 27 yes 25 0 0 0 2
6414 26 yes 25 0 0 1 0
6423 27 no 24 1 0 1 1
6602 27 yes 25 0 0 0 3
6603 28 yes 25 0 0 0 4
6604 26 yes 25 0 0 0 1
6617 30 yes 25 0 0 0 5
6646 26 yes 25 0 0 0 2
6676 27 yes 25 0 0 0 2
6694 30 yes 25 0 0 0 5
6705 28 yes 25 0 0 0 3
6730 29 yes 25 0 0 0 4
6765 29 yes 25 0 0 0 4
6781 27 yes 25 0 0 0 2
6805 28 yes 25 0 0 0 4
6836 28 yes 25 0 0 0 3
6858 27 yes 25 0 0 0 3
6859 27 no 25 0 0 1 1
Sum 888 797 3 0 13 86
工作模式部分最令人不安。几乎每一个都处于读取模式:
RRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRR
RRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRR
RRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRR
RRRRRRR_RRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRR
_RRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRWRRRRRRRRRRRRRRRRRRRRRRRRRRRR
RRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRR
RRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRR_RRRRRRRRRRRRRRRRRRRRRRRRRRRR
RRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRR
RRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRR
RRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRR
RRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRR
RRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRR
RRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRR
最后是这样的:
SSL/TLS Session Cache Status:
cache type: SHMCB, shared memory: 512000 bytes, current entries: 2176
subcaches: 32, indexes per subcache: 88
time left on oldest entries' objects: avg: 220 seconds, (range: 197...243)
index usage: 77%, cache usage: 99%
total entries stored since starting: 60122
total entries replaced since starting: 0
total entries expired since starting: 0
total (pre-expiry) entries scrolled out of the cache: 57946
total retrieves since starting: 3405 hit, 59594 miss
total removes since starting: 0 hit, 0 miss
netstat 显示端口 80 和端口 443 上有超过 3000 个连接:
$ netstat -n | egrep ":80|443" | wc -l
3715
到底发生了什么事?该服务器已经运行了几个月,更加适中的配置设置。昨晚凌晨 3 点左右似乎发生了一些突然的变化。
任何指导都将不胜感激。我先在这里搜索了一下,发现另一个线程但这是运行在 prefork 模式中的不同版本的 apache,而不是像我的一样运行在 event 模式中。我也不明白该帖子中的那一点点信息是如何导致 SlowLoris 诊断的。
编辑看来我必须更精确地表述我的问题:
1) 我如何恢复服务器的响应能力。显然,Apache Workers 陷入了R模式是某些问题的征兆。
2)我可以采取一些可靠的步骤来更具体地识别实际问题吗?
3)有什么方法可以确认机器是否遭受了DoS攻击?
答案1
仅计算记分板上的连接数不足以证明客户态度粗鲁且不跟进他们的连接。这是一个急剧的增长,所以要么是网络应用程序非常受欢迎,要么是有人提出了愚蠢的请求。
查看每秒完成的请求率。假设您的 Web 应用性能良好,那么在有这么多工作线程的情况下,请求率应该相当高。检查 Web 服务器性能的各个方面,包括用户可用带宽、服务器负载以及相关组件(如任何数据库)的性能。修复由于资源不足导致的任何性能问题。
分析连接网络端口的 IP 地址分布。一个 IP 执行数百个连接的情况并不常见,尽管 IPv4 NAT 使这种情况变得复杂。确定源地址的 ISP。检查 IP 地址的安全信誉评分,看看它是否可能是一个巨大的 NAT。
在进行监控的同时,对传入请求进行数据包捕获。您应该至少看到一些来自行为良好的客户端的 HTTP 请求。如果客户端只是连接并待在那里,这看起来有点像 SlowLoris 式的资源耗尽。
考虑链接答案中的调整建议。在 Linux 上,使用 sysctl 等减少超时 net.ipv4.tcp_fin_timeout = 10
是值得尝试的。
考虑将此 Web 服务器置于安全导向和负载平衡代理之后。Web 应用程序防火墙功能可让您采取巧妙措施来过滤请求。水平扩展可让您处理更多请求。
答案2
有什么方法可以确认机器是否遭受了 DoS 攻击?
拒绝服务是拒绝服务。
攻击是为了造成伤害而采取的敌对行动。
(被动攻击是那些不明白这一点的人使用的矛盾修辞法被动的意味着没有采取任何行动——按定义,不采取行动,侵略(按定义来说)也意味着敌对行动。不过,这当然是另一回事了。)
在这两者之间存在一个差距,即它是 DoS,但就敌对行为而言它不是攻击。比如说,除非采取对策,否则用户键盘上的 F5 键卡住会导致 DoS,但它不是以造成伤害为目的的敌对行为的攻击。另一方面,如果用户知道这会导致 DoS 并故意按住该键,则这是一种攻击。
所以回答你的问题——除非你能证明有意图,否则显然不可能确定。如果由于资源不足(超载)导致服务中断,则可以判断它是否是 DoS。