使用 Cloudflare 时,NGINX 速率限制不起作用。我可以使用简单的“ab”命令关闭我的网站

2024-03-02

我根据这篇博客文章实现了一个非常简单但超级有效的速率限制:https://www.nginx.com/blog/rate-limiting-nginx/ https://www.nginx.com/blog/rate-limiting-nginx/

基本上:

limit_req_zone $binary_remote_addr zone=ip:10m rate=10r/s;

limit_req zone=ip burst=20 nodelay;

效果很好。然而,最近我尝试了 Cloudflare,这不再能保护我了。我可以使用以下简单命令自行关闭该网站:

ab -k -c 1000 -n 10000 site.com/

发生了什么?


ab -k -c 1000 -n 10000 site.com/并行运行 1000 个请求,直到总共完成 10 000 个请求。

这也太残忍了吧客户端和服务器很可能都没有经过调整,无法在几秒钟内处理数千个连接。

调整nginx配置并进行温和测试ab -k -c 5 -n 500 site.com/

limit_req_zone $http_cf_connecting_ip zone=ip:10m rate=3r/s;
limit_req zone=ip;

limit_conn_status 429;
limit_req_status 429;

429 请求过多

这配置 nginx 返回标准状态代码429 请求过多 https://developer.mozilla.org/en-US/docs/Web/HTTP/Status/429当请求由于速率限制而被拒绝时。

nginx 返回一个503默认错误(错误的默认值)意味着应用程序失败,但它并没有失败,而是受到速率限制。适当配置状态代码以区分服务器错误和速率限制非常重要。

Cloudflare 和客户端 IP

当在cloudflare后面时,nginx不会看到客户端的IP,而是看到cloudflare服务器的IP。人们可能会认为它打破了 IP 的速率限制,但实际上并没有,只是一点点。

使用 ab 进行本地测试时,您的测试计算机仅解析少数 cloudflare 服务器,并且ab可能只使用第一个IP。因此,不存在大量客户端 IP,速率限制应该可以正常工作。

生产时,会有不同的客户端通过不同的cloudflare服务器访问。尽管如此,一个地理区域内并没有那么多的 cloudflare 服务器和客户端很可能会解析到相同的 cloudflare 服务器。因此,将会有一堆不同的 IP 在某种程度上打破了速率限制,但可能不会那么多。

> nslookup mycloudflaresite.com

Name:    mycloudflaresite.com
Addresses:  104.28.14.125
            104.28.15.125
            2606:4700:3037::681c:e7d
            2606:4700:3036::681c:f7d

Cloudflare 将原始客户端 IP 放入CF-Connecting-IP header.它也可以在X-Forwarded-For标头或X-Real-Ip or True-Client-IP取决于设置和要求。看https://support.cloudflare.com/hc/en-us/articles/200170986-How-does-Cloudflare-handle-HTTP-Request-headers- https://support.cloudflare.com/hc/en-us/articles/200170986-How-does-Cloudflare-handle-HTTP-Request-headers-

因此,上述配置使用客户端 IP 进行速率限制CF-Connecting-IP标头。 nginx 变量$binary_remote_addr将是 cloudflare 服务器 IP。

不使用X-Forwarded-For达到速率限制

The X-Forwarded-Forheader 可以由客户端控制。它不应该用于速率限制,因为它很容易规避。

具有 IP 的客户端的示例100.11.22.33:

  • 根据请求,无需X-Forwarded-Forheader => Cloudflare 集X-Forwarded-For: 100.11.22.33 and CF-Connecting-IP: 100.11.22.33根据要求。
  • 根据要求X-Forwarded-For: dummyvalue标头已设置 => CloudFlare 设置X-Forwarded-For: dummyvalue,100.11.22.33 and CF-Connecting-IP: 100.11.22.33根据要求。

正如您所看到的,客户端为每个请求放置一个随机值并完全规避基于该值的任何速率限制是微不足道的X-Forwaded-For标头。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

使用 Cloudflare 时,NGINX 速率限制不起作用。我可以使用简单的“ab”命令关闭我的网站 的相关文章

  • Pthreads - 高内存使用率

    我正在用 C 编写一些东西 在 256Mb 系统上的 Linux 中创建大量 Pthread 我通常有 200Mb 的免费空间 当我使用少量线程运行该程序时 它可以工作 但是一旦我让它创建大约 100 个线程 它就会出现错误 因为系统内存不
  • 何时用引号将 shell 变量括起来?

    我应该或不应该在 shell 脚本中用引号括住变量吗 例如 下列说法正确的是 xdg open URL eq 2 or xdg open URL eq 2 如果是这样 为什么 一般规则 如果它可以为空或包含空格 或实际上任何空格 或特殊字符
  • Squid 可以在 nginx 后面运行吗?

    我正在尝试在 nginx 后面运行一个鱿鱼服务器 我这样配置 nginx server listen 8080 location proxy pass http localhost 3128 proxy set header Host ho
  • 如何通过ssh获取远程命令的退出代码

    我正在通过 ssh 从远程计算机运行脚本 ssh some cmd my script 现在 我想在本地计算机上存储 shell 脚本的退出状态 我该怎么做 假设没有任何问题ssh其本身 其退出状态是在远程主机上执行的最后一个命令的退出状态
  • Apache 端口转发 80 到 8080 并访问 Apache (80) 中托管的应用程序,即 phpMyadmin 和 Tomcat (8080)

    我想访问托管在 tomcat 服务器 8080 中的应用程序 myapp 当前可以通过以下方式访问http example com 8080 myapp http example com 8080 myapp in http example
  • 选择fasta文件中氨基酸超过300个且“C”出现至少4次的序列

    我有一个包含蛋白质序列的 fasta 文件 我想选择超过 300 个氨基酸且半胱氨酸 C 氨基酸出现超过 4 次的序列 我使用此命令来选择具有超过 300 个 aa 的序列 cat 72hDOWN fasta fasta bioawk c
  • 应用程序中两个不同版本的库

    考虑一个场景 其中有两个不同版本的共享库 考虑 A 1 so 链接到 B so A 2 so 链接到 C so 现在 B so 和 C so 都链接到 d exe 当 B so 想要调用 A 1 so 中的函数时 它最终会调用 A 2 so
  • 任何退出 bash 脚本但不退出终端的方法

    当我使用exitshell 脚本中的命令 该脚本将终止终端 提示符 有什么方法可以终止脚本然后停留在终端中吗 我的剧本run sh预计通过直接获取或从另一个脚本获取来执行 编辑 更具体地说 有两个脚本run2 sh as run sh ec
  • 如何获取与 shell 中的文件名模式匹配的所有文件的总文件大小?

    我正在尝试仅使用 shell 来计算与文件名模式匹配的所有文件 在目录树中 的总大小 以字节为单位 这是我到目前为止所拥有的 find name undo exec stat c s awk 总计 1 END 打印总计 有没有更简单的方法来
  • 在 Linux 中重新启动时,新创建的文件变为 0 kb(数据被覆盖为空)

    我遇到了一个奇怪的问题 这让我发疯 当前的任务是在 root 用户第一次登录时启动一组文件 并在同一用户第二次登录时启动另一组文件 我决定使用 profile 和 bashrc 文件 并在第一次登录期间发生的任务结束时重新加载 bashrc
  • nginx 502 错误网关

    当使用 Spawn fcgi 生成 php5 cgi 时 我收到 502 Bad Gateway with nginx 我使用它来跨越服务器启动上的实例 并在 rc local 中使用以下行 usr bin spawn fcgi a 127
  • MySQL 与 PHP 的连接无法正常工作

    这是我的情况 我正在尝试使用 Apache 服务器上的 PHP 文件连接到 MySQL 数据库 现在 当我从终端运行 PHP 时 我的 PHP 可以连接到 MySQL 数据库 使用 php f file php 但是当我从网页执行它时 它只
  • Python glob,操作系统,相对路径,将文件名放入列表中[重复]

    这个问题在这里已经有答案了 我正在尝试创建一个目录中所有文件的列表 其中文件名以 root 结尾 在阅读了论坛中的一些文章后 我尝试使用 glob 和 os listdir 的基本策略 但我都遇到了麻烦 首先 当我使用 import glo
  • 链接错误:命令行中缺少 DSO

    我对 Linux 使用 Ubuntu 14 04 LTS 64 位 相当陌生 来自 Windows 并且正在尝试移植我现有的 CUDA 项目 当通过链接时 usr local cuda bin nvcc arch compute 30 co
  • 如何在 Linux 上通过 FTP 递归下载文件夹 [关闭]

    Closed 这个问题不符合堆栈溢出指南 help closed questions 目前不接受答案 Locked 这个问题及其答案是locked help locked posts因为这个问题是题外话 但却具有历史意义 目前不接受新的答案
  • nginx设置问题

    我知道这不是一个直接的编程问题 但是 stackoverflow 上的人似乎能够回答任何问题 我有一台运行 Centos 5 2 64 位的服务器 非常强大的双核 2 服务器 具有 4GB 内存 它主要提供静态文件 Flash 和图片 当我
  • awk 在循环中使用时不打印任何内容[重复]

    这个问题在这里已经有答案了 我有一堆使用 file 1 a 1 txt 格式的文件 如下所示 A 1 B 2 C 3 D 4 并使用以下命令添加包含每个文件名称的新列 awk print FILENAME NF t 0 file 1 a 1
  • 相当于Linux中的导入库

    在 Windows C 中 当您想要链接 DLL 时 您必须提供导入库 但是在 GNU 构建系统中 当您想要链接 so 文件 相当于 dll 时 您就不需要链接 为什么是这样 是否有等效的 Windows 导入库 注意 我不会谈论在 Win
  • 如何使用 JSch 将多行命令输出存储到变量中

    所以 我有一段很好的代码 我很难理解 它允许我向我的服务器发送命令 并获得一行响应 该代码有效 但我想从服务器返回多行 主要类是 JSch jSch new JSch MyUserInfo ui new MyUserInfo String
  • FileOutputStream.close() 中的设备 ioctl 不合适

    我有一些代码可以使用以下命令将一些首选项保存到文件中FileOutputStream 这是我已经写了一千遍的标准代码 FileOutputStream out new FileOutputStream file try BufferedOu

随机推荐