使用iptables connlimit模块限制单ip并发连接数,需在input链中配合--syn匹配新建连接,指定端口和--connlimit-above阈值,如iptables -a input -p tcp --syn --dport 80 -m connlimit --connlimit-above 10 -j reject;必须加--syn且置于-m connlimit前,否则会误拦已建立连接或语法错误。

connlimit模块怎么限制单IP并发连接数
用 iptables 的 connlimit 模块是最直接、最轻量的运行时连接数限制手段,适用于 Web、SSH、数据库等服务端口。它不依赖用户级配置,也不改内核参数,只在 Netfilter 层做连接计数拦截。
常见错误是把 --syn 漏掉或写错位置——不加 --syn 会匹配所有包(包括 ACK、FIN),导致误拦已建立连接;写在 -m connlimit 后面则语法报错。
- 限制每个 IP 对 80 端口最多 10 个并发 TCP 连接:
iptables -A INPUT -p tcp --syn --dport 80 -m connlimit --connlimit-above 10 -j REJECT - 限制 SSH(22 端口)每 IP 最多 3 个新连接,超限直接丢弃(不发 RST):
iptables -A INPUT -p tcp --syn --dport 22 -m connlimit --connlimit-above 3 -j DROP - 若服务监听多个端口(如 80+443),需为每个端口单独加规则,
connlimit不支持端口范围写法(--dport 80:443无效)
注意:该规则仅对 IPv4 生效;IPv6 需用 ip6tables 单独配置,且模块名相同、参数一致。
systemd 服务的文件描述符限制为什么总不生效
很多用户改完 /etc/security/limits.conf,ulimit -n 也显示正确,但 nginx 或 redis 进程的 Max open files 仍是 1024——根本原因是 systemd 完全不读 limits.conf,哪怕你给 root 写了硬限制也没用。
必须显式配置 unit 文件,否则服务启动时继承的是 systemd 默认的 LimitNOFILE=1024(CentOS/RHEL 8+ 和 Ubuntu 20.04+ 均如此)。
- 全局设默认值(影响所有新启服务):
sudo systemctl edit --full systemd-system.conf,加入DefaultLimitNOFILE=65536 - 单服务精准控制(推荐):
sudo systemctl edit nginx.service,写入:[Service] LimitNOFILE=65536
- 改完必须执行
sudo systemctl daemon-reload,再sudo systemctl restart nginx,否则旧进程不会重读 - 验证是否生效:
cat /proc/$(pgrep -f "nginx: master")/limits | grep "Max open files",看Soft Limit和Hard Limit是否匹配
net.core.somaxconn 和 fs.file-max 有什么区别
net.core.somaxconn 控制的是单个 socket 的**监听队列长度**,即 accept 队列能暂存多少个已完成三次握手但还没被应用 accept() 的连接;而 fs.file-max 是系统级**所有进程能打开的文件描述符总数上限**,TCP 连接只是其中一种 fd 类型。
两者缺一不可,但作用层级不同:前者过小会导致高并发下连接被内核直接丢弃(客户端看到 connection timeout 或 connection refused);后者过小则进程 socket() 或 accept() 直接失败(日志里出现 “Too many open files”)。
- 查当前值:
sysctl net.core.somaxconn、cat /proc/sys/fs/file-max - 临时调大:
sysctl -w net.core.somaxconn=32768、sysctl -w fs.file-max=2097152 - 永久生效:写入
/etc/sysctl.conf,然后sysctl -p - 注意:
fs.file-max建议设为内存 KB 数的 10% 左右(例如 32GB 内存 → ~3.2M),但不要盲目设到 10M 以上,可能引发 slab 内存碎片问题
为什么开了 connlimit 还被扫号工具打穿
因为 connlimit 只防“连接数”,不防“连接频次”。扫号工具常使用大量代理 IP 轮换,每个 IP 只建 1–2 个连接,绕过单 IP 限制;或者用短连接快速发请求,靠的是请求密度而非并发数。
这时候需要组合策略:
- 用
limit模块限制新连接速率(如每分钟最多 5 个 SYN 包):iptables -A INPUT -p tcp --syn --dport 22 -m limit --limit 5/min --limit-burst 5 -j ACCEPT - 配合
recent模块封禁频繁试探的源 IP:iptables -A INPUT -p tcp --syn --dport 22 -m recent --name ssh --set+iptables -A INPUT -p tcp --syn --dport 22 -m recent --name ssh --rcheck --seconds 60 --hitcount 10 -j REJECT - 真正要防自动化攻击,得上
fail2ban解析应用日志(如 Nginx access.log 中的 401/403),比 iptables 规则更准
最后提醒一句:所有 iptables 规则重启后丢失,记得用 iptables-save > /etc/sysconfig/iptables(RHEL/CentOS)或 iptables-persistent(Debian/Ubuntu)固化;systemd 的 LimitNOFILE 和 sysctl 参数也务必写进配置文件,否则 reboot 就回退。











