Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How can I tell nginx to silently ignore requests that dont match and let them time out instead of giving 404

Tags:

nginx

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

like image 846
Paralife Avatar asked Jul 18 '12 10:07

Paralife


2 Answers

There is a way to ignore every request and tell nginx to respond nothing:

server {
  listen 80 default_server;
  return 444;
}

Documented here: http://nginx.org/en/docs/http/ngx_http_rewrite_module.html

The non-standard code 444 closes a connection without sending a response header.

like image 185
ahofmann Avatar answered Sep 23 '22 05:09

ahofmann


How can I make nginx treat any request that doesnt match as if it hadnt received it, that is let it time out?

You can't unwind the clock. To find out what server name is being requested (from TLS-SNI and/or Host header), nginx must first accept the connection (which will cause the operating system's TCP/IP stack to send a SYN-ACK packet back to the requestor, in order to advance the TCP handshake). Once the connection has been accepted, the other side knows something is listening. So you've already foregone the opportunity for a connection timeout.

Having irrevocably lost that opportunity, the next opportunity you have is to hit the socket receive timeout. Since the client will be waiting for the server to respond with something, you could theoretically trigger its receive timeout by not responding at all. There is no mechanism in standard nginx currently to tell it to sit there and do nothing for a while, but if you are willing to involve another piece of software as well, then you could use the proxy_pass directive or similar to offload that responsibility to another server. Beware, however, that this will keep some amount of operating system resources in use by your server for the life of the connection. Nginx operates on sockets, not raw packets, and the operating system manages those sockets.

Having answered the question as asked, I think it's better to question the premise of the question. Why do you want the client to time out? If your goal is to mess with or "pay back" a malicious attacker, nginx is the wrong tool. This is the space of computer security and you're going to need to use tools that operate at a lower layer on the networking stack. Nginx is designed to be a webserver, not a honeypot.

If your goal is simply to hide the fact that there's a server listening at all, then your goal is impossible to achieve with the way HTTP works currently. Firewalls are only able to achieve ghosting like that by rejecting the connection before it's accepted. Thus, the TCP handshake never proceeds, no SYN-ACK packet gets sent back to the client, and as far as anyone can tell that entire port is a black hole. But it's not possible to do this after determining what server name has been requested. The IP address and port are available from the very first packet; the server name is not.

Someday in the not-so-distant future, HTTP may use UDP instead of TCP, and the request parameters (such as the server name) may be presented up front on the first packet. Unless and until that becomes the norm, however, the situation I describe above will remain.

like image 35
kbolino Avatar answered Sep 21 '22 05:09

kbolino