Syn 攻击是最常见又最容易被利用的一种攻击手法, 利用 TCP 协议的缺陷, 发送大量伪造 TCP 连接请求, 常用假冒的 IP 发来海量的 SYN 包, 被攻击的服务器回应 SYN+ACK, 因为对方是假冒的 IP, 永远收不到包并且不会回应, 导致被攻击服务器保持大量 SYN_RECV 状态的半连接, 并且会重试默认 5 次回应握手包, 塞满 TCP 等待连接队列, 资源耗尽, 让正常的业务请求连接不进来.
Syn 攻击常见于应用服务器, 而数据库服务器在内网中, 应该很难碰到类似的攻击, 但有时候应用程序如果和数据库建连姿势不正确, 在数据库端, 也会被认为是 Syn 攻击, 并拒绝连接建立.
[问题描述]
数据库突发的拒绝链接, 应用报错, 出问题的时间点上, 数据库服务器的操作系统日志里, 即 / var/log/messages, 可看到如下报错信息:
kernel: possible SYN flooding on port 3306. Sending cookies.
[问题分析]
出问题的点上, 从数据库的监控指标来看, Threads Connected 这个指标有增长. 这个也是很明显, 因为对数据库来说, Syn Flooding 就是应用程序突发的对数据库发起建连, 操作系统处理不过来, 所以报 Syn Flooding, 从数据库的性能指标来看, 连接数肯定是会有一个突发的增长. 应对方案就是需要分析这些突发的增长是怎么来的, 削峰填谷, 让连接更平稳.
[解决方案]
在数据库服务端, 做如下调整: 这个调整的意思是说: 增加 TCP 半连接的缓冲, 默认值是 2048, 我们调整到 8192, 让系统的抗突发压力增大一些. Tcp_syn_retires 和 Tcp_synack_retires 默认是 5, 也就是服务器端要发送五次包, 才会终止重试, 我们把这个参数调整为 2. 只重试一次, 让出错的包尽量提早出错, 以减少缓存的连接数.
- echo 8192> /proc/sys.NET/ipv4/tcp_max_syn_backlog
- echo 2> /proc/sys.NET/ipv4/tcp_syn_retries
- echo 2> /proc/sys.NET/ipv4/tcp_synack_retries
这个参数调整, 即时生效, 无需重启. 当然服务器重启后, 这些参数也会回退到默认值. 经此调整, 数据库端的抗压能力得到加强, 但并没有完全解决问题.
我们在客户端也做相应调整:
为减少数据库的连接数压力, 通常我们建议连接池做如下配置:
testWhileIdle="false". 空闲时不检测连接串健康
minIdle="0". 连接池里面空闲连接的最小个数
maxAge="30000". 一个链接超过多少毫秒就可以回收掉.
initialSize="1". 连接池里面初始连接的最小个数
timeBetweenEvictionRunsMillis="5000". 回收线程的运行间隔 (毫秒)
对于现在的场景, 我们建议调高 minIdle 这个参数, 从 0 调整到 5. 让连接池平时有 5 个空闲连接存在, 这样, 发起对数据库请求的时候, 会先使用这 5 个空闲连接. 达到削峰填谷的作用. 当然, 副作用就是数据库平时的连接数会增长. 具体调整到多少合适, 需要结合实际的数据库连接负载情况. 对于. NET 程序, 也有相应的连接池参数可以调整: 可以适当修改 minPoolSize 这个参数, 也调整到 5.
经此调整, 基本上大部分的数据库 Syn Flooding 问题都能解决.
当然, 这些都是调优的手段, 只能是微微的改善系统. 提高抗压能力. 最终的分析, 还是要看连接压力从何而来. 以及为何需要突发建立大量连接到数据库. 对于此种突发场景, 用数据库是否合适. 替代方案是前面用 Redis 加一层缓冲. 避免突发的对数据库发起建连请求. 这个就涉及到应用的改造了.
来源: https://www.cnblogs.com/CtripDBA/p/11038499.html