服务器限制一个IP多个访问权限,本质是从Web层、系统内核层、防火墙层、硬件层四个维度设置并发连接数、访问频率和带宽阈值,且必须结合业务场景分层施策,才能既阻断恶意高频访问,又保证正常用户不受误伤。
什么场景下必须限制单个IP的访问量
一台服务器收到来自同一IP的大量请求,不见得都是攻击,但无论出于什么原因,超出业务承载能力的访问都会拖垮服务。
- CC攻击与DDoS变种:攻击者通过代理池或肉鸡,用少数IP发起海量应用层请求,直接打满CPU和数据库连接池,这类场景下,单个IP的请求速率往往数倍于正常用户。
- 爬虫与数据采集:竞争对手或搜索引擎爬虫高频抓取列表页、详情页,消耗带宽和数据库IO,导致真实用户访问变慢。
- 下载站与视频站的热点资源:某个文件被大量用户通过同一出口IP(如公司网络、校园网)下载,带宽被瞬时占满。
- 注册接口与短信接口滥用:同一IP批量注册账号或触发短信验证码,直接造成经济损失。
行业共识认为,服务器层面限制单个IP的访问权限,主要靠四类手段:Web服务器连接数限制、系统内核参数调优、防火墙动态封禁、CDN或负载均衡层的流量清洗,其中前两者解决“并发高”的问题,后两者解决“频率快”和“来源杂”的问题。
服务器限制IP并发连接数的Web层配置方法
大多数业务流量首先到达Nginx或Apache,在Web层做限制是最直接、最灵活的方式,可以按路径、按用户身份区分对待,不用动系统底层。
Nginx限制单IP连接数和请求速率
Nginx提供了ngx_http_limit_conn_module(连接数限制)和ngx_http_limit_req_module(请求速率限制)两个模块,编译安装时通常已内置。
第一步:定义限制维度。 在http块中添加:
limit_conn_zone $binary_remote_addr zone=perip_conn:10m; limit_req_zone $binary_remote_addr zone=perip_req:10m rate=10r/s;
$binary_remote_addr表示以IP地址为key,比$remote_addr节省内存。zone=perip_conn:10m为连接数限制分配10MB共享内存,约能存储16万个IP状态。rate=10r/s表示每秒允许10个请求,超出部分进入排队或直接返回503。
第二步:在server或location块中生效。
server {
limit_conn perip_conn 20; # 单个IP最多同时保持20个连接
limit_req zone=perip_req burst=20 nodelay; # 每秒10个请求,允许突发20个
}
burst=20表示瞬时超过限制的20个请求可以先放入队列,nodelay则让这些突发请求立即被处理而不是排队等待,对于API接口,建议rate=5r/s、burst=10;对于静态资源,可以放宽到rate=30r/s
。
第三步:自定义拒绝页面。 明确告诉来访者被限制的原因,便于排查问题:
limit_conn_status 503; limit_req_status 429; error_page 429 /429.html; error_page 503 /503.html;
- 429状态码表示“请求过多”,适合限速场景。
- 503状态码表示“服务不可用”,适合连接数耗尽场景。
Apache限制单IP并发连接的两种方式
Apache常用mod_evasive模块应对单IP高频访问,但更轻量的是使用mod_ratelimit按客户端IP限制带宽。
mod_evasive(防爆力攻击)
<IfModule mod_evasive20.c>
DOSHashTableSize 3097
DOSPageCount 5 # 同一页面5秒内最多5次
DOSSiteCount 50 # 同一站点5秒内最多50次
DOSBlockingPeriod 10 # 封禁10秒
</IfModule>
mod_ratelimit(按IP限制带宽)
<Location /download>
SetOutputFilter RATE_LIMIT
SetEnv rate-limit 200 # 每秒200KB
</Location>
如何用防火墙限制IP访问频率和连接数
Web层限制在应用进程之内,请求已经到达Nginx或Apache,如果想在流量进入服务器之前就拦截,需要借助Linux防火墙或者云服务商的安全组。
iptables的connlimit模块限制并发连接数
connlimit模块允许你限制每个客户端IP与服务器建立的并发连接数,超过阈值的新连接直接丢弃。
# 限制每个IP最多50个TCP连接 iptables -A INPUT -p tcp --syn --dport 80 -m connlimit --connlimit-above 50 -j REJECT # 限制每个IP最多20个SSH连接(防爆破) iptables -A INPUT -p tcp --syn --dport 22 -m connlimit --connlimit-above 20 -j REJECT
--connlimit-mask参数可以控制匹配的IP网段范围,例如--connlimit-mask 24表示限制一个C段(/24)的总连接数,适合封禁整个出口IP段。
fail2ban动态封禁高频访问IP
fail2ban会扫描日志文件,匹配到预设模式后,自动调用iptables或firewalld封禁IP一段时间,配置路径为/etc/fail2ban/jail.local。
[nginx-limit-req] enabled = true filter = nginx-limit-req action = iptables-multiport[name=nginx, port="http,https"] logpath = /var/log/nginx/error.log findtime = 60 # 60秒内 maxretry = 5 # 出现5次匹配 bantime = 600 # 封禁600秒
对应的过滤器/etc/fail2ban/filter.d/nginx-limit-req.conf:
[Definition] failregex = limiting requests, excess:.client: <HOST>
当Nginx的limit_req日志中反复出现某个IP时,fail2ban会直接升级为防火墙封禁,比Nginx层面的拒绝更彻底。
服务器系统内核参数对单IP访问的限制
Web层和防火墙层都是从应用和网络栈入手,而Linux内核的net.ipv4.tcp参数则从TCP协议栈层面控制连接行为,如果你的服务器频繁出现TIME_WAIT堆积或SYN洪水,调优内核参数往往比加硬件更有效。
| 内核参数 | 默认值 | 推荐值 | 作用 |
|---|---|---|---|
net.ipv4.tcp_max_syn_backlog |
128 | 1024 | 增大半连接队列,抗SYN洪水 |
net.ipv4.tcp_syn_retries |
6 | 2 | 减少SYN重试次数,降低无效连接等待 |
net.ipv4.tcp_fin_timeout |
60 | 15 | 缩短TIME_WAIT回收时间 |
net.ipv4.tcp_tw_reuse |
0 | 1 | 允许复用TIME_WAIT连接 |
修改方式:
sysctl -w net.ipv4.tcp_syn_retries=2 sysctl -w net.ipv4.tcp_fin_timeout=15 sysctl -w net.ipv4.tcp_tw_reuse=1 sysctl -p # 永久生效需写入/etc/sysctl.conf
但请注意,内核参数调优能改善服务器整体并发承载能力,无法精确限制“某一个IP”的访问权限,它更适合配合Web层限制使用,防止单IP拒绝服务后系统资源无法及时释放。
高防IP和CDN的流量清洗对单IP访问频次的控制
如果服务器直接暴露公网IP,无论怎么在系统层限制,攻击流量依然会消耗机房带宽和硬件资源,对于业务价值较高的站点,更稳妥的做法是前置CDN或高防IP。
- 云WAF(Web应用防火墙):在DNS解析层就将流量导向清洗节点,按IP维度设置访问频率阈值,单个IP每分钟超过120次请求自动封禁”,云厂商控制台通常提供图形化配置,无需改动源站代码和系统配置。
- CDN的CC防护:大部分主流CDN提供“访问频率控制”功能,按IP+URL维度统计,支持封禁时长自定义,最小粒度到5秒。
- 高防IP:对于超大流量攻击,高防IP的T级带宽可以吸收DDoS流量,其智能识别算法能区分真实用户和恶意机器人,价格方面,国内主流云厂商的高防IP费用按保底带宽和弹性带宽计费,保底30Gbps的实例月费在数千元区间,具体依地域和套餐而定。
选择这类方案时,需要考虑一个现实问题:源站IP一旦泄露,所有防护都会失效,即使配置了高防IP,服务器本身也要启用安全组或防火墙白名单,只允许高防节点的回源IP访问服务器的80/443端口。
限制单个IP访问权限的四大误区和应对方案
限制措施设置不当,极容易伤及无辜,以下几个问题在实战中相当常见:
连接数阈值设置过低,误伤局域网用户。 校园网、企业出口通常复用少量公网IP,连接数限制在20以内,可能一个办公室的员工共同访问站点就会触发封禁,应对方式:先观察一周的Nginx访问日志,统计正常用户的最大连接数,再乘以1.5~2倍作为阈值。
所有接口统一限速,拖慢正常业务。 登录接口、支付回调、图片上传的请求频率完全不同,应对方式:在Nginx的location块中精细化配置,例如location = /api/login { limit_req zone=login_req burst=5; }
,单独定义宽松或严格的策略。
封禁时间过长,导致搜索引擎爬虫被屏蔽。 百度蜘蛛、谷歌bot的抓取频率较高,且经常从同一IP段发起请求,如果把封禁时间设置为1小时,可能导致站点收录停滞,应对方式:对已知的搜索引擎User-Agent放行,或者在fail2ban中配置ignoreself和ignoreip白名单。
只在单一层级做限制,攻击者轻松绕过。 例如只做了应用层连接数限制,攻击者可以绕开Nginx直接打后端端口,应对方式:Web层、防火墙层、云清洗层三层联动,例如Nginx限制5r/s,iptables限制并发100,云WAF限制每分钟2000次,让每一层各司其职。
服务器怎么限制一个ip多个访问权限的实操顺序
根据上面的分析,实际部署时建议按以下顺序操作,每完成一步就观察效果再进入下一步:
- 开启Nginx或Apache的请求速率限制,这是最精准、影响范围最小的手段,先设置为业务峰值的2倍,观察1~2天。
- 配置iptables的connlimit模块,把并发连接数上限设为Web层限制的5~10倍,防止超量连接占满文件描述符。
- 部署fail2ban动态封禁,让反复触碰限速规则的IP自动进入黑名单,封禁时间从10分钟起逐步递增。
- 调优内核TCP参数,提升服务器的整体抗压能力,避免被限制的IP通过大量半连接耗光系统资源。
- 接入云WAF或高防IP,在源头清洗攻击流量,这一步适合业务已经稳定、有明确营收的场景,因为涉及额外费用。
常见问题
限制单IP访问权限会影响百度蜘蛛抓取吗?
会,但可以通过白名单规避,nginx的limit_req_zone允许通过geo模块或map模块对指定网段放行,百度蜘蛛的IP段是公开的,可以在geo中定义baiduspider网段并跳过限速模块,更简单的做法是优先用robots.txt限制爬虫抓取频率,再用Web层限制兜底。
Nginx的limit_req和iptables的connlimit有什么区别,应该选哪个?
两者解决不同阶段的问题。limit_req是应用层限速,统计的是已完成HTTP握手的请求数,能区分URL和User-Agent,适合精细化控制;connlimit是内核层限制,统计的是TCP连接数,在数据包进入协议栈时就开始拦截,性能更好但无法区分业务,生产环境一般先配connlimit做粗粒度拦截,再配limit_req做细粒度控制,两者并不冲突。
使用云服务器厂商的防火墙安全组能限制单个IP的并发吗?
云厂商安全组本身不支持按IP维度限制并发数,它只能设置源IP的允许或拒绝规则,要限制单个IP的并发,必须在云服务器内部使用iptables的conntrack模块,或者使用云厂商提供的DDoS高防IP和Web应用防火墙产品,部分云厂商的负载均衡SLB实例支持配置“监听连接数限制”,也可以作为前置手段。
首发原创文章,作者:王坚,如若转载,请注明出处:https://idctop.com/article/716516.html





