nginxproxysubdomain

Nginx proxy all subdomains


I currently proxy a website on my.domain:6799 to remote.com but that domain also uses subdomains like img.remote.com or video.remote.com.

It it possible to add some kind of rule that proxys the subdomain without repeating the whole server block for every subdomain?

In my head it would look like server_name *.my.domain; with proxy_pass https://*.remote.com/; and proxy_set_header Host *.remote.com;.

Does something like that exist?

server {
    listen 6799 default_server ssl http2;
    server_name my.domain;

    # SSL Configuration
    ssl_certificate /home/nginxproxymanager/letsencrypt/live/npm-4/fullchain.pem;
    ssl_certificate_key /home/nginxproxymanager/letsencrypt/live/npm-4/privkey.pem;
    ssl_protocols TLSv1.2 TLSv1.3;

    location / {
        proxy_pass https://remote.com/;
        proxy_ssl_server_name on;
        proxy_ssl_session_reuse off;
        proxy_redirect off;
        #proxy_set_header Host $host;
        #proxy_set_header X-Forwarded-Proto $scheme;
        proxy_hide_header "Cache-Control";
        add_header Cache-Control "no-store, no-cache, must-revalidate, post-check=0, pre-check=0";
        proxy_hide_header "Pragma";
        add_header Pragma "no-cache";
        expires -1;
        add_header Last-Modified $sent_http_Expires;
        proxy_set_header Host remote.com;
        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;
    }
}

Solution

  • You can use regular expressions for that purpose. Try this (you'd need a resolver being defined when you use variables for the upstream definition):

    server {
        server_name ~^(?<subdomain>.+\.)?my\.domain$;
        ...
        resolver 8.8.8.8; # or any other working DNS
        location / {
            proxy_ssl_server_name on;
            proxy_ssl_name ${subdomain}remote.com;
            proxy_pass https://${subdomain}remote.com;
            proxy_set_header Host ${subdomain}remote.com;
            ...
        }
    }
    

    Update

    While debugging the above configuration, I found that both

    proxy_ssl_name ${subdomain}remote.com;
    

    and

    proxy_set_header Host ${subdomain}remote.com;
    

    directives can be omitted. Their default value is the $proxy_host internal nginx variable, which is correctly evaluated from the proxy_pass directive's upstream definition, even when variables are used to define it.

    Therefore, the above configuration can be simplified as follows:

    server {
        server_name ~^(?<subdomain>.+\.)?my\.domain$;
        ...
        resolver 8.8.8.8; # or any other working DNS
        location / {
            proxy_ssl_server_name on;
            proxy_pass https://${subdomain}remote.com;
            ...
        }
    }