I have a server block listening to 80 port requests on a specific server name along with some location directives. How can I make nginx treat any request that doesnt match as if it hadnt received it, that is let it time out? Currently those requests are treated with an 404 error
3 回答
有一种方法可以忽略每个请求并告诉 nginx 什么都不响应:
server {
listen 80 default_server;
return 444;
}
记录在这里: http: //nginx.org/en/docs/http/ngx_http_rewrite_module.html
非标准代码 444 关闭连接而不发送响应头。
如何让 nginx 处理任何不匹配的请求,就好像它没有收到它一样,那就是让它超时?
你不能松开时钟。要找出正在请求的服务器名称(来自 TLS-SNI 和/或Host
标头),nginx 必须首先accept
连接(这将导致操作系统的 TCP/IP 堆栈将 SYN-ACK 数据包发送回请求者,以便推进 TCP 握手)。一旦连接被接受,对方就知道有东西在监听。所以你已经放弃了连接超时的机会。
已经不可挽回地失去了这个机会,下一个机会就是点击套接字接收超时。由于客户端将等待服务器响应某些内容,因此理论上您可以通过完全不响应来触发其接收超时。目前标准 nginx 中没有机制告诉它坐在那里暂时什么都不做,但是如果您也愿意涉及另一块软件,那么您可以使用proxy_pass
指令或类似的指令将该责任转移到另一台服务器. 但是请注意,这将使您的服务器在连接的整个生命周期内使用一定数量的操作系统资源。Nginx 在套接字上运行,而不是原始数据包,操作系统管理这些套接字。
按要求回答了问题后,我认为最好质疑问题的前提。为什么要让客户端超时?如果您的目标是惹恼或“报复”恶意攻击者,那么 nginx 是错误的工具。这是计算机安全领域,您将需要使用在网络堆栈的较低层运行的工具。Nginx 被设计成一个网络服务器,而不是一个蜜罐。
如果您的目标只是隐藏有一个服务器正在侦听的事实,那么您的目标是不可能通过当前 HTTP 的工作方式实现的。防火墙只能通过在连接被接受之前拒绝连接来实现这样的重影。因此,TCP 握手永远不会进行,没有 SYN-ACK 数据包被发送回客户端,并且据任何人所知,整个端口都是一个黑洞。但是在确定请求的服务器名称之后,就不可能这样做了。IP 地址和端口可从第一个数据包获得;服务器名称不是。
在不远的将来的某一天,HTTP 可能会使用 UDP 而不是 TCP,并且请求参数(例如服务器名称)可能会在第一个数据包上预先呈现。然而,除非并且直到这成为常态,否则我上面描述的情况将继续存在。
我假设您正在尝试转移恶意请求。像这样的东西可能会起作用(未经测试)。
设置默认服务器(捕获与现有服务器名称不匹配的任何请求),然后将客户端重定向回自身:
server {
listen 80 default_server;
rewrite ^ http://127.0.0.1/;
}
您必须为有效服务器块内的无效位置设置类似的包罗万象。可能比你想要的更令人头疼。
我不知道这在实践中会有多大用处。考虑 fail2ban 或其他一些可以监控您的日志并在防火墙处禁止客户端的工具可能会更好。