26

I've got a wildcard ssl certification and I'm trying to redirect all non-ssl traffic to ssl. Currently I'm using the following for redirection the non-subdomainded url which is working fine.

server {
listen      80;
server_name mydomain.com;

#Rewrite all nonssl requests to ssl.
rewrite     ^ https://$server_name$request_uri? permanent;
}

when I do the same thing for *.mydomain.com it logically redirects to

https://%2A.mydomain.com/

How do you redirect all subdomains to their https equivalent?

1
  • 2
    Instead of $server_name, why not $host?
    – cjc
    Nov 9, 2012 at 22:18

3 Answers 3

61

That's all...

server {
    listen      80;
    server_name *.mydomain.com;

     #Rewrite all nonssl requests to ssl.
     return 301 https://$host$request_uri;
}
5
  • 3
    A bit more explanation might make this a better answer.
    – Dave M
    Jun 25, 2013 at 15:24
  • 3
    @dave-m, that there needs to be explained? $host variable? $request_uri?
    – cadmi
    Jun 29, 2013 at 10:46
  • It doesn't work, still got https://%2A.handy.travel/
    – Damon Yuan
    Jan 9, 2018 at 8:21
  • I can confirm that this solution works
    – lhermann
    Feb 14, 2021 at 17:18
  • @DamonYuan This might be a bit late, but just in case someone else comes across this, you can't visit a website "*.handy.travel". The wildcard character will forward everything on that subdomain, but that isn't a website itself. You've either typed the wildcard character in a browser/cURL, or you've mistakenly put it on line 6 (of the answer). Aug 12, 2021 at 5:35
3

The NGINX official documentation encourages to use the return directive instead of using rewrite directive for effecting redirection. This is so, as the request being rewritten is not meant for that server, but it still gets processed in that server block. So redirects are correctly done with a return directive instead, as all processing is stopped and a response is sent immediately. NGINX discourages rewrite for redirection here: http://nginx.org/en/docs/http/converting_rewrite_rules.html

The syntax for return directive is: return code URL; As you were originally doing a permanent rewrite, so accordingly you can use 301 as the code to respond with, indicating it is a permanent redirect. Your https address will be passed in the url section. Reference: http://nginx.org/en/docs/http/ngx_http_rewrite_module.html#return

So your correct configuration would be

server {
listen      80;
server_name *.mydomain.com;

#Redirect all nonssl requests to ssl.
return 301 https://$server_name$request_uri;
}

This would probably let you redirect correctly to your ssl domain, with a wildcard server block. You can also try the underscore generic server name '_' or $host as suggested in the comment above. Let us know!

5
  • 1
    While using return is generally better, suggested configuration isn't correct as it still uses $server_name for redirection, which will be "*.mydomain.com". Correct fix was already outlined by @cjc in the comment above - $host should be used instead of $server_name. Nov 12, 2012 at 9:24
  • Yes agreed. Ah seems my attention spans are a fadin'! Nov 12, 2012 at 9:48
  • In lieu of the detraction above, allow me to offer you a tip with your ssl configuration which should significantly improve performance. The most efficient way to set up SSL if you are using wildcard certificate is to set up 'ssl stapling' This allows you to set up SSL once on your default server for all sub domains, and saves separate ssl authentication for each sub domain. ssl_stapling on; resolver 8.8.8.8; ssl_stapling_file /ssl_keys/example.com_staple; ssl_stapling_verify on; Refference- calomel.org/nginx.html Nov 12, 2012 at 10:11
  • 3
    Should be return 301 https://$host$request_uri;
    – scarver2
    Jan 14, 2015 at 14:56
  • I'm listening for ports 80, 8080 AND 8181 return 301 https://$server_name$request_uri; to get them to use https on port 443. The problem is that the redirected url still has the original port number. 80 isn't a problem, but 8080 comes out as https://example.com:8080
    – A.Grandt
    Jun 4, 2016 at 13:58
-1

Try something like this:

server {
  listen 80;
  server_name ~^(.*)\.mydomain\.com$;
  set $servername $1;
  rewrite ^(.*)$ https://$servername.mydomain.com/$1;
}

The catch is to define wildcard server and do redirects based on its name.

1
  • Overly permissive regex group.
    – Kzqai
    Apr 5, 2017 at 21:25

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .