Score:1

NginX website returns default page with HTTP (HTTPS works correctly)

br flag

This has to be a duplicate, but I have been searching for a long time and have not found anything.

When I type in the address of my website using http, I get the NginX default page (https works fine):

http://svija.love

The NginX config file contains, at the end:

server {
    if ($host = svija.love) {
        return 301 https://$host$request_uri;
    } # managed by Certbot

    server_name svija.love;
    listen 80;
    return 404; # managed by Certbot
}

This was added automatically by Certbot.

I would expect that the statement if ($host = svija.love) would catch the http request and redirect to HTTPS.

But it is not working that way.

Not being expert, it seems to me that the second bit, beginning with server_name svija.love, is in direct contradiction with the first part:

  • the first block redirects if the host is svija.love
  • the second block returns 404 if the host is svija.love

The actual, configured server name is live.svija.love, if that makes a difference.

Any clarification would be greatly appreciated.

[UPDATE] I removed the NginX default config file and HTTP now redirects to HTTPS as expected.

Still, if anyone can explain the two config blocks above I would love to better understand what they're doing.

[UPDATE] This was not a good solution (see below).

[UPDATE Here is the config given by nginx -T:

# configuration file /etc/nginx/nginx.conf:
user www-data;
worker_processes auto;
pid /run/nginx.pid;
include /etc/nginx/modules-enabled/*.conf;

events {
    worker_connections 768;
    # multi_accept on;
}

http {

    ##
    # Basic Settings
    ##

    sendfile off;
    tcp_nopush on;
    tcp_nodelay on;
    keepalive_timeout 65;
    types_hash_max_size 2048;
    # server_tokens off;

    # server_names_hash_bucket_size 64;
    # server_name_in_redirect off;

    include /etc/nginx/mime.types;
    default_type application/octet-stream;

    ##
    # SSL Settings
    ##

    ssl_protocols TLSv1 TLSv1.1 TLSv1.2 TLSv1.3; # Dropping SSLv3, ref: POODLE
    ssl_prefer_server_ciphers on;

    ##
    # Logging Settings
    ##

    access_log /var/log/nginx/access.log;
    error_log /var/log/nginx/error.log;

    ##
    # Gzip Settings
    ##

    gzip on;

    # gzip_vary on;
    # gzip_proxied any;
    # gzip_comp_level 6;
    # gzip_buffers 16 8k;
    # gzip_http_version 1.1;
    # gzip_types text/plain text/css application/json application/javascript text/xml application/xml application/xml+rss text/javascript;

    ##
    # Virtual Host Configs
    ##

    include /etc/nginx/conf.d/*.conf;
    include /etc/nginx/sites-enabled/*;
}

# configuration file /etc/nginx/modules-enabled/50-mod-http-image-filter.conf:
load_module modules/ngx_http_image_filter_module.so;

# configuration file /etc/nginx/modules-enabled/50-mod-http-xslt-filter.conf:
load_module modules/ngx_http_xslt_filter_module.so;

# configuration file /etc/nginx/modules-enabled/50-mod-mail.conf:
load_module modules/ngx_mail_module.so;

# configuration file /etc/nginx/modules-enabled/50-mod-stream.conf:
load_module modules/ngx_stream_module.so;

# configuration file /etc/nginx/mime.types:

server {

    # must match domain name or IP address
    # or else the default Nginx page will be shown
    server_name antretoise.svija.site;

    # directory of site's static elements
    location /static/ {
        root /home/antretoise;
    }

    access_log /opt/logs/access.antretoise;
    error_log /opt/logs/error.antretoise error;

    # pass all additional queries to our application
    location / {

        # parameters from /etc/nginx/uwsgi_params
        include uwsgi_params;

        # pass the traffic to the socket
        # that the uWSGI server sets up
        # SOCKETS MUST MATCH IN:
        # /etc/uwsgi/sites/antretoise.ini
        uwsgi_pass unix:/run/uwsgi/antretoise.sock;
    }

    listen 443 ssl; # managed by Certbot
    ssl_certificate /etc/letsencrypt/live/antretoise.svija.site/fullchain.pem; # managed by Certbot
    ssl_certificate_key /etc/letsencrypt/live/antretoise.svija.site/privkey.pem; # managed by Certbot
    include /etc/letsencrypt/options-ssl-nginx.conf; # managed by Certbot
    ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem; # managed by Certbot

}


server {
    if ($host = antretoise.svija.site) {
        return 301 https://$host$request_uri;
    } # managed by Certbot


    listen 80;
    server_name antretoise.svija.site;
    return 404; # managed by Certbot


}
# configuration file /etc/nginx/uwsgi_params:

uwsgi_param  QUERY_STRING       $query_string;
uwsgi_param  REQUEST_METHOD     $request_method;
uwsgi_param  CONTENT_TYPE       $content_type;
uwsgi_param  CONTENT_LENGTH     $content_length;

uwsgi_param  REQUEST_URI        $request_uri;
uwsgi_param  PATH_INFO          $document_uri;
uwsgi_param  DOCUMENT_ROOT      $document_root;
uwsgi_param  SERVER_PROTOCOL    $server_protocol;
uwsgi_param  REQUEST_SCHEME     $scheme;
uwsgi_param  HTTPS              $https if_not_empty;

uwsgi_param  REMOTE_ADDR        $remote_addr;
uwsgi_param  REMOTE_PORT        $remote_port;
uwsgi_param  SERVER_PORT        $server_port;
uwsgi_param  SERVER_NAME        $server_name;

ssl_session_cache shared:le_nginx_SSL:10m;
ssl_session_timeout 1440m;
ssl_session_tickets off;

ssl_protocols TLSv1.2 TLSv1.3;
ssl_prefer_server_ciphers off;

ssl_ciphers "EC-AES128-SHA";

#———————————————————————————————————————— default

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

    root /var/www/html;

    # Add index.php to the list if you are using PHP
    index index.html index.htm index.nginx-debian.html;

    server_name _;

    location / {
        # First attempt to serve request as file, then
        # as directory, then fall back to displaying a 404.
        try_files $uri $uri/ =404;
    }

}

#———————————————————————————————————————— svija.love

server {

    server_name svija.love;

    # directory of site's static elements
    location /static/ {
        root /home/svijalove;
    }

    access_log /opt/logs/access.svijalove;
    error_log /opt/logs/error.svijalove error;

    # pass all additional queries to our application
    location / {

        # parameters from /etc/nginx/uwsgi_params
        include uwsgi_params;

        # pass the traffic to the socket
        # that the uWSGI server sets up
        # SOCKETS MUST MATCH IN:
        # /etc/uwsgi/sites/svijalove.ini
        uwsgi_pass unix:/run/uwsgi/svijalove.sock;
    }

    listen 443 ssl; # managed by Certbot
    ssl_certificate /etc/letsencrypt/live/svija.love/fullchain.pem; # managed by Certbot
    ssl_certificate_key /etc/letsencrypt/live/svija.love/privkey.pem; # managed by Certbot
    include /etc/letsencrypt/options-ssl-nginx.conf; # managed by Certbot
    ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem; # managed by Certbot
}

server {
    if ($host = svija.love) {
        return 301 https://$host$request_uri;
    } # managed by Certbot

    server_name svija.love;
    listen 80;
    return 404; # managed by Certbot
}

# 6 other sites at end, all configured the same way
# except that in the last two lines,
# listen 80; is sometimes listed BEFORE return 404;
in flag
FYI: When I query `http://svija.love` I get a redirect to `https://svija.love/` which results in a 500. Afterwards wget retries the second requests and receives a 200. I don't get a 404. For the 500 you need to check your server logs.
br flag
How did you do the query? I realize that I misstated the problem — it's not a 404 that I get (in my browser) but the NginX default page (I fixed the question). I don't see the 500 error, but I'll check the log.
in flag
Just a simple `wget -S http://svija.love`
br flag
I removed the NginX default configuration, and now it redirects correctly. I expect it was because it was interpreting the default config before arriving at the svija.love config.
us flag
Please add full nginx configuration that is given by `nginx -T` command.
us flag
My only guess is that the `if` block before `server_name` somehow disturbs nginx. Usually I start the `server` block with `listen`, `server_name` on top for readability, and then other directives.
us flag
Another option for debugging this is to enable nginx debug logs by using `error_log /opt/logs/error.antretoise debug;` Depending on distribution, nginx might be needed to be started with a different command. With the debug log, one can see how exactly nginx handles the request internally.
br flag
I spent a couple of hours looking at the logs, and tried various modifications of the config files, without success. In the end it started working with the original configuration (see answer I posted) — possibly some sort of DNS caching problem. Thanks for your suggestions they gave me the courage to keep trying and ideas for what to try.
Score:2
us flag

If there is no matching virtual host for the Host header in the request, then nginx will serve the default virtual host content.

In your case, your virtual host matches the Host field with svija.love. However, it seems you were testing with live.svija.love.

Since nginx cannot find the matching virtual host, it uses its default one.

After you deleted the default virtual host configuration, nginx uses your virtual host as the default virtual host. That is not a good practice. Anyone could set up a DNS record for a domain that points to your website. The end result would be that http://example.com would show contents of http://live.svija.love.

That could result in Google penalties for duplicate content.

To prevent this, you should restore the default virtual host, and adjust your current configuration for correct server_name.

br flag
I was not testing with live.svija.love — that's the name of the server (/etc/hosts), but I never tried to visit the server at that address. I'll put back the default setting as you suggest, and see if I can get it to work based on your answer.
br flag
Now when I visit svija.love, I again get the NginX default page. What I don't understand is why svija.love doesn't match "if ($host = svija.love) {" in the configuration.
br flag
I added the full nginx configuration to the question.
Score:0
br flag

I have solved the problem without really understanding it.

There are seven websites on my server, and six function correctly (http redirects to https as expected.)

All seven sites contain a block at the end of their NginX config files resembling this:

server {

# redirects traffic from http to https for each relevant domain

    if ($host = svija.love) {
        return 301 https://$host$request_uri;
    } # managed by Certbot

# ensures that any caught requests are not inadvertently redirected

    listen 80;
    server_name svija.love;
    return 404; # managed by Certbot
}

The actual server host is live.svija.love, but the website that had issues is simply svija.love (there's no website configured for live.svija.love).

It became obvious that the problem was caused by the following line not being evaluated correctly:

if ($host = svija.love) {

Parenthetically, there was no IPv6 configuration for the server (live.svija.love), and there was an IPv6 configuration for the website (svija.love), which should not have existed.

I added the IPv6 record for the server, and deleted it for the website.
This did not affect the problem.

Then I thought that perhaps the $host variable was set to live.svija.love (who knows why), so I tried a test where I changed

if ($host = svija.love) {

to

if ($host = live.svija.love) {

As expected, the NginX default page was replaced by a 404 error (see the configuration block above).

So, I put back

if ($host = live.svija.love) {

and everything now works correctly. HTTP requests to svija.love are redirected to https://svija.love and my problem is solved.

I assume that there was some sort of DNS caching mechanism in NginX that was failing, possibly have been because I changed the name of the server at some point in the past.

mangohost

Post an answer

Most people don’t grasp that asking a lot of questions unlocks learning and improves interpersonal bonding. In Alison’s studies, for example, though people could accurately recall how many questions had been asked in their conversations, they didn’t intuit the link between questions and liking. Across four studies, in which participants were engaged in conversations themselves or read transcripts of others’ conversations, people tended not to realize that question asking would influence—or had influenced—the level of amity between the conversationalists.