Sammaye
Sammaye

Reputation: 43884

Redirect dynamic top level domains to www subdomains with Nginx

I am trying to get it so that any non-subdomained top level URL within my Nginx gets rewritten to a subdomain of www.

I cannot do the normal trick of using a normal server name since I have about 20 top level domains pointing to this server. Yes I could write a function out for each one, though I can feel my soul start to fade by just saying it.

I cannot create blanket rules since I use the subdomains of these top level domains in other configurations within the Nginx server.

So essentially I need to pickout example.com/example.co.uk/example.eu/example.ly all the same and redirect them to their www subdomain while ensuring I only pick them if they are not subdomains.

I go thus far:

    server {
            listen 80 default_server;
            listen [::]:80 default_server;
            server_name ~^([^\.].*)\.(com|co.uk|eu|ly)$;
            rewrite ^/(.*)$ $scheme://www.$host$request_uri permanent;
    }

However, it keeps adding the www twice, making the URL www.www.example.com and I have no clue why.

Can someone tell me what's going on?

Upvotes: 1

Views: 1702

Answers (2)

Sammaye
Sammaye

Reputation: 43884

As an advancement on the accepted I changed my config to be more like:

server {
    server_name ~^www\.[^.]+\.(com|co.uk|eu|ly)$;
    return 444;
}


server {
    listen 80 default_server;
    listen [::]:80 default_server;
    server_name ~^[^.]+\.(com|co.uk|eu|ly)$;
    rewrite ^/(.*)$ $scheme://www.$host$request_uri permanent;
}

So now when the latter sever redirects it will instantly be picked up by the prior server but the first server will not pickup what the second should.

I have tested this a couple of times and it seems to work well.

Upvotes: 0

Xavier Lucas
Xavier Lucas

Reputation: 2642

As discussed, either you declare your subdomains server blocks and make sure if you are using a regex too that it's preceding the server block redirecting to www (regex are tested sequentially), or you refine your regex so it would be ^[^.]+\.(com|co.uk|eu|ly)$.

Edit : As you are only letting one server block in your configuration, everything will go throw this unique server block anyway, so you need at least to add :

server {
    listen 80 default_server;
    listen [::]:80 default_server;
    return 444;
}

So headers not matching the regex will fallback into this default server block and connections will be closed by nginx. Then add your subdomain server blocks back.

Upvotes: 1

Related Questions