0

There are a lot of questions on ServerFault that cover parts of this question, but I'm having a hard time piecing them together. I have a fresh nginx server with a Wildcard SSL cert installed. All that works fine. I'd like to create redirect rules that enforce the following:

1) There must be either www or a subdomain enforced. So, subdomain.domain.com and www.domain.com is fine. domain.com by itself is not, and should automatically add the www.

2) HTTPS must be enforced throughout the site, regardless of subdomain.

In other words:

ttp://domain.com >> ttps://www.domain.com

ttp://subdomain.domain.com >> ttps://subdomain.domain.com

ttps://domain.com >> ttps://www.domain.com

ttps://subdomain.domain.com (this is fine)

Per the Nginx rewrite pitfalls page and other answers on this site, I've been using this config code:

server {
  listen 80;
  server_name *.domain.com;
  return 301 https://$server_name$request_uri;
}

as well as this:

server {
  listen 80;
  server_name ~^(.*)domain\.com;
  return 301 https://$server_name$request_uri;
}

I've also tried using $host instead of $server_name.

All of this redirects the http > https just fine, but it always defaults to https://domain.com, regardless of subdomain or www. Thoughts?

John D.
  • 11
  • 3

2 Answers2

1

I found the answer after spending a few more hours on it this morning. You need two additional server blocks: one to enforce the www, one to enforce the https while keeping the wildcard subdomain. Here's the code:

server {
    listen 80;
    listen 443;
    server_name domain.com;
    return 301 https://www.domain.com$request_uri;
}

server {
    listen 80;
    server_name ~^(?<subdomain>.+)\.domain\.com$;
    return 301 https://$subdomain.domain.com$request_uri;
}

server {
    listen 443 default_server;
    listen [::]:433 default_server ipv6only=on;

... the rest of your HTTPS server configuration goes here ...

The first block looks for no-www, regardless of whether or not it's HTTP or HTTPS. This redirects to www.domain.com, easy enough. The second block uses regex to put the subdomain in a variable, then return to that same subdomain + domain, just with https. After that, the third block can contain the usual server config.

Hope it helps!

John D.
  • 11
  • 3
0

It looks to me like you're explicity forwarding it to domain.com. Have you tried adding www between the https:// and the $server_name? That's what I do, and I have a tutorial on this kind of thing. The sample config files may be of some use.

server {
  listen 80;
  server_name *.domain.com;
  return 301 https://www.$server_name$request_uri;
}

Report back how that works, we can tweak it as required.

Tim
  • 31,888
  • 7
  • 52
  • 78
  • So, I have tried that, but that doesn't solve my problem. One of the requirements I have is that the redirect rules need to maintain wildcard subdomains. Explicitly adding the www on the 301 return does enforce the www, at the expense of any other subdomain. In other words, I need both of these redirects: ttp://domain.com >> ttps://www.domain.com ttp://subdomain.domain.com >> ttps://subdomain.domain.com – John D. Jul 22 '16 at 15:55
  • That wasn't meant to solve every problem, just the main domain. Does it work for that? If it does I can think about the subdomains. It'll involve regular expression capture groups, which I can work out with enough time, but I'm not great at it. – Tim Jul 22 '16 at 20:45