0

I've added an SSL certificate to my site, and I have a config file that looks like this:

server {
    listen 80;
    listen [::]:80;

    server_name www.default.com default.com;
    return 301 https://default.com$request_uri;
}

server {
    listen 443 ssl;
    listen [::]:443 ssl;
    server_name default.com;

   ...
}

I had a couple of clients viewing a staging site at the server's IP address, so for instance I'd ask them to look at a few changes at http://123.123.123.123

Now that the IP address has been shared with a few hundred people, and the SSL addition has broken the IP address' link I'd like to redirect it to the domain name.

Do I add the redirect into the top block, or create a third block?

For instance:

server {
    listen 80;
    listen [::]:80;

    server_name www.default.com default.com;
    return 301 https://default.com$request_uri;
}

server {
    listen 80;
    listen 123.123.123.123:80;

    server_name 123.123.123.123;
    return 301 https://default.com$request_uri;
}

server {
    listen 443 ssl;
    listen [::]:443 ssl;
    server_name default.com;

   ...
}

Does the above look right? This is my first nginx config I've ever done – I've googled the layout of the redirect but I'm not sure if it should go in its own block or not.

1

The simplest method is to make the default server the redirector. So your second block can just go and your first becomes:

server {
    listen 80 default_server;
    listen [::]:80 default_server;
    listen 443 default_server ssl;
    listen [::]:443 default_server ssl;
    server_name localhost;

    root /var/empty;
    return 301 https://default.com$request_uri;
}

Think of this server block as the fallback that also consumes the server name 'localhost'. So you cannot use that name later on. Your third block (now the second block) has the same matching properties as the first for port 443, but specifies a different hostname. When the client sends the correct hostname, this server block is a more precise match and as such overrides the fallback.

When a client connects on port 80, there is no more specific match so the fallback applies.

When it connects on port 443, but sends a different hostname, nginx sees the default_server and so ignores the server_name for matching purposes. All responses that contain a hostname will use the server_name and the variable $host that may be included in logs will use this name.

Note that I prefer to use default_server instead of relying on ordering of the server blocks.

Finally - redirecting on port 443 will only work if your certificate covers the hostname the client sends. Otherwise the SSL/TLS handshake will fail before the HTTP part even comes into play. Since we have letsencrypt this shouldn't be an issue. You can simply use their certificate for any valid or advertized hostname and use a validated certificate for your official site.

0

Note: “VirtualHost” is an Apache term. NGINX does not have Virtual hosts, it has “Server Blocks” that use the server_name and listen directives to bind to tcp sockets.

https://www.nginx.com/resources/wiki/start/topics/examples/server_blocks

Server blocks are regarded as independant. So if you want a redirection, you need to specify that in each server block that should redirect a visitor to somewhere else.

For example, this is an improved config

server {
    listen 80;
    listen [::]:80;

    listen 443 ssl;
    listen [::]:443 ssl;

    # Add SSL stuff here.

    server_name www.default.com default.com;
}

server {
    listen 80;
    # Add SSL stuff, if you want to redirect from HTTPS via IP to Domain, too.

    server_name 123.123.123.123;
    return 301 https://default.com$request_uri;
}
  • Thanks Daniel. So in my example does that redirection look OK for the IP address to the domain name? – Djave Dec 1 '16 at 10:37
  • The placement of the directive is okay. You can remove listen 123.123.123.123:80; as it is already covered by listen 80; and server_name 123.123.123.123;. And you could actually put the listen ... 442 ...ssl; directives into the same server block as the listen 80 directive if they have the same server_name's anyway. – Daniel Dec 1 '16 at 10:53

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.