I already have a working configuration to redirect all non-existent subdomains to a specific domain. Now I want to add a configuration that redirects all HTTP requests to HTTPS on the same domain.

This config file does the subdomain redirects:

# redirect any non-existent subdomain (blah.domain.de -> domain.de)
server {
    listen 80 default_server;
    listen [::]:80 default_server;
    server_name _;
    return 301 https://domain.de$request_uri;

And this is the config I try to use for HTTP->HTTPS:

# redirect any HTTP request to its HTTPS address (http://domain.de/blub -> https://domain.de/blub)
server {
    listen 80 default_server;
    listen [::]:80 default_server;
    server_name domain.de mail.domain.de admin.domain.de;
    return 301 https://$server_name$request_uri;

But this doesn't work because the default_server is defined twice. How can combine these two functions?

Do I really have to add the second config to every single subdomain config?


You need to remove default_server from the latter configuration and add every domain name to the server_name part.

Then you need to use return 301 https://$host$request_uri; for the redirect statement.

  • This doesn't work. I get redirected from "mail.domain.de" to "domain.de". – Michael Sep 13 '16 at 13:23
  • True, didn't notice that. Using $host instead of $server_name like in my fixed answer should make it work. – Tero Kilkanen Sep 13 '16 at 15:19
  • Tero's edited answer and above comment provide the best way to do it. An if-condition isn't a good approach to handle this in Nginx. – Jens Bradler Sep 14 '16 at 11:09

Nginx does not support nested if statements (it also doesn't support complex conditions).

  • How should this work? This default config only works for non-existent domains. So if someone requests "mail.osor.de" it will not work. Also return statement stops processing - rewrite will never be reached. – Michael Sep 13 '16 at 13:38
  • My bad, I haven't had my coffee yet. In this case, I am not aware of a way to do what you are asking. – user5870571 Sep 13 '16 at 13:40

I got it working in another way. I added it to every subdomains config via a SSL snippet. Every subdomain config includes the same SSL config. So I added to this config a http check:

if ($scheme = http ){
    rewrite ^ https://$server_name$request_uri permanent;
# ... followed by ssl config

And this is included in every subdomain server block config:

include snippets/ssl.conf;

It does what I want. Maybe there is another way without including it to every subdomain.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.