在公网裸奔的服务是脆弱的。本篇探讨如何防御常见的网络攻击,并处理各种异常情况。
1. 资源耗尽攻击 (DoS)
1.1. Slowloris 攻击
攻击者建立连接后,发送数据极慢,占满你的连接数。 *
对策: 设置读超时
(bufferevent_set_timeouts)。如果 N
秒内没有读到数据,断开连接。
1.2. 内存撑爆
攻击者疯狂发送数据,如果你处理不过来,input
buffer 会无限增长,导致 OOM。 * 对策:
设置高水位 (bufferevent_setwatermark)。当
buffer 积压超过阈值,停止读取。
1.3. FD 耗尽
当连接数达到 ulimit -n
时,accept 会失败(甚至导致死循环)。 *
对策: 预留一个空闲 fd。当
accept 返回 EMFILE 时,关闭空闲
fd,accept
那个连接,然后立即关闭它,再重新打开空闲 fd。
2. 异常处理
2.1. SIGPIPE
向已关闭的 socket 写入会触发 SIGPIPE
信号,默认终止进程。 * 对策:
在程序启动时忽略它:signal(SIGPIPE, SIG_IGN);。
2.2. 自动重连 (Auto-Reconnect)
客户端断线后需要重连。为了防止雪崩(所有客户端同时重连),必须使用 指数退避 + 抖动 (Exponential Backoff + Jitter)。
// 伪代码
delay = min(cap, base * 2^attempt);
delay = delay / 2 + random(0, delay / 2); // 引入抖动
evtimer_add(reconnect_ev, &delay);3. TLS 安全
在公网传输敏感数据,必须使用 TLS。 * 使用
bufferevent_openssl。 * 定期更新 OpenSSL 库。 *
禁用不安全的协议版本 (SSLv3, TLS 1.0/1.1)。
4. 总结
健壮性不是写出来的,是“防”出来的。通过超时、水位、限流和 TLS,我们可以构建一个“抗揍”的网络服务。
上一篇: 07-hardening/testing.md - 测试与 QA 下一篇: 07-hardening/performance.md - 性能调优