Http request not caught by nginx server block?What is the difference between server_name _ and server_name “” in Nginx?nginx ssl proxy for one hostname onlyProperly setting up a “default” nginx server for httpsNGINX don't parse .php5 as .phpNginx/Apache: set HSTS only if X-Forwarded-Proto is httpsNginX + WordPress + SSL + non-www + W3TC vhost config file questions403 Forbidden nginx (nginx/1.8.0)nginx PHP files downloading instead of executingHow to serve Autodiscover.xml using NginxWhy Nginx calls for invalid certificate in non-existent subdomains just to redirect to 404?Nginx reverse proxy to many local servers + webserver duty
I have found ports on my Samsung smart tv running a display service. What can I do with it?
At what temperature should the earth be cooked to prevent human infection?
How to avoid offending original culture when making conculture inspired from original
How should a Buddhist approach honoring parents who abused them?
How do I become a better writer when I hate reading?
Cut power on a remote Raspberry Pi 3 via another raspi
What is a Cawdle?
1960s sci-fi anthology with a Viking fighting a U.S. army MP on the cover
What are the mechanical differences between Adapt and Monstrosity?
Is it possible for underground bunkers on different continents to be connected?
Someone who is granted access to information but not expected to read it
Basic power tool set for Home repair and simple projects
How to address players struggling with simple controls?
My student in one course asks for paid tutoring in another course. Appropriate?
First occurrence in the Sixers sequence
What uses does D&D 5e have for a d100?
TiKZ won't graph 1/sqrt(x)
How can Caller ID be faked?
How to search for Android apps without ads?
100-doors puzzle
Sci-fi series about a mercenary with a spaceship with AI
Arduino simple resistors in series
Usage of "Es tut mir leid" by male German speakers and appropriate expressions to express empathy and understaning
Right indicator flash-frequency has increased and rear-right bulb is out
Http request not caught by nginx server block?
What is the difference between server_name _ and server_name “” in Nginx?nginx ssl proxy for one hostname onlyProperly setting up a “default” nginx server for httpsNGINX don't parse .php5 as .phpNginx/Apache: set HSTS only if X-Forwarded-Proto is httpsNginX + WordPress + SSL + non-www + W3TC vhost config file questions403 Forbidden nginx (nginx/1.8.0)nginx PHP files downloading instead of executingHow to serve Autodiscover.xml using NginxWhy Nginx calls for invalid certificate in non-existent subdomains just to redirect to 404?Nginx reverse proxy to many local servers + webserver duty
.everyoneloves__top-leaderboard:empty,.everyoneloves__mid-leaderboard:empty,.everyoneloves__bot-mid-leaderboard:empty height:90px;width:728px;box-sizing:border-box;
I have an nginx server with exactly one site configuration (the default site).
I keep seeing the following lines in my access.log
xxx.xxx.xxx.xxx - - [10/Jul/2018:16:32:14 +0200] "GET / HTTP/1.1" 400 37 "-" "-"
I know for a fact that this happens if the request doesn't send a Host:header, as in curl -v -H "Host:" https:// server_ip
root@mypc:~# curl -v -H "Host:" http:// server_ip
* Rebuilt URL to: http:// server_ip /
* Trying server_ip ...
* Connected to server_ip ( server_ip ) port 80 (#0)
> GET / HTTP/1.1
> User-Agent: curl/7.47.0
> Accept: */*
>
< HTTP/1.1 400 Bad Request
< Server: nginx/1.14.0 (Ubuntu)
< Date: Wed, 11 Jul 2018 08:14:07 GMT
< Content-Type: text/html
< Content-Length: 182
< Connection: close
<
<html>
<head><title>400 Bad Request</title></head>
<body bgcolor="white">
<center><h1>400 Bad Request</h1></center>
<hr><center>nginx/1.14.0 (Ubuntu)</center>
</body>
</html>
* Closing connection 0
I did configure my site to respond to requests with no Host: header with an 444 error code. Obviously, this doesn't work. I assume I did misunderstand the docs and my config is incorrect. I would be glad if someone could point out what's missing:
ssl_certificate /etc/letsencrypt/live/ hostname_fqdn /fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/ hostname_fqdn /privkey.pem;
# Respond to requests without a host header with HTTP status 444
server
listen 80 default_server;
listen [::]:80 default_server;
server_name "";
return 444;
server
listen 80;
listen [::]:80;
server_name hostname_fqdn ;
if ($allowed_country = no)
return 444;
return 301 https:// hostname_fqdn $request_uri;
server
listen 443 ssl;
#listen [::]:443 ssl;
include /etc/letsencrypt/options-ssl-nginx.conf;
ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem;
server_name hostname_fqdn ;
if ($allowed_country = no)
return 444;
location /
include uwsgi_params;
uwsgi_pass unix:/run/uwsgi/app/ django_project_name /socket;
location /static/
root django_static_root ;
server
listen 80;
listen [::]:80;
listen 443 ssl;
#listen [::]:443 ssl;
include /etc/letsencrypt/options-ssl-nginx.conf;
ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem;
server_name api.zeitschrift.hausbesitzerverlag.de;
if ($allowed_country = no)
return 444;
location /
include uwsgi_params;
uwsgi_pass unix:/run/uwsgi/app/ django_project_name /socket;
location /pmx-api/
auth_basic "Restricted Content";
auth_basic_user_file /etc/nginx/htpasswd;
limit_req zone=api burst=5;
include uwsgi_params;
uwsgi_pass unix:/run/uwsgi/app/ django_project_name /socket;
location /komtrigon-api/
limit_req zone=api burst=5;
include uwsgi_params;
uwsgi_pass unix:/run/uwsgi/app/ django_project_name /socket;
location /static/
root django_static_root ;
nginx
|
show 1 more comment
I have an nginx server with exactly one site configuration (the default site).
I keep seeing the following lines in my access.log
xxx.xxx.xxx.xxx - - [10/Jul/2018:16:32:14 +0200] "GET / HTTP/1.1" 400 37 "-" "-"
I know for a fact that this happens if the request doesn't send a Host:header, as in curl -v -H "Host:" https:// server_ip
root@mypc:~# curl -v -H "Host:" http:// server_ip
* Rebuilt URL to: http:// server_ip /
* Trying server_ip ...
* Connected to server_ip ( server_ip ) port 80 (#0)
> GET / HTTP/1.1
> User-Agent: curl/7.47.0
> Accept: */*
>
< HTTP/1.1 400 Bad Request
< Server: nginx/1.14.0 (Ubuntu)
< Date: Wed, 11 Jul 2018 08:14:07 GMT
< Content-Type: text/html
< Content-Length: 182
< Connection: close
<
<html>
<head><title>400 Bad Request</title></head>
<body bgcolor="white">
<center><h1>400 Bad Request</h1></center>
<hr><center>nginx/1.14.0 (Ubuntu)</center>
</body>
</html>
* Closing connection 0
I did configure my site to respond to requests with no Host: header with an 444 error code. Obviously, this doesn't work. I assume I did misunderstand the docs and my config is incorrect. I would be glad if someone could point out what's missing:
ssl_certificate /etc/letsencrypt/live/ hostname_fqdn /fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/ hostname_fqdn /privkey.pem;
# Respond to requests without a host header with HTTP status 444
server
listen 80 default_server;
listen [::]:80 default_server;
server_name "";
return 444;
server
listen 80;
listen [::]:80;
server_name hostname_fqdn ;
if ($allowed_country = no)
return 444;
return 301 https:// hostname_fqdn $request_uri;
server
listen 443 ssl;
#listen [::]:443 ssl;
include /etc/letsencrypt/options-ssl-nginx.conf;
ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem;
server_name hostname_fqdn ;
if ($allowed_country = no)
return 444;
location /
include uwsgi_params;
uwsgi_pass unix:/run/uwsgi/app/ django_project_name /socket;
location /static/
root django_static_root ;
server
listen 80;
listen [::]:80;
listen 443 ssl;
#listen [::]:443 ssl;
include /etc/letsencrypt/options-ssl-nginx.conf;
ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem;
server_name api.zeitschrift.hausbesitzerverlag.de;
if ($allowed_country = no)
return 444;
location /
include uwsgi_params;
uwsgi_pass unix:/run/uwsgi/app/ django_project_name /socket;
location /pmx-api/
auth_basic "Restricted Content";
auth_basic_user_file /etc/nginx/htpasswd;
limit_req zone=api burst=5;
include uwsgi_params;
uwsgi_pass unix:/run/uwsgi/app/ django_project_name /socket;
location /komtrigon-api/
limit_req zone=api burst=5;
include uwsgi_params;
uwsgi_pass unix:/run/uwsgi/app/ django_project_name /socket;
location /static/
root django_static_root ;
nginx
I think you are getting a Bad request, because you are using http in the Host header http:// server_ip
– c4f4t0r
Jul 11 '18 at 9:34
Nah, just-H "Host:". I think you missed the ending quote.
– Daniel
Jul 11 '18 at 9:41
Now is clear, you are sending the Host header without any value :)
– c4f4t0r
Jul 11 '18 at 12:57
@c4f4t0r-H "Host:"does not send thehostheader at all.
– Rick
May 31 at 4:06
1
@c4f4t0r Yes, withHTTP/1.0it's valid.
– Rick
May 31 at 8:52
|
show 1 more comment
I have an nginx server with exactly one site configuration (the default site).
I keep seeing the following lines in my access.log
xxx.xxx.xxx.xxx - - [10/Jul/2018:16:32:14 +0200] "GET / HTTP/1.1" 400 37 "-" "-"
I know for a fact that this happens if the request doesn't send a Host:header, as in curl -v -H "Host:" https:// server_ip
root@mypc:~# curl -v -H "Host:" http:// server_ip
* Rebuilt URL to: http:// server_ip /
* Trying server_ip ...
* Connected to server_ip ( server_ip ) port 80 (#0)
> GET / HTTP/1.1
> User-Agent: curl/7.47.0
> Accept: */*
>
< HTTP/1.1 400 Bad Request
< Server: nginx/1.14.0 (Ubuntu)
< Date: Wed, 11 Jul 2018 08:14:07 GMT
< Content-Type: text/html
< Content-Length: 182
< Connection: close
<
<html>
<head><title>400 Bad Request</title></head>
<body bgcolor="white">
<center><h1>400 Bad Request</h1></center>
<hr><center>nginx/1.14.0 (Ubuntu)</center>
</body>
</html>
* Closing connection 0
I did configure my site to respond to requests with no Host: header with an 444 error code. Obviously, this doesn't work. I assume I did misunderstand the docs and my config is incorrect. I would be glad if someone could point out what's missing:
ssl_certificate /etc/letsencrypt/live/ hostname_fqdn /fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/ hostname_fqdn /privkey.pem;
# Respond to requests without a host header with HTTP status 444
server
listen 80 default_server;
listen [::]:80 default_server;
server_name "";
return 444;
server
listen 80;
listen [::]:80;
server_name hostname_fqdn ;
if ($allowed_country = no)
return 444;
return 301 https:// hostname_fqdn $request_uri;
server
listen 443 ssl;
#listen [::]:443 ssl;
include /etc/letsencrypt/options-ssl-nginx.conf;
ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem;
server_name hostname_fqdn ;
if ($allowed_country = no)
return 444;
location /
include uwsgi_params;
uwsgi_pass unix:/run/uwsgi/app/ django_project_name /socket;
location /static/
root django_static_root ;
server
listen 80;
listen [::]:80;
listen 443 ssl;
#listen [::]:443 ssl;
include /etc/letsencrypt/options-ssl-nginx.conf;
ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem;
server_name api.zeitschrift.hausbesitzerverlag.de;
if ($allowed_country = no)
return 444;
location /
include uwsgi_params;
uwsgi_pass unix:/run/uwsgi/app/ django_project_name /socket;
location /pmx-api/
auth_basic "Restricted Content";
auth_basic_user_file /etc/nginx/htpasswd;
limit_req zone=api burst=5;
include uwsgi_params;
uwsgi_pass unix:/run/uwsgi/app/ django_project_name /socket;
location /komtrigon-api/
limit_req zone=api burst=5;
include uwsgi_params;
uwsgi_pass unix:/run/uwsgi/app/ django_project_name /socket;
location /static/
root django_static_root ;
nginx
I have an nginx server with exactly one site configuration (the default site).
I keep seeing the following lines in my access.log
xxx.xxx.xxx.xxx - - [10/Jul/2018:16:32:14 +0200] "GET / HTTP/1.1" 400 37 "-" "-"
I know for a fact that this happens if the request doesn't send a Host:header, as in curl -v -H "Host:" https:// server_ip
root@mypc:~# curl -v -H "Host:" http:// server_ip
* Rebuilt URL to: http:// server_ip /
* Trying server_ip ...
* Connected to server_ip ( server_ip ) port 80 (#0)
> GET / HTTP/1.1
> User-Agent: curl/7.47.0
> Accept: */*
>
< HTTP/1.1 400 Bad Request
< Server: nginx/1.14.0 (Ubuntu)
< Date: Wed, 11 Jul 2018 08:14:07 GMT
< Content-Type: text/html
< Content-Length: 182
< Connection: close
<
<html>
<head><title>400 Bad Request</title></head>
<body bgcolor="white">
<center><h1>400 Bad Request</h1></center>
<hr><center>nginx/1.14.0 (Ubuntu)</center>
</body>
</html>
* Closing connection 0
I did configure my site to respond to requests with no Host: header with an 444 error code. Obviously, this doesn't work. I assume I did misunderstand the docs and my config is incorrect. I would be glad if someone could point out what's missing:
ssl_certificate /etc/letsencrypt/live/ hostname_fqdn /fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/ hostname_fqdn /privkey.pem;
# Respond to requests without a host header with HTTP status 444
server
listen 80 default_server;
listen [::]:80 default_server;
server_name "";
return 444;
server
listen 80;
listen [::]:80;
server_name hostname_fqdn ;
if ($allowed_country = no)
return 444;
return 301 https:// hostname_fqdn $request_uri;
server
listen 443 ssl;
#listen [::]:443 ssl;
include /etc/letsencrypt/options-ssl-nginx.conf;
ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem;
server_name hostname_fqdn ;
if ($allowed_country = no)
return 444;
location /
include uwsgi_params;
uwsgi_pass unix:/run/uwsgi/app/ django_project_name /socket;
location /static/
root django_static_root ;
server
listen 80;
listen [::]:80;
listen 443 ssl;
#listen [::]:443 ssl;
include /etc/letsencrypt/options-ssl-nginx.conf;
ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem;
server_name api.zeitschrift.hausbesitzerverlag.de;
if ($allowed_country = no)
return 444;
location /
include uwsgi_params;
uwsgi_pass unix:/run/uwsgi/app/ django_project_name /socket;
location /pmx-api/
auth_basic "Restricted Content";
auth_basic_user_file /etc/nginx/htpasswd;
limit_req zone=api burst=5;
include uwsgi_params;
uwsgi_pass unix:/run/uwsgi/app/ django_project_name /socket;
location /komtrigon-api/
limit_req zone=api burst=5;
include uwsgi_params;
uwsgi_pass unix:/run/uwsgi/app/ django_project_name /socket;
location /static/
root django_static_root ;
nginx
nginx
edited Jul 11 '18 at 9:20
Daniel
asked Jul 11 '18 at 9:06
DanielDaniel
5,11922153
5,11922153
I think you are getting a Bad request, because you are using http in the Host header http:// server_ip
– c4f4t0r
Jul 11 '18 at 9:34
Nah, just-H "Host:". I think you missed the ending quote.
– Daniel
Jul 11 '18 at 9:41
Now is clear, you are sending the Host header without any value :)
– c4f4t0r
Jul 11 '18 at 12:57
@c4f4t0r-H "Host:"does not send thehostheader at all.
– Rick
May 31 at 4:06
1
@c4f4t0r Yes, withHTTP/1.0it's valid.
– Rick
May 31 at 8:52
|
show 1 more comment
I think you are getting a Bad request, because you are using http in the Host header http:// server_ip
– c4f4t0r
Jul 11 '18 at 9:34
Nah, just-H "Host:". I think you missed the ending quote.
– Daniel
Jul 11 '18 at 9:41
Now is clear, you are sending the Host header without any value :)
– c4f4t0r
Jul 11 '18 at 12:57
@c4f4t0r-H "Host:"does not send thehostheader at all.
– Rick
May 31 at 4:06
1
@c4f4t0r Yes, withHTTP/1.0it's valid.
– Rick
May 31 at 8:52
I think you are getting a Bad request, because you are using http in the Host header http:// server_ip
– c4f4t0r
Jul 11 '18 at 9:34
I think you are getting a Bad request, because you are using http in the Host header http:// server_ip
– c4f4t0r
Jul 11 '18 at 9:34
Nah, just
-H "Host:". I think you missed the ending quote.– Daniel
Jul 11 '18 at 9:41
Nah, just
-H "Host:". I think you missed the ending quote.– Daniel
Jul 11 '18 at 9:41
Now is clear, you are sending the Host header without any value :)
– c4f4t0r
Jul 11 '18 at 12:57
Now is clear, you are sending the Host header without any value :)
– c4f4t0r
Jul 11 '18 at 12:57
@c4f4t0r
-H "Host:" does not send the host header at all.– Rick
May 31 at 4:06
@c4f4t0r
-H "Host:" does not send the host header at all.– Rick
May 31 at 4:06
1
1
@c4f4t0r Yes, with
HTTP/1.0 it's valid.– Rick
May 31 at 8:52
@c4f4t0r Yes, with
HTTP/1.0 it's valid.– Rick
May 31 at 8:52
|
show 1 more comment
3 Answers
3
active
oldest
votes
HTTP requests without a Host: header are not valid in HTTP/1.1 (or later), and nginx is correctly sending a 400 Bad Request error without even attempting to serve it with any server block. From RFC 7230 section 5.4:
A server MUST respond with a 400 (Bad Request) status code to any
HTTP/1.1 request message that lacks a Host header field and to any
request message that contains more than one Host header field or a
Host header field with an invalid field-value.
Your server block which serves requests without a Host: header will only be hit when a request comes in with the ancient HTTP/1.0. You can simulate this using curl with the -0 command line option:
curl -v -0 http://203.0.113.87/
From the man page:
-0, --http1.0
(HTTP) Tells curl to use HTTP version 1.0 instead of using its
internally preferred HTTP version.
Hey Michael, your answer seemed plausible, but then I figured out that the 400-code was served by the application behind it, so it wasn't nginx that returned the 400. Guess they don't follow that RFC. But I noticed that the spammers were doing a https-request, which made me aware that the default server didn't listen to ssl requests. Rookie mistake. Still, thanks for making me aware about that RFC. It's good to know!
– Daniel
Jul 11 '18 at 13:47
@Daniel Michael is right about this. Try a plain nginx server. Set aseverblock withserver_name "", and test it without theHostheader bycurl -v -H "Host:" http://localhost, you can't reach thatserverblock. But you can reach it with additional-0.
– Rick
May 31 at 3:58
add a comment |
Beginner's mistake. I forgot to add listen 443 ssl default_server; to the first server block.
...
server
listen 80 default_server;
listen 443 ssl default_server;
listen [::]:80 default_server;
server_name "";
return 444;
...
Although Micheal is completely correct about the RFC, it wasn't true in regards on how nginx works, as nginx has no built-in functionality that returns a 400 in that case.
It also didn't specifically answer my question. Since 10 out of 10 times my web server receives a request without host header, the request is sent by a spammer, I decided to ignore the RFC and just close the connection without letting the spammer know (return 444;).
add a comment |
I think you misunderstood something.
I did configure my site to respond to requests with no Host: header with an 444 error code. Obviously, this doesn't work.
You does not configure specifically your site to respond to requests with no Host header with 444.
It is: you configure your site that any host value that do not match other server_name value in server blocks, will come to the default_server block.
It's the default_server directive that actually matters. you can put any logically invaild value in server_name, within the default server, server block.
https://nginx.org/en/docs/http/server_names.html
There is nothing special about this name(
server_name ""), it is just one of a myriad of invalid domain names which never intersect with any real name. Other invalid names like “--” and “!@#” may equally be used.
add a comment |
Your Answer
StackExchange.ready(function()
var channelOptions =
tags: "".split(" "),
id: "2"
;
initTagRenderer("".split(" "), "".split(" "), channelOptions);
StackExchange.using("externalEditor", function()
// Have to fire editor after snippets, if snippets enabled
if (StackExchange.settings.snippets.snippetsEnabled)
StackExchange.using("snippets", function()
createEditor();
);
else
createEditor();
);
function createEditor()
StackExchange.prepareEditor(
heartbeatType: 'answer',
autoActivateHeartbeat: false,
convertImagesToLinks: true,
noModals: true,
showLowRepImageUploadWarning: true,
reputationToPostImages: 10,
bindNavPrevention: true,
postfix: "",
imageUploader:
brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
allowUrls: true
,
onDemand: true,
discardSelector: ".discard-answer"
,immediatelyShowMarkdownHelp:true
);
);
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function ()
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fserverfault.com%2fquestions%2f920434%2fhttp-request-not-caught-by-nginx-server-block%23new-answer', 'question_page');
);
Post as a guest
Required, but never shown
3 Answers
3
active
oldest
votes
3 Answers
3
active
oldest
votes
active
oldest
votes
active
oldest
votes
HTTP requests without a Host: header are not valid in HTTP/1.1 (or later), and nginx is correctly sending a 400 Bad Request error without even attempting to serve it with any server block. From RFC 7230 section 5.4:
A server MUST respond with a 400 (Bad Request) status code to any
HTTP/1.1 request message that lacks a Host header field and to any
request message that contains more than one Host header field or a
Host header field with an invalid field-value.
Your server block which serves requests without a Host: header will only be hit when a request comes in with the ancient HTTP/1.0. You can simulate this using curl with the -0 command line option:
curl -v -0 http://203.0.113.87/
From the man page:
-0, --http1.0
(HTTP) Tells curl to use HTTP version 1.0 instead of using its
internally preferred HTTP version.
Hey Michael, your answer seemed plausible, but then I figured out that the 400-code was served by the application behind it, so it wasn't nginx that returned the 400. Guess they don't follow that RFC. But I noticed that the spammers were doing a https-request, which made me aware that the default server didn't listen to ssl requests. Rookie mistake. Still, thanks for making me aware about that RFC. It's good to know!
– Daniel
Jul 11 '18 at 13:47
@Daniel Michael is right about this. Try a plain nginx server. Set aseverblock withserver_name "", and test it without theHostheader bycurl -v -H "Host:" http://localhost, you can't reach thatserverblock. But you can reach it with additional-0.
– Rick
May 31 at 3:58
add a comment |
HTTP requests without a Host: header are not valid in HTTP/1.1 (or later), and nginx is correctly sending a 400 Bad Request error without even attempting to serve it with any server block. From RFC 7230 section 5.4:
A server MUST respond with a 400 (Bad Request) status code to any
HTTP/1.1 request message that lacks a Host header field and to any
request message that contains more than one Host header field or a
Host header field with an invalid field-value.
Your server block which serves requests without a Host: header will only be hit when a request comes in with the ancient HTTP/1.0. You can simulate this using curl with the -0 command line option:
curl -v -0 http://203.0.113.87/
From the man page:
-0, --http1.0
(HTTP) Tells curl to use HTTP version 1.0 instead of using its
internally preferred HTTP version.
Hey Michael, your answer seemed plausible, but then I figured out that the 400-code was served by the application behind it, so it wasn't nginx that returned the 400. Guess they don't follow that RFC. But I noticed that the spammers were doing a https-request, which made me aware that the default server didn't listen to ssl requests. Rookie mistake. Still, thanks for making me aware about that RFC. It's good to know!
– Daniel
Jul 11 '18 at 13:47
@Daniel Michael is right about this. Try a plain nginx server. Set aseverblock withserver_name "", and test it without theHostheader bycurl -v -H "Host:" http://localhost, you can't reach thatserverblock. But you can reach it with additional-0.
– Rick
May 31 at 3:58
add a comment |
HTTP requests without a Host: header are not valid in HTTP/1.1 (or later), and nginx is correctly sending a 400 Bad Request error without even attempting to serve it with any server block. From RFC 7230 section 5.4:
A server MUST respond with a 400 (Bad Request) status code to any
HTTP/1.1 request message that lacks a Host header field and to any
request message that contains more than one Host header field or a
Host header field with an invalid field-value.
Your server block which serves requests without a Host: header will only be hit when a request comes in with the ancient HTTP/1.0. You can simulate this using curl with the -0 command line option:
curl -v -0 http://203.0.113.87/
From the man page:
-0, --http1.0
(HTTP) Tells curl to use HTTP version 1.0 instead of using its
internally preferred HTTP version.
HTTP requests without a Host: header are not valid in HTTP/1.1 (or later), and nginx is correctly sending a 400 Bad Request error without even attempting to serve it with any server block. From RFC 7230 section 5.4:
A server MUST respond with a 400 (Bad Request) status code to any
HTTP/1.1 request message that lacks a Host header field and to any
request message that contains more than one Host header field or a
Host header field with an invalid field-value.
Your server block which serves requests without a Host: header will only be hit when a request comes in with the ancient HTTP/1.0. You can simulate this using curl with the -0 command line option:
curl -v -0 http://203.0.113.87/
From the man page:
-0, --http1.0
(HTTP) Tells curl to use HTTP version 1.0 instead of using its
internally preferred HTTP version.
edited May 31 at 4:08
answered Jul 11 '18 at 12:33
Michael Hampton♦Michael Hampton
180k28331663
180k28331663
Hey Michael, your answer seemed plausible, but then I figured out that the 400-code was served by the application behind it, so it wasn't nginx that returned the 400. Guess they don't follow that RFC. But I noticed that the spammers were doing a https-request, which made me aware that the default server didn't listen to ssl requests. Rookie mistake. Still, thanks for making me aware about that RFC. It's good to know!
– Daniel
Jul 11 '18 at 13:47
@Daniel Michael is right about this. Try a plain nginx server. Set aseverblock withserver_name "", and test it without theHostheader bycurl -v -H "Host:" http://localhost, you can't reach thatserverblock. But you can reach it with additional-0.
– Rick
May 31 at 3:58
add a comment |
Hey Michael, your answer seemed plausible, but then I figured out that the 400-code was served by the application behind it, so it wasn't nginx that returned the 400. Guess they don't follow that RFC. But I noticed that the spammers were doing a https-request, which made me aware that the default server didn't listen to ssl requests. Rookie mistake. Still, thanks for making me aware about that RFC. It's good to know!
– Daniel
Jul 11 '18 at 13:47
@Daniel Michael is right about this. Try a plain nginx server. Set aseverblock withserver_name "", and test it without theHostheader bycurl -v -H "Host:" http://localhost, you can't reach thatserverblock. But you can reach it with additional-0.
– Rick
May 31 at 3:58
Hey Michael, your answer seemed plausible, but then I figured out that the 400-code was served by the application behind it, so it wasn't nginx that returned the 400. Guess they don't follow that RFC. But I noticed that the spammers were doing a https-request, which made me aware that the default server didn't listen to ssl requests. Rookie mistake. Still, thanks for making me aware about that RFC. It's good to know!
– Daniel
Jul 11 '18 at 13:47
Hey Michael, your answer seemed plausible, but then I figured out that the 400-code was served by the application behind it, so it wasn't nginx that returned the 400. Guess they don't follow that RFC. But I noticed that the spammers were doing a https-request, which made me aware that the default server didn't listen to ssl requests. Rookie mistake. Still, thanks for making me aware about that RFC. It's good to know!
– Daniel
Jul 11 '18 at 13:47
@Daniel Michael is right about this. Try a plain nginx server. Set a
sever block with server_name "", and test it without the Host header by curl -v -H "Host:" http://localhost, you can't reach that server block. But you can reach it with additional -0.– Rick
May 31 at 3:58
@Daniel Michael is right about this. Try a plain nginx server. Set a
sever block with server_name "", and test it without the Host header by curl -v -H "Host:" http://localhost, you can't reach that server block. But you can reach it with additional -0.– Rick
May 31 at 3:58
add a comment |
Beginner's mistake. I forgot to add listen 443 ssl default_server; to the first server block.
...
server
listen 80 default_server;
listen 443 ssl default_server;
listen [::]:80 default_server;
server_name "";
return 444;
...
Although Micheal is completely correct about the RFC, it wasn't true in regards on how nginx works, as nginx has no built-in functionality that returns a 400 in that case.
It also didn't specifically answer my question. Since 10 out of 10 times my web server receives a request without host header, the request is sent by a spammer, I decided to ignore the RFC and just close the connection without letting the spammer know (return 444;).
add a comment |
Beginner's mistake. I forgot to add listen 443 ssl default_server; to the first server block.
...
server
listen 80 default_server;
listen 443 ssl default_server;
listen [::]:80 default_server;
server_name "";
return 444;
...
Although Micheal is completely correct about the RFC, it wasn't true in regards on how nginx works, as nginx has no built-in functionality that returns a 400 in that case.
It also didn't specifically answer my question. Since 10 out of 10 times my web server receives a request without host header, the request is sent by a spammer, I decided to ignore the RFC and just close the connection without letting the spammer know (return 444;).
add a comment |
Beginner's mistake. I forgot to add listen 443 ssl default_server; to the first server block.
...
server
listen 80 default_server;
listen 443 ssl default_server;
listen [::]:80 default_server;
server_name "";
return 444;
...
Although Micheal is completely correct about the RFC, it wasn't true in regards on how nginx works, as nginx has no built-in functionality that returns a 400 in that case.
It also didn't specifically answer my question. Since 10 out of 10 times my web server receives a request without host header, the request is sent by a spammer, I decided to ignore the RFC and just close the connection without letting the spammer know (return 444;).
Beginner's mistake. I forgot to add listen 443 ssl default_server; to the first server block.
...
server
listen 80 default_server;
listen 443 ssl default_server;
listen [::]:80 default_server;
server_name "";
return 444;
...
Although Micheal is completely correct about the RFC, it wasn't true in regards on how nginx works, as nginx has no built-in functionality that returns a 400 in that case.
It also didn't specifically answer my question. Since 10 out of 10 times my web server receives a request without host header, the request is sent by a spammer, I decided to ignore the RFC and just close the connection without letting the spammer know (return 444;).
edited Jul 11 '18 at 13:50
answered Jul 11 '18 at 13:44
DanielDaniel
5,11922153
5,11922153
add a comment |
add a comment |
I think you misunderstood something.
I did configure my site to respond to requests with no Host: header with an 444 error code. Obviously, this doesn't work.
You does not configure specifically your site to respond to requests with no Host header with 444.
It is: you configure your site that any host value that do not match other server_name value in server blocks, will come to the default_server block.
It's the default_server directive that actually matters. you can put any logically invaild value in server_name, within the default server, server block.
https://nginx.org/en/docs/http/server_names.html
There is nothing special about this name(
server_name ""), it is just one of a myriad of invalid domain names which never intersect with any real name. Other invalid names like “--” and “!@#” may equally be used.
add a comment |
I think you misunderstood something.
I did configure my site to respond to requests with no Host: header with an 444 error code. Obviously, this doesn't work.
You does not configure specifically your site to respond to requests with no Host header with 444.
It is: you configure your site that any host value that do not match other server_name value in server blocks, will come to the default_server block.
It's the default_server directive that actually matters. you can put any logically invaild value in server_name, within the default server, server block.
https://nginx.org/en/docs/http/server_names.html
There is nothing special about this name(
server_name ""), it is just one of a myriad of invalid domain names which never intersect with any real name. Other invalid names like “--” and “!@#” may equally be used.
add a comment |
I think you misunderstood something.
I did configure my site to respond to requests with no Host: header with an 444 error code. Obviously, this doesn't work.
You does not configure specifically your site to respond to requests with no Host header with 444.
It is: you configure your site that any host value that do not match other server_name value in server blocks, will come to the default_server block.
It's the default_server directive that actually matters. you can put any logically invaild value in server_name, within the default server, server block.
https://nginx.org/en/docs/http/server_names.html
There is nothing special about this name(
server_name ""), it is just one of a myriad of invalid domain names which never intersect with any real name. Other invalid names like “--” and “!@#” may equally be used.
I think you misunderstood something.
I did configure my site to respond to requests with no Host: header with an 444 error code. Obviously, this doesn't work.
You does not configure specifically your site to respond to requests with no Host header with 444.
It is: you configure your site that any host value that do not match other server_name value in server blocks, will come to the default_server block.
It's the default_server directive that actually matters. you can put any logically invaild value in server_name, within the default server, server block.
https://nginx.org/en/docs/http/server_names.html
There is nothing special about this name(
server_name ""), it is just one of a myriad of invalid domain names which never intersect with any real name. Other invalid names like “--” and “!@#” may equally be used.
answered May 31 at 4:25
RickRick
577
577
add a comment |
add a comment |
Thanks for contributing an answer to Server Fault!
- Please be sure to answer the question. Provide details and share your research!
But avoid …
- Asking for help, clarification, or responding to other answers.
- Making statements based on opinion; back them up with references or personal experience.
To learn more, see our tips on writing great answers.
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function ()
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fserverfault.com%2fquestions%2f920434%2fhttp-request-not-caught-by-nginx-server-block%23new-answer', 'question_page');
);
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
I think you are getting a Bad request, because you are using http in the Host header http:// server_ip
– c4f4t0r
Jul 11 '18 at 9:34
Nah, just
-H "Host:". I think you missed the ending quote.– Daniel
Jul 11 '18 at 9:41
Now is clear, you are sending the Host header without any value :)
– c4f4t0r
Jul 11 '18 at 12:57
@c4f4t0r
-H "Host:"does not send thehostheader at all.– Rick
May 31 at 4:06
1
@c4f4t0r Yes, with
HTTP/1.0it's valid.– Rick
May 31 at 8:52