Score:1

NGINX: localhost redirecting to _

in flag

nginx version/1.18.0 (Ubuntu) — Ubuntu 22.04.01 LTS x86_64 kernel 6.0.8


I've got a server (install specs above) that has multiple host names, is running nginx, and everything is working (including nginx, with redirects from http: to https:).

In fact, here's how I'm doing that in my default server:

listen 80 default_server;

listen 443 default_server ssl;
# force https-redirects
if ($scheme = http) {
  return 301 https://$host$request_uri;
}

server_name _;

Here's the strange behavior:

URL Redirects to Notes
http://mumblefrotz/ https://mumblefrotz/ (works as expected)
http://mumblefrotz.fullyqualified.com/ https://mumblefrotz.fullyqualified.com/ (works as expected)
http://127.0.0.1/ https://127.0.0.1/ (works as expected)
http://localhost/ https://_ FAILURE

Why's it doing this? I suspect it has something to do with the server_name directive being taken literally, though am not quite certain why it only happens for localhost.

In looking at this Stack Overflow suggestion, I attempted both of the following and still got the surprising underscore:

  • server_name ~.;
  • server_name ~^(.+)$;

My expectation is that $host is the host name passed in the HTTP request, with a virtual host picking it up if one has been defined and falling back to the default server definition if not.

From what I can tell http://localhost/ is the only one that doesn't resolve properly. I'd like to fix that.

in flag
Do you have for some reason added `_` to the hosts file on your server?
Score:1
us flag

There was no information on the question what client was used to make the request. As written in nginx documentation, $host variable contains:

in this order of precedence: host name from the request line, or host name from the “Host” request header field, or the server name matching a request

Here, "request line" means the hostname after GET verb in HTTP request.

Second one means the Host header field.

Third one means the name configured in server_name.

In your case, I think the test client did a request that did not contain Host header. Therefore nginx used the server_name configuration for the content of $host variable.

Personally I just generate the HTTP -> HTTPS forward block for every virtual server, since I manage nginx configurations with Ansible. That way I can have a return 404 vhost for all other host names I am not interested in.

But if you need to implement a common vhost for the redirects, you can use following approach:

map $http_host $redirect_host {
    ~ (^.+$) $http_host;
    default  example.com;
}

server {
    listen 80 default_server;
    ...

    if ($scheme = http) {
        return 301 https://$redirect_host$request_uri;
    }
}

This always uses the HTTP host header for redirect target, except when there is no Host header. In that case it uses example.com for the redirect target. You can assign your main domain name as the redirect target for example.

I sit in a Tesla and translated this thread with Ai:

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.