job.answiz.com
  • 4
Votes
name
name Punditsdkoslkdosdkoskdo

How can force or redirect/ to SSL in nginx?

I have a signup page on a subdomain like: https://signup.example.com

It should only be accessible via HTTPS but I'm worried people might somehow stumble upon it via HTTP and get a 404.

My html/server block in nginx looks like this:

html {
  server {
    listen 443;
    server_name signup.example.com;

    ssl                        on;
    ssl_certificate        /path/to/my/cert;
    ssl_certificate_key  /path/to/my/key;

    ssl_session_timeout 30m;

    location / {
      root /path/to/my/rails/app/public;
      index index.html;
        passenger_enabled on;
    }
  }
}

What can I add so that people who go to http://signup.example.com get redirected to https://signup.example.com ? (FYI I know there are Rails plugins that can force SSL but was hoping to avoid that)

 

This is the correct and most efficient way if you want to keep it all in one server block:

server {
    listen   80;
    listen   [::]:80;
    listen   443 default_server ssl;

    server_name www.example.com;

    ssl_certificate        /path/to/my/cert;
    ssl_certificate_key  /path/to/my/key;

    if ($scheme = http) {
        return 301 https://$server_name$request_uri;
    }
}

Everything else above, using "rewrite" or "if ssl_protocol" etc is slower and worse.

Here is the same, but even more efficient, by only running the rewrite on the http protocol it avoids having to check the $scheme variable on every request. But seriously, it's such a minor thing that you don't need to separate them.

server {
    listen   80;
    listen   [::]:80;

    server_name www.example.com;

    return 301 https://$server_name$request_uri;
}
server {
    listen   443 default_server ssl;

    server_name www.example.com;

    ssl_certificate        /path/to/my/cert;
    ssl_certificate_key  /path/to/my/key;
}
  • 1
Reply Report

According to nginx pitfalls, it's slightly better to omit the unnecessary capture, using $request_uriinstead. In that case, append a question mark to prevent nginx from doubling any query args.

server {
    listen      80;
    server_name signup.mysite.com;
    rewrite     ^   https://$server_name$request_uri? permanent;
}
  • 0
Reply Report