4

For some reason NGINX doesn't work if I set a bare IP address in server_name directive:

server {
    listen 80;
    server_name xx.xx.xxx.xx; # doesn't work

server {
    listen 80;
    server_name ec2-xx-xx-xxx-xx.ap-southeast-2.compute.amazonaws.com; # this works fine

Why doesn't NGINX accept IP address? How to force it to accept IPs?

I use Dynamic DNS with my domain name registrar (namecheap, to be exact) and there is an "A" record I have that maps my public domain name to AWS EC2 instance:

enter image description here

So when I go to example.com I'm redirected to my EC2 instance app. However I see a default NGINX landing page instead of my app's landing page. NGINX doesn't proxies the request further to Node.js.

Green
  • 157
  • 1
  • 2
  • 7

4 Answers4

6

Have you tried using "example.com" instead of the IP address?

At least with Apache, the whole point of the server_name field is to allow multiple websites (name spaces) to be served from a single IP address. The client that is following "http://example.com" does the DNS lookup and sends the request to the IP address it gets from the DNS lookup, but includes "example.com" in the request so that the web server (NGINX) can figure out which website the request belongs to.

craigster0
  • 161
  • 2
  • I did. Namecheap indicates an error, doesn't allow to save changes – Green Jul 26 '16 at 06:29
  • 3
    Why is namecheap vetting your changes to your nginx config file? – MadHatter Jul 26 '16 at 06:44
  • I'd reiterate @MadHatter question: what is the error from namecheap and how does your DNS hosting site know that you're editing your nginx config file? Note that i'm not suggesting any changes to your Dynamic DNS configuration at namecheap ... – craigster0 Jul 26 '16 at 07:11
5

If you have only one site configured, then you can try using this in nginx config:

server_name _ ;

If will force server to accept all HTTP requests, no matter what Host header is.

Pavel Kazhevets
  • 180
  • 1
  • 4
5

This question shows a misunderstanding of the purpose of the server_name declaration. It is common amongst servers to be able to specify the IP address of the interfaces that you wish to create the listening socket. However, with NGINX, that is not achieved using the server_name directive.

To understand the server_name directive, you need to understand part of the HTTP protocol. When your web browser makes a HTTP request to a website, for example the stack overflow https://serverfault.com/questions triggers your web browser to look up serverfault.com in DNS to obtain an IP address - This is why you need a DNS entry.

Once your web browser has the IP address, it opens a TCP connection to port 80 on that IP address. The web browser then needs to tell the webserver which page is being requested. It does this by using the HTTP protocol. The first line of the request will be:

GET /questions HTTP/1.1

This tells the server the URL path, and the HTTP version that the client is using to communicate.

The second line is:

Host: serverfault.com

This is called a HTTP header, and the Host header tells the webserver which website needs to handle the request. When a server only hosts a single website, this probably feels overkill. But often, webservers handle many websites.

This matches up to the nginx directive server_name. This directive tells nginx to only use this nginx site when the Host header matches this string.

So, to answer your question, it does not make sense to set an IP address in the server_name directive. It would be more normal to register a domain name, and to then create a CNAME DNS entry to refer to the AWS servers DNS name. When you spin up a replacement server, update the CNAME to point to the new servers DNS name.

A professional website would be placed behind an elastic load balancer, which then maintains a constant DNS name for you to reference with your DNS entry.

Michael Shaw
  • 663
  • 4
  • 9
0

I'm new to NGINX but according to the official docs (https://nginx.org/en/docs/http/server_names.html) it IS permissible to use a numeric IP address:

"If someone makes a request using an IP address instead of a server name, the “Host” request header field will contain the IP address and the request can be handled using the IP address as the server name:

server {
          listen       80;
           server_name  example.org
           www.example.org
           ""
           192.168.1.1
           ;
    ...
}

It would make sense to do this if you are in control of your IP address DNS records

ckapilla
  • 101
  • 2