Nginx – Why is nginx giving 200 OK response , even though domain is not hosted on the server ? and how can i fix it

curlnginx

i have hosted example.com on nginx web server at ip 123.123.123.123 and if i use curl with host headers like this from remote machine

curl -v -H "Host: example.com" 123.123.123.123/

i get

curl -v -H "Host: example.com" 123.123.123.123/
*   Trying 123.123.123.123...
* Connected to 123.123.123.123 (123.123.123.123) port 80 (#0)
> GET / HTTP/1.1
> Host: example.com
> User-Agent: curl/7.43.0
> Accept: */*
>
< HTTP/1.1 200 OK
< Server: nginx/1.9.9
< Date: Tue, 15 Dec 2015 01:34:22 GMT
< Content-Type: text/html; charset=UTF-8
< Transfer-Encoding: chunked
< Connection: keep-alive
< Set-Cookie: __cfduid=d2a30e617da2fbe890a6855ba4d993bc61450143261; expires=Wed, 14-Dec-16 01:34:21 GMT; path=/; domain=.example.com; HttpOnly
< Vary: Accept-Encoding
< Set-Cookie: PHPSESSID=mmdnqp3j4fnf0ph57krl696rb2; path=/
< CF-RAY: 254e67dae06335a8-LHR

which is fine as example.com is hosted on server having ip 123.123.123.123

but if i change the host header to any other domain e.g. anyother_domain.com

curl -v -H "Host: anyother_domain.com" 123.123.123.123/

i get this

curl -v -H "Host: anyother_domain.com" 123.123.123.123/
*   Trying 123.123.123.123...
* Connected to 123.123.123.123 (123.123.123.123) port 80 (#0)
> GET / HTTP/1.1
> Host: anyother_domain.com
> User-Agent: curl/7.43.0
> Accept: */*
>
< HTTP/1.1 200 OK
< Server: nginx/1.9.9
< Date: Tue, 15 Dec 2015 01:30:29 GMT
< Content-Type: text/html; charset=utf-8
< Content-Length: 612
< Last-Modified: Sat, 12 Dec 2015 16:03:23 GMT
< Connection: keep-alive
< ETag: "566c454b-264"
< Accept-Ranges: bytes

here is my nginx.conf file

worker_processes 4;

events {
  worker_connections 1024;
}

http {
        include  mime.types;
        default_type application/octet-stream;
        sendfile on;
        gzip on;
        charset utf-8;

include /usr/local/nginx/conf/sites-enabled/*.conf;
}

default.conf

server {
    listen       80;
    server_name  123.123.123.123;

charset utf-8;
}

example.com.conf

server {
    server_name  www.example.com;
    return       301 http://example.com$request_uri;
    access_log  /dev/null;
}

server {
server_name  example.com;
}
  1. Why is this happening ?
    i mean why is server giving 200 OK status even though the domain is not hosted at my server ?
  2. how can i fix this ?
    i mean how can i not give 200 OK status and throw some other header response code ?

Best Answer

Here is answer: http://nginx.org/en/docs/http/request_processing.html

Why is this happening ? i mean why is server giving 200 OK status even though the domain is not hosted at my server ?

[Usually] nginx tests only the request’s header field “Host” to determine which server the request should be routed to. If its value does not match any server name, or the request does not contain this header field at all, then nginx will route the request to the default server for this port. In the configuration above, the default server is the first one — which is nginx’s standard default behaviour.

how can i fix this ? i mean how can i not give 200 OK status and throw some other header response code ?

If requests without the “Host” header field should not be allowed, a server that just drops the requests can be defined:

server { listen 80; server_name ""; return 444; }

Here, the server name is set to an empty string that will match requests without the “Host” header field, and a special nginx’s non-standard code 444 is returned that closes the connection.

Or try this for all 'default' requests

server {
    listen      80 default_server;
    server_name "";
    return      444;
}