Search code examples
http-redirectsslnginxproxypass

Nginx proxy_pass redirecting to wrong domain


I have three different proxy_pass in my nginx configuration. Two of them are redirecting to an https host and the last one through standard port 80.

The two first ones (example.com and proxmox.example.com) are working properly.

But the problem is about the third one. http://blog.example.com redirects to https://example.com and I can't understand why.

If someone has an idea... I am new to nginx and I still have difficulties to understand proxy_pass with or without SSL.

Here is my configuration.

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

server {
    listen 80;
    server_name example.com proxmox.example.com;
    rewrite ^(.*) https://$host$1 permanent;
}

server {
    listen 443;
    server_name example.com;
    ssl on;
    ssl_certificate /etc/nginx/ssl/server.crt;
    ssl_certificate_key /etc/nginx/ssl/server.key;
    proxy_redirect off;
    location / {
        proxy_pass https://localhost:8000;

        proxy_set_header    Host              $host;
        proxy_set_header    X-Real-IP         $remote_addr;
        proxy_set_header    X-Forwarded-For   $proxy_add_x_forwarded_for;
        proxy_set_header    X-Forwarded-Proto $scheme;
    }
}
server {
    listen 443;
    server_name proxmox.example.com;
    ssl on;
    ssl_certificate /etc/nginx/ssl/server.crt;
    ssl_certificate_key /etc/nginx/ssl/server.key;
    proxy_redirect off;
    location / {
        proxy_pass https://localhost:8006;

        proxy_set_header    Host              $host;
        proxy_set_header    X-Real-IP         $remote_addr;
        proxy_set_header    X-Forwarded-For   $proxy_add_x_forwarded_for;
        proxy_set_header    X-Forwarded-Proto $scheme;

        proxy_http_version 1.1;
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection "upgrade";
    }
}

server {
    listen 80;
    server_name blog.example.com;
    proxy_redirect off;
    location / {
        proxy_pass http://10.0.0.3:80;

        proxy_set_header    Host              $host;
        proxy_set_header    X-Real-IP         $remote_addr;
        proxy_set_header    X-Forwarded-For   $proxy_add_x_forwarded_for;
        proxy_set_header    X-Forwarded-Proto $scheme;
    }
}

Thanks

EDIT

I have read this on Nginx doc. It is maybe the cause of the problem.

With this configuration a browser receives the default server’s certificate, i.e. www.example.com regardless of the requested server name. This is caused by SSL protocol behaviour. The SSL connection is established before the browser sends an HTTP request and nginx does not know the name of the requested server. Therefore, it may only offer the default server’s certificate.

Link: see in Name-based HTTPS servers


Solution

  • Finally, it is was because my certificate was only for example.com and not for *.example.com. So it was not matching subdomain and I was redirected to the first available SSL config (which was example.com). So I have added a subjectAltName to my certificate to allow *.example.com.

    Then I also changed the definition of my certificate declaration directly into html section of Nginx config for a caching purpose. Here is my final configuration:

    # Certificates
    ssl_certificate /etc/nginx/ssl/server.crt;
    ssl_certificate_key /etc/nginx/ssl/server.key;
    
    # Return 404 if no server name matches
    server {
        listen 80 default_server;
        server_name _;
        return 404;
    }
    
    # Redirect chosen domain to https
    server {
        listen 80;
        server_name example.com proxmox.example.com;
        rewrite ^(.*) https://$host$1 permanent;
    }
    
    # Main configuration
    server {
        listen 443;
        server_name example.com;
        ssl on;
        proxy_redirect off;
        location / {
            proxy_pass https://localhost:8000;
    
            proxy_set_header    Host              $host;
            proxy_set_header    X-Real-IP         $remote_addr;
            proxy_set_header    X-Forwarded-For   $proxy_add_x_forwarded_for;
            proxy_set_header    X-Forwarded-Proto $scheme;
        }
    }
    
    # Proxmox configuration
    server {
        listen 443;
        server_name proxmox.example.com;
        ssl on;
        proxy_redirect off;
        location / {
            proxy_pass https://localhost:8006;
    
            proxy_set_header    Host              $host;
            proxy_set_header    X-Real-IP         $remote_addr;
            proxy_set_header    X-Forwarded-For   $proxy_add_x_forwarded_for;
            proxy_set_header    X-Forwarded-Proto $scheme;
    
            proxy_http_version 1.1;
            proxy_set_header Upgrade $http_upgrade;
            proxy_set_header Connection "upgrade";
        }
    }