My issue:
I have configured a default server for port 80 with simply a “return 444;” statement in it. I expected nginx to close all connections that are matched by this server, but it doesn’t. If the client sends a bad request, nginx will return the bad request page instead of dropping the connection.
How I encountered the problem:
I see in the logs that there are not many 444 responses returned, but mostly 400 responses. The correct server block seems to be matched as it logs to its own file.
Solutions I’ve tried:
I have the return statement directly in the server block and I’ve tried in a location /
block, but it still does not trigger as expected.
My config:
http {
include mime.types;
default_type application/octet-stream;
index index.html index.htm;
log_format main '$host $remote_addr - $remote_user [$time_local] "$request" '
'$status $body_bytes_sent "$http_referer" '
'"$http_user_agent" "$http_x_forwarded_for"';
access_log logs/httpblock-default.log main;
sendfile on;
tcp_nopush on;
keepalive_timeout 65;
server_tokens off;
server {
listen 80 default_server;
listen [::]:80 default_server;
server_name _;
access_log logs/server80-default.log main;
return 444;
}
server {
listen 80;
listen [::]:80;
server_name example.com www.example.com;
access_log logs/server80-domain.log main;
return 301 https://$host$request_uri;
}
}
Log examples:
# Remove host: header from request
curl -v -H 'Host:' http://127.0.0.1
# Result:
_ 127.0.0.1 - - [16/Apr/2025:12:48:59 +0100] "GET / HTTP/1.1" 400 150 "-" "curl/8.10.1" "-"
# Set blank host: header on request
curl -v -H 'Host: ' http://127.0.0.1
# Result (user agent suddenly not logged):
_ 127.0.0.1 - - [16/Apr/2025:12:49:08 +0100] "GET / HTTP/1.1" 400 150 "-" "-" "-"
# Requesting a host that doesn't exist works as expected:
curl -v -H 'Host: wrong-host' http://127.0.0.1
# Result ok:
wrong-host 127.0.0.1 - - [16/Apr/2025:12:49:31 +0100] "GET / HTTP/1.1" 444 0 "-" "curl/8.10.1" "-"