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;








1















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 ;











share|improve this question
























  • 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 the host header at all.

    – Rick
    May 31 at 4:06






  • 1





    @c4f4t0r Yes, with HTTP/1.0 it's valid.

    – Rick
    May 31 at 8:52

















1















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 ;











share|improve this question
























  • 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 the host header at all.

    – Rick
    May 31 at 4:06






  • 1





    @c4f4t0r Yes, with HTTP/1.0 it's valid.

    – Rick
    May 31 at 8:52













1












1








1








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 ;











share|improve this question
















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






share|improve this question















share|improve this question













share|improve this question




share|improve this question








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 the host header at all.

    – Rick
    May 31 at 4:06






  • 1





    @c4f4t0r Yes, with HTTP/1.0 it'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











  • 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 the host header at all.

    – Rick
    May 31 at 4:06






  • 1





    @c4f4t0r Yes, with HTTP/1.0 it'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










3 Answers
3






active

oldest

votes


















3














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.





share|improve this answer

























  • 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



















0














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;).






share|improve this answer
































    0














    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.







    share|improve this answer























      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
      );



      );













      draft saved

      draft discarded


















      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









      3














      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.





      share|improve this answer

























      • 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
















      3














      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.





      share|improve this answer

























      • 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














      3












      3








      3







      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.





      share|improve this answer















      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.






      share|improve this answer














      share|improve this answer



      share|improve this answer








      edited May 31 at 4:08

























      answered Jul 11 '18 at 12:33









      Michael HamptonMichael 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 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


















      • 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

















      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














      0














      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;).






      share|improve this answer





























        0














        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;).






        share|improve this answer



























          0












          0








          0







          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;).






          share|improve this answer















          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;).







          share|improve this answer














          share|improve this answer



          share|improve this answer








          edited Jul 11 '18 at 13:50

























          answered Jul 11 '18 at 13:44









          DanielDaniel

          5,11922153




          5,11922153





















              0














              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.







              share|improve this answer



























                0














                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.







                share|improve this answer

























                  0












                  0








                  0







                  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.







                  share|improve this answer













                  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.








                  share|improve this answer












                  share|improve this answer



                  share|improve this answer










                  answered May 31 at 4:25









                  RickRick

                  577




                  577



























                      draft saved

                      draft discarded
















































                      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.




                      draft saved


                      draft discarded














                      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





















































                      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







                      Popular posts from this blog

                      How to write a 12-bar blues melodyI-IV-V blues progressionHow to play the bridges in a standard blues progressionHow does Gdim7 fit in C# minor?question on a certain chord progressionMusicology of Melody12 bar blues, spread rhythm: alternative to 6th chord to avoid finger stretchChord progressions/ Root key/ MelodiesHow to put chords (POP-EDM) under a given lead vocal melody (starting from a good knowledge in music theory)Are there “rules” for improvising with the minor pentatonic scale over 12-bar shuffle?Confusion about blues scale and chords

                      What if the end-user didn't have the required library?What is setup.py?What is a clean, pythonic way to have multiple constructors in Python?What does Ruby have that Python doesn't, and vice versa?What is the reason for having '//' in Python?How do I create a namespace package in Python?How to package shared objects that python modules depend on?setuptools vs. distutils: why is distutils still a thing?Navigation in Windows 10 vs code not going to virtualenv library when the same library is installed at user levelPython create package for local usePackaging a project that uses multiple python versionsWhy is permission denied on pip install except for when “--user” is included at end of command?

                      Esgonzo ibérico Índice Descrición Distribución Hábitat Ameazas Notas Véxase tamén "Acerca dos nomes dos anfibios e réptiles galegos""Chalcides bedriagai"Chalcides bedriagai en Carrascal, L. M. Salvador, A. (Eds). Enciclopedia virtual de los vertebrados españoles. Museo Nacional de Ciencias Naturales, Madrid. España.Fotos